From f58e882b7594c59b6050d3c87562fcf836d10f60 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2015 10:58:26 +0200 Subject: QLockFile: fix deadlock when the lock file is corrupted [ChangeLog][QtCore][QLockFile] Fixed a deadlock when the lock file is corrupted. Task-number: QTBUG-44771 Change-Id: Ic490b09d70ff1cc1733b64949889a73720b2d0f3 Reviewed-by: David Faure --- src/corelib/io/qlockfile_unix.cpp | 10 +++++----- src/corelib/io/qlockfile_win.cpp | 22 +++++++++++----------- tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index bf1015a7be..dc9f8f73c4 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -181,11 +181,11 @@ bool QLockFilePrivate::isApparentlyStale() const { qint64 pid; QString hostname, appname; - if (!getLockInfo(&pid, &hostname, &appname)) - return false; - if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { - if (::kill(pid, 0) == -1 && errno == ESRCH) - return true; // PID doesn't exist anymore + if (getLockInfo(&pid, &hostname, &appname)) { + if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { + if (::kill(pid, 0) == -1 && errno == ESRCH) + return true; // PID doesn't exist anymore + } } const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); return staleLockTime > 0 && age > staleLockTime; diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index f9f29090d7..3587c7bffe 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -115,21 +115,21 @@ bool QLockFilePrivate::isApparentlyStale() const { qint64 pid; QString hostname, appname; - if (!getLockInfo(&pid, &hostname, &appname)) - return false; // On WinRT there seems to be no way of obtaining information about other // processes due to sandboxing #ifndef Q_OS_WINRT - if (hostname == QString::fromLocal8Bit(localHostName())) { - HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); - if (!procHandle) - return true; - // We got a handle but check if process is still alive - DWORD dwR = ::WaitForSingleObject(procHandle, 0); - ::CloseHandle(procHandle); - if (dwR == WAIT_TIMEOUT) - return true; + if (getLockInfo(&pid, &hostname, &appname)) { + if (hostname == QString::fromLocal8Bit(localHostName())) { + HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); + if (!procHandle) + return true; + // We got a handle but check if process is still alive + DWORD dwR = ::WaitForSingleObject(procHandle, 0); + ::CloseHandle(procHandle); + if (dwR == WAIT_TIMEOUT) + return true; + } } #endif // !Q_OS_WINRT const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp index 77bef94550..12bea6769c 100644 --- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp +++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp @@ -58,6 +58,7 @@ private slots: void staleLongLockFromBusyProcess(); void staleLockRace(); void noPermissions(); + void corruptedLockFile(); public: QString m_helperApp; @@ -415,5 +416,21 @@ void tst_QLockFile::noPermissions() QCOMPARE(int(lockFile.error()), int(QLockFile::PermissionError)); } +void tst_QLockFile::corruptedLockFile() +{ + const QString fileName = dir.path() + "/corruptedLockFile"; + + { + // Create a empty file. Typically the result of a computer crash or hard disk full. + QFile file(fileName); + QVERIFY(file.open(QFile::WriteOnly)); + } + + QLockFile secondLock(fileName); + secondLock.setStaleLockTime(100); + QVERIFY(secondLock.tryLock(10000)); + QCOMPARE(int(secondLock.error()), int(QLockFile::NoError)); +} + QTEST_MAIN(tst_QLockFile) #include "tst_qlockfile.moc" -- cgit v1.2.3 From 0c28e1ab7a430d56702cb8545320356de3bda711 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 14 Jan 2015 19:27:22 +0300 Subject: Fix finding the closest active touch point for the pressed touch point Currently pressed touch point is added to the list of active touch points in Gui module. It must be excluded from consideration when we traverse the list. Task-number: QTBUG-43255 Change-Id: Idddab093b1f6a79122cf18fad7f43bfc93ce7eea Reviewed-by: Shawn Rutledge Reviewed-by: Marc Mutz --- src/widgets/kernel/qapplication.cpp | 7 +-- src/widgets/kernel/qapplication_p.h | 2 +- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 53 +++++++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index abd0231b00..ba14a06af4 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -4275,15 +4275,16 @@ void QApplicationPrivate::cleanupMultitouch_sys() { } -QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, const QPointF &screenPos) +QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, const QTouchEvent::TouchPoint &touchPoint) { + const QPointF screenPos = touchPoint.screenPos(); int closestTouchPointId = -1; QObject *closestTarget = 0; qreal closestDistance = qreal(0.); QHash::const_iterator it = activeTouchPoints.constBegin(), ite = activeTouchPoints.constEnd(); while (it != ite) { - if (it.key().device == device) { + if (it.key().device == device && it.key().touchPointId != touchPoint.id()) { const QTouchEvent::TouchPoint &touchPoint = it->touchPoint; qreal dx = screenPos.x() - touchPoint.screenPos().x(); qreal dy = screenPos.y() - touchPoint.screenPos().y(); @@ -4339,7 +4340,7 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window, } if (device->type() == QTouchDevice::TouchScreen) { - QWidget *closestWidget = d->findClosestTouchPointTarget(device, touchPoint.screenPos()); + QWidget *closestWidget = d->findClosestTouchPointTarget(device, touchPoint); QWidget *widget = static_cast(target.data()); if (closestWidget && (widget->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget))) { diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 7d97235c66..7f76d1ba97 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -280,7 +280,7 @@ public: void initializeMultitouch_sys(); void cleanupMultitouch(); void cleanupMultitouch_sys(); - QWidget *findClosestTouchPointTarget(QTouchDevice *device, const QPointF &screenPos); + QWidget *findClosestTouchPointTarget(QTouchDevice *device, const QTouchEvent::TouchPoint &touchPoint); void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint); void removeTouchPoint(int touchPointId); static bool translateRawTouchEvent(QWidget *widget, diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index ae6d62c332..717039d64e 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -435,6 +435,7 @@ private slots: void grabKeyboard(); void touchEventSynthesizedMouseEvent(); + void touchUpdateOnNewTouch(); void styleSheetPropagation(); @@ -9763,6 +9764,9 @@ class TouchMouseWidget : public QWidget { public: explicit TouchMouseWidget(QWidget *parent = 0) : QWidget(parent), + m_touchBeginCount(0), + m_touchUpdateCount(0), + m_touchEndCount(0), m_touchEventCount(0), m_acceptTouch(false), m_mouseEventCount(0), @@ -9789,6 +9793,12 @@ protected: case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: + if (e->type() == QEvent::TouchBegin) + ++m_touchBeginCount; + else if (e->type() == QEvent::TouchUpdate) + ++m_touchUpdateCount; + else if (e->type() == QEvent::TouchEnd) + ++m_touchEndCount; ++m_touchEventCount; if (m_acceptTouch) e->accept(); @@ -9813,6 +9823,9 @@ protected: } public: + int m_touchBeginCount; + int m_touchUpdateCount; + int m_touchEndCount; int m_touchEventCount; bool m_acceptTouch; int m_mouseEventCount; @@ -9933,6 +9946,46 @@ void tst_QWidget::touchEventSynthesizedMouseEvent() } } +void tst_QWidget::touchUpdateOnNewTouch() +{ + QTouchDevice *device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + + TouchMouseWidget widget; + widget.setAcceptTouch(true); + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(new QWidget); + widget.setLayout(layout); + widget.show(); + + QWindow* window = widget.windowHandle(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + QCOMPARE(widget.m_touchBeginCount, 0); + QCOMPARE(widget.m_touchUpdateCount, 0); + QCOMPARE(widget.m_touchEndCount, 0); + QTest::touchEvent(window, device).press(0, QPoint(20, 20), window); + QCOMPARE(widget.m_touchBeginCount, 1); + QCOMPARE(widget.m_touchUpdateCount, 0); + QCOMPARE(widget.m_touchEndCount, 0); + QTest::touchEvent(window, device).move(0, QPoint(25, 25), window); + QCOMPARE(widget.m_touchBeginCount, 1); + QCOMPARE(widget.m_touchUpdateCount, 1); + QCOMPARE(widget.m_touchEndCount, 0); + QTest::touchEvent(window, device).stationary(0).press(1, QPoint(40, 40), window); + QCOMPARE(widget.m_touchBeginCount, 1); + QCOMPARE(widget.m_touchUpdateCount, 2); + QCOMPARE(widget.m_touchEndCount, 0); + QTest::touchEvent(window, device).stationary(1).release(0, QPoint(25, 25), window); + QCOMPARE(widget.m_touchBeginCount, 1); + QCOMPARE(widget.m_touchUpdateCount, 3); + QCOMPARE(widget.m_touchEndCount, 0); + QTest::touchEvent(window, device).release(1, QPoint(40, 40), window); + QCOMPARE(widget.m_touchBeginCount, 1); + QCOMPARE(widget.m_touchUpdateCount, 3); + QCOMPARE(widget.m_touchEndCount, 1); +} + void tst_QWidget::styleSheetPropagation() { QTableView tw; -- cgit v1.2.3 From 6cea45cc24ff1e29ded753656b2830f0fae06742 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 15 Apr 2015 14:34:35 +0200 Subject: Doc: fix description of QWindowsPipeReader::read Change-Id: Ib34fc77cc05125cf698e255a5d80dbf83cf4575e Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index e932fc0c02..c3159ca367 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -119,7 +119,7 @@ qint64 QWindowsPipeReader::bytesAvailable() const } /*! - Stops the asynchronous read sequence. + Copies at most \c{maxlen} bytes from the internal read buffer to \c{data}. */ qint64 QWindowsPipeReader::read(char *data, qint64 maxlen) { -- cgit v1.2.3 From 5fc52ba6e2a5425ea8edcef8aad80d9d20f47f9c Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 16 Apr 2015 14:13:44 +0200 Subject: QWindowsPipeReader: zero OVERLAPPED struct before every ReadFile According to the documentation we should always pass a zeroed OVERLAPPED object to ReadFile. Change-Id: I3f822af46a2c38e029e02461f706c4fd91c00c50 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index c3159ca367..8b1ec83833 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -89,7 +89,6 @@ void QWindowsPipeReader::setHandle(HANDLE hPipeReadEnd) readBuffer.clear(); actualReadBufferSize = 0; handle = hPipeReadEnd; - ZeroMemory(&overlapped, sizeof(overlapped)); pipeBroken = false; readyReadEmitted = false; if (hPipeReadEnd != INVALID_HANDLE_VALUE) { @@ -206,6 +205,7 @@ void QWindowsPipeReader::startAsyncRead() char *ptr = readBuffer.reserve(bytesToRead); readSequenceStarted = true; + ZeroMemory(&overlapped, sizeof(overlapped)); if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) { // We get notified by the QWinOverlappedIoNotifier - even in the synchronous case. return; -- cgit v1.2.3 From bb8f62148052e1208b4fe00a3fc6f25fa74432ac Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 16 Apr 2015 13:46:45 +0200 Subject: remove emitReadyReadTimer from QWindowsPipeReader The zero timeout singleshot timer emitReadyReadTimer was used to emit the readyRead signal via the event loop in case of a synchronous read. In that particular case, ReadFile would return successfully, and the notified slot would not be called. Now, that we use an I/O completion port, the notified slot is always called, even in the synchronous case. The emitReadyReadTimer is not needed anymore. This is also supported by the fact that the timer is immediately stopped in notified() after it was started in completeAsyncRead(). Change-Id: I93bcde5f067bf89a1d49005a3fddda4c8c8c95fc Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 9 --------- src/corelib/io/qwindowspipereader_p.h | 2 -- 2 files changed, 11 deletions(-) diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index 8b1ec83833..64f21d5a92 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -36,7 +36,6 @@ #include #include #include -#include QT_BEGIN_NAMESPACE @@ -46,12 +45,9 @@ QWindowsPipeReader::QWindowsPipeReader(QObject *parent) readBufferMaxSize(0), actualReadBufferSize(0), readSequenceStarted(false), - emitReadyReadTimer(new QTimer(this)), pipeBroken(false), readyReadEmitted(false) { - emitReadyReadTimer->setSingleShot(true); - connect(emitReadyReadTimer, SIGNAL(timeout()), SIGNAL(readyRead())); dataReadNotifier = new QWinOverlappedIoNotifier(this); connect(dataReadNotifier, &QWinOverlappedIoNotifier::notified, this, &QWindowsPipeReader::notified); } @@ -146,8 +142,6 @@ qint64 QWindowsPipeReader::read(char *data, qint64 maxlen) } if (!pipeBroken) { - if (!actualReadBufferSize) - emitReadyReadTimer->stop(); if (!readSequenceStarted) startAsyncRead(); if (readSoFar == 0) @@ -177,7 +171,6 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode, return; } startAsyncRead(); - emitReadyReadTimer->stop(); readyReadEmitted = true; emit readyRead(); } @@ -266,8 +259,6 @@ bool QWindowsPipeReader::completeAsyncRead(DWORD bytesRead, DWORD errorCode) actualReadBufferSize += bytesRead; readBuffer.truncate(actualReadBufferSize); - if (!emitReadyReadTimer->isActive()) - emitReadyReadTimer->start(); return true; } diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h index ecc6974efa..6eead60fd5 100644 --- a/src/corelib/io/qwindowspipereader_p.h +++ b/src/corelib/io/qwindowspipereader_p.h @@ -47,7 +47,6 @@ #include #include -#include #include #include @@ -100,7 +99,6 @@ private: QRingBuffer readBuffer; int actualReadBufferSize; bool readSequenceStarted; - QTimer *emitReadyReadTimer; bool pipeBroken; bool readyReadEmitted; }; -- cgit v1.2.3 From a7f1c97d6096b7f9cc44df275b20d91cc75f7347 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 16 Apr 2015 16:18:45 +0200 Subject: inline QWindowsPipeReader::completeAsyncRead There's exactly one caller for this private method, and future code will be a bit simpler after moving the code to the calling site. Change-Id: Ibc65f91c770f9f29b317ceddb39a67d52106da33 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 54 +++++++++++++++-------------------- src/corelib/io/qwindowspipereader_p.h | 1 - 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index 64f21d5a92..cc407dbed9 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -165,11 +165,33 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode, { if (&overlapped != notifiedOverlapped) return; - if (!completeAsyncRead(numberOfBytesRead, errorCode)) { + + switch (errorCode) { + case ERROR_SUCCESS: + break; + case ERROR_MORE_DATA: + // This is not an error. We're connected to a message mode + // pipe and the message didn't fit into the pipe's system + // buffer. We will read the remaining data in the next call. + break; + case ERROR_BROKEN_PIPE: + case ERROR_PIPE_NOT_CONNECTED: pipeBroken = true; + break; + default: + emit winError(errorCode, QLatin1String("QWindowsPipeReader::completeAsyncRead")); + pipeBroken = true; + break; + } + + readSequenceStarted = false; + if (pipeBroken) { emit pipeClosed(); return; } + + actualReadBufferSize += numberOfBytesRead; + readBuffer.truncate(actualReadBufferSize); startAsyncRead(); readyReadEmitted = true; emit readyRead(); @@ -232,36 +254,6 @@ void QWindowsPipeReader::startAsyncRead() } } -/*! - \internal - Sets the correct size of the read buffer after a read operation. - Returns \c false, if an error occurred or the connection dropped. - */ -bool QWindowsPipeReader::completeAsyncRead(DWORD bytesRead, DWORD errorCode) -{ - readSequenceStarted = false; - - switch (errorCode) { - case ERROR_SUCCESS: - break; - case ERROR_MORE_DATA: - // This is not an error. We're connected to a message mode - // pipe and the message didn't fit into the pipe's system - // buffer. We will read the remaining data in the next call. - break; - case ERROR_BROKEN_PIPE: - case ERROR_PIPE_NOT_CONNECTED: - return false; - default: - emit winError(errorCode, QLatin1String("QWindowsPipeReader::completeAsyncRead")); - return false; - } - - actualReadBufferSize += bytesRead; - readBuffer.truncate(actualReadBufferSize); - return true; -} - /*! \internal Returns the number of available bytes in the pipe. diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h index 6eead60fd5..7651093b05 100644 --- a/src/corelib/io/qwindowspipereader_p.h +++ b/src/corelib/io/qwindowspipereader_p.h @@ -88,7 +88,6 @@ private Q_SLOTS: void notified(quint32 numberOfBytesRead, quint32 errorCode, OVERLAPPED *notifiedOverlapped); private: - bool completeAsyncRead(DWORD bytesRead, DWORD errorCode); DWORD checkPipeState(); private: -- cgit v1.2.3 From 5ce567c536fde6b7cb93657d14df404f3e270119 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 15 Apr 2015 15:37:24 +0200 Subject: let QWindowsPipeReader::stop() cancel the current I/O operation In rare cases the I/O operation was still running after the destructor was running, which then modified free'd memory and caused a malformed heap. To prevent this, we ensure that QWindowsPipeReader::stop() cancels a running I/O operation and sets the readSequenceStarted flag correctly. Also, we prevent the start of a new read operation after we called stop(). Change-Id: If8a28bdf23a39a0e88c1770a6f66e2b24ea426bb Task-number: QTBUG-45601 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwindowspipereader.cpp | 35 +++++++++++++++++++++++++---------- src/corelib/io/qwindowspipereader_p.h | 1 + 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp index cc407dbed9..4ed9674f36 100644 --- a/src/corelib/io/qwindowspipereader.cpp +++ b/src/corelib/io/qwindowspipereader.cpp @@ -44,6 +44,7 @@ QWindowsPipeReader::QWindowsPipeReader(QObject *parent) handle(INVALID_HANDLE_VALUE), readBufferMaxSize(0), actualReadBufferSize(0), + stopped(true), readSequenceStarted(false), pipeBroken(false), readyReadEmitted(false) @@ -69,12 +70,7 @@ static bool qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped) QWindowsPipeReader::~QWindowsPipeReader() { - if (readSequenceStarted) { - if (qt_cancelIo(handle, &overlapped)) - dataReadNotifier->waitForNotified(-1, &overlapped); - else - qErrnoWarning("QWindowsPipeReader: qt_cancelIo on handle %x failed.", handle); - } + stop(); } /*! @@ -87,6 +83,7 @@ void QWindowsPipeReader::setHandle(HANDLE hPipeReadEnd) handle = hPipeReadEnd; pipeBroken = false; readyReadEmitted = false; + stopped = false; if (hPipeReadEnd != INVALID_HANDLE_VALUE) { dataReadNotifier->setHandle(hPipeReadEnd); dataReadNotifier->setEnabled(true); @@ -95,13 +92,24 @@ void QWindowsPipeReader::setHandle(HANDLE hPipeReadEnd) /*! Stops the asynchronous read sequence. - This function assumes that the file already has been closed. - It does not cancel any I/O operation. + If the read sequence is running then the I/O operation is canceled. */ void QWindowsPipeReader::stop() { - dataReadNotifier->setEnabled(false); + stopped = true; + if (readSequenceStarted) { + if (qt_cancelIo(handle, &overlapped)) { + dataReadNotifier->waitForNotified(-1, &overlapped); + } else { + const DWORD dwError = GetLastError(); + if (dwError != ERROR_NOT_FOUND) { + qErrnoWarning(dwError, "QWindowsPipeReader: qt_cancelIo on handle %x failed.", + handle); + } + } + } readSequenceStarted = false; + dataReadNotifier->setEnabled(false); handle = INVALID_HANDLE_VALUE; } @@ -142,7 +150,7 @@ qint64 QWindowsPipeReader::read(char *data, qint64 maxlen) } if (!pipeBroken) { - if (!readSequenceStarted) + if (!readSequenceStarted && !stopped) startAsyncRead(); if (readSoFar == 0) return -2; // signal EWOULDBLOCK @@ -185,6 +193,13 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode, } readSequenceStarted = false; + + // After the reader was stopped, the only reason why this function can be called is the + // completion of a cancellation. No signals should be emitted, and no new read sequence should + // be started in this case. + if (stopped) + return; + if (pipeBroken) { emit pipeClosed(); return; diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h index 7651093b05..b0a23e1a51 100644 --- a/src/corelib/io/qwindowspipereader_p.h +++ b/src/corelib/io/qwindowspipereader_p.h @@ -97,6 +97,7 @@ private: qint64 readBufferMaxSize; QRingBuffer readBuffer; int actualReadBufferSize; + bool stopped; bool readSequenceStarted; bool pipeBroken; bool readyReadEmitted; -- cgit v1.2.3 From 50ce5a68301dee2fd00b7c6ccc615257a2353098 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 30 Mar 2015 14:07:22 +0200 Subject: Cocoa: Handle the event passed into the global monitor correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the global monitor was used it did not get the right position for the mouse event and as a result it caused context menus to appear and disappear instantly when right clicking over a non active window. This ensures that the events are sent correctly with the right position and button information. Task-number: QTBUG-45015 Change-Id: I9b17a725e656c716c4e22117b4513e64c357b266 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 2adea0f493..0f9c2c1c86 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -680,8 +680,10 @@ void QCocoaWindow::setVisible(bool visible) && [m_nsWindow isKindOfClass:[NSPanel class]]) { [(NSPanel *)m_nsWindow setWorksWhenModal:YES]; if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) { - monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDown handler:^(NSEvent *) { - QWindowSystemInterface::handleMouseEvent(window(), QPointF(-1, -1), QPointF(window()->framePosition() - QPointF(1, 1)), Qt::LeftButton); + monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDownMask|NSMouseMovedMask handler:^(NSEvent *e) { + QPointF localPoint = qt_mac_flipPoint([NSEvent mouseLocation]); + QWindowSystemInterface::handleMouseEvent(window(), window()->mapFromGlobal(localPoint.toPoint()), localPoint, + cocoaButton2QtButton([e buttonNumber])); }]; } } -- cgit v1.2.3 From cff39fba10ffc10ee4dcfdc66ff6528eb26462d3 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Fri, 10 Apr 2015 14:09:53 +0200 Subject: QNAM: Fix upload corruptions when server closes connection This patch fixes several upload corruptions if the server closes the connection while/before we send data into it. They happen inside multiple places in the HTTP layer and are explained in the comments. Corruptions are: * The upload byte device has an in-flight signal with pending upload data, if it gets reset (because server closes the connection) then the re-send of the request was sometimes taking this stale in-flight pending upload data. * Because some signals were DirectConnection and some were QueuedConnection, there was a chance that a direct signal overtakes a queued signal. The state machine then sent data down the socket which was buffered there (and sent later) although it did not match the current state of the state machine when it was actually sent. * A socket was seen as being able to have requests sent even though it was not encrypted yet. This relates to the previous corruption where data is stored inside the socket's buffer and then sent later. The included auto test produces all fixed corruptions, I detected no regressions via the other tests. This code also adds a bit of sanity checking to protect from possible further problems. [ChangeLog][QtNetwork] Fix HTTP(s) upload corruption when server closes connection Change-Id: I54c883925ec897050941498f139c4b523030432e Reviewed-by: Peter Hartmann --- src/corelib/io/qnoncontiguousbytedevice.cpp | 18 +++ src/corelib/io/qnoncontiguousbytedevice_p.h | 4 + .../access/qhttpnetworkconnectionchannel.cpp | 35 ++++- .../access/qhttpnetworkconnectionchannel_p.h | 2 + src/network/access/qhttpprotocolhandler.cpp | 7 + src/network/access/qhttpthreaddelegate_p.h | 36 ++++- src/network/access/qnetworkreplyhttpimpl.cpp | 25 ++- src/network/access/qnetworkreplyhttpimpl_p.h | 7 +- .../access/qnetworkreply/tst_qnetworkreply.cpp | 175 ++++++++++++++++++++- 9 files changed, 279 insertions(+), 30 deletions(-) diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp index 11510a8397..760ca3d933 100644 --- a/src/corelib/io/qnoncontiguousbytedevice.cpp +++ b/src/corelib/io/qnoncontiguousbytedevice.cpp @@ -236,6 +236,11 @@ qint64 QNonContiguousByteDeviceByteArrayImpl::size() return byteArray->size(); } +qint64 QNonContiguousByteDeviceByteArrayImpl::pos() +{ + return currentPosition; +} + QNonContiguousByteDeviceRingBufferImpl::QNonContiguousByteDeviceRingBufferImpl(QSharedPointer rb) : QNonContiguousByteDevice(), currentPosition(0) { @@ -273,6 +278,11 @@ bool QNonContiguousByteDeviceRingBufferImpl::atEnd() return currentPosition >= size(); } +qint64 QNonContiguousByteDeviceRingBufferImpl::pos() +{ + return currentPosition; +} + bool QNonContiguousByteDeviceRingBufferImpl::reset() { if (resetDisabled) @@ -406,6 +416,14 @@ qint64 QNonContiguousByteDeviceIoDeviceImpl::size() return device->size() - initialPosition; } +qint64 QNonContiguousByteDeviceIoDeviceImpl::pos() +{ + if (device->isSequential()) + return -1; + + return device->pos(); +} + QByteDeviceWrappingIoDevice::QByteDeviceWrappingIoDevice(QNonContiguousByteDevice *bd) : QIODevice((QObject*)0) { byteDevice = bd; diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h index c05ae11b0f..4d7b7b043e 100644 --- a/src/corelib/io/qnoncontiguousbytedevice_p.h +++ b/src/corelib/io/qnoncontiguousbytedevice_p.h @@ -61,6 +61,7 @@ public: virtual const char* readPointer(qint64 maximumLength, qint64 &len) = 0; virtual bool advanceReadPointer(qint64 amount) = 0; virtual bool atEnd() = 0; + virtual qint64 pos() { return -1; } virtual bool reset() = 0; void disableReset(); bool isResetDisabled() { return resetDisabled; } @@ -106,6 +107,7 @@ public: bool atEnd(); bool reset(); qint64 size(); + qint64 pos() Q_DECL_OVERRIDE; protected: QByteArray* byteArray; qint64 currentPosition; @@ -121,6 +123,7 @@ public: bool atEnd(); bool reset(); qint64 size(); + qint64 pos() Q_DECL_OVERRIDE; protected: QSharedPointer ringBuffer; qint64 currentPosition; @@ -138,6 +141,7 @@ public: bool atEnd(); bool reset(); qint64 size(); + qint64 pos() Q_DECL_OVERRIDE; protected: QIODevice* device; QByteArray* currentReadBuffer; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 9f63280bf8..49c6793b1f 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -106,15 +106,19 @@ void QHttpNetworkConnectionChannel::init() socket->setProxy(QNetworkProxy::NoProxy); #endif + // We want all signals (except the interactive ones) be connected as QueuedConnection + // because else we're falling into cases where we recurse back into the socket code + // and mess up the state. Always going to the event loop (and expecting that when reading/writing) + // is safer. QObject::connect(socket, SIGNAL(bytesWritten(qint64)), this, SLOT(_q_bytesWritten(qint64)), - Qt::DirectConnection); + Qt::QueuedConnection); QObject::connect(socket, SIGNAL(connected()), this, SLOT(_q_connected()), - Qt::DirectConnection); + Qt::QueuedConnection); QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(_q_readyRead()), - Qt::DirectConnection); + Qt::QueuedConnection); // The disconnected() and error() signals may already come // while calling connectToHost(). @@ -143,13 +147,13 @@ void QHttpNetworkConnectionChannel::init() // won't be a sslSocket if encrypt is false QObject::connect(sslSocket, SIGNAL(encrypted()), this, SLOT(_q_encrypted()), - Qt::DirectConnection); + Qt::QueuedConnection); QObject::connect(sslSocket, SIGNAL(sslErrors(QList)), this, SLOT(_q_sslErrors(QList)), Qt::DirectConnection); QObject::connect(sslSocket, SIGNAL(encryptedBytesWritten(qint64)), this, SLOT(_q_encryptedBytesWritten(qint64)), - Qt::DirectConnection); + Qt::QueuedConnection); if (ignoreAllSslErrors) sslSocket->ignoreSslErrors(); @@ -186,8 +190,11 @@ void QHttpNetworkConnectionChannel::close() // pendingEncrypt must only be true in between connected and encrypted states pendingEncrypt = false; - if (socket) + if (socket) { + // socket can be 0 since the host lookup is done from qhttpnetworkconnection.cpp while + // there is no socket yet. socket->close(); + } } @@ -353,6 +360,14 @@ bool QHttpNetworkConnectionChannel::ensureConnection() } return false; } + + // This code path for ConnectedState + if (pendingEncrypt) { + // Let's only be really connected when we have received the encrypted() signal. Else the state machine seems to mess up + // and corrupt the things sent to the server. + return false; + } + return true; } @@ -659,6 +674,12 @@ bool QHttpNetworkConnectionChannel::isSocketReading() const void QHttpNetworkConnectionChannel::_q_bytesWritten(qint64 bytes) { Q_UNUSED(bytes); + if (ssl) { + // In the SSL case we want to send data from encryptedBytesWritten signal since that one + // is the one going down to the actual network, not only into some SSL buffer. + return; + } + // bytes have been written to the socket. write even more of them :) if (isSocketWriting()) sendRequest(); @@ -734,7 +755,7 @@ void QHttpNetworkConnectionChannel::_q_connected() // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again! //channels[i].reconnectAttempts = 2; - if (pendingEncrypt) { + if (ssl || pendingEncrypt) { // FIXME: Didn't work properly with pendingEncrypt only, we should refactor this into an EncrypingState #ifndef QT_NO_SSL if (connection->sslContext().isNull()) { // this socket is making the 1st handshake for this connection, diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index 692c0e6a94..231fe11135 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -83,6 +83,8 @@ typedef QPair HttpMessagePair; class QHttpNetworkConnectionChannel : public QObject { Q_OBJECT public: + // TODO: Refactor this to add an EncryptingState (and remove pendingEncrypt). + // Also add an Unconnected state so IdleState does not have double meaning. enum ChannelState { IdleState = 0, // ready to send request ConnectingState = 1, // connecting to host diff --git a/src/network/access/qhttpprotocolhandler.cpp b/src/network/access/qhttpprotocolhandler.cpp index 28e10f751e..3357948519 100644 --- a/src/network/access/qhttpprotocolhandler.cpp +++ b/src/network/access/qhttpprotocolhandler.cpp @@ -368,6 +368,13 @@ bool QHttpProtocolHandler::sendRequest() // nothing to read currently, break the loop break; } else { + if (m_channel->written != uploadByteDevice->pos()) { + // Sanity check. This was useful in tracking down an upload corruption. + qWarning() << "QHttpProtocolHandler: Internal error in sendRequest. Expected to write at position" << m_channel->written << "but read device is at" << uploadByteDevice->pos(); + Q_ASSERT(m_channel->written == uploadByteDevice->pos()); + m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::ProtocolFailure); + return false; + } qint64 currentWriteSize = m_socket->write(readPointer, currentReadSize); if (currentWriteSize == -1 || currentWriteSize != currentReadSize) { // socket broke down diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h index 16610828cb..b553409391 100644 --- a/src/network/access/qhttpthreaddelegate_p.h +++ b/src/network/access/qhttpthreaddelegate_p.h @@ -187,6 +187,7 @@ protected: QByteArray m_dataArray; bool m_atEnd; qint64 m_size; + qint64 m_pos; // to match calls of haveDataSlot with the expected position public: QNonContiguousByteDeviceThreadForwardImpl(bool aE, qint64 s) : QNonContiguousByteDevice(), @@ -194,7 +195,8 @@ public: m_amount(0), m_data(0), m_atEnd(aE), - m_size(s) + m_size(s), + m_pos(0) { } @@ -202,6 +204,11 @@ public: { } + qint64 pos() Q_DECL_OVERRIDE + { + return m_pos; + } + const char* readPointer(qint64 maximumLength, qint64 &len) { if (m_amount > 0) { @@ -229,11 +236,10 @@ public: m_amount -= a; m_data += a; + m_pos += a; - // To main thread to inform about our state - emit processedData(a); - - // FIXME possible optimization, already ask user thread for some data + // To main thread to inform about our state. The m_pos will be sent as a sanity check. + emit processedData(m_pos, a); return true; } @@ -250,10 +256,21 @@ public: { m_amount = 0; m_data = 0; + m_dataArray.clear(); + + if (wantDataPending) { + // had requested the user thread to send some data (only 1 in-flight at any moment) + wantDataPending = false; + } // Communicate as BlockingQueuedConnection bool b = false; emit resetData(&b); + if (b) { + // the reset succeeded, we're at pos 0 again + m_pos = 0; + // the HTTP code will anyway abort the request if !b. + } return b; } @@ -264,8 +281,13 @@ public: public slots: // From user thread: - void haveDataSlot(QByteArray dataArray, bool dataAtEnd, qint64 dataSize) + void haveDataSlot(qint64 pos, QByteArray dataArray, bool dataAtEnd, qint64 dataSize) { + if (pos != m_pos) { + // Sometimes when re-sending a request in the qhttpnetwork* layer there is a pending haveData from the + // user thread on the way to us. We need to ignore it since it is the data for the wrong(later) chunk. + return; + } wantDataPending = false; m_dataArray = dataArray; @@ -285,7 +307,7 @@ signals: // to main thread: void wantData(qint64); - void processedData(qint64); + void processedData(qint64 pos, qint64 amount); void resetData(bool *b); }; diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 4ce7303dbb..974a101e9c 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -424,6 +424,7 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate() , synchronous(false) , state(Idle) , statusCode(0) + , uploadByteDevicePosition(false) , uploadDeviceChoking(false) , outgoingData(0) , bytesUploaded(-1) @@ -863,9 +864,9 @@ void QNetworkReplyHttpImplPrivate::postRequest() q, SLOT(uploadByteDeviceReadyReadSlot()), Qt::QueuedConnection); - // From main thread to user thread: - QObject::connect(q, SIGNAL(haveUploadData(QByteArray,bool,qint64)), - forwardUploadDevice, SLOT(haveDataSlot(QByteArray,bool,qint64)), Qt::QueuedConnection); + // From user thread to http thread: + QObject::connect(q, SIGNAL(haveUploadData(qint64,QByteArray,bool,qint64)), + forwardUploadDevice, SLOT(haveDataSlot(qint64,QByteArray,bool,qint64)), Qt::QueuedConnection); QObject::connect(uploadByteDevice.data(), SIGNAL(readyRead()), forwardUploadDevice, SIGNAL(readyRead()), Qt::QueuedConnection); @@ -873,8 +874,8 @@ void QNetworkReplyHttpImplPrivate::postRequest() // From http thread to user thread: QObject::connect(forwardUploadDevice, SIGNAL(wantData(qint64)), q, SLOT(wantUploadDataSlot(qint64))); - QObject::connect(forwardUploadDevice, SIGNAL(processedData(qint64)), - q, SLOT(sentUploadDataSlot(qint64))); + QObject::connect(forwardUploadDevice,SIGNAL(processedData(qint64, qint64)), + q, SLOT(sentUploadDataSlot(qint64,qint64))); QObject::connect(forwardUploadDevice, SIGNAL(resetData(bool*)), q, SLOT(resetUploadDataSlot(bool*)), Qt::BlockingQueuedConnection); // this is the only one with BlockingQueued! @@ -1268,12 +1269,22 @@ void QNetworkReplyHttpImplPrivate::replySslConfigurationChanged(const QSslConfig void QNetworkReplyHttpImplPrivate::resetUploadDataSlot(bool *r) { *r = uploadByteDevice->reset(); + if (*r) { + // reset our own position which is used for the inter-thread communication + uploadByteDevicePosition = 0; + } } // Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread -void QNetworkReplyHttpImplPrivate::sentUploadDataSlot(qint64 amount) +void QNetworkReplyHttpImplPrivate::sentUploadDataSlot(qint64 pos, qint64 amount) { + if (uploadByteDevicePosition + amount != pos) { + // Sanity check, should not happen. + error(QNetworkReply::UnknownNetworkError, ""); + return; + } uploadByteDevice->advanceReadPointer(amount); + uploadByteDevicePosition += amount; } // Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread @@ -1298,7 +1309,7 @@ void QNetworkReplyHttpImplPrivate::wantUploadDataSlot(qint64 maxSize) QByteArray dataArray(data, currentUploadDataLength); // Communicate back to HTTP thread - emit q->haveUploadData(dataArray, uploadByteDevice->atEnd(), uploadByteDevice->size()); + emit q->haveUploadData(uploadByteDevicePosition, dataArray, uploadByteDevice->atEnd(), uploadByteDevice->size()); } void QNetworkReplyHttpImplPrivate::uploadByteDeviceReadyReadSlot() diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h index 77d9c5a368..1940922f6e 100644 --- a/src/network/access/qnetworkreplyhttpimpl_p.h +++ b/src/network/access/qnetworkreplyhttpimpl_p.h @@ -120,7 +120,7 @@ public: Q_PRIVATE_SLOT(d_func(), void resetUploadDataSlot(bool *r)) Q_PRIVATE_SLOT(d_func(), void wantUploadDataSlot(qint64)) - Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64)) + Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64,qint64)) Q_PRIVATE_SLOT(d_func(), void uploadByteDeviceReadyReadSlot()) Q_PRIVATE_SLOT(d_func(), void emitReplyUploadProgress(qint64, qint64)) Q_PRIVATE_SLOT(d_func(), void _q_cacheSaveDeviceAboutToClose()) @@ -144,7 +144,7 @@ signals: void startHttpRequestSynchronously(); - void haveUploadData(QByteArray dataArray, bool dataAtEnd, qint64 dataSize); + void haveUploadData(const qint64 pos, QByteArray dataArray, bool dataAtEnd, qint64 dataSize); }; class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate @@ -195,6 +195,7 @@ public: // upload QNonContiguousByteDevice* createUploadByteDevice(); QSharedPointer uploadByteDevice; + qint64 uploadByteDevicePosition; bool uploadDeviceChoking; // if we couldn't readPointer() any data at the moment QIODevice *outgoingData; QSharedPointer outgoingDataBuffer; @@ -283,7 +284,7 @@ public: // From QNonContiguousByteDeviceThreadForwardImpl in HTTP thread: void resetUploadDataSlot(bool *r); void wantUploadDataSlot(qint64); - void sentUploadDataSlot(qint64); + void sentUploadDataSlot(qint64, qint64); // From user's QNonContiguousByteDevice void uploadByteDeviceReadyReadSlot(); diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 3ccedf6248..d2edf67a82 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -457,6 +457,10 @@ private Q_SLOTS: void putWithRateLimiting(); +#ifndef QT_NO_SSL + void putWithServerClosingConnectionImmediately(); +#endif + // NOTE: This test must be last! void parentingRepliesToTheApp(); private: @@ -4718,18 +4722,22 @@ void tst_QNetworkReply::ioPostToHttpNoBufferFlag() class SslServer : public QTcpServer { Q_OBJECT public: - SslServer() : socket(0) {}; + SslServer() : socket(0), m_ssl(true) {} void incomingConnection(qintptr socketDescriptor) { QSslSocket *serverSocket = new QSslSocket; serverSocket->setParent(this); if (serverSocket->setSocketDescriptor(socketDescriptor)) { + connect(serverSocket, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); + if (!m_ssl) { + emit newPlainConnection(serverSocket); + return; + } QString testDataDir = QFileInfo(QFINDTESTDATA("rfc3252.txt")).absolutePath(); if (testDataDir.isEmpty()) testDataDir = QCoreApplication::applicationDirPath(); connect(serverSocket, SIGNAL(encrypted()), this, SLOT(encryptedSlot())); - connect(serverSocket, SIGNAL(readyRead()), this, SLOT(readyReadSlot())); serverSocket->setProtocol(QSsl::AnyProtocol); connect(serverSocket, SIGNAL(sslErrors(QList)), serverSocket, SLOT(ignoreSslErrors())); serverSocket->setLocalCertificate(testDataDir + "/certs/server.pem"); @@ -4740,11 +4748,12 @@ public: } } signals: - void newEncryptedConnection(); + void newEncryptedConnection(QSslSocket *s); + void newPlainConnection(QSslSocket *s); public slots: void encryptedSlot() { socket = (QSslSocket*) sender(); - emit newEncryptedConnection(); + emit newEncryptedConnection(socket); } void readyReadSlot() { // for the incoming sockets, not the server socket @@ -4753,6 +4762,7 @@ public slots: public: QSslSocket *socket; + bool m_ssl; }; // very similar to ioPostToHttpUploadProgress but for SSL @@ -4780,7 +4790,7 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress() QNetworkReplyPtr reply(manager.post(request, sourceFile)); QSignalSpy spy(reply.data(), SIGNAL(uploadProgress(qint64,qint64))); - connect(&server, SIGNAL(newEncryptedConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); + connect(&server, SIGNAL(newEncryptedConnection(QSslSocket*)), &QTestEventLoop::instance(), SLOT(exitLoop())); connect(reply, SIGNAL(sslErrors(QList)), reply.data(), SLOT(ignoreSslErrors())); // get the request started and the incoming socket connected @@ -4788,7 +4798,7 @@ void tst_QNetworkReply::ioPostToHttpsUploadProgress() QVERIFY(!QTestEventLoop::instance().timeout()); QTcpSocket *incomingSocket = server.socket; QVERIFY(incomingSocket); - disconnect(&server, SIGNAL(newEncryptedConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); + disconnect(&server, SIGNAL(newEncryptedConnection(QSslSocket*)), &QTestEventLoop::instance(), SLOT(exitLoop())); incomingSocket->setReadBufferSize(1*1024); @@ -7905,6 +7915,159 @@ void tst_QNetworkReply::putWithRateLimiting() } +#ifndef QT_NO_SSL + +class PutWithServerClosingConnectionImmediatelyHandler: public QObject +{ + Q_OBJECT +public: + bool m_parsedHeaders; + QByteArray m_receivedData; + QByteArray m_expectedData; + QSslSocket *m_socket; + PutWithServerClosingConnectionImmediatelyHandler(QSslSocket *s, QByteArray expected) :m_parsedHeaders(false), m_expectedData(expected), m_socket(s) + { + m_socket->setParent(this); + connect(m_socket, SIGNAL(readyRead()), SLOT(readyReadSlot())); + connect(m_socket, SIGNAL(disconnected()), SLOT(disconnectedSlot())); + } +signals: + void correctFileUploadReceived(); + void corruptFileUploadReceived(); + +public slots: + void closeDelayed() { + m_socket->close(); + } + + void readyReadSlot() + { + QByteArray data = m_socket->readAll(); + m_receivedData += data; + if (!m_parsedHeaders && m_receivedData.contains("\r\n\r\n")) { + m_parsedHeaders = true; + QTimer::singleShot(qrand()%10, this, SLOT(closeDelayed())); // simulate random network latency + // This server simulates a web server connection closing, e.g. because of Apaches MaxKeepAliveRequests or KeepAliveTimeout + // In this case QNAM needs to re-send the upload data but it had a bug which then corrupts the upload + // This test catches that. + } + + } + void disconnectedSlot() + { + if (m_parsedHeaders) { + //qDebug() << m_receivedData.left(m_receivedData.indexOf("\r\n\r\n")); + m_receivedData = m_receivedData.mid(m_receivedData.indexOf("\r\n\r\n")+4); // check only actual data + } + if (m_receivedData.length() > 0 && !m_expectedData.startsWith(m_receivedData)) { + // We had received some data but it is corrupt! + qDebug() << "CORRUPT" << m_receivedData.count(); + + // Use this to track down the pattern of the corruption and conclude the source +// QFile a("/tmp/corrupt"); +// a.open(QIODevice::WriteOnly); +// a.write(m_receivedData); +// a.close(); + +// QFile b("/tmp/correct"); +// b.open(QIODevice::WriteOnly); +// b.write(m_expectedData); +// b.close(); + //exit(1); + emit corruptFileUploadReceived(); + } else { + emit correctFileUploadReceived(); + } + } +}; + +class PutWithServerClosingConnectionImmediatelyServer: public SslServer +{ + Q_OBJECT +public: + int m_correctUploads; + int m_corruptUploads; + int m_repliesFinished; + int m_expectedReplies; + QByteArray m_expectedData; + PutWithServerClosingConnectionImmediatelyServer() : SslServer(), m_correctUploads(0), m_corruptUploads(0), m_repliesFinished(0), m_expectedReplies(0) + { + QObject::connect(this, SIGNAL(newEncryptedConnection(QSslSocket*)), this, SLOT(createHandlerForConnection(QSslSocket*))); + QObject::connect(this, SIGNAL(newPlainConnection(QSslSocket*)), this, SLOT(createHandlerForConnection(QSslSocket*))); + } + +public slots: + void createHandlerForConnection(QSslSocket* s) { + PutWithServerClosingConnectionImmediatelyHandler *handler = new PutWithServerClosingConnectionImmediatelyHandler(s, m_expectedData); + handler->setParent(this); + QObject::connect(handler, SIGNAL(correctFileUploadReceived()), this, SLOT(increaseCorrect())); + QObject::connect(handler, SIGNAL(corruptFileUploadReceived()), this, SLOT(increaseCorrupt())); + } + void increaseCorrect() { + m_correctUploads++; + } + void increaseCorrupt() { + m_corruptUploads++; + } + void replyFinished() { + m_repliesFinished++; + if (m_repliesFinished == m_expectedReplies) { + QTestEventLoop::instance().exitLoop(); + } + } +}; + + + +void tst_QNetworkReply::putWithServerClosingConnectionImmediately() +{ + const int numUploads = 40; + qint64 wantedSize = 512*1024; // 512 kB + QByteArray sourceFile; + for (int i = 0; i < wantedSize; ++i) { + sourceFile += (char)'a' +(i%26); + } + bool withSsl = false; + + for (int s = 0; s <= 1; s++) { + withSsl = (s == 1); + // Test also needs to run several times because of 9c2ecf89 + for (int j = 0; j < 20; j++) { + // emulate a minimal https server + PutWithServerClosingConnectionImmediatelyServer server; + server.m_ssl = withSsl; + server.m_expectedData = sourceFile; + server.m_expectedReplies = numUploads; + server.listen(QHostAddress(QHostAddress::LocalHost), 0); + + for (int i = 0; i < numUploads; i++) { + // create the request + QUrl url = QUrl(QString("http%1://127.0.0.1:%2/file=%3").arg(withSsl ? "s" : "").arg(server.serverPort()).arg(i)); + QNetworkRequest request(url); + QNetworkReply *reply = manager.put(request, sourceFile); + connect(reply, SIGNAL(sslErrors(QList)), reply, SLOT(ignoreSslErrors())); + connect(reply, SIGNAL(finished()), &server, SLOT(replyFinished())); + reply->setParent(&server); + } + + // get the request started and the incoming socket connected + QTestEventLoop::instance().enterLoop(10); + + //qDebug() << "correct=" << server.m_correctUploads << "corrupt=" << server.m_corruptUploads << "expected=" < 5); + // Because actually important is that we don't get any corruption: + QCOMPARE(server.m_corruptUploads, 0); + + server.close(); + } + } + + +} + +#endif // NOTE: This test must be last testcase in tst_qnetworkreply! void tst_QNetworkReply::parentingRepliesToTheApp() -- cgit v1.2.3 From 2e5cfa1ad46ecfcfe7aea8950434bedfbbb6f43b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 20 Apr 2015 12:27:33 +0200 Subject: Bump version Change-Id: I9435dd001b6067464d7c04fbdf92b5b3ad546bac --- src/corelib/global/qglobal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 455582e310..6d7874ecb6 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -37,11 +37,11 @@ #include -#define QT_VERSION_STR "5.4.2" +#define QT_VERSION_STR "5.4.3" /* QT_VERSION is (major << 16) + (minor << 8) + patch. */ -#define QT_VERSION 0x050402 +#define QT_VERSION 0x050403 /* can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) */ -- cgit v1.2.3 From 1b4ce37371252d54ddd08c0e5325d0385217ef26 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 27 Apr 2015 17:09:31 +0200 Subject: Blacklist task258920_mouseBorder on Mac The test keeps failing, perfectly when run singly btw. However the approach of sending mouse move events is inherently fragile due to the use of QCursor::setPos and the expectation that that produces the correct sequence of mouse move events. Change-Id: I12ba1afcfd3fab965b8f93d5def48b435fd2ff33 Reviewed-by: Andy Shaw --- tests/auto/widgets/widgets/qmenu/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/auto/widgets/widgets/qmenu/BLACKLIST diff --git a/tests/auto/widgets/widgets/qmenu/BLACKLIST b/tests/auto/widgets/widgets/qmenu/BLACKLIST new file mode 100644 index 0000000000..de49d5ff45 --- /dev/null +++ b/tests/auto/widgets/widgets/qmenu/BLACKLIST @@ -0,0 +1,2 @@ +[task258920_mouseBorder] +osx -- cgit v1.2.3 From d0eba497c1c34d35ddda2b5d44902ebd636d4f9e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 Apr 2015 09:05:06 +0200 Subject: configure: Change default of CFG_REDUCE_RELOCATIONS to "no". Suppress QMAKE_LFLAGS_BSYMBOLIC_FUNC (-Bsymbolic-functions for g++) by default since it causes crashes with gcc 5.X. Since applications compiled with gcc 5.X might run against Qt compiled with gcc 4.9.X and CLANG might also be affected, turn it off by default. Task-number: QTBUG-45755 Change-Id: I5704c3156db6b6f74e1c14576e5d02bcbd3082a4 Reviewed-by: Simon Hausmann Reviewed-by: BogDan Vatra --- configure | 2 +- tools/configure/configureapp.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 6ce6753e3f..15a75bbccd 100755 --- a/configure +++ b/configure @@ -674,7 +674,7 @@ CFG_SSE4_1=auto CFG_SSE4_2=auto CFG_AVX=auto CFG_AVX2=auto -CFG_REDUCE_RELOCATIONS=auto +CFG_REDUCE_RELOCATIONS=no CFG_ACCESSIBILITY=auto CFG_ACCESSIBILITY_ATSPI_BRIDGE=no # will be enabled depending on dbus and accessibility being enabled CFG_NEON=auto diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 6e9d4aa80b..db0791b75c 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1696,7 +1696,7 @@ void Configure::applySpecSpecifics() dictionary[ "LARGE_FILE" ] = "no"; dictionary[ "ANGLE" ] = "no"; dictionary[ "DYNAMICGL" ] = "no"; - dictionary[ "REDUCE_RELOCATIONS" ] = "yes"; + dictionary[ "REDUCE_RELOCATIONS" ] = "no"; dictionary[ "QT_GETIFADDRS" ] = "no"; dictionary[ "QT_XKBCOMMON" ] = "no"; dictionary["ANDROID_STYLE_ASSETS"] = "yes"; -- cgit v1.2.3 From 518f886b6128331ce47932edd637471d58d0d877 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Fri, 17 Apr 2015 10:43:19 +0200 Subject: Revert "Rotate images according to Exif orientation" Due to a behavior change. This reverts commit 9157087334186ff3ef811f2ec234a3bf5d4a4889. This reverts commit 16c32c6dfbca03a46d1a2bb87b6c1c365e6179d5. Task-number: QTBUG-37946 Task-number: QTBUG-45552 Task-number: QTBUG-43563 Change-Id: Idf8df7d8f22465e8f6b51acb68993ac97208b184 Reviewed-by: Konstantin Ritt Reviewed-by: Gunnar Sletta --- src/gui/image/qjpeghandler.cpp | 150 +-------------------- .../images/jpeg_exif_orientation_value_1.jpg | Bin 910 -> 0 bytes .../images/jpeg_exif_orientation_value_2.jpg | Bin 910 -> 0 bytes .../images/jpeg_exif_orientation_value_3.jpg | Bin 988 -> 0 bytes .../images/jpeg_exif_orientation_value_4.jpg | Bin 995 -> 0 bytes .../images/jpeg_exif_orientation_value_5.jpg | Bin 912 -> 0 bytes .../images/jpeg_exif_orientation_value_6.jpg | Bin 911 -> 0 bytes .../jpeg_exif_orientation_value_6_motorola.jpg | Bin 911 -> 0 bytes .../images/jpeg_exif_orientation_value_7.jpg | Bin 987 -> 0 bytes .../images/jpeg_exif_orientation_value_8.jpg | Bin 991 -> 0 bytes tests/auto/gui/image/qimage/tst_qimage.cpp | 33 ----- 11 files changed, 1 insertion(+), 182 deletions(-) delete mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg delete mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg delete mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg delete mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg delete mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg delete mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg delete mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6_motorola.jpg delete mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg delete mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 9cf9947b6c..14c8b4c0f4 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -726,7 +726,7 @@ public: }; QJpegHandlerPrivate(QJpegHandler *qq) - : quality(75), exifOrientation(1), iod_src(0), state(Ready), q(qq) + : quality(75), iod_src(0), state(Ready), q(qq) {} ~QJpegHandlerPrivate() @@ -741,10 +741,8 @@ public: bool readJpegHeader(QIODevice*); bool read(QImage *image); - void applyExifOrientation(QImage *image); int quality; - int exifOrientation; QVariant size; QImage::Format format; QSize scaledSize; @@ -762,97 +760,6 @@ public: QJpegHandler *q; }; -static bool readExifHeader(QDataStream &stream) -{ - char prefix[6]; - if (stream.readRawData(prefix, sizeof(prefix)) != sizeof(prefix)) - return false; - if (prefix[0] != 'E' || prefix[1] != 'x' || prefix[2] != 'i' || prefix[3] != 'f' || prefix[4] != 0 || prefix[5] != 0) - return false; - return true; -} - -/* - * Returns -1 on error - * Returns 0 if no Exif orientation was found - * Returns 1 orientation is horizontal (normal) - * Returns 2 mirror horizontal - * Returns 3 rotate 180 - * Returns 4 mirror vertical - * Returns 5 mirror horizontal and rotate 270 CCW - * Returns 6 rotate 90 CW - * Returns 7 mirror horizontal and rotate 90 CW - * Returns 8 rotate 270 CW - */ -static int getExifOrientation(QByteArray &exifData) -{ - QDataStream stream(&exifData, QIODevice::ReadOnly); - - if (!readExifHeader(stream)) - return -1; - - quint16 val; - quint32 offset; - - // read byte order marker - stream >> val; - if (val == 0x4949) // 'II' == Intel - stream.setByteOrder(QDataStream::LittleEndian); - else if (val == 0x4d4d) // 'MM' == Motorola - stream.setByteOrder(QDataStream::BigEndian); - else - return -1; // unknown byte order - - // read size - stream >> val; - if (val != 0x2a) - return -1; - - stream >> offset; - // we have already used 8 bytes of TIFF header - offset -= 8; - - // read IFD - while (!stream.atEnd()) { - quint16 numEntries; - - // skip offset bytes to get the next IFD - if (stream.skipRawData(offset) != (qint32)offset) - return -1; - - stream >> numEntries; - - for (;numEntries > 0; --numEntries) { - quint16 tag; - quint16 type; - quint32 components; - quint16 value; - quint16 dummy; - - stream >> tag >> type >> components >> value >> dummy; - if (tag == 0x0112) { // Tag Exif.Image.Orientation - if (components !=1) - return -1; - if (type != 3) // we are expecting it to be an unsigned short - return -1; - if (value < 1 || value > 8) // check for valid range - return -1; - - // It is possible to include the orientation multiple times. - // Right now the first value is returned. - return value; - } - } - - // read offset to next IFD - stream >> offset; - if (offset == 0) // this is the last IFD - break; - } - - // No Exif orientation was found - return 0; -} /*! \internal */ @@ -872,7 +779,6 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) if (!setjmp(err.setjmp_buffer)) { jpeg_save_markers(&info, JPEG_COM, 0xFFFF); - jpeg_save_markers(&info, JPEG_APP0+1, 0xFFFF); // Exif uses APP1 marker (void) jpeg_read_header(&info, TRUE); @@ -884,8 +790,6 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) format = QImage::Format_Invalid; read_jpeg_format(format, &info); - QByteArray exifData; - for (jpeg_saved_marker_ptr marker = info.marker_list; marker != NULL; marker = marker->next) { if (marker->marker == JPEG_COM) { QString key, value; @@ -903,18 +807,9 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) description += key + QLatin1String(": ") + value.simplified(); readTexts.append(key); readTexts.append(value); - } else if (marker->marker == JPEG_APP0+1) { - exifData.append((const char*)marker->data, marker->data_length); } } - if (exifData.size()) { - // Exif data present - int orientation = getExifOrientation(exifData); - if (orientation > 0) - exifOrientation = orientation; - } - state = ReadHeader; return true; } @@ -928,48 +823,6 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) return true; } -void QJpegHandlerPrivate::applyExifOrientation(QImage *image) -{ - // This is not an optimized implementation, but easiest to maintain - QTransform transform; - - switch (exifOrientation) { - case 1: // normal - break; - case 2: // mirror horizontal - *image = image->mirrored(true, false); - break; - case 3: // rotate 180 - transform.rotate(180); - *image = image->transformed(transform); - break; - case 4: // mirror vertical - *image = image->mirrored(false, true); - break; - case 5: // mirror horizontal and rotate 270 CCW - *image = image->mirrored(true, false); - transform.rotate(270); - *image = image->transformed(transform); - break; - case 6: // rotate 90 CW - transform.rotate(90); - *image = image->transformed(transform); - break; - case 7: // mirror horizontal and rotate 90 CW - *image = image->mirrored(true, false); - transform.rotate(90); - *image = image->transformed(transform); - break; - case 8: // rotate 270 CW - transform.rotate(-90); - *image = image->transformed(transform); - break; - default: - qWarning("This should never happen"); - } - exifOrientation = 1; -} - bool QJpegHandlerPrivate::read(QImage *image) { if(state == Ready) @@ -981,7 +834,6 @@ bool QJpegHandlerPrivate::read(QImage *image) if (success) { for (int i = 0; i < readTexts.size()-1; i+=2) image->setText(readTexts.at(i), readTexts.at(i+1)); - applyExifOrientation(image); state = Ready; return true; diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg deleted file mode 100644 index aaa4ac4e10..0000000000 Binary files a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg and /dev/null differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg deleted file mode 100644 index a61d2723d7..0000000000 Binary files a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg and /dev/null differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg deleted file mode 100644 index 43e56dcef7..0000000000 Binary files a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg and /dev/null differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg deleted file mode 100644 index d5d06f7409..0000000000 Binary files a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg and /dev/null differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg deleted file mode 100644 index 1886f3775e..0000000000 Binary files a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg and /dev/null differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg deleted file mode 100644 index 5cec757354..0000000000 Binary files a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg and /dev/null differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6_motorola.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6_motorola.jpg deleted file mode 100644 index 0aa164b78b..0000000000 Binary files a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6_motorola.jpg and /dev/null differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg deleted file mode 100644 index b3dcc466a9..0000000000 Binary files a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg and /dev/null differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg deleted file mode 100644 index 8bc390e2b9..0000000000 Binary files a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg and /dev/null differ diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 309d3a80c5..33302edfeb 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -173,9 +173,6 @@ private slots: void invertPixelsRGB_data(); void invertPixelsRGB(); - void exifOrientation_data(); - void exifOrientation(); - void cleanupFunctions(); private: @@ -2649,36 +2646,6 @@ void tst_QImage::invertPixelsRGB() QCOMPARE(qBlue(pixel) >> 4, (255 - 96) >> 4); } -void tst_QImage::exifOrientation_data() -{ - QTest::addColumn("fileName"); - QTest::newRow("Orientation 1, Intel format") << m_prefix + "jpeg_exif_orientation_value_1.jpg"; - QTest::newRow("Orientation 2, Intel format") << m_prefix + "jpeg_exif_orientation_value_2.jpg"; - QTest::newRow("Orientation 3, Intel format") << m_prefix + "jpeg_exif_orientation_value_3.jpg"; - QTest::newRow("Orientation 4, Intel format") << m_prefix + "jpeg_exif_orientation_value_4.jpg"; - QTest::newRow("Orientation 5, Intel format") << m_prefix + "jpeg_exif_orientation_value_5.jpg"; - QTest::newRow("Orientation 6, Intel format") << m_prefix + "jpeg_exif_orientation_value_6.jpg"; - QTest::newRow("Orientation 6, Motorola format") << m_prefix + "jpeg_exif_orientation_value_6_motorola.jpg"; - QTest::newRow("Orientation 7, Intel format") << m_prefix + "jpeg_exif_orientation_value_7.jpg"; - QTest::newRow("Orientation 8, Intel format") << m_prefix + "jpeg_exif_orientation_value_8.jpg"; -} - -void tst_QImage::exifOrientation() -{ - QFETCH(QString, fileName); - - QImage img; - QRgb px; - - QVERIFY(img.load(fileName)); - - px = img.pixel(0, 0); - QVERIFY(qRed(px) > 250 && qGreen(px) < 5 && qBlue(px) < 5); - - px = img.pixel(img.width() - 1, 0); - QVERIFY(qRed(px) < 5 && qGreen(px) < 5 && qBlue(px) > 250); -} - static void cleanupFunction(void* info) { bool *called = static_cast(info); -- cgit v1.2.3 From 225270978786a19eccd60fee0097d866ec0a9d78 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 20 Apr 2015 10:35:37 -0700 Subject: Add the changelog for 5.4.2 Change-Id: I27eaacb532114dd188c4ffff13d6c95e1026b99d Reviewed-by: Gunnar Sletta Reviewed-by: Simon Hausmann --- dist/changes-5.4.2 | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 dist/changes-5.4.2 diff --git a/dist/changes-5.4.2 b/dist/changes-5.4.2 new file mode 100644 index 0000000000..e1ad9b6846 --- /dev/null +++ b/dist/changes-5.4.2 @@ -0,0 +1,107 @@ +Qt 5.4.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.4.1. Compatibility with Qt +5.4.0 is also retained, except on Windows when using MSVC 2012 or MSVC +2013. See note below. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://doc.qt.io/qt-5.4/ + +The Qt version 5.4 series is binary compatible with the 5.3.x series. +Applications compiled for 5.3 will continue to run with 5.4 with the +exception of on Windows when using MSVC 2012 or MSVC 2013. See note +below. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** +- Restored binary compatibility with Qt 5.3.2 on Windows when using MSVC + 2012 or MSVC 2013. This means that Qt 5.4.1 and 5.4.2 are no longer + binary compatible with Qt 5.4.0 when using either of those compilers. +- [QTBUG-42594] OS X binary package: fixed incorrect linking to libraries in + /opt/local/lib +- EXIF orientation is no longer applied to JPEG images on read. EXIF + orientation on JPEG was introduced in 5.4.0, but due to a bug the most + common EXIF-format (big-endian) was not working until 5.4.1. 5.4.2 restores the + behavior of 5.4.0 and earlier for most EXIF-tagged JPEGs. + EXIF orientation will be an opt-in starting with Qt 5.5. + +**************************************************************************** +* Library * +**************************************************************************** + +QtCore +------ + - [QTBUG-43893] Fixed memory leak in qSetMessagePattern + - [QTBUG-43513] QXmlStreamReader: Correctly parse XML containing NUL bytes + in the input stream + - [QTBUG-43352] QTemporaryDirectory: Properly clean up in case of a failure + - [QTBUG-43827] Fixed regression in QSortFilterProxyModel which crashed when + sorting a tree model + +QtGui +----- + - [QTBUG-44273] Fixed misplacement of outlined text with native text rendering + - [QTBUG-44147] Fixed VNC not working on some VNC servers + - [QTBUG-43850] Fixed crash with multi-threaded font usage + - [QTBUG-43850] Made the old harfbuzz fallback available at runtime + - Improvements to the experimental high-dpi support + - [QTBUG-43318] Better resolution of GLES 3 functions to avoid issues when + deploying on systems with GLES 2.0 only + +QtWidgets +--------- + - [QTBUG-43830] Fixed crash in stylesheets when styling QProgressBar + - [QTBUG-43663] QColorDialog: Don't lose focus while color picking + +QtNetwork +--------- + - [QTBUG-43793] Fixed disconnects of QSSLSocket after starting encryption + +QtPrintSupport +-------------- + - [QTBUG-43124] Fixed QPrinter::{width,height} return values + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + +Android +------- + + - [QTBUG-44648] Fixed rendering Chinese text on Android 5 + +Linux/XCB +--------- + + - [QTBUG-45071] Don't crash when resizing windows to bigger than 3840x2160 + +**************************************************************************** +* Tools * +**************************************************************************** + +configure & build system +------------------------ + + - CMake-based projects using Qt will now always be built with -fPIE, + which fixes function pointer based QObject::connect() on ARM. This + is consistent with qmake + - [Android] Fixed compilation on armv5 with 4.9 toolchain + +qmake +----- + + - [VS] Fixed handling of files that are excluded from build + - [QTBUG-44413][VS] Fixed vcxproj generation for CONFIG-=flat, again + - [QTBUG-44595] Restored Qt 4 behavior of qtLibraryTarget() + - [QTBUG-45118][Windows] Fixed parallel build when using TYPELIBS + - [OS X/iOS] Fixed QMAKE_INFO_PLIST path resolution for shadow builds -- cgit v1.2.3 From ef622d55ca990e70f60d11964fa2f3651ccd4522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Fri, 24 Apr 2015 17:13:39 +0200 Subject: Android: Use Holo theme on Android 5.1 We already fallback to the Holo theme on Android 5.0 devices, see: 7c539579b9e883c87e5f7fb3bbec80847fc83ae2 Task-number: QTBUG-45714 Change-Id: I18b0700321b27ab5bbe3f1642a0bc9de1774864a Reviewed-by: BogDan Vatra --- src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java index 75f10ad3ba..a790e0ef6f 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java @@ -187,7 +187,7 @@ public class QtActivity extends Activity QT_ANDROID_THEMES = new String[] {"Theme_Light"}; QT_ANDROID_DEFAULT_THEME = "Theme_Light"; } - else if ((Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT <= 13) || Build.VERSION.SDK_INT == 21){ + else if ((Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT <= 13) || Build.VERSION.SDK_INT >= 21){ QT_ANDROID_THEMES = new String[] {"Theme_Holo_Light"}; QT_ANDROID_DEFAULT_THEME = "Theme_Holo_Light"; } else { -- cgit v1.2.3 From 119c5ec93f3b32cb62456c3a42c54ebb2c42e567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Fri, 24 Apr 2015 15:21:21 +0200 Subject: Android: Fix wrong field name in ExtractStyle.java In Android 5.1 the field name for the inset state member in InsetDrawable changed from mInsetState to mState. Task-number: QTBUG-45714 Change-Id: I0ebada1ef90954013e5357cbd10df925f8f05295 Reviewed-by: BogDan Vatra --- src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java index a8583cde17..79722183bf 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java @@ -1100,7 +1100,9 @@ public class ExtractStyle { { try { InsetDrawable d = (InsetDrawable)drawable; - Object mInsetStateObject = getAccessibleField(InsetDrawable.class, "mInsetState").get(d); + // mInsetState changed to mState in Android 5.1 (22) + Object mInsetStateObject = getAccessibleField(InsetDrawable.class, (Build.VERSION.SDK_INT > 21) ? "mState" + : "mInsetState").get(d); Rect _padding = new Rect(); boolean hasPadding = d.getPadding(_padding); return getDrawable(getAccessibleField(mInsetStateObject.getClass(), "mDrawable").get(mInsetStateObject), filename, hasPadding ? _padding : null); -- cgit v1.2.3 From 1f281bfd63402b50f3db378a027da26ca52ffb27 Mon Sep 17 00:00:00 2001 From: Christoph Schleifenbaum Date: Sat, 18 Apr 2015 14:39:18 +0200 Subject: ItemViews: Fix acceptance of drag enter events Always accept drag enter events if the mime type and the drop actions matches. Whether the drop can actually happen on the currently hovered index will be decided in the following drag move event. Change-Id: I27e865cb65513dfe3f57ad3f1bc8cebf4c29a692 Task-number: QTBUG-45037 Reviewed-by: David Faure --- src/widgets/itemviews/qabstractitemview_p.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h index c3bd1fb504..be5d4b7b71 100644 --- a/src/widgets/itemviews/qabstractitemview_p.h +++ b/src/widgets/itemviews/qabstractitemview_p.h @@ -168,8 +168,20 @@ public: QModelIndex index; int col = -1; int row = -1; + const QMimeData *mime = event->mimeData(); + + // Drag enter event shall always be accepted, if mime type and action match. + // Whether the data can actually be dropped will be checked in drag move. + if (event->type() == QEvent::DragEnter) { + const QStringList modelTypes = model->mimeTypes(); + for (int i = 0; i < modelTypes.count(); ++i) + if (mime->hasFormat(modelTypes.at(i)) + && (event->dropAction() & model->supportedDropActions())) + return true; + } + if (dropOn(event, &row, &col, &index)) { - return model->canDropMimeData(event->mimeData(), + return model->canDropMimeData(mime, dragDropMode == QAbstractItemView::InternalMove ? Qt::MoveAction : event->dropAction(), row, col, index); } -- cgit v1.2.3 From 4db5d3ccd17d448b59db491e2f261892f31fec74 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 10 Nov 2014 12:04:56 +0100 Subject: Fix shortcuts when using setDefaultAction Don't remove ampersands when setting the text: they will be removed when the text is displayed. This fixes double removal of ampersands. [ChangeLog][QtWidgets][QToolButton] Fix double removal of ampersands Task-number: QTBUG-23396 Change-Id: I56bf50eb24aae32a81d614824aca0b63363587c8 Reviewed-by: Timur Pocheptsov --- src/widgets/widgets/qtoolbutton.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index bb3f2d74a8..e897b578c3 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -897,7 +897,7 @@ void QToolButton::setDefaultAction(QAction *action) return; if (!actions().contains(action)) addAction(action); - setText(action->iconText()); + setText(action->text()); setIcon(action->icon()); #ifndef QT_NO_TOOLTIP setToolTip(action->toolTip()); -- cgit v1.2.3 From e445f3c47bea3e2d3dffa1215b24cb90dccd8c73 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 21 Apr 2015 16:25:25 +0200 Subject: Add noexcept to move constructors and assignment operators Add the noexcept attribute to all move constructors and assignment operators in QtGui that didn't already have it. Change-Id: Idcdf79ae8349b8793e7394b5ae7c08e6111fbc9a Reviewed-by: Konstantin Ritt Reviewed-by: Gunnar Sletta --- src/gui/image/qicon.cpp | 2 +- src/gui/image/qicon.h | 12 +++++++----- src/gui/image/qimage.cpp | 2 +- src/gui/image/qimage.h | 9 +++++---- src/gui/image/qpicture.h | 5 +++-- src/gui/image/qpixmap.h | 5 +++-- src/gui/kernel/qevent.h | 9 ++++++--- src/gui/kernel/qpalette.h | 10 ++++++---- src/gui/painting/qbrush.h | 5 +++-- src/gui/painting/qpaintdevice.cpp | 2 +- src/gui/painting/qpaintdevice.h | 2 +- src/gui/painting/qpainterpath.cpp | 2 +- src/gui/painting/qpainterpath.h | 6 +++--- src/gui/painting/qregion.h | 4 ++-- src/gui/text/qfont.h | 2 +- src/gui/text/qfontmetrics.h | 5 +++-- 16 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 6d7a40c2ef..40ba84bb14 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -606,7 +606,7 @@ QFactoryLoader *qt_iconEngineFactoryLoader() /*! Constructs a null icon. */ -QIcon::QIcon() +QIcon::QIcon() Q_DECL_NOEXCEPT : d(0) { } diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h index d87468b4f0..63e77eef99 100644 --- a/src/gui/image/qicon.h +++ b/src/gui/image/qicon.h @@ -51,22 +51,24 @@ public: enum Mode { Normal, Disabled, Active, Selected }; enum State { On, Off }; - QIcon(); + QIcon() Q_DECL_NOEXCEPT; QIcon(const QPixmap &pixmap); QIcon(const QIcon &other); #ifdef Q_COMPILER_RVALUE_REFS - QIcon(QIcon &&other) - :d(0) { qSwap(d, other.d); } + QIcon(QIcon &&other) Q_DECL_NOEXCEPT + : d(0) + { qSwap(d, other.d); } #endif explicit QIcon(const QString &fileName); // file or resource name explicit QIcon(QIconEngine *engine); ~QIcon(); QIcon &operator=(const QIcon &other); #ifdef Q_COMPILER_RVALUE_REFS - inline QIcon &operator=(QIcon &&other) + inline QIcon &operator=(QIcon &&other) Q_DECL_NOEXCEPT { qSwap(d, other.d); return *this; } #endif - inline void swap(QIcon &other) { qSwap(d, other.d); } + inline void swap(QIcon &other) Q_DECL_NOEXCEPT + { qSwap(d, other.d); } operator QVariant() const; diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 1bbbc3e1f2..8a0f570f47 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -734,7 +734,7 @@ bool QImageData::checkForAlphaPixels() const \sa isNull() */ -QImage::QImage() +QImage::QImage() Q_DECL_NOEXCEPT : QPaintDevice() { d = 0; diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 99044bd4e3..26057f366c 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -121,7 +121,7 @@ public: #endif }; - QImage(); + QImage() Q_DECL_NOEXCEPT; QImage(const QSize &size, Format format); QImage(int width, int height, Format format); QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0); @@ -136,7 +136,7 @@ public: QImage(const QImage &); #ifdef Q_COMPILER_RVALUE_REFS - inline QImage(QImage &&other) + inline QImage(QImage &&other) Q_DECL_NOEXCEPT : QPaintDevice(), d(0) { qSwap(d, other.d); } #endif @@ -144,10 +144,11 @@ public: QImage &operator=(const QImage &); #ifdef Q_COMPILER_RVALUE_REFS - inline QImage &operator=(QImage &&other) + inline QImage &operator=(QImage &&other) Q_DECL_NOEXCEPT { qSwap(d, other.d); return *this; } #endif - inline void swap(QImage &other) { qSwap(d, other.d); } + inline void swap(QImage &other) Q_DECL_NOEXCEPT + { qSwap(d, other.d); } bool isNull() const; diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h index 9bb193321b..c3897a1935 100644 --- a/src/gui/image/qpicture.h +++ b/src/gui/image/qpicture.h @@ -72,10 +72,11 @@ public: QPicture& operator=(const QPicture &p); #ifdef Q_COMPILER_RVALUE_REFS - inline QPicture &operator=(QPicture &&other) + inline QPicture &operator=(QPicture &&other) Q_DECL_NOEXCEPT { qSwap(d_ptr, other.d_ptr); return *this; } #endif - inline void swap(QPicture &other) { d_ptr.swap(other.d_ptr); } + inline void swap(QPicture &other) Q_DECL_NOEXCEPT + { d_ptr.swap(other.d_ptr); } void detach(); bool isDetached() const; diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index 810883ea6c..51b02acfcf 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -67,10 +67,11 @@ public: QPixmap &operator=(const QPixmap &); #ifdef Q_COMPILER_RVALUE_REFS - inline QPixmap &operator=(QPixmap &&other) + inline QPixmap &operator=(QPixmap &&other) Q_DECL_NOEXCEPT { qSwap(data, other.data); return *this; } #endif - inline void swap(QPixmap &other) { qSwap(data, other.data); } + inline void swap(QPixmap &other) Q_DECL_NOEXCEPT + { qSwap(data, other.data); } operator QVariant() const; diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index e931e28a2e..a1f32026ac 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -789,8 +789,10 @@ public: explicit TouchPoint(int id = -1); TouchPoint(const TouchPoint &other); #ifdef Q_COMPILER_RVALUE_REFS - TouchPoint(TouchPoint &&other) : d(other.d) { other.d = 0; } - TouchPoint &operator=(TouchPoint &&other) + TouchPoint(TouchPoint &&other) Q_DECL_NOEXCEPT + : d(0) + { qSwap(d, other.d); } + TouchPoint &operator=(TouchPoint &&other) Q_DECL_NOEXCEPT { qSwap(d, other.d); return *this; } #endif ~TouchPoint(); @@ -798,7 +800,8 @@ public: TouchPoint &operator=(const TouchPoint &other) { if ( d != other.d ) { TouchPoint copy(other); swap(copy); } return *this; } - void swap(TouchPoint &other) { qSwap(d, other.d); } + void swap(TouchPoint &other) Q_DECL_NOEXCEPT + { qSwap(d, other.d); } int id() const; diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h index e8b35aa82a..78dd2ce9d7 100644 --- a/src/gui/kernel/qpalette.h +++ b/src/gui/kernel/qpalette.h @@ -61,16 +61,18 @@ public: ~QPalette(); QPalette &operator=(const QPalette &palette); #ifdef Q_COMPILER_RVALUE_REFS - QPalette(QPalette &&other) Q_DECL_NOTHROW - : d(other.d), data(other.data) { other.d = Q_NULLPTR; } - inline QPalette &operator=(QPalette &&other) + QPalette(QPalette &&other) Q_DECL_NOEXCEPT + : d(other.d), data(other.data) + { other.d = Q_NULLPTR; } + inline QPalette &operator=(QPalette &&other) Q_DECL_NOEXCEPT { for_faster_swapping_dont_use = other.for_faster_swapping_dont_use; qSwap(d, other.d); return *this; } #endif - void swap(QPalette &other) { + void swap(QPalette &other) Q_DECL_NOEXCEPT + { qSwap(d, other.d); qSwap(for_faster_swapping_dont_use, other.for_faster_swapping_dont_use); } diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h index a3b88a50ef..ceb95f5676 100644 --- a/src/gui/painting/qbrush.h +++ b/src/gui/painting/qbrush.h @@ -73,10 +73,11 @@ public: ~QBrush(); QBrush &operator=(const QBrush &brush); #ifdef Q_COMPILER_RVALUE_REFS - inline QBrush &operator=(QBrush &&other) + inline QBrush &operator=(QBrush &&other) Q_DECL_NOEXCEPT { qSwap(d, other.d); return *this; } #endif - inline void swap(QBrush &other) { qSwap(d, other.d); } + inline void swap(QBrush &other) Q_DECL_NOEXCEPT + { qSwap(d, other.d); } operator QVariant() const; diff --git a/src/gui/painting/qpaintdevice.cpp b/src/gui/painting/qpaintdevice.cpp index 36e0bbe223..bbf8e8f170 100644 --- a/src/gui/painting/qpaintdevice.cpp +++ b/src/gui/painting/qpaintdevice.cpp @@ -35,7 +35,7 @@ QT_BEGIN_NAMESPACE -QPaintDevice::QPaintDevice() +QPaintDevice::QPaintDevice() Q_DECL_NOEXCEPT { reserved = 0; painters = 0; diff --git a/src/gui/painting/qpaintdevice.h b/src/gui/painting/qpaintdevice.h index 7c756c66de..4eb972786b 100644 --- a/src/gui/painting/qpaintdevice.h +++ b/src/gui/painting/qpaintdevice.h @@ -80,7 +80,7 @@ public: int depth() const { return metric(PdmDepth); } protected: - QPaintDevice(); + QPaintDevice() Q_DECL_NOEXCEPT; virtual int metric(PaintDeviceMetric metric) const; virtual void initPainter(QPainter *painter) const; virtual QPaintDevice *redirected(QPoint *offset) const; diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index e3c6eabbc3..88cf05c646 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -521,7 +521,7 @@ void QPainterPath::setElementPositionAt(int i, qreal x, qreal y) /*! Constructs an empty QPainterPath object. */ -QPainterPath::QPainterPath() +QPainterPath::QPainterPath() Q_DECL_NOEXCEPT : d_ptr(0) { } diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h index eb32782a96..e037cd5bfb 100644 --- a/src/gui/painting/qpainterpath.h +++ b/src/gui/painting/qpainterpath.h @@ -81,16 +81,16 @@ public: inline bool operator!=(const Element &e) const { return !operator==(e); } }; - QPainterPath(); + QPainterPath() Q_DECL_NOEXCEPT; explicit QPainterPath(const QPointF &startPoint); QPainterPath(const QPainterPath &other); QPainterPath &operator=(const QPainterPath &other); #ifdef Q_COMPILER_RVALUE_REFS - inline QPainterPath &operator=(QPainterPath &&other) + inline QPainterPath &operator=(QPainterPath &&other) Q_DECL_NOEXCEPT { qSwap(d_ptr, other.d_ptr); return *this; } #endif ~QPainterPath(); - inline void swap(QPainterPath &other) { d_ptr.swap(other.d_ptr); } + inline void swap(QPainterPath &other) Q_DECL_NOEXCEPT { d_ptr.swap(other.d_ptr); } void closeSubpath(); diff --git a/src/gui/painting/qregion.h b/src/gui/painting/qregion.h index bab07b5a5d..ab2404e887 100644 --- a/src/gui/painting/qregion.h +++ b/src/gui/painting/qregion.h @@ -66,10 +66,10 @@ public: ~QRegion(); QRegion &operator=(const QRegion &); #ifdef Q_COMPILER_RVALUE_REFS - inline QRegion &operator=(QRegion &&other) + inline QRegion &operator=(QRegion &&other) Q_DECL_NOEXCEPT { qSwap(d, other.d); return *this; } #endif - inline void swap(QRegion &other) { qSwap(d, other.d); } + inline void swap(QRegion &other) Q_DECL_NOEXCEPT { qSwap(d, other.d); } bool isEmpty() const; bool isNull() const; diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index cc78ea7f45..72e4197fc5 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -237,7 +237,7 @@ public: operator QVariant() const; bool isCopyOf(const QFont &) const; #ifdef Q_COMPILER_RVALUE_REFS - inline QFont &operator=(QFont &&other) + inline QFont &operator=(QFont &&other) Q_DECL_NOEXCEPT { qSwap(d, other.d); qSwap(resolve_mask, other.resolve_mask); return *this; } #endif diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index 12aa2dadb4..65ec219a99 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -58,11 +58,12 @@ public: QFontMetrics &operator=(const QFontMetrics &); #ifdef Q_COMPILER_RVALUE_REFS - inline QFontMetrics &operator=(QFontMetrics &&other) + inline QFontMetrics &operator=(QFontMetrics &&other) Q_DECL_NOEXCEPT { qSwap(d, other.d); return *this; } #endif - void swap(QFontMetrics &other) { qSwap(d, other.d); } + void swap(QFontMetrics &other) Q_DECL_NOEXCEPT + { qSwap(d, other.d); } int ascent() const; int descent() const; -- cgit v1.2.3 From bd15b23987e9d6d1f42fa8987e5c1ff5a1eeee8b Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 20 Mar 2015 14:20:16 +0100 Subject: QStateMachine: cache expensive calculations. As nothing changes in the state machine when selecting transitions for events and then calculating the exit- and entry-sets, some calculations can be cached. The exit set for a transition was calculated multiple times. First in removeConflictingTransitions, where the two loops would each calculate them multiple times. Then secondly in microstep(), which would calculate the exit set for all transitions. Transition selection, exit set calculation, and entry set calculation all calculate the transition domain and effective target states for transitions. Change-Id: I217328a73db2f71e371eb5f60a0c7b222303f0ca Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine.cpp | 243 +++++++++++++++++---- src/corelib/statemachine/qstatemachine_p.h | 17 +- .../qstatemachine/tst_qstatemachine.cpp | 27 ++- 3 files changed, 220 insertions(+), 67 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index f02e27330d..d91b4ba14a 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -177,6 +177,100 @@ QT_BEGIN_NAMESPACE // #define QSTATEMACHINE_DEBUG // #define QSTATEMACHINE_RESTORE_PROPERTIES_DEBUG +struct CalculationCache { + struct TransitionInfo { + QList effectiveTargetStates; + QSet exitSet; + QAbstractState *transitionDomain; + + bool effectiveTargetStatesIsKnown: 1; + bool exitSetIsKnown : 1; + bool transitionDomainIsKnown : 1; + + TransitionInfo() + : transitionDomain(0) + , effectiveTargetStatesIsKnown(false) + , exitSetIsKnown(false) + , transitionDomainIsKnown(false) + {} + }; + + typedef QHash TransitionInfoCache; + TransitionInfoCache cache; + + bool effectiveTargetStates(QAbstractTransition *t, QList *targets) const + { + Q_ASSERT(targets); + + TransitionInfoCache::const_iterator cacheIt = cache.find(t); + if (cacheIt == cache.end() || !cacheIt->effectiveTargetStatesIsKnown) + return false; + + *targets = cacheIt->effectiveTargetStates; + return true; + } + + void insert(QAbstractTransition *t, const QList &targets) + { + TransitionInfoCache::iterator cacheIt = cache.find(t); + TransitionInfo &ti = cacheIt == cache.end() + ? *cache.insert(t, TransitionInfo()) + : *cacheIt; + + Q_ASSERT(!ti.effectiveTargetStatesIsKnown); + ti.effectiveTargetStates = targets; + ti.effectiveTargetStatesIsKnown = true; + } + + bool exitSet(QAbstractTransition *t, QSet *exits) const + { + Q_ASSERT(exits); + + TransitionInfoCache::const_iterator cacheIt = cache.find(t); + if (cacheIt == cache.end() || !cacheIt->exitSetIsKnown) + return false; + + *exits = cacheIt->exitSet; + return true; + } + + void insert(QAbstractTransition *t, const QSet &exits) + { + TransitionInfoCache::iterator cacheIt = cache.find(t); + TransitionInfo &ti = cacheIt == cache.end() + ? *cache.insert(t, TransitionInfo()) + : *cacheIt; + + Q_ASSERT(!ti.exitSetIsKnown); + ti.exitSet = exits; + ti.exitSetIsKnown = true; + } + + bool transitionDomain(QAbstractTransition *t, QAbstractState **domain) const + { + Q_ASSERT(domain); + + TransitionInfoCache::const_iterator cacheIt = cache.find(t); + if (cacheIt == cache.end() || !cacheIt->transitionDomainIsKnown) + return false; + + *domain = cacheIt->transitionDomain; + return true; + } + + void insert(QAbstractTransition *t, QAbstractState *domain) + { + TransitionInfoCache::iterator cacheIt = cache.find(t); + TransitionInfo &ti = cacheIt == cache.end() + ? *cache.insert(t, TransitionInfo()) + : *cacheIt; + + Q_ASSERT(!ti.transitionDomainIsKnown); + ti.transitionDomain = domain; + ti.transitionDomainIsKnown = true; + } +}; + /* The function as described in http://www.w3.org/TR/2014/WD-scxml-20140529/ : function isDescendant(state1, state2) @@ -245,8 +339,14 @@ function getEffectiveTargetStates(transition) targets.add(s) return targets */ -static QSet getEffectiveTargetStates(QAbstractTransition *transition) +static QList getEffectiveTargetStates(QAbstractTransition *transition, CalculationCache *cache) { + Q_ASSERT(cache); + + QList targetsList; + if (cache->effectiveTargetStates(transition, &targetsList)) + return targetsList; + QSet targets; foreach (QAbstractState *s, transition->targetStates()) { if (QHistoryState *historyState = QStateMachinePrivate::toHistoryState(s)) { @@ -266,7 +366,10 @@ static QSet getEffectiveTargetStates(QAbstractTransition *tran targets.insert(s); } } - return targets; + + targetsList = targets.toList(); + cache->insert(transition, targetsList); + return targetsList; } template @@ -417,8 +520,9 @@ QState *QStateMachinePrivate::findLCCA(const QList &states) con return findLCA(states, true); } -QList QStateMachinePrivate::selectTransitions(QEvent *event) +QList QStateMachinePrivate::selectTransitions(QEvent *event, CalculationCache *cache) { + Q_ASSERT(cache); Q_Q(const QStateMachine); QVarLengthArray configuration_sorted; @@ -453,7 +557,7 @@ QList QStateMachinePrivate::selectTransitions(QEvent *even } if (!enabledTransitions.isEmpty()) { - removeConflictingTransitions(enabledTransitions); + removeConflictingTransitions(enabledTransitions, cache); #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": enabled transitions after removing conflicts:" << enabledTransitions; #endif @@ -486,15 +590,20 @@ function removeConflictingTransitions(enabledTransitions): Note: the implementation below does not build the transitionsToRemove, but removes them in-place. */ -void QStateMachinePrivate::removeConflictingTransitions(QList &enabledTransitions) +void QStateMachinePrivate::removeConflictingTransitions(QList &enabledTransitions, CalculationCache *cache) { + Q_ASSERT(cache); + + if (enabledTransitions.size() == 1) + return; // There is no transition to conflict with. + QList filteredTransitions; filteredTransitions.reserve(enabledTransitions.size()); std::sort(enabledTransitions.begin(), enabledTransitions.end(), transitionStateEntryLessThan); foreach (QAbstractTransition *t1, enabledTransitions) { bool t1Preempted = false; - QSet exitSetT1 = computeExitSet_Unordered(QList() << t1); + QSet exitSetT1 = computeExitSet_Unordered(t1, cache); QList::iterator t2It = filteredTransitions.begin(); while (t2It != filteredTransitions.end()) { QAbstractTransition *t2 = *t2It; @@ -505,7 +614,7 @@ void QStateMachinePrivate::removeConflictingTransitions(QList exitSetT2 = computeExitSet_Unordered(QList() << t2); + QSet exitSetT2 = computeExitSet_Unordered(t2, cache); if (exitSetT1.intersect(exitSetT2).isEmpty()) { // No conflict, no cry. Next patient please. ++t2It; @@ -529,17 +638,20 @@ void QStateMachinePrivate::removeConflictingTransitions(QList &enabledTransitions) +void QStateMachinePrivate::microstep(QEvent *event, const QList &enabledTransitions, + CalculationCache *cache) { + Q_ASSERT(cache); + #ifdef QSTATEMACHINE_DEBUG qDebug() << q_func() << ": begin microstep( enabledTransitions:" << enabledTransitions << ')'; qDebug() << q_func() << ": configuration before exiting states:" << configuration; #endif - QList exitedStates = computeExitSet(enabledTransitions); + QList exitedStates = computeExitSet(enabledTransitions, cache); QHash pendingRestorables = computePendingRestorables(exitedStates); QSet statesForDefaultEntry; - QList enteredStates = computeEntrySet(enabledTransitions, statesForDefaultEntry); + QList enteredStates = computeEntrySet(enabledTransitions, statesForDefaultEntry, cache); #ifdef QSTATEMACHINE_DEBUG qDebug() << q_func() << ": computed exit set:" << exitedStates; @@ -598,42 +710,61 @@ function computeExitSet(transitions) statesToExit.add(s) return statesToExit */ -QList QStateMachinePrivate::computeExitSet(const QList &enabledTransitions) +QList QStateMachinePrivate::computeExitSet(const QList &enabledTransitions, + CalculationCache *cache) { - QList statesToExit_sorted = computeExitSet_Unordered(enabledTransitions).toList(); + Q_ASSERT(cache); + + QList statesToExit_sorted = computeExitSet_Unordered(enabledTransitions, cache).toList(); std::sort(statesToExit_sorted.begin(), statesToExit_sorted.end(), stateExitLessThan); return statesToExit_sorted; } -QSet QStateMachinePrivate::computeExitSet_Unordered(const QList &enabledTransitions) +QSet QStateMachinePrivate::computeExitSet_Unordered(const QList &enabledTransitions, + CalculationCache *cache) { + Q_ASSERT(cache); + QSet statesToExit; - for (int i = 0; i < enabledTransitions.size(); ++i) { - QAbstractTransition *t = enabledTransitions.at(i); - QList effectiveTargetStates = getEffectiveTargetStates(t).toList(); - QAbstractState *domain = getTransitionDomain(t, effectiveTargetStates); - if (domain == Q_NULLPTR && !t->targetStates().isEmpty()) { - // So we didn't find the least common ancestor for the source and target states of the - // transition. If there were not target states, that would be fine: then the transition - // will fire any events or signals, but not exit the state. - // - // However, there are target states, so it's either a node without a parent (or parent's - // parent, etc), or the state belongs to a different state machine. Either way, this - // makes the state machine invalid. - if (error == QStateMachine::NoError) - setError(QStateMachine::NoCommonAncestorForTransitionError, t->sourceState()); - QList lst = pendingErrorStates.toList(); - lst.prepend(t->sourceState()); - - domain = findLCCA(lst); - Q_ASSERT(domain != 0); - } + foreach (QAbstractTransition *t, enabledTransitions) + statesToExit.unite(computeExitSet_Unordered(t, cache)); + return statesToExit; +} - foreach (QAbstractState* s, configuration) { - if (isDescendant(s, domain)) - statesToExit.insert(s); - } - } +QSet QStateMachinePrivate::computeExitSet_Unordered(QAbstractTransition *t, + CalculationCache *cache) +{ + Q_ASSERT(cache); + + QSet statesToExit; + if (cache->exitSet(t, &statesToExit)) + return statesToExit; + + QList effectiveTargetStates = getEffectiveTargetStates(t, cache); + QAbstractState *domain = getTransitionDomain(t, effectiveTargetStates, cache); + if (domain == Q_NULLPTR && !t->targetStates().isEmpty()) { + // So we didn't find the least common ancestor for the source and target states of the + // transition. If there were not target states, that would be fine: then the transition + // will fire any events or signals, but not exit the state. + // + // However, there are target states, so it's either a node without a parent (or parent's + // parent, etc), or the state belongs to a different state machine. Either way, this + // makes the state machine invalid. + if (error == QStateMachine::NoError) + setError(QStateMachine::NoCommonAncestorForTransitionError, t->sourceState()); + QList lst = pendingErrorStates.toList(); + lst.prepend(t->sourceState()); + + domain = findLCCA(lst); + Q_ASSERT(domain != 0); + } + + foreach (QAbstractState* s, configuration) { + if (isDescendant(s, domain)) + statesToExit.insert(s); + } + + cache->insert(t, statesToExit); return statesToExit; } @@ -695,8 +826,11 @@ void QStateMachinePrivate::executeTransitionContent(QEvent *event, const QList QStateMachinePrivate::computeEntrySet(const QList &enabledTransitions, - QSet &statesForDefaultEntry) + QSet &statesForDefaultEntry, + CalculationCache *cache) { + Q_ASSERT(cache); + QSet statesToEnter; if (pendingErrorStates.isEmpty()) { foreach (QAbstractTransition *t, enabledTransitions) { @@ -704,8 +838,8 @@ QList QStateMachinePrivate::computeEntrySet(const QList effectiveTargetStates = getEffectiveTargetStates(t).toList(); - QAbstractState *ancestor = getTransitionDomain(t, effectiveTargetStates); + QList effectiveTargetStates = getEffectiveTargetStates(t, cache); + QAbstractState *ancestor = getTransitionDomain(t, effectiveTargetStates, cache); foreach (QAbstractState *s, effectiveTargetStates) { addAncestorStatesToEnter(s, ancestor, statesToEnter, statesForDefaultEntry); } @@ -742,11 +876,19 @@ function getTransitionDomain(t) else: return findLCCA([t.source].append(tstates)) */ -QAbstractState *QStateMachinePrivate::getTransitionDomain(QAbstractTransition *t, const QList &effectiveTargetStates) const +QAbstractState *QStateMachinePrivate::getTransitionDomain(QAbstractTransition *t, + const QList &effectiveTargetStates, + CalculationCache *cache) const { + Q_ASSERT(cache); + if (effectiveTargetStates.isEmpty()) return 0; + QAbstractState *domain = Q_NULLPTR; + if (cache->transitionDomain(t, &domain)) + return domain; + #if 0 // Qt only has external transitions, so skip the special case for the internal transitions if (QState *tSource = t->sourceState()) { @@ -768,7 +910,9 @@ QAbstractState *QStateMachinePrivate::getTransitionDomain(QAbstractTransition *t QList states(effectiveTargetStates); if (QAbstractState *src = t->sourceState()) states.prepend(src); - return findLCCA(states); + domain = findLCCA(states); + cache->insert(t, domain); + return domain; } void QStateMachinePrivate::enterStates(QEvent *event, const QList &exitedStates_sorted, @@ -1683,6 +1827,7 @@ void QStateMachinePrivate::_q_start() processingScheduled = true; // we call _q_process() below QList transitions; + CalculationCache calculationCache; QAbstractTransition *initialTransition = createInitialTransition(); transitions.append(initialTransition); @@ -1690,7 +1835,7 @@ void QStateMachinePrivate::_q_start() executeTransitionContent(&nullEvent, transitions); QList exitedStates = QList(); QSet statesForDefaultEntry; - QList enteredStates = computeEntrySet(transitions, statesForDefaultEntry); + QList enteredStates = computeEntrySet(transitions, statesForDefaultEntry, &calculationCache); QHash pendingRestorables; QHash > assignmentsForEnteredStates = computePropertyAssignments(enteredStates, pendingRestorables); @@ -1743,8 +1888,10 @@ void QStateMachinePrivate::_q_process() break; } QList enabledTransitions; + CalculationCache calculationCache; + QEvent *e = new QEvent(QEvent::None); - enabledTransitions = selectTransitions(e); + enabledTransitions = selectTransitions(e, &calculationCache); if (enabledTransitions.isEmpty()) { delete e; e = 0; @@ -1753,7 +1900,7 @@ void QStateMachinePrivate::_q_process() #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": dequeued internal event" << e << "of type" << e->type(); #endif - enabledTransitions = selectTransitions(e); + enabledTransitions = selectTransitions(e, &calculationCache); if (enabledTransitions.isEmpty()) { delete e; e = 0; @@ -1764,7 +1911,7 @@ void QStateMachinePrivate::_q_process() #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": dequeued external event" << e << "of type" << e->type(); #endif - enabledTransitions = selectTransitions(e); + enabledTransitions = selectTransitions(e, &calculationCache); if (enabledTransitions.isEmpty()) { delete e; e = 0; @@ -1778,7 +1925,7 @@ void QStateMachinePrivate::_q_process() } if (!enabledTransitions.isEmpty()) { q->beginMicrostep(e); - microstep(e, enabledTransitions); + microstep(e, enabledTransitions, &calculationCache); q->endMicrostep(e); } #ifdef QSTATEMACHINE_DEBUG diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index a88f95f1f5..28fd96f507 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -75,6 +75,7 @@ class QState; class QAbstractAnimation; #endif +struct CalculationCache; class QStateMachine; class Q_CORE_EXPORT QStateMachinePrivate : public QStatePrivate { @@ -124,13 +125,14 @@ public: void clearHistory(); QAbstractTransition *createInitialTransition() const; - void removeConflictingTransitions(QList &enabledTransitions); - void microstep(QEvent *event, const QList &transitionList); - QList selectTransitions(QEvent *event); + void removeConflictingTransitions(QList &enabledTransitions, CalculationCache *cache); + void microstep(QEvent *event, const QList &transitionList, CalculationCache *cache); + QList selectTransitions(QEvent *event, CalculationCache *cache); void exitStates(QEvent *event, const QList &statesToExit_sorted, const QHash > &assignmentsForEnteredStates); - QList computeExitSet(const QList &enabledTransitions); - QSet computeExitSet_Unordered(const QList &enabledTransitions); + QList computeExitSet(const QList &enabledTransitions, CalculationCache *cache); + QSet computeExitSet_Unordered(const QList &enabledTransitions, CalculationCache *cache); + QSet computeExitSet_Unordered(QAbstractTransition *t, CalculationCache *cache); void executeTransitionContent(QEvent *event, const QList &transitionList); void enterStates(QEvent *event, const QList &exitedStates_sorted, const QList &statesToEnter_sorted, @@ -141,9 +143,10 @@ public: #endif ); QList computeEntrySet(const QList &enabledTransitions, - QSet &statesForDefaultEntry); + QSet &statesForDefaultEntry, CalculationCache *cache); QAbstractState *getTransitionDomain(QAbstractTransition *t, - const QList &effectiveTargetStates) const; + const QList &effectiveTargetStates, + CalculationCache *cache) const; void addDescendantStatesToEnter(QAbstractState *state, QSet &statesToEnter, QSet &statesForDefaultEntry); diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 96d0a62f6b..9fb2e40cb8 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -256,10 +256,12 @@ public: Entry, Exit }; - TestState(QState *parent) - : QState(parent) {} - TestState(ChildMode mode) - : QState(mode) {} + TestState(QState *parent, const QString &objectName = QString()) + : QState(parent) + { setObjectName(objectName); } + TestState(ChildMode mode, const QString &objectName = QString()) + : QState(mode) + { setObjectName(objectName); } QList > events; protected: virtual void onEntry(QEvent *) { @@ -273,9 +275,9 @@ protected: class TestTransition : public QAbstractTransition { public: - TestTransition(QAbstractState *target) + TestTransition(QAbstractState *target, const QString &objectName = QString()) : QAbstractTransition() - { setTargetState(target); } + { setTargetState(target); setObjectName(objectName); } QList triggers; protected: virtual bool eventTest(QEvent *) { @@ -1352,15 +1354,16 @@ void tst_QStateMachine::stateEntryAndExit() { QStateMachine machine; - TestState *s1 = new TestState(&machine); - TestState *s11 = new TestState(s1); - TestState *s12 = new TestState(s1); - TestState *s2 = new TestState(&machine); + TestState *s1 = new TestState(&machine, "s1"); + TestState *s11 = new TestState(s1, "s11"); + TestState *s12 = new TestState(s1, "s12"); + TestState *s2 = new TestState(&machine, "s2"); QFinalState *s3 = new QFinalState(&machine); + s3->setObjectName("s3"); s1->setInitialState(s11); - TestTransition *t1 = new TestTransition(s12); + TestTransition *t1 = new TestTransition(s12, "t1"); s11->addTransition(t1); - TestTransition *t2 = new TestTransition(s2); + TestTransition *t2 = new TestTransition(s2, "t2"); s12->addTransition(t2); s2->addTransition(s3); -- cgit v1.2.3 From c07f5b801bd6a94fe862073eb1f1965115a56385 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 13 Apr 2015 13:54:20 +0200 Subject: QStateMachine: add internal transitions. The behavior of "external" and "internal" transitions is identical, except in the case of a transition whose source state is a compound state and whose target(s) is a descendant of the source. In such a case, an internal transition will not exit and re-enter its source state, while an external one will. [ChangeLog][State machine] Added support for internal transitions. Change-Id: I9efb1e7368ee52aa2544eb84709a00ae3d5350d3 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qabstracttransition.cpp | 46 ++++++++++++++++++++++ src/corelib/statemachine/qabstracttransition.h | 10 +++++ src/corelib/statemachine/qabstracttransition_p.h | 1 + src/corelib/statemachine/qstatemachine.cpp | 25 ++++++------ .../qstatemachine/tst_qstatemachine.cpp | 44 +++++++++++++++++++++ 5 files changed, 113 insertions(+), 13 deletions(-) diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp index f128acd54e..81b38ea4c4 100644 --- a/src/corelib/statemachine/qabstracttransition.cpp +++ b/src/corelib/statemachine/qabstracttransition.cpp @@ -101,7 +101,35 @@ QT_BEGIN_NAMESPACE parallel group state. */ +/*! + \property QAbstractTransition::transitionType + + \brief indicates whether this transition is an internal transition, or an external transition. + + Internal and external transitions behave the same, except for the case of a transition whose + source state is a compound state and whose target(s) is a descendant of the source. In such a + case, an internal transition will not exit and re-enter its source state, while an external one + will. + + By default, the type is an external transition. +*/ + +/*! + \enum QAbstractTransition::TransitionType + + This enum specifies the kind of transition. By default, the type is an external transition. + + \value ExternalTransition Any state that is the source state of a transition (which is not a + target-less transition) is left, and re-entered when necessary. + \value InternalTransition If the target state of a transition is a sub-state of a compound state, + and that compound state is the source state, an internal transition will + not leave the source state. + + \sa QAbstractTransition::transitionType +*/ + QAbstractTransitionPrivate::QAbstractTransitionPrivate() + : transitionType(QAbstractTransition::ExternalTransition) { } @@ -248,6 +276,24 @@ void QAbstractTransition::setTargetStates(const QList &targets) emit targetStatesChanged(QPrivateSignal()); } +/*! + Returns the type of the transition. +*/ +QAbstractTransition::TransitionType QAbstractTransition::transitionType() const +{ + Q_D(const QAbstractTransition); + return d->transitionType; +} + +/*! + Sets the type of the transition to \a type. +*/ +void QAbstractTransition::setTransitionType(TransitionType type) +{ + Q_D(QAbstractTransition); + d->transitionType = type; +} + /*! Returns the state machine that this transition is part of, or 0 if the transition is not part of a state machine. diff --git a/src/corelib/statemachine/qabstracttransition.h b/src/corelib/statemachine/qabstracttransition.h index 768a364a4b..bf32b3e825 100644 --- a/src/corelib/statemachine/qabstracttransition.h +++ b/src/corelib/statemachine/qabstracttransition.h @@ -59,7 +59,14 @@ class Q_CORE_EXPORT QAbstractTransition : public QObject Q_PROPERTY(QState* sourceState READ sourceState) Q_PROPERTY(QAbstractState* targetState READ targetState WRITE setTargetState NOTIFY targetStateChanged) Q_PROPERTY(QList targetStates READ targetStates WRITE setTargetStates NOTIFY targetStatesChanged) + Q_PROPERTY(TransitionType transitionType READ transitionType WRITE setTransitionType) public: + enum TransitionType { + ExternalTransition, + InternalTransition + }; + Q_ENUM(TransitionType) + QAbstractTransition(QState *sourceState = 0); virtual ~QAbstractTransition(); @@ -69,6 +76,9 @@ public: QList targetStates() const; void setTargetStates(const QList &targets); + TransitionType transitionType() const; + void setTransitionType(TransitionType type); + QStateMachine *machine() const; #ifndef QT_NO_ANIMATION diff --git a/src/corelib/statemachine/qabstracttransition_p.h b/src/corelib/statemachine/qabstracttransition_p.h index d89d057497..4b0644acd9 100644 --- a/src/corelib/statemachine/qabstracttransition_p.h +++ b/src/corelib/statemachine/qabstracttransition_p.h @@ -73,6 +73,7 @@ public: void emitTriggered(); QList > targetStates; + QAbstractTransition::TransitionType transitionType; #ifndef QT_NO_ANIMATION QList animations; diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index d91b4ba14a..6e36f93c40 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -889,23 +889,22 @@ QAbstractState *QStateMachinePrivate::getTransitionDomain(QAbstractTransition *t if (cache->transitionDomain(t, &domain)) return domain; -#if 0 - // Qt only has external transitions, so skip the special case for the internal transitions - if (QState *tSource = t->sourceState()) { - if (isCompound(tSource)) { - bool allDescendants = true; - foreach (QAbstractState *s, effectiveTargetStates) { - if (!isDescendant(s, tSource)) { - allDescendants = false; - break; + if (t->transitionType() == QAbstractTransition::InternalTransition) { + if (QState *tSource = t->sourceState()) { + if (isCompound(tSource)) { + bool allDescendants = true; + foreach (QAbstractState *s, effectiveTargetStates) { + if (!isDescendant(s, tSource)) { + allDescendants = false; + break; + } } - } - if (allDescendants) - return tSource; + if (allDescendants) + return tSource; + } } } -#endif QList states(effectiveTargetStates); if (QAbstractState *src = t->sourceState()) diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 9fb2e40cb8..6ddfb828e8 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -247,6 +247,7 @@ private slots: void qtbug_44963(); void qtbug_44783(); + void internalTransition(); }; class TestState : public QState @@ -6338,5 +6339,48 @@ void tst_QStateMachine::qtbug_44783() QVERIFY(machine.isRunning()); } +void tst_QStateMachine::internalTransition() +{ + SignalEmitter emitter; + + QStateMachine machine; + QState *s = new QState(&machine); + QState *s1 = new QState(s); + QState *s11 = new QState(s1); + + DEFINE_ACTIVE_SPY(s); + DEFINE_ACTIVE_SPY(s1); + DEFINE_ACTIVE_SPY(s11); + + machine.setInitialState(s); + s->setInitialState(s1); + s1->setInitialState(s11); + QSignalTransition *t = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s11); + t->setObjectName("s1->s11"); + t->setTransitionType(QAbstractTransition::InternalTransition); + + s->setObjectName("s"); + s1->setObjectName("s1"); + s11->setObjectName("s11"); + + machine.start(); + + QTRY_COMPARE(machine.configuration().contains(s), true); + QTRY_COMPARE(machine.configuration().contains(s1), true); + QTRY_COMPARE(machine.configuration().contains(s11), true); + TEST_ACTIVE_CHANGED(s, 1); + TEST_ACTIVE_CHANGED(s1, 1); + TEST_ACTIVE_CHANGED(s11, 1); + + emitter.emitSignalWithNoArg(); + + QTRY_COMPARE(machine.configuration().contains(s), true); + QTRY_COMPARE(machine.configuration().contains(s1), true); + QTRY_COMPARE(machine.configuration().contains(s11), true); + TEST_ACTIVE_CHANGED(s11, 3); + TEST_ACTIVE_CHANGED(s1, 1); // external transitions will return 3, internal transitions should return 1. + TEST_ACTIVE_CHANGED(s, 1); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" -- cgit v1.2.3 From cecd52b89ae6c58476c39079830908d22f52ef2d Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Tue, 17 Feb 2015 17:37:32 +0100 Subject: qstatemachine: add methods detect when a machine has processed an event currently when adding an event it is not possible to know when processing it has finished. In particular if the event is ignored no method is called. Adding virtual methods to the private implementation (binary compatibility). These methods allow for extended automatic testing of the state machines. (cherry picked from commit e7feb956280105113b3e58f12e5f32f54199a95a) Change-Id: Iaa48fb9d7f6a6cde1a8a7a2bece7b4df55c147e8 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine.cpp | 50 ++++++++++++++++++++++++++++-- src/corelib/statemachine/qstatemachine_p.h | 4 +++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 6e36f93c40..7e9d99a416 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -1878,9 +1878,11 @@ void QStateMachinePrivate::_q_process() Q_ASSERT(!processing); processing = true; processingScheduled = false; + beginMacrostep(); #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": starting the event processing loop"; #endif + bool didChange = false; while (processing) { if (stop) { processing = false; @@ -1923,15 +1925,17 @@ void QStateMachinePrivate::_q_process() } } if (!enabledTransitions.isEmpty()) { + didChange = true; q->beginMicrostep(e); microstep(e, enabledTransitions, &calculationCache); q->endMicrostep(e); } -#ifdef QSTATEMACHINE_DEBUG else { + noMicrostep(); +#ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": no transitions enabled"; - } #endif + } delete e; } #ifdef QSTATEMACHINE_DEBUG @@ -1944,6 +1948,7 @@ void QStateMachinePrivate::_q_process() switch (stopProcessingReason) { case EventQueueEmpty: + processedPendingEvents(didChange); break; case Finished: state = NotRunning; @@ -1960,6 +1965,7 @@ void QStateMachinePrivate::_q_process() emit q->runningChanged(false); break; } + endMacrostep(didChange); } void QStateMachinePrivate::_q_startDelayedEventTimer(int id, int delay) @@ -2081,6 +2087,46 @@ void QStateMachinePrivate::emitStateFinished(QState *forState, QFinalState *guil QStatePrivate::get(forState)->emitFinished(); } +/* + This function is called when the state machine is performing no + microstep because no transition is enabled (i.e. an event is ignored). + + The default implementation does nothing. +*/ +void QStateMachinePrivate::noMicrostep() +{ } + +/* + This function is called when the state machine has reached a stable + state (no pending events), and has not finished yet. + For each event the state machine receives it is guaranteed that + 1) beginMacrostep is called + 2) selectTransition is called at least once + 3) begin/endMicrostep is called at least once or noMicrostep is called + at least once (possibly both, but at least one) + 4) the state machine either enters an infinite loop, or stops (runningChanged(false), + and either finished or stopped are emitted), or processedPendingEvents() is called. + 5) if the machine is not in an infinite loop endMacrostep is called + + didChange is set to true if at least one microstep was performed, it is possible + that the machine returned to exactly the same state as before, but some transitions + were triggered. + + The default implementation does nothing. +*/ +void QStateMachinePrivate::processedPendingEvents(bool didChange) +{ + Q_UNUSED(didChange); +} + +void QStateMachinePrivate::beginMacrostep() +{ } + +void QStateMachinePrivate::endMacrostep(bool didChange) +{ + Q_UNUSED(didChange); +} + namespace _QStateMachine_Internal{ class GoToStateTransition : public QAbstractTransition diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 28fd96f507..5584bc91ab 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -128,6 +128,10 @@ public: void removeConflictingTransitions(QList &enabledTransitions, CalculationCache *cache); void microstep(QEvent *event, const QList &transitionList, CalculationCache *cache); QList selectTransitions(QEvent *event, CalculationCache *cache); + virtual void noMicrostep(); + virtual void processedPendingEvents(bool didChange); + virtual void beginMacrostep(); + virtual void endMacrostep(bool didChange); void exitStates(QEvent *event, const QList &statesToExit_sorted, const QHash > &assignmentsForEnteredStates); QList computeExitSet(const QList &enabledTransitions, CalculationCache *cache); -- cgit v1.2.3 From ec73b5d4b83df954ea68076c51e8ab6a85477a0d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 24 Apr 2015 10:24:44 +0200 Subject: QQuaternion: prepare isNull(), isIdentity() for constexpr'ification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...by dropping the use of qIsNull(), which, in Qt 4, distinguished between -0.0f and +0.0f. But mathematically, whether x, y, z are ±0 doesn't change the fact that the result is the identity element (x, y, z should contain the identity element for addition and w the one for multiplication), or the null element (additive identity). So using qIsNull() was wrong even in Qt 4. In Qt 5, qIsNull() returns true for both ±0, so we can just as well compare to 0.0f instead, which allows to mark these functions constexpr (qIsNull() can't be). Do so. Change-Id: I78b1fa7890036dd3cb4de7f90b75d439f9835e73 Reviewed-by: Konstantin Ritt --- src/gui/math3d/qquaternion.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index 52c717072d..6bed397893 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -161,12 +161,12 @@ inline QQuaternion::QQuaternion(float aScalar, float xpos, float ypos, float zpo inline bool QQuaternion::isNull() const { - return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && qIsNull(wp); + return xp == 0.0f && yp == 0.0f && zp == 0.0f && wp == 0.0f; } inline bool QQuaternion::isIdentity() const { - return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && wp == 1.0f; + return xp == 0.0f && yp == 0.0f && zp == 0.0f && wp == 1.0f; } inline float QQuaternion::x() const { return xp; } -- cgit v1.2.3 From f44f2136e07bfea792a7aafd7c2058eac0ba595d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sun, 3 May 2015 17:16:54 +0100 Subject: Add Q_REQUIRED_RESULT in several places Change-Id: Icda3000f1d9f0d41612a50a816aa5de5e32028d4 Reviewed-by: Thiago Macieira Reviewed-by: Marc Mutz --- src/corelib/io/qurl.h | 4 ++-- src/corelib/tools/qsize.h | 2 +- src/corelib/tools/qstring.h | 2 +- src/gui/math3d/qgenericmatrix.h | 2 +- src/gui/math3d/qquaternion.h | 4 ++-- src/gui/math3d/qvector2d.h | 2 +- src/gui/math3d/qvector4d.h | 2 +- src/gui/painting/qpainterpath.h | 16 ++++++++-------- src/gui/painting/qpolygon.h | 8 ++++---- 9 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h index 945b7df930..e6c570d1db 100644 --- a/src/corelib/io/qurl.h +++ b/src/corelib/io/qurl.h @@ -186,7 +186,7 @@ public: QString url(FormattingOptions options = FormattingOptions(PrettyDecoded)) const; QString toString(FormattingOptions options = FormattingOptions(PrettyDecoded)) const; QString toDisplayString(FormattingOptions options = FormattingOptions(PrettyDecoded)) const; - QUrl adjusted(FormattingOptions options) const; + QUrl adjusted(FormattingOptions options) const Q_REQUIRED_RESULT; QByteArray toEncoded(FormattingOptions options = FullyEncoded) const; static QUrl fromEncoded(const QByteArray &url, ParsingMode mode = TolerantMode); @@ -243,7 +243,7 @@ public: QString fragment(ComponentFormattingOptions options = PrettyDecoded) const; void setFragment(const QString &fragment, ParsingMode mode = TolerantMode); - QUrl resolved(const QUrl &relative) const; + QUrl resolved(const QUrl &relative) const Q_REQUIRED_RESULT; bool isRelative() const; bool isParentOf(const QUrl &url) const; diff --git a/src/corelib/tools/qsize.h b/src/corelib/tools/qsize.h index 6e7ed40dff..a5e30b10b6 100644 --- a/src/corelib/tools/qsize.h +++ b/src/corelib/tools/qsize.h @@ -54,7 +54,7 @@ public: Q_DECL_RELAXED_CONSTEXPR inline void setWidth(int w) Q_DECL_NOTHROW; Q_DECL_RELAXED_CONSTEXPR inline void setHeight(int h) Q_DECL_NOTHROW; void transpose() Q_DECL_NOTHROW; - Q_DECL_CONSTEXPR inline QSize transposed() const Q_DECL_NOTHROW; + Q_DECL_CONSTEXPR inline QSize transposed() const Q_DECL_NOTHROW Q_REQUIRED_RESULT; inline void scale(int w, int h, Qt::AspectRatioMode mode) Q_DECL_NOTHROW; inline void scale(const QSize &s, Qt::AspectRatioMode mode) Q_DECL_NOTHROW; diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index bb918f36c8..63107ff688 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -495,7 +495,7 @@ public: }; QString normalized(NormalizationForm mode, QChar::UnicodeVersion version = QChar::Unicode_Unassigned) const Q_REQUIRED_RESULT; - QString repeated(int times) const; + QString repeated(int times) const Q_REQUIRED_RESULT; const ushort *utf16() const; diff --git a/src/gui/math3d/qgenericmatrix.h b/src/gui/math3d/qgenericmatrix.h index c08faaaa8b..19809056fd 100644 --- a/src/gui/math3d/qgenericmatrix.h +++ b/src/gui/math3d/qgenericmatrix.h @@ -57,7 +57,7 @@ public: void fill(T value); - QGenericMatrix transposed() const; + QGenericMatrix transposed() const Q_REQUIRED_RESULT; QGenericMatrix& operator+=(const QGenericMatrix& other); QGenericMatrix& operator-=(const QGenericMatrix& other); diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index 6bed397893..95ce5ce6d0 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -83,12 +83,12 @@ public: float length() const; float lengthSquared() const; - QQuaternion normalized() const; + QQuaternion normalized() const Q_REQUIRED_RESULT; void normalize(); inline QQuaternion inverted() const; - QQuaternion conjugate() const; + QQuaternion conjugate() const Q_REQUIRED_RESULT; QVector3D rotatedVector(const QVector3D& vector) const; diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h index 20264fa84f..137142f381 100644 --- a/src/gui/math3d/qvector2d.h +++ b/src/gui/math3d/qvector2d.h @@ -75,7 +75,7 @@ public: float length() const; float lengthSquared() const; //In Qt 6 convert to inline and constexpr - QVector2D normalized() const; + QVector2D normalized() const Q_REQUIRED_RESULT; void normalize(); float distanceToPoint(const QVector2D &point) const; diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h index aa69104f55..72db8ac754 100644 --- a/src/gui/math3d/qvector4d.h +++ b/src/gui/math3d/qvector4d.h @@ -81,7 +81,7 @@ public: float length() const; float lengthSquared() const; //In Qt 6 convert to inline and constexpr - QVector4D normalized() const; + QVector4D normalized() const Q_REQUIRED_RESULT; void normalize(); QVector4D &operator+=(const QVector4D &vector); diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h index e037cd5bfb..4a7bd98234 100644 --- a/src/gui/painting/qpainterpath.h +++ b/src/gui/painting/qpainterpath.h @@ -147,8 +147,8 @@ public: void translate(qreal dx, qreal dy); inline void translate(const QPointF &offset); - QPainterPath translated(qreal dx, qreal dy) const; - inline QPainterPath translated(const QPointF &offset) const; + QPainterPath translated(qreal dx, qreal dy) const Q_REQUIRED_RESULT; + inline QPainterPath translated(const QPointF &offset) const Q_REQUIRED_RESULT; QRectF boundingRect() const; QRectF controlPointRect() const; @@ -158,7 +158,7 @@ public: bool isEmpty() const; - QPainterPath toReversed() const; + QPainterPath toReversed() const Q_REQUIRED_RESULT; QList toSubpathPolygons(const QMatrix &matrix = QMatrix()) const; QList toFillPolygons(const QMatrix &matrix = QMatrix()) const; QPolygonF toFillPolygon(const QMatrix &matrix = QMatrix()) const; @@ -178,12 +178,12 @@ public: bool intersects(const QPainterPath &p) const; bool contains(const QPainterPath &p) const; - QPainterPath united(const QPainterPath &r) const; - QPainterPath intersected(const QPainterPath &r) const; - QPainterPath subtracted(const QPainterPath &r) const; - QPainterPath subtractedInverted(const QPainterPath &r) const; + QPainterPath united(const QPainterPath &r) const Q_REQUIRED_RESULT; + QPainterPath intersected(const QPainterPath &r) const Q_REQUIRED_RESULT; + QPainterPath subtracted(const QPainterPath &r) const Q_REQUIRED_RESULT; + QPainterPath subtractedInverted(const QPainterPath &r) const Q_REQUIRED_RESULT; - QPainterPath simplified() const; + QPainterPath simplified() const Q_REQUIRED_RESULT; bool operator==(const QPainterPath &other) const; bool operator!=(const QPainterPath &other) const; diff --git a/src/gui/painting/qpolygon.h b/src/gui/painting/qpolygon.h index ee7d4d31ad..1549ebe2b5 100644 --- a/src/gui/painting/qpolygon.h +++ b/src/gui/painting/qpolygon.h @@ -138,7 +138,7 @@ public: void translate(const QPointF &offset); inline QPolygonF translated(qreal dx, qreal dy) const; - QPolygonF translated(const QPointF &offset) const; + QPolygonF translated(const QPointF &offset) const Q_REQUIRED_RESULT; QPolygon toPolygon() const; @@ -148,9 +148,9 @@ public: bool containsPoint(const QPointF &pt, Qt::FillRule fillRule) const; - QPolygonF united(const QPolygonF &r) const; - QPolygonF intersected(const QPolygonF &r) const; - QPolygonF subtracted(const QPolygonF &r) const; + QPolygonF united(const QPolygonF &r) const Q_REQUIRED_RESULT; + QPolygonF intersected(const QPolygonF &r) const Q_REQUIRED_RESULT; + QPolygonF subtracted(const QPolygonF &r) const Q_REQUIRED_RESULT; }; inline QPolygonF::QPolygonF(int asize) : QVector(asize) {} -- cgit v1.2.3 From 3287e7a68a3feff5c34f109b6af0f894a0362801 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 1 May 2015 18:31:54 +0200 Subject: QGraphicsWidget: call normal "setParent" when setting a parent QGraphicsWidgetPrivate::init had a special code path for setting the item's parent. For some reason that code path caused the ItemChildAddedChange notification not to be sent to the parent element, which is wrong. Instead use the "normal" path, which is what the QGraphicsItem constructor does anyhow. Change-Id: Iad84cae05d797022a45977d35ca00c80c17c306a Task-number: QTBUG-45867 Reviewed-by: Andreas Aardal Hanssen --- src/widgets/graphicsview/qgraphicswidget_p.cpp | 4 +-- .../qgraphicswidget/tst_qgraphicswidget.cpp | 32 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicswidget_p.cpp b/src/widgets/graphicsview/qgraphicswidget_p.cpp index 402d54d2d8..e9ab6dffec 100644 --- a/src/widgets/graphicsview/qgraphicswidget_p.cpp +++ b/src/widgets/graphicsview/qgraphicswidget_p.cpp @@ -64,9 +64,7 @@ void QGraphicsWidgetPrivate::init(QGraphicsItem *parentItem, Qt::WindowFlags wFl adjustWindowFlags(&wFlags); windowFlags = wFlags; - if (parentItem) - setParentItemHelper(parentItem, 0, 0); - + q->setParentItem(parentItem); q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType)); q->setGraphicsItem(q); diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp index da0c5532a5..9b92c34fb5 100644 --- a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp @@ -179,6 +179,7 @@ private slots: void task250119_shortcutContext(); void QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems(); void QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems(); + void QTBUG_45867_send_itemChildAddedChange_to_parent(); }; @@ -3490,5 +3491,36 @@ void tst_QGraphicsWidget::QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems() //This should not crash } +void tst_QGraphicsWidget::QTBUG_45867_send_itemChildAddedChange_to_parent() +{ + class GraphicsItem : public QGraphicsItem + { + public: + int m_itemChildAddedChangeNotificationsCount; + + GraphicsItem() + : QGraphicsItem(), + m_itemChildAddedChangeNotificationsCount(0) + { + } + + QRectF boundingRect() const Q_DECL_OVERRIDE { return QRectF(); } + + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) Q_DECL_OVERRIDE {} + + protected: + QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) Q_DECL_OVERRIDE + { + if (change == QGraphicsItem::ItemChildAddedChange) + ++m_itemChildAddedChangeNotificationsCount; + return QGraphicsItem::itemChange(change, value); + } + }; + + GraphicsItem item; + QGraphicsWidget widget(&item); + QCOMPARE(item.m_itemChildAddedChangeNotificationsCount, 1); +} + QTEST_MAIN(tst_QGraphicsWidget) #include "tst_qgraphicswidget.moc" -- cgit v1.2.3 From 337c279215fa6daf12a1cd1370bcbf10db809bb0 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Fri, 1 May 2015 13:15:22 +0200 Subject: Make data tables const. Moves some of them to the .rodata section, the rest at least to .data.rel.ro[.local]. Change-Id: I85676ddf22b0c0097f3f0dce4c3dc018dc29d045 Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira Reviewed-by: Giuseppe D'Angelo --- src/corelib/codecs/qicucodec.cpp | 2 +- src/gui/opengl/qopengl.cpp | 2 +- src/gui/opengl/qopenglengineshadermanager.cpp | 2 +- src/gui/opengl/qopenglfunctions.cpp | 2 +- src/gui/painting/qbrush.cpp | 2 +- src/gui/painting/qdrawhelper.cpp | 6 +++--- src/gui/painting/qdrawhelper_p.h | 4 ++-- src/gui/painting/qpaintengineex.cpp | 8 ++++---- src/gui/painting/qpdf.cpp | 2 +- src/gui/painting/qtransform.cpp | 2 +- src/gui/text/qfontengine_qpf2.cpp | 2 +- src/gui/text/qzip.cpp | 2 +- src/network/access/qnetworkcookie.cpp | 2 +- src/network/ssl/qsslcertificate.cpp | 2 +- src/opengl/gl2paintengineex/qglengineshadermanager.cpp | 2 +- src/testlib/qtestmouse.h | 2 +- src/widgets/styles/qcommonstylepixmaps_p.h | 2 +- src/widgets/styles/qstylesheetstyle.cpp | 2 +- 18 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/corelib/codecs/qicucodec.cpp b/src/corelib/codecs/qicucodec.cpp index 65cc337708..b375999aeb 100644 --- a/src/corelib/codecs/qicucodec.cpp +++ b/src/corelib/codecs/qicucodec.cpp @@ -121,7 +121,7 @@ struct MibToName { short index; }; -static MibToName mibToName[] = { +static const MibToName mibToName[] = { { 3, 0 }, { 4, 9 }, { 5, 20 }, diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index c8d33df4ba..622e014746 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -128,7 +128,7 @@ QDebug operator<<(QDebug d, const QOpenGLConfig::Gpu &g) } enum Operator { NotEqual, LessThan, LessEqualThan, Equals, GreaterThan, GreaterEqualThan }; -static const char *operators[] = {"!=", "<", "<=", "=", ">", ">="}; +static const char operators[][3] = {"!=", "<", "<=", "=", ">", ">="}; static inline QString valueKey() { return QStringLiteral("value"); } static inline QString opKey() { return QStringLiteral("op"); } diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp index 853ad8b711..7e53c01cba 100644 --- a/src/gui/opengl/qopenglengineshadermanager.cpp +++ b/src/gui/opengl/qopenglengineshadermanager.cpp @@ -511,7 +511,7 @@ GLuint QOpenGLEngineShaderManager::getUniformLocation(Uniform id) if (uniformLocations.isEmpty()) uniformLocations.fill(GLuint(-1), NumUniforms); - static const char *uniformNames[] = { + static const char *const uniformNames[] = { "imageTexture", "patternColor", "globalOpacity", diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index c60532b90b..49926a4d93 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -3568,7 +3568,7 @@ void QOpenGLExtensions::flushShared() d->flushIsSufficientToSyncContexts = false; // default to false, not guaranteed by the spec const char *vendor = (const char *) glGetString(GL_VENDOR); if (vendor) { - static const char *flushEnough[] = { "Apple", "ATI", "Intel", "NVIDIA" }; + static const char *const flushEnough[] = { "Apple", "ATI", "Intel", "NVIDIA" }; for (size_t i = 0; i < sizeof(flushEnough) / sizeof(const char *); ++i) { if (strstr(vendor, flushEnough[i])) { d->flushIsSufficientToSyncContexts = true; diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 5bf8387400..670717c5f1 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -999,7 +999,7 @@ bool QBrush::operator==(const QBrush &b) const */ QDebug operator<<(QDebug dbg, const QBrush &b) { - static const char *BRUSH_STYLES[] = { + static const char *const BRUSH_STYLES[] = { "NoBrush", "SolidPattern", "Dense1Pattern", diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 37f2de98b6..d34b2b9a44 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -675,7 +675,7 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertGrayscale8ToRGB32, convertGrayscale8FromARGB32PM, convertGrayscale8FromRGB32 } // Format_Grayscale8 }; -FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = { +const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = { 0, // BPPNone fetchPixels, // BPP1MSB fetchPixels, // BPP1LSB @@ -685,7 +685,7 @@ FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = { fetchPixels // BPP32 }; -StorePixelsFunc qStorePixels[QPixelLayout::BPPCount] = { +const StorePixelsFunc qStorePixels[QPixelLayout::BPPCount] = { 0, // BPPNone storePixels, // BPP1MSB storePixels, // BPP1LSB @@ -697,7 +697,7 @@ StorePixelsFunc qStorePixels[QPixelLayout::BPPCount] = { typedef uint (QT_FASTCALL *FetchPixelFunc)(const uchar *src, int index); -FetchPixelFunc qFetchPixel[QPixelLayout::BPPCount] = { +static const FetchPixelFunc qFetchPixel[QPixelLayout::BPPCount] = { 0, // BPPNone fetchPixel, // BPP1MSB fetchPixel, // BPP1LSB diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 0d391b2cec..66ef5949d9 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -1126,8 +1126,8 @@ typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *sr typedef void (QT_FASTCALL *StorePixelsFunc)(uchar *dest, const uint *src, int index, int count); extern QPixelLayout qPixelLayouts[QImage::NImageFormats]; -extern FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount]; -extern StorePixelsFunc qStorePixels[QPixelLayout::BPPCount]; +extern const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount]; +extern const StorePixelsFunc qStorePixels[QPixelLayout::BPPCount]; diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 0f80cd18a0..f00bc8d9df 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -238,7 +238,7 @@ bool QPaintEngineExPrivate::hasClipOperations() const * */ -static QPainterPath::ElementType qpaintengineex_ellipse_types[] = { +static const QPainterPath::ElementType qpaintengineex_ellipse_types[] = { QPainterPath::MoveToElement, QPainterPath::CurveToElement, QPainterPath::CurveToDataElement, @@ -257,7 +257,7 @@ static QPainterPath::ElementType qpaintengineex_ellipse_types[] = { QPainterPath::CurveToDataElement }; -static QPainterPath::ElementType qpaintengineex_line_types_16[] = { +static const QPainterPath::ElementType qpaintengineex_line_types_16[] = { QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::MoveToElement, QPainterPath::LineToElement, @@ -276,7 +276,7 @@ static QPainterPath::ElementType qpaintengineex_line_types_16[] = { QPainterPath::MoveToElement, QPainterPath::LineToElement }; -static QPainterPath::ElementType qpaintengineex_rect4_types_32[] = { +static const QPainterPath::ElementType qpaintengineex_rect4_types_32[] = { QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 1 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 2 QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 3 @@ -312,7 +312,7 @@ static QPainterPath::ElementType qpaintengineex_rect4_types_32[] = { }; -static QPainterPath::ElementType qpaintengineex_roundedrect_types[] = { +static const QPainterPath::ElementType qpaintengineex_roundedrect_types[] = { QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::CurveToElement, diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 3f2ebb92a0..6ea0800538 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -384,7 +384,7 @@ QByteArray QPdf::generateDashes(const QPen &pen) -static const char* pattern_for_brush[] = { +static const char* const pattern_for_brush[] = { 0, // NoBrush 0, // SolidPattern "0 J\n" diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 31d7a2300b..a3e9db2057 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1078,7 +1078,7 @@ QDataStream & operator>>(QDataStream &s, QTransform &t) #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const QTransform &m) { - static const char *typeStr[] = + static const char *const typeStr[] = { "TxNone", "TxTranslate", diff --git a/src/gui/text/qfontengine_qpf2.cpp b/src/gui/text/qfontengine_qpf2.cpp index 7e16983b6c..a678b4c8ea 100644 --- a/src/gui/text/qfontengine_qpf2.cpp +++ b/src/gui/text/qfontengine_qpf2.cpp @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE //#define DEBUG_HEADER //#define DEBUG_FONTENGINE -static QFontEngineQPF2::TagType tagTypes[QFontEngineQPF2::NumTags] = { +static const QFontEngineQPF2::TagType tagTypes[QFontEngineQPF2::NumTags] = { QFontEngineQPF2::StringType, // FontName QFontEngineQPF2::StringType, // FileName QFontEngineQPF2::UInt32Type, // FileIndex diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index 9f561dcb02..edd3447357 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -670,7 +670,7 @@ void QZipReaderPrivate::scanFiles() void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const QByteArray &contents/*, QFile::Permissions permissions, QZip::Method m*/) { #ifndef NDEBUG - static const char *entryTypes[] = { + static const char *const entryTypes[] = { "directory", "file ", "symlink " }; diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 2b11e5f993..8a24fc55fd 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -499,7 +499,7 @@ static const char zones[] = "eet\0" // 2 "jst\0" // 9 "\0"; -static int zoneOffsets[] = {-8, -8, -7, -7, -6, -6, -5, -5, -4, -3, 0, 0, 0, 1, 2, 9 }; +static const int zoneOffsets[] = {-8, -8, -7, -7, -6, -6, -5, -5, -4, -3, 0, 0, 0, 1, 2, 9 }; static const char months[] = "jan\0" diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 1aac152ca3..6f91ccdb4d 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -594,7 +594,7 @@ bool QSslCertificate::importPkcs12(QIODevice *device, // These certificates are known to be fraudulent and were created during the comodo // compromise. See http://www.comodo.com/Comodo-Fraud-Incident-2011-03-23.html -static const char *certificate_blacklist[] = { +static const char *const certificate_blacklist[] = { "04:7e:cb:e9:fc:a5:5f:7b:d0:9e:ae:36:e1:0c:ae:1e", "mail.google.com", // Comodo "f5:c8:6a:f3:61:62:f1:3a:64:f5:4f:6d:c9:58:7c:06", "www.google.com", // Comodo "d7:55:8f:da:f5:f1:10:5b:b2:13:28:2b:70:77:29:a3", "login.yahoo.com", // Comodo diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 637bd1c560..8e5d93dce2 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -508,7 +508,7 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id) if (uniformLocations.isEmpty()) uniformLocations.fill(GLuint(-1), NumUniforms); - static const char *uniformNames[] = { + static const char *const uniformNames[] = { "imageTexture", "patternColor", "globalOpacity", diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h index 2cf84a7ea0..ad6671af02 100644 --- a/src/testlib/qtestmouse.h +++ b/src/testlib/qtestmouse.h @@ -198,7 +198,7 @@ namespace QTest } QSpontaneKeyEvent::setSpontaneous(&me); if (!qApp->notify(widget, &me)) { - static const char *mouseActionNames[] = + static const char *const mouseActionNames[] = { "MousePress", "MouseRelease", "MouseClick", "MouseDClick", "MouseMove" }; QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving widget"); QTest::qWarn(warning.arg(QString::fromLatin1(mouseActionNames[static_cast(action)])).toLatin1().data()); diff --git a/src/widgets/styles/qcommonstylepixmaps_p.h b/src/widgets/styles/qcommonstylepixmaps_p.h index 471903e927..8075256158 100644 --- a/src/widgets/styles/qcommonstylepixmaps_p.h +++ b/src/widgets/styles/qcommonstylepixmaps_p.h @@ -348,7 +348,7 @@ static const char * const qt_unshade_xpm[] = { "..........", ".........."}; -static const char * dock_widget_close_xpm[] = { +static const char * const dock_widget_close_xpm[] = { "8 8 2 1", "# c #000000", ". c None", diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 4993457b32..ae7accf7d0 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -586,7 +586,7 @@ public: }; /////////////////////////////////////////////////////////////////////////////////////////// -static const char *knownStyleHints[] = { +static const char *const knownStyleHints[] = { "activate-on-singleclick", "alignment", "arrow-keys-navigate-into-children", -- cgit v1.2.3 From 2c00943da02064e776cac9b1fad6a33958ff0a3e Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Mon, 4 May 2015 09:44:59 +0300 Subject: winrt: properly retrieve font writing systems from unicode ranges This was completely broken until now because the ranges were assumed to be from the OS/2 header map. These are actual unicode ranges from the cmap, so they need to be matched by looping over the values and checking if they fall within a given writing system range. Task-number: QTBUG-44155 Done-with: Peng Wu Change-Id: I933429627c4dbf3377f41c9281df5a801057698f Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtfontdatabase.cpp | 89 ++++++++++++++++++++-- 1 file changed, 82 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp index 15767c2805..8a3205220b 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp @@ -46,6 +46,71 @@ using namespace Microsoft::WRL; QT_BEGIN_NAMESPACE +// Based on unicode range tables at http://www.microsoft.com/typography/otspec/os2.htm#ur +static QFontDatabase::WritingSystem writingSystemFromUnicodeRange(const DWRITE_UNICODE_RANGE &range) +{ + if (range.first >= 0x0000 && range.last <= 0x007F) + return QFontDatabase::Latin; + if (range.first >= 0x0370 && range.last <= 0x03FF) + return QFontDatabase::Greek; + if (range.first >= 0x0400 && range.last <= 0x04FF) + return QFontDatabase::Cyrillic; + if (range.first >= 0x0530 && range.last <= 0x058F) + return QFontDatabase::Armenian; + if (range.first >= 0x0590 && range.last <= 0x05FF) + return QFontDatabase::Hebrew; + if (range.first >= 0x0600 && range.last <= 0x06FF) + return QFontDatabase::Arabic; + if (range.first >= 0x0700 && range.last <= 0x074F) + return QFontDatabase::Syriac; + if (range.first >= 0x0780 && range.last <= 0x07BF) + return QFontDatabase::Thaana; + if (range.first >= 0x0900 && range.last <= 0x097F) + return QFontDatabase::Devanagari; + if (range.first >= 0x0980 && range.last <= 0x09FF) + return QFontDatabase::Bengali; + if (range.first >= 0x0A00 && range.last <= 0x0A7F) + return QFontDatabase::Gurmukhi; + if (range.first >= 0x0A80 && range.last <= 0x0AFF) + return QFontDatabase::Gujarati; + if (range.first >= 0x0B00 && range.last <= 0x0B7F) + return QFontDatabase::Oriya; + if (range.first >= 0x0B80 && range.last <= 0x0BFF) + return QFontDatabase::Tamil; + if (range.first >= 0x0C00 && range.last <= 0x0C7F) + return QFontDatabase::Telugu; + if (range.first >= 0x0C80 && range.last <= 0x0CFF) + return QFontDatabase::Kannada; + if (range.first >= 0x0D00 && range.last <= 0x0D7F) + return QFontDatabase::Malayalam; + if (range.first >= 0x0D80 && range.last <= 0x0DFF) + return QFontDatabase::Sinhala; + if (range.first >= 0x0E00 && range.last <= 0x0E7F) + return QFontDatabase::Thai; + if (range.first >= 0x0E80 && range.last <= 0x0EFF) + return QFontDatabase::Lao; + if (range.first >= 0x0F00 && range.last <= 0x0FFF) + return QFontDatabase::Tibetan; + if (range.first >= 0x1000 && range.last <= 0x109F) + return QFontDatabase::Myanmar; + if (range.first >= 0x10A0 && range.last <= 0x10FF) + return QFontDatabase::Georgian; + if (range.first >= 0x1780 && range.last <= 0x17FF) + return QFontDatabase::Khmer; + if (range.first >= 0x4E00 && range.last <= 0x9FFF) + return QFontDatabase::SimplifiedChinese; + if (range.first >= 0xAC00 && range.last <= 0xD7AF) + return QFontDatabase::Korean; + if (range.first >= 0x1680 && range.last <= 0x169F) + return QFontDatabase::Ogham; + if (range.first >= 0x16A0 && range.last <= 0x16FF) + return QFontDatabase::Runic; + if (range.first >= 0x07C0 && range.last <= 0x07FF) + return QFontDatabase::Nko; + + return QFontDatabase::Other; +} + QString QWinRTFontDatabase::fontDir() const { QString fontDirectory = QBasicFontDatabase::fontDir(); @@ -260,17 +325,27 @@ void QWinRTFontDatabase::populateFamily(const QString &familyName) const bool fixedPitch = fontFace->IsMonospacedFont(); - quint32 unicodeRange[4]; + // Get writing systems from unicode ranges quint32 actualRangeCount; - hr = fontFace->GetUnicodeRanges( - 2, reinterpret_cast(unicodeRange), &actualRangeCount); - if (FAILED(hr) && hr != E_NOT_SUFFICIENT_BUFFER) { // Ignore insufficient buffer; we only need 4 indices + hr = fontFace->GetUnicodeRanges(0, nullptr, &actualRangeCount); + Q_ASSERT(hr == E_NOT_SUFFICIENT_BUFFER); + QVector unicodeRanges(actualRangeCount); + hr = fontFace->GetUnicodeRanges(actualRangeCount, unicodeRanges.data(), &actualRangeCount); + if (FAILED(hr)) { qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr))); continue; } - quint32 codePageRange[2] = { 0, 0 }; - QSupportedWritingSystems writingSystems = - QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange); + QSupportedWritingSystems writingSystems; + for (quint32 i = 0; i < actualRangeCount; ++i) { + const QFontDatabase::WritingSystem writingSystem = writingSystemFromUnicodeRange(unicodeRanges.at(i)); + writingSystems.setSupported(writingSystem); + } + if (writingSystems.supported(QFontDatabase::SimplifiedChinese)) { + writingSystems.setSupported(QFontDatabase::TraditionalChinese); + writingSystems.setSupported(QFontDatabase::Japanese); + } + if (writingSystems.supported(QFontDatabase::Latin)) + writingSystems.setSupported(QFontDatabase::Vietnamese); IDWriteFontFile *fontFile; hr = fontFace->GetFiles(&fileCount, &fontFile); -- cgit v1.2.3 From 827232a74d0910252df1ea226d4db54c3a029568 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 10 Apr 2015 10:58:54 +0200 Subject: qstandardpaths_ios: return writable locations for Fonts, Music, Movies, Pictures and Download MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QStandardPaths::writableLocation() for FontsLocation, MusicLocation, MoviesLocation, PicturesLocation and DownloadLocation all return directories that point inside the sandbox, but don't exist and cannot be created. In other words, they are not usable for writing or anything else. According to iOS File System Programming Guide (*), such files should instead be located inside Documents, or sub-directories within. (*) https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW4 Task-number: QTBUG-42804 Change-Id: I54145af8058d68e0346d29de5a2bec18dafc21e7 Reviewed-by: Tor Arne Vestbø --- src/corelib/io/qstandardpaths_ios.mm | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm index 27d28526c2..4af1d93589 100644 --- a/src/corelib/io/qstandardpaths_ios.mm +++ b/src/corelib/io/qstandardpaths_ios.mm @@ -62,19 +62,22 @@ QString QStandardPaths::writableLocation(StandardLocation type) location = pathForDirectory(NSDocumentDirectory); break; case FontsLocation: - location = bundlePath() + QLatin1String("/.fonts"); + location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/.fonts"); break; case ApplicationsLocation: location = pathForDirectory(NSApplicationDirectory); break; case MusicLocation: - location = pathForDirectory(NSMusicDirectory); + // NSMusicDirectory points to a non-existing write-protected path. Use sensible fallback. + location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/Music"); break; case MoviesLocation: - location = pathForDirectory(NSMoviesDirectory); + // NSMoviesDirectory points to a non-existing write-protected path. Use sensible fallback. + location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/Movies"); break; case PicturesLocation: - location = pathForDirectory(NSPicturesDirectory); + // NSPicturesDirectory points to a non-existing write-protected path. Use sensible fallback. + location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/Pictures"); break; case TempLocation: location = QString::fromNSString(NSTemporaryDirectory()); @@ -99,7 +102,8 @@ QString QStandardPaths::writableLocation(StandardLocation type) location = pathForDirectory(NSDocumentDirectory); break; case DownloadLocation: - location = pathForDirectory(NSDownloadsDirectory); + // NSDownloadsDirectory points to a non-existing write-protected path. + location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/Download"); break; default: break; -- cgit v1.2.3 From 25311df450b1c3677091d209ebc1899bbe461869 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 10 Apr 2015 12:32:41 +0200 Subject: qstandardpaths_ios: use fallback for DesktopLocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NSDesktopDirectory points to a non-existing write-protected path inside the app sandbox. According to QSP documentation, we should fall back to use the home directory instead. Change-Id: I2c370af7758ac043eddcff84aa287eacc754ae38 Reviewed-by: Tor Arne Vestbø --- src/corelib/io/qstandardpaths_ios.mm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm index 4af1d93589..3cbdfbf40f 100644 --- a/src/corelib/io/qstandardpaths_ios.mm +++ b/src/corelib/io/qstandardpaths_ios.mm @@ -55,9 +55,6 @@ QString QStandardPaths::writableLocation(StandardLocation type) QString location; switch (type) { - case DesktopLocation: - location = pathForDirectory(NSDesktopDirectory); - break; case DocumentsLocation: location = pathForDirectory(NSDocumentDirectory); break; @@ -82,6 +79,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) case TempLocation: location = QString::fromNSString(NSTemporaryDirectory()); break; + case DesktopLocation: case HomeLocation: location = bundlePath(); break; -- cgit v1.2.3 From 12970e03123521192fa468548bf9235deabead79 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 10 Apr 2015 12:51:04 +0200 Subject: qstandardpaths_ios: return empty path for ApplicationsLocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no ApplicationsLocation on iOS (at least not one that is public API). NSApplicationDirectory just points to a non-existing write-protected path inside the app sandbox. Rather than returning something we know is wrong, it's better to return an empty string. Change-Id: I2ebc151f15509ed5699af05def5c708a56eeaf31 Reviewed-by: Tor Arne Vestbø --- src/corelib/io/qstandardpaths_ios.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm index 3cbdfbf40f..6e53b75df4 100644 --- a/src/corelib/io/qstandardpaths_ios.mm +++ b/src/corelib/io/qstandardpaths_ios.mm @@ -62,7 +62,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/.fonts"); break; case ApplicationsLocation: - location = pathForDirectory(NSApplicationDirectory); + // NSApplicationDirectory points to a non-existing write-protected path. break; case MusicLocation: // NSMusicDirectory points to a non-existing write-protected path. Use sensible fallback. -- cgit v1.2.3 From 4c8bbf8dda02a2e1f40d8b13911dbf055fbb5fcc Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 4 May 2015 16:54:54 +0200 Subject: Revert change of NOTHROW to NOEXCEPT The change would remove the noexception hint on MSVC versions that doesn't support noexcept but supports their older 'throw()' hint. Change-Id: Ie5163f2413522f427279f59c8562c0ce4769bc82 Reviewed-by: Marc Mutz --- src/gui/kernel/qpalette.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h index 78dd2ce9d7..66b3f039f4 100644 --- a/src/gui/kernel/qpalette.h +++ b/src/gui/kernel/qpalette.h @@ -61,7 +61,7 @@ public: ~QPalette(); QPalette &operator=(const QPalette &palette); #ifdef Q_COMPILER_RVALUE_REFS - QPalette(QPalette &&other) Q_DECL_NOEXCEPT + QPalette(QPalette &&other) Q_DECL_NOTHROW : d(other.d), data(other.data) { other.d = Q_NULLPTR; } inline QPalette &operator=(QPalette &&other) Q_DECL_NOEXCEPT -- cgit v1.2.3 From 96527f74e253817ce1c7ac67346d6bfd849802ab Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Tue, 28 Apr 2015 13:40:26 +0200 Subject: TestCase: Also check main source path when looking for test data This is for example useful when looking for a possible BLACKLIST file while doing a shadow build. Add autotests for blacklist. Change-Id: I41d3939d31d21d10187fefcb82604736d911b6ad Reviewed-by: Friedemann Kleint Reviewed-by: Simon Hausmann --- src/testlib/qtest.h | 11 +++ src/testlib/qtestcase.cpp | 21 +++++ src/testlib/qtestcase.h | 2 + tests/auto/testlib/selftests/blacklisted/BLACKLIST | 12 +++ .../testlib/selftests/blacklisted/blacklisted.pro | 7 ++ .../selftests/blacklisted/tst_blacklisted.cpp | 94 ++++++++++++++++++++++ .../testlib/selftests/expected_blacklisted.txt | 26 ++++++ tests/auto/testlib/selftests/selftests.pri | 1 + tests/auto/testlib/selftests/selftests.qrc | 1 + tests/auto/testlib/selftests/tst_selftests.cpp | 8 +- 10 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 tests/auto/testlib/selftests/blacklisted/BLACKLIST create mode 100644 tests/auto/testlib/selftests/blacklisted/blacklisted.pro create mode 100644 tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp create mode 100644 tests/auto/testlib/selftests/expected_blacklisted.txt diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 81cc07c410..70e923927b 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -274,10 +274,17 @@ inline bool qCompare(quint32 const &t1, quint64 const &t2, const char *actual, } QT_END_NAMESPACE +#ifdef QT_TESTCASE_BUILDDIR +# define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__, QT_TESTCASE_BUILDDIR); +#else +# define QTEST_SET_MAIN_SOURCE_PATH QTest::setMainSourcePath(__FILE__); +#endif + #define QTEST_APPLESS_MAIN(TestObject) \ int main(int argc, char *argv[]) \ { \ TestObject tc; \ + QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ } @@ -300,6 +307,7 @@ int main(int argc, char *argv[]) \ app.setAttribute(Qt::AA_Use96Dpi, true); \ QTEST_DISABLE_KEYPAD_NAVIGATION \ TestObject tc; \ + QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ } @@ -313,6 +321,7 @@ int main(int argc, char *argv[]) \ QGuiApplication app(argc, argv); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ TestObject tc; \ + QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ } @@ -324,6 +333,7 @@ int main(int argc, char *argv[]) \ QCoreApplication app(argc, argv); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ TestObject tc; \ + QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ } @@ -335,6 +345,7 @@ int main(int argc, char *argv[]) \ QCoreApplication app(argc, argv); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ TestObject tc; \ + QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ } diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index e2f98c2f04..b76e5544ba 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1332,6 +1332,7 @@ static bool installCoverageTool(const char * appname, const char * testname) namespace QTest { static QObject *currentTestObject = 0; + static QString mainSourcePath; class TestFunction { public: @@ -2932,6 +2933,13 @@ QString QTest::qFindTestData(const QString& base, const char *file, int line, co found = candidate; } + // 6. Try main source directory + if (found.isEmpty()) { + QString candidate = QTest::mainSourcePath % QLatin1Char('/') % base; + if (QFileInfo(candidate).exists()) + found = candidate; + } + if (found.isEmpty()) { QTest::qWarn(qPrintable( QString::fromLatin1("testdata %1 could not be located!").arg(base)), @@ -3118,6 +3126,19 @@ QObject *QTest::testObject() return currentTestObject; } +/*! \internal + */ +void QTest::setMainSourcePath(const char *file, const char *builddir) +{ + QString mainSourceFile = QFile::decodeName(file); + QFileInfo fi; + if (builddir) + fi.setFile(QDir(QFile::decodeName(builddir)), mainSourceFile); + else + fi.setFile(mainSourceFile); + QTest::mainSourcePath = fi.absolutePath(); +} + /*! \internal This function is called by various specializations of QTest::qCompare to decide whether to report a failure and to produce verbose test output. diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 45290de6de..2c6a94faa1 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -236,6 +236,8 @@ namespace QTest Q_TESTLIB_EXPORT int qExec(QObject *testObject, int argc = 0, char **argv = 0); Q_TESTLIB_EXPORT int qExec(QObject *testObject, const QStringList &arguments); + Q_TESTLIB_EXPORT void setMainSourcePath(const char *file, const char *builddir = 0); + Q_TESTLIB_EXPORT bool qVerify(bool statement, const char *statementStr, const char *description, const char *file, int line); Q_TESTLIB_EXPORT void qFail(const char *statementStr, const char *file, int line); diff --git a/tests/auto/testlib/selftests/blacklisted/BLACKLIST b/tests/auto/testlib/selftests/blacklisted/BLACKLIST new file mode 100644 index 0000000000..36b7699cbd --- /dev/null +++ b/tests/auto/testlib/selftests/blacklisted/BLACKLIST @@ -0,0 +1,12 @@ +[pass] +* +[skip] +* +[fail] +* +[xpass] +* +[xfail] +* +[messages] +* diff --git a/tests/auto/testlib/selftests/blacklisted/blacklisted.pro b/tests/auto/testlib/selftests/blacklisted/blacklisted.pro new file mode 100644 index 0000000000..5bd22910b1 --- /dev/null +++ b/tests/auto/testlib/selftests/blacklisted/blacklisted.pro @@ -0,0 +1,7 @@ +SOURCES += tst_blacklisted.cpp +QT = core testlib-private + +mac: CONFIG -= app_bundle +CONFIG -= debug_and_release_target + +TARGET = blacklisted diff --git a/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp b/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp new file mode 100644 index 0000000000..f1df285a51 --- /dev/null +++ b/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +class tst_Blacklisted : public QObject +{ + Q_OBJECT + +private slots: + void pass(); + void skip(); + void fail(); + void xfail(); + void xpass(); + + // This test function must be last, as it calls qFatal(). + void messages(); +}; + +// All the tests below have been blacklisted in blacklisted/BLACKLIST + +void tst_Blacklisted::pass() +{ + QVERIFY(true); +} + +void tst_Blacklisted::skip() +{ + QSKIP("This test should SKIP"); +} + +void tst_Blacklisted::fail() +{ + QVERIFY2(false, "This test should BFAIL"); +} + +void tst_Blacklisted::xfail() +{ + QEXPECT_FAIL("", "This test should XFAIL then BFAIL", Abort); + QVERIFY(false); +} + +void tst_Blacklisted::xpass() +{ + QEXPECT_FAIL("", "This test should XPASS", Abort); + QVERIFY2(true, "This test should XPASS, blacklist ignored for XPASS"); +} + +void tst_Blacklisted::messages() +{ + qWarning("This is a warning that should not appear in silent test output"); + QWARN("This is an internal testlib warning that should not appear in silent test output"); + qDebug("This is a debug message that should not appear in silent test output"); + qCritical("This is a critical message that should not appear in silent test output"); + qInfo("This is an info message that should not appear in silent test output"); + QTestLog::info("This is an internal testlib info message that should not appear in silent test output", __FILE__, __LINE__); + qFatal("This is a fatal error message that should still appear in silent test output"); +} + +QTEST_MAIN(tst_Blacklisted) +#include "tst_blacklisted.moc" diff --git a/tests/auto/testlib/selftests/expected_blacklisted.txt b/tests/auto/testlib/selftests/expected_blacklisted.txt new file mode 100644 index 0000000000..3afd93b0cc --- /dev/null +++ b/tests/auto/testlib/selftests/expected_blacklisted.txt @@ -0,0 +1,26 @@ +********* Start testing of tst_Blacklisted ********* +Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@ +PASS : tst_Blacklisted::initTestCase() +BPASS : tst_Blacklisted::pass() +SKIP : tst_Blacklisted::skip() This test should SKIP + Loc: [tst_blacklisted.cpp(62)] +BFAIL : tst_Blacklisted::fail() 'false' returned FALSE. (This test should BFAIL) + Loc: [tst_blacklisted.cpp(67)] +XFAIL : tst_Blacklisted::xfail() This test should XFAIL then BFAIL + Loc: [tst_blacklisted.cpp(73)] +BPASS : tst_Blacklisted::xfail() +XPASS : tst_Blacklisted::xpass() 'true' returned TRUE unexpectedly. (This test should XPASS, blacklist ignored for XPASS) + Loc: [tst_blacklisted.cpp(79)] +QWARN : tst_Blacklisted::messages() This is a warning that should not appear in silent test output +WARNING: tst_Blacklisted::messages() This is an internal testlib warning that should not appear in silent test output + Loc: [tst_blacklisted.cpp(85)] +QDEBUG : tst_Blacklisted::messages() This is a debug message that should not appear in silent test output +QSYSTEM: tst_Blacklisted::messages() This is a critical message that should not appear in silent test output +QINFO : tst_Blacklisted::messages() This is an info message that should not appear in silent test output +INFO : tst_Blacklisted::messages() This is an internal testlib info message that should not appear in silent test output + Loc: [tst_blacklisted.cpp(89)] +QFATAL : tst_Blacklisted::messages() This is a fatal error message that should still appear in silent test output +BFAIL : tst_Blacklisted::messages() Received a fatal error. + Loc: [Unknown file(0)] +Totals: 1 passed, 1 failed, 1 skipped, 4 blacklisted +********* Finished testing of tst_Blacklisted ********* diff --git a/tests/auto/testlib/selftests/selftests.pri b/tests/auto/testlib/selftests/selftests.pri index 7b706735a9..7404a1c49b 100644 --- a/tests/auto/testlib/selftests/selftests.pri +++ b/tests/auto/testlib/selftests/selftests.pri @@ -8,6 +8,7 @@ SUBPROGRAMS = \ benchliboptions \ benchlibtickcounter \ benchlibwalltime \ + blacklisted \ cmptest \ commandlinedata \ counting \ diff --git a/tests/auto/testlib/selftests/selftests.qrc b/tests/auto/testlib/selftests/selftests.qrc index ba567f1fb4..715e255e76 100644 --- a/tests/auto/testlib/selftests/selftests.qrc +++ b/tests/auto/testlib/selftests/selftests.qrc @@ -151,5 +151,6 @@ expected_xunit.txt expected_xunit.xml expected_xunit.xunitxml + expected_blacklisted.txt diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 488b65c657..6536f103ac 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -352,6 +352,7 @@ void tst_Selftests::runSubTest_data() << "benchlibcounting" << "benchlibeventcounter" << "benchliboptions" + << "blacklisted" << "cmptest" << "commandlinedata" << "counting" @@ -470,6 +471,9 @@ void tst_Selftests::runSubTest_data() if (subtest == "benchliboptions") { continue; } + if (subtest == "blacklisted") { + continue; + } if (subtest == "printdatatags") { continue; } @@ -503,7 +507,8 @@ void tst_Selftests::runSubTest_data() const bool crashes = subtest == QLatin1String("assert") || subtest == QLatin1String("exceptionthrow") || subtest == QLatin1String("fetchbogus") || subtest == QLatin1String("crashedterminate") - || subtest == QLatin1String("crashes") || subtest == QLatin1String("silent"); + || subtest == QLatin1String("crashes") || subtest == QLatin1String("silent") + || subtest == QLatin1String("blacklisted"); QTest::newRow(qPrintable(QString("%1 %2").arg(subtest).arg(loggerSet.name))) << subtest << loggers @@ -610,6 +615,7 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge && subdir != QLatin1String("fetchbogus") && subdir != QLatin1String("xunit") #ifdef Q_CC_MINGW + && subdir != QLatin1String("blacklisted") // calls qFatal() && subdir != QLatin1String("silent") // calls qFatal() #endif && subdir != QLatin1String("benchlibcallgrind")) -- cgit v1.2.3 From 67a24c260b910c5ada1c8c266c6d1bed9d8c5a04 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 22 Apr 2015 13:09:36 +0200 Subject: rpath: use new DTAGS if available this allows LD_LIBRARY_PATH to take precedence over the hard-coded rpath, which is the only sane thing to do (which is also why i'm not adding an option to disable it). this behavior is consistent with non-linux systems. the windows version has no auto-detection, just like for gold linker usage. Task-number: QTBUG-3069 Change-Id: Ief9ba032291c898d75d76ecc740390954382a804 Reviewed-by: Simon Hausmann --- configure | 10 ++++++++++ mkspecs/common/gcc-base-unix.conf | 1 + mkspecs/features/default_post.prf | 1 + tools/configure/configureapp.cpp | 12 ++++++++++++ 4 files changed, 24 insertions(+) diff --git a/configure b/configure index 6b59a888d4..8116d731e2 100755 --- a/configure +++ b/configure @@ -728,6 +728,7 @@ CFG_EVENTFD=auto CFG_RPATH=yes CFG_FRAMEWORK=auto CFG_USE_GOLD_LINKER=auto +CFG_ENABLE_NEW_DTAGS=auto DEFINES= INCLUDES= D_FLAGS= @@ -3442,6 +3443,13 @@ if [ "$CFG_USE_GOLD_LINKER" != "no" ]; then fi fi +# auto-detect --enable-new-dtags support +if linkerSupportsFlag $TEST_COMPILER --enable-new-dtags; then + CFG_ENABLE_NEW_DTAGS=yes +else + CFG_ENABLE_NEW_DTAGS=no +fi + # auto-detect -fstack-protector-strong support (for QNX only currently) if [ "$XPLATFORM_QNX" = "yes" ]; then if compilerSupportsFlag $TEST_COMPILER -fstack-protector-strong; then @@ -6067,6 +6075,7 @@ fi [ "$CFG_STRIP" = "no" ] && QMAKE_CONFIG="$QMAKE_CONFIG nostrip" [ "$CFG_PRECOMPILE" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG precompile_header" [ "$CFG_USE_GOLD_LINKER" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG use_gold_linker" +[ "$CFG_ENABLE_NEW_DTAGS" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG enable_new_dtags" if [ "$CFG_SEPARATE_DEBUG_INFO" = "yes" ]; then QT_CONFIG="$QT_CONFIG separate_debug_info" fi @@ -6980,6 +6989,7 @@ unset build_mode release echo " Using sanitizer(s)...... $CFG_SANITIZERS" echo " Using C++11 ............ $CFG_CXX11" echo " Using gold linker....... $CFG_USE_GOLD_LINKER" +echo " Using new DTAGS ........ $CFG_ENABLE_NEW_DTAGS" echo " Using PCH .............. $CFG_PRECOMPILE" echo " Target compiler supports:" if [ "$CFG_ARCH" = "i386" -o "$CFG_ARCH" = "x86_64" ]; then diff --git a/mkspecs/common/gcc-base-unix.conf b/mkspecs/common/gcc-base-unix.conf index 29e0521927..f82c8a8430 100644 --- a/mkspecs/common/gcc-base-unix.conf +++ b/mkspecs/common/gcc-base-unix.conf @@ -16,6 +16,7 @@ QMAKE_LFLAGS_SONAME += -Wl,-soname, QMAKE_LFLAGS_THREAD += QMAKE_LFLAGS_RPATH = -Wl,-rpath, QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link, +QMAKE_LFLAGS_NEW_DTAGS = -Wl,--enable-new-dtags QMAKE_LFLAGS_USE_GOLD = -fuse-ld=gold # -Bsymbolic-functions (ld) support diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index e967399258..8e68b95dd5 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -63,6 +63,7 @@ debug { } use_gold_linker: QMAKE_LFLAGS += $$QMAKE_LFLAGS_USE_GOLD +enable_new_dtags: QMAKE_LFLAGS += $$QMAKE_LFLAGS_NEW_DTAGS dll:win32: QMAKE_LFLAGS += $$QMAKE_LFLAGS_DLL static:mac: QMAKE_LFLAGS += $$QMAKE_LFLAGS_STATIC_LIB diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index c0e98507c7..8ea5b2ed3b 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -244,6 +244,8 @@ Configure::Configure(int& argc, char** argv) dictionary[ "USE_GOLD_LINKER" ] = "no"; + dictionary[ "ENABLE_NEW_DTAGS" ] = "no"; + dictionary[ "SHARED" ] = "yes"; dictionary[ "STATIC_RUNTIME" ] = "no"; @@ -471,6 +473,10 @@ void Configure::parseCmdLine() dictionary[ "USE_GOLD_LINKER" ] = "yes"; else if (configCmdLine.at(i) == "-no-use-gold-linker") dictionary[ "USE_GOLD_LINKER" ] = "no"; + else if (configCmdLine.at(i) == "-enable-new-dtags") + dictionary[ "ENABLE_NEW_DTAGS" ] = "yes"; + else if (configCmdLine.at(i) == "-disable-new-dtags") + dictionary[ "ENABLE_NEW_DTAGS" ] = "no"; else if (configCmdLine.at(i) == "-shared") dictionary[ "SHARED" ] = "yes"; else if (configCmdLine.at(i) == "-static") @@ -1793,6 +1799,9 @@ bool Configure::displayHelp() desc("USE_GOLD_LINKER", "yes", "-use-gold-linker", "Link using the GNU gold linker (gcc only)."); desc("USE_GOLD_LINKER", "no", "-no-use-gold-linker", "Do not link using the GNU gold linker.\n"); + desc("ENABLE_NEW_DTAGS", "yes", "-enable-new-dtags", "Use new DTAGS for RPATH (Linux only)."); + desc("ENABLE_NEW_DTAGS", "no", "-disable-new-dtags", "Do not use new DTAGS for RPATH.\n"); + desc("SHARED", "yes", "-shared", "Create and use shared Qt libraries."); desc("SHARED", "no", "-static", "Create and use static Qt libraries.\n"); @@ -2675,6 +2684,9 @@ void Configure::generateOutputVars() if (dictionary[ "USE_GOLD_LINKER" ] == "yes") qmakeConfig += "use_gold_linker"; + if (dictionary[ "ENABLE_NEW_DTAGS" ] == "yes") + qmakeConfig += "enable_new_dtags"; + if (dictionary[ "SHARED" ] == "no") qtConfig += "static"; else -- cgit v1.2.3 From 934e14127bd119c72a5c7049e0547e813180df2d Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Wed, 29 Apr 2015 13:47:01 +0200 Subject: Tests: Remove insignificant for tst_QGraphicsProxyWidget The failing test has been blacklisted in 3ed6f74fb2b. Change-Id: I5a2defd839e2f98690fc8cea9ff18e7503caf0de Task-number: QTBUG-25294 Reviewed-by: Friedemann Kleint --- .../widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro index d9d9818d6c..38fef51394 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro @@ -6,5 +6,4 @@ QT += core-private gui-private SOURCES += tst_qgraphicsproxywidget.cpp -contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-25294 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 -- cgit v1.2.3 From 7c6b6876aa8841a56a6571c6a039c67a5d649bdb Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 5 May 2015 13:51:16 +0200 Subject: qdoc: Enable prepare-phase warnings in single-exec mode In single-exec mode, QDoc must never skip documentation warnings as there is no subsequent QDoc run to re-execute the same code paths (in generate phase) that generate warnings. Change-Id: I8da2f16cfb12b3b3509249d1c9941d63733176a9 Reviewed-by: Martin Smith --- src/tools/qdoc/location.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/qdoc/location.cpp b/src/tools/qdoc/location.cpp index 12dc9e1b4c..5eba2a69ef 100644 --- a/src/tools/qdoc/location.cpp +++ b/src/tools/qdoc/location.cpp @@ -256,7 +256,7 @@ QString Location::canonicalRelativePath(const QString &path) */ void Location::warning(const QString& message, const QString& details) const { - if (!Generator::preparing()) + if (!Generator::preparing() || Generator::singleExec()) emitMessage(Warning, message, details); } @@ -267,7 +267,7 @@ void Location::warning(const QString& message, const QString& details) const */ void Location::error(const QString& message, const QString& details) const { - if (!Generator::preparing()) + if (!Generator::preparing() || Generator::singleExec()) emitMessage(Error, message, details); } -- cgit v1.2.3 From a6bcdf151647ab7a97c9fe1d2c8c8dd2b718244e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 22 Apr 2015 13:50:21 +0200 Subject: Clean up API of QPlatformPrintDevice (QPA). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The class inherited QSharedData, had a non-virtual clone() function and a non-virtual operator==() which compared QPlatformPrintDevice::id(). Derived classes implemented clone() and operator==() comparing ids to no effect. The class does not have any setters modifying its values, so detaching, copying and assigning does not make sense. Remove the inheritance, clone(), and operator==() and make the class a non-copyable base class. Use a QSharedPointer instead of a QSharedDataPointer to store it in QPrintDevice. Remove copy constructors and clone() reimplementations that were never called in implementations. Found while investigating QTBUG-44991. Task-number: QTBUG-44991 Change-Id: Ib79354b37048d04d50d936f1d0ae06c36efaac00 Reviewed-by: Morten Johan Sørvig Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/cocoa/qcocoaprintdevice.h | 5 ---- src/plugins/platforms/cocoa/qcocoaprintdevice.mm | 28 ---------------------- src/plugins/platforms/cocoa/qprintengine_mac.mm | 4 ++-- src/plugins/platforms/cocoa/qprintengine_mac_p.h | 2 +- src/plugins/printsupport/cups/qppdprintdevice.cpp | 24 ------------------- src/plugins/printsupport/cups/qppdprintdevice.h | 7 ------ .../printsupport/windows/qwindowsprintdevice.cpp | 17 ------------- .../printsupport/windows/qwindowsprintdevice.h | 7 ------ src/printsupport/kernel/qplatformprintdevice.cpp | 5 ---- src/printsupport/kernel/qplatformprintdevice.h | 7 ++---- src/printsupport/kernel/qprintdevice.cpp | 2 +- src/printsupport/kernel/qprintdevice_p.h | 2 +- 12 files changed, 7 insertions(+), 103 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.h b/src/plugins/platforms/cocoa/qcocoaprintdevice.h index 2133900048..3ac112781f 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.h +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.h @@ -60,13 +60,8 @@ class QCocoaPrintDevice : public QPlatformPrintDevice public: QCocoaPrintDevice(); explicit QCocoaPrintDevice(const QString &id); - QCocoaPrintDevice(const QCocoaPrintDevice &other); virtual ~QCocoaPrintDevice(); - QCocoaPrintDevice *clone(); - - bool operator==(const QCocoaPrintDevice &other) const; - bool isValid() const Q_DECL_OVERRIDE; bool isDefault() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm index b92ec31a11..4d319e149b 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm @@ -96,24 +96,6 @@ QCocoaPrintDevice::QCocoaPrintDevice(const QString &id) } } -QCocoaPrintDevice::QCocoaPrintDevice(const QCocoaPrintDevice &other) - : QPlatformPrintDevice(other), - m_printer(0), - m_session(0), - m_ppd(0) -{ - m_printer = other.m_printer; - PMRetain(m_printer); - m_session = other.m_session; - PMRetain(m_session); - m_macPapers = other.m_macPapers; - foreach (PMPaper paper, m_macPapers.values()) - PMRetain(paper); - openPpdFile(); - m_customMargins = other.m_customMargins; - m_printableMargins = other.m_printableMargins; -} - QCocoaPrintDevice::~QCocoaPrintDevice() { if (m_ppd) @@ -127,16 +109,6 @@ QCocoaPrintDevice::~QCocoaPrintDevice() PMRelease(m_printer); } -QCocoaPrintDevice *QCocoaPrintDevice::clone() -{ - return new QCocoaPrintDevice(*this); -} - -bool QCocoaPrintDevice::operator==(const QCocoaPrintDevice &other) const -{ - return (m_id == other.m_id); -} - bool QCocoaPrintDevice::isValid() const { return m_printer ? true : false; diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index 348b537691..9e8fe8f1c8 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -50,7 +50,7 @@ QMacPrintEngine::QMacPrintEngine(QPrinter::PrinterMode mode) : QPaintEngine(*(ne { Q_D(QMacPrintEngine); d->mode = mode; - d->m_printDevice = new QCocoaPrintDevice(QCocoaPrinterSupport().defaultPrintDeviceId()); + d->m_printDevice.reset(new QCocoaPrintDevice(QCocoaPrinterSupport().defaultPrintDeviceId())); d->m_pageLayout.setPageSize(d->m_printDevice->defaultPageSize()); d->initialize(); } @@ -558,7 +558,7 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va id = QCocoaPrinterSupport().defaultPrintDeviceId(); else if (!QCocoaPrinterSupport().availablePrintDeviceIds().contains(id)) break; - d->m_printDevice = new QCocoaPrintDevice(id); + d->m_printDevice.reset(new QCocoaPrintDevice(id)); PMPrinter printer = d->m_printDevice->macPrinter(); PMRetain(printer); PMSessionSetCurrentPMPrinter(d->session(), printer); diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h index 6a795a55d8..494fb5b9d1 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h +++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h @@ -116,7 +116,7 @@ class QMacPrintEnginePrivate : public QPaintEnginePrivate public: QPrinter::PrinterMode mode; QPrinter::PrinterState state; - QSharedDataPointer m_printDevice; + QSharedPointer m_printDevice; QPageLayout m_pageLayout; NSPrintInfo *printInfo; PMResolution resolution; diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index c2bd2872a9..808424b1ed 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -89,16 +89,6 @@ QPpdPrintDevice::QPpdPrintDevice(const QString &id) } } -QPpdPrintDevice::QPpdPrintDevice(const QPpdPrintDevice &other) - : QPlatformPrintDevice(other), - m_cupsDest(0), - m_ppd(0) -{ - m_cupsName = other.m_cupsName; - m_cupsInstance = other.m_cupsInstance; - loadPrinter(); -} - QPpdPrintDevice::~QPpdPrintDevice() { if (m_ppd) @@ -109,20 +99,6 @@ QPpdPrintDevice::~QPpdPrintDevice() m_ppd = 0; } -QPpdPrintDevice &QPpdPrintDevice::operator=(const QPpdPrintDevice &other) -{ - m_cupsName = other.m_cupsName; - m_cupsInstance = other.m_cupsInstance; - if (other.m_cupsDest && other.m_ppd) - loadPrinter(); - return *this; -} - -bool QPpdPrintDevice::operator==(const QPpdPrintDevice &other) const -{ - return (m_id == other.m_id); -} - bool QPpdPrintDevice::isValid() const { return m_cupsDest && m_ppd; diff --git a/src/plugins/printsupport/cups/qppdprintdevice.h b/src/plugins/printsupport/cups/qppdprintdevice.h index 0d618192fe..5ebcf39566 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.h +++ b/src/plugins/printsupport/cups/qppdprintdevice.h @@ -59,15 +59,8 @@ class QPpdPrintDevice : public QPlatformPrintDevice public: QPpdPrintDevice(); explicit QPpdPrintDevice(const QString &id); - QPpdPrintDevice(const QPpdPrintDevice &other); virtual ~QPpdPrintDevice(); - QPpdPrintDevice &operator=(const QPpdPrintDevice &other); - - QPpdPrintDevice *clone(); - - bool operator==(const QPpdPrintDevice &other) const; - bool isValid() const Q_DECL_OVERRIDE; bool isDefault() const Q_DECL_OVERRIDE; diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp index af8e07edd2..505f3138ca 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp @@ -113,28 +113,11 @@ QWindowsPrintDevice::QWindowsPrintDevice(const QString &id) } } -QWindowsPrintDevice::QWindowsPrintDevice(const QWindowsPrintDevice &other) - : QPlatformPrintDevice(other) -{ - OpenPrinter((LPWSTR)other.m_id.utf16(), &m_hPrinter, NULL); -} - QWindowsPrintDevice::~QWindowsPrintDevice() { ClosePrinter(m_hPrinter); } -QWindowsPrintDevice &QWindowsPrintDevice::operator=(const QWindowsPrintDevice &other) -{ - OpenPrinter((LPWSTR)other.m_id.utf16(), &m_hPrinter, NULL); - return *this; -} - -bool QWindowsPrintDevice::operator==(const QWindowsPrintDevice &other) const -{ - return (m_id == other.m_id); -} - bool QWindowsPrintDevice::isValid() const { return m_hPrinter; diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.h b/src/plugins/printsupport/windows/qwindowsprintdevice.h index 2e0f6e4658..8ab487a59c 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.h +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.h @@ -58,15 +58,8 @@ class QWindowsPrintDevice : public QPlatformPrintDevice public: QWindowsPrintDevice(); explicit QWindowsPrintDevice(const QString &id); - QWindowsPrintDevice(const QWindowsPrintDevice &other); virtual ~QWindowsPrintDevice(); - QWindowsPrintDevice &operator=(const QWindowsPrintDevice &other); - - QWindowsPrintDevice *clone(); - - bool operator==(const QWindowsPrintDevice &other) const; - bool isValid() const Q_DECL_OVERRIDE; bool isDefault() const Q_DECL_OVERRIDE; diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp index bd6d81774c..6385f58aa1 100644 --- a/src/printsupport/kernel/qplatformprintdevice.cpp +++ b/src/printsupport/kernel/qplatformprintdevice.cpp @@ -75,11 +75,6 @@ QPlatformPrintDevice::~QPlatformPrintDevice() { } -bool QPlatformPrintDevice::operator==(const QPlatformPrintDevice &other) const -{ - return m_id == other.m_id; -} - QString QPlatformPrintDevice::id() const { return m_id; diff --git a/src/printsupport/kernel/qplatformprintdevice.h b/src/printsupport/kernel/qplatformprintdevice.h index 1e21e608ad..8bb87a70f9 100644 --- a/src/printsupport/kernel/qplatformprintdevice.h +++ b/src/printsupport/kernel/qplatformprintdevice.h @@ -55,17 +55,14 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_PRINTER -class Q_PRINTSUPPORT_EXPORT QPlatformPrintDevice : public QSharedData +class Q_PRINTSUPPORT_EXPORT QPlatformPrintDevice { + Q_DISABLE_COPY(QPlatformPrintDevice) public: QPlatformPrintDevice(); explicit QPlatformPrintDevice(const QString &id); virtual ~QPlatformPrintDevice(); - QPlatformPrintDevice *clone(); - - bool operator==(const QPlatformPrintDevice &other) const; - virtual QString id() const; virtual QString name() const; virtual QString location() const; diff --git a/src/printsupport/kernel/qprintdevice.cpp b/src/printsupport/kernel/qprintdevice.cpp index 7c18b53e09..a640c14483 100644 --- a/src/printsupport/kernel/qprintdevice.cpp +++ b/src/printsupport/kernel/qprintdevice.cpp @@ -73,7 +73,7 @@ QPrintDevice &QPrintDevice::operator=(const QPrintDevice &other) bool QPrintDevice::operator==(const QPrintDevice &other) const { if (d && other.d) - return *d == *other.d; + return d->id() == other.d->id(); return d == other.d; } diff --git a/src/printsupport/kernel/qprintdevice_p.h b/src/printsupport/kernel/qprintdevice_p.h index ad55cded0e..ddf5595734 100644 --- a/src/printsupport/kernel/qprintdevice_p.h +++ b/src/printsupport/kernel/qprintdevice_p.h @@ -136,7 +136,7 @@ private: friend class QPlatformPrinterSupport; friend class QPlatformPrintDevice; QPrintDevice(QPlatformPrintDevice *dd); - QSharedDataPointer d; + QSharedPointer d; }; Q_DECLARE_SHARED(QPrintDevice) -- cgit v1.2.3 From cb0705952541f3b6d83b60ea680953a43c7bfdcf Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 30 Apr 2015 15:26:58 +0200 Subject: QShapedPixmapWindow: don't accept input focus Inform the platform that it should not activate the window when shown by setting Qt::WindowDoesNotAcceptFocus. This compliments the already set Qt::WindowTransparentForInput, which specifies that mouse/touch events should also pass through the window. In other words, the window is just for showing output and should not respond to input. Change-Id: I3e90a28be2f2e27e2044effedf64f47c94a857a5 Reviewed-by: Friedemann Kleint --- src/gui/kernel/qshapedpixmapdndwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp index 253a09e407..9d0197ef9d 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow.cpp +++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp @@ -47,7 +47,7 @@ QShapedPixmapWindow::QShapedPixmapWindow() setFormat(format); setSurfaceType(RasterSurface); setFlags(Qt::ToolTip | Qt::FramelessWindowHint | - Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput); + Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus); create(); m_backingStore = new QBackingStore(this); } -- cgit v1.2.3 From 1c7e3a2a33b890a19bbac57cd068aef04c134527 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 30 Apr 2015 15:18:44 +0200 Subject: QShapedPixmapWindow: ensure we set a valid geometry On touch platforms, QCursor::pos() will only be 'valid' when a touch event has (at least once) been translated to a mouse event. Currently this never happens in QtQuick since QtQuick always accepts all touch events and performs its own translations. So rather than setting the geometry of QShapedPixmapWindow from QCursor directly, we instead base it on mouse events. This will ensure that we never try to set the geometry of the window to an 'invalid' value, which can cause a crash on platforms like iOS. Note that we currenly miss an API in Qt to get the current touch points. When that is in place, we can also set a correct start position for the window before the first mouse move event arrives. Task-number: QTBUG-45877 Change-Id: I320598e87d43f6e9e087c204a69b95465128f468 Reviewed-by: Friedemann Kleint --- src/gui/kernel/qshapedpixmapdndwindow.cpp | 8 +++----- src/gui/kernel/qshapedpixmapdndwindow_p.h | 2 +- src/gui/kernel/qsimpledrag.cpp | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp index 9d0197ef9d..8f80789fb0 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow.cpp +++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp @@ -86,16 +86,14 @@ void QShapedPixmapWindow::setHotspot(const QPoint &hotspot) m_hotSpot = hotspot; } -void QShapedPixmapWindow::updateGeometry() +void QShapedPixmapWindow::updateGeometry(const QPoint &pos) { -#ifndef QT_NO_CURSOR - QRect rect(QCursor::pos() - m_hotSpot, m_pixmap.size()); if (m_pixmap.isNull()) m_backingStore->resize(QSize(1,1)); else if (m_backingStore->size() != m_pixmap.size()) m_backingStore->resize(m_pixmap.size()); - setGeometry(rect); -#endif + + setGeometry(QRect(pos - m_hotSpot, m_backingStore->size())); } void QShapedPixmapWindow::exposeEvent(QExposeEvent *) diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h index ec56573195..fc311cff92 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow_p.h +++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h @@ -63,7 +63,7 @@ public: void setPixmap(const QPixmap &pixmap); void setHotspot(const QPoint &hotspot); - void updateGeometry(); + void updateGeometry(const QPoint &pos); protected: void exposeEvent(QExposeEvent *) Q_DECL_OVERRIDE; diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp index 090e88c118..b850f53014 100644 --- a/src/gui/kernel/qsimpledrag.cpp +++ b/src/gui/kernel/qsimpledrag.cpp @@ -201,7 +201,16 @@ void QBasicDrag::startDrag() m_drag_icon_window->setPixmap(m_drag->pixmap()); m_drag_icon_window->setHotspot(m_drag->hotSpot()); - m_drag_icon_window->updateGeometry(); + +#ifndef QT_NO_CURSOR + QPoint pos = QCursor::pos(); + if (pos.x() == int(qInf())) { + // ### fixme: no mouse pos registered. Get pos from touch... + pos = QPoint(); + } + m_drag_icon_window->updateGeometry(pos); +#endif + m_drag_icon_window->setVisible(true); enableEventFilter(); @@ -218,10 +227,10 @@ void QBasicDrag::cancel() m_drag_icon_window->setVisible(false); } -void QBasicDrag::move(const QMouseEvent *) +void QBasicDrag::move(const QMouseEvent *e) { if (m_drag) - m_drag_icon_window->updateGeometry(); + m_drag_icon_window->updateGeometry(e->globalPos()); } void QBasicDrag::drop(const QMouseEvent *) -- cgit v1.2.3 From 9166e7a50ad15da7ca4907dd99a9bef68a67ab5b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 16 Apr 2015 10:32:53 +0200 Subject: ios: resolve m_assetUrl already in QIOSFileEngineAssetsLibrary::setFileName() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve m_assetUrl already when setting file name. The variable will be used several places in patches that follows. At the same time, change the logic to be more robust to work around QDir removing slashes (both single a double) after the scheme. In the end, what matters is that we still recognize the file name as an asset url, and that we can restore the original url based on the hash-tag contained inside the file name. Change-Id: I988c6a73b2484e46d63917b442c13aa5a3666787 Reviewed-by: Tor Arne Vestbø --- .../platforms/ios/qiosfileengineassetslibrary.h | 1 + .../platforms/ios/qiosfileengineassetslibrary.mm | 26 ++++++++++------------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.h b/src/plugins/platforms/ios/qiosfileengineassetslibrary.h index 043e101a21..0f5eb1af8a 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.h +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.h @@ -59,6 +59,7 @@ public: private: QString m_fileName; + QString m_assetUrl; qint64 m_offset; mutable QIOSAssetData *m_data; diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index 73bfc2a87f..46a43c886e 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -130,10 +130,10 @@ QPointer QIOSAssetData::g_currentAssetData = 0; // ------------------------------------------------------------------------- QIOSFileEngineAssetsLibrary::QIOSFileEngineAssetsLibrary(const QString &fileName) - : m_fileName(fileName) - , m_offset(0) + : m_offset(0) , m_data(0) { + setFileName(fileName); } QIOSFileEngineAssetsLibrary::~QIOSFileEngineAssetsLibrary() @@ -143,18 +143,8 @@ QIOSFileEngineAssetsLibrary::~QIOSFileEngineAssetsLibrary() ALAsset *QIOSFileEngineAssetsLibrary::loadAsset() const { - if (!m_data) { - // QUrl::fromLocalFile() will remove double slashes. Since the asset url is passed around as a file - // name in the app (and converted to/from a file url, e.g in QFileDialog), we need to check if we still - // have two leading slashes after the scheme, and restore the second slash if not. - QString assetUrl = m_fileName; - const int index = 16; // "assets-library://" - if (assetUrl[index] != QLatin1Char('/')) - assetUrl.insert(index, '/'); - - m_data = new QIOSAssetData(assetUrl, const_cast(this)); - } - + if (!m_data) + m_data = new QIOSAssetData(m_assetUrl, const_cast(this)); return m_data->m_asset; } @@ -245,6 +235,14 @@ void QIOSFileEngineAssetsLibrary::setFileName(const QString &file) if (m_data) close(); m_fileName = file; + // QUrl::fromLocalFile() will remove double slashes. Since the asset url is + // passed around as a file name in the app (and converted to/from a file url, e.g + // in QFileDialog), we need to ensure that m_assetUrl ends up being valid. + int index = file.indexOf(QLatin1String("asset.JPG?")); + if (index == -1) + m_assetUrl = QLatin1String("assets-library://"); + else + m_assetUrl = QLatin1String("assets-library://asset/") + file.mid(index); } QStringList QIOSFileEngineAssetsLibrary::entryList(QDir::Filters filters, const QStringList &filterNames) const -- cgit v1.2.3 From 7bc241c8d3db142c2f01b908b16cf4ede43b7301 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 24 Apr 2015 12:34:36 +0200 Subject: ios: don't report read access to assets if unauthorized access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't report read access to assets if we know that we are unauthorized to load them. Note that if authorization is ALAuthorizationStatusNotDetermined we continue to report read access, since we don't really know the permissions until we try to load. Change-Id: If51cfe9f5c57f8f33f463bddf81a77fade5fb89d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosfileengineassetslibrary.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index 46a43c886e..b7b7a589d7 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -174,8 +174,11 @@ QAbstractFileEngine::FileFlags QIOSFileEngineAssetsLibrary::fileFlags(QAbstractF if (type & FlagsMask) flags |= ExistsFlag; - if (type & PermsMask) - flags |= ReadOwnerPerm | ReadUserPerm | ReadGroupPerm | ReadOtherPerm; + if (type & PermsMask) { + ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus]; + if (status != ALAuthorizationStatusRestricted && status != ALAuthorizationStatusDenied) + flags |= ReadOwnerPerm | ReadUserPerm | ReadGroupPerm | ReadOtherPerm; + } if (type & TypesMask) flags |= FileType; -- cgit v1.2.3 From 4a4faedc3d457893058a829b3dfe74eb8170085a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 24 Apr 2015 13:24:42 +0200 Subject: ios: report correct file flags for assets 'directory' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the asset url indicates that this file engine points to the asset folder, report the file as a directory. Also, if the app is authorized to access assets, report that the directory has read access. Change-Id: Ic8f656fa30a1b2a0ec6402e8b19256bdf5f7345e Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosfileengineassetslibrary.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index b7b7a589d7..43d40e9f56 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -169,7 +169,10 @@ bool QIOSFileEngineAssetsLibrary::close() QAbstractFileEngine::FileFlags QIOSFileEngineAssetsLibrary::fileFlags(QAbstractFileEngine::FileFlags type) const { QAbstractFileEngine::FileFlags flags = 0; - if (!loadAsset()) + const bool isDir = (m_assetUrl == QLatin1String("assets-library://")); + const bool exists = isDir || loadAsset(); + + if (!exists) return flags; if (type & FlagsMask) @@ -180,7 +183,7 @@ QAbstractFileEngine::FileFlags QIOSFileEngineAssetsLibrary::fileFlags(QAbstractF flags |= ReadOwnerPerm | ReadUserPerm | ReadGroupPerm | ReadOtherPerm; } if (type & TypesMask) - flags |= FileType; + flags |= isDir ? DirectoryType : FileType; return flags; } -- cgit v1.2.3 From 39e3977cc532bcab90410bb85b7bda664dd6bfd3 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 21 Apr 2015 11:05:07 +0200 Subject: Add flip support to QPlatformBackingStore::toTexture() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Necessary for iOS. In addition to swizzle we also need to communicate the need for flipping, so switch to flags instead of bools. Task-number: QTBUG-40034 Change-Id: I055e591afd838878503be6f5f69aa7347965d9cf Reviewed-by: Tor Arne Vestbø --- src/gui/painting/qplatformbackingstore.cpp | 62 ++++++++++++++++++------------ src/gui/painting/qplatformbackingstore.h | 11 +++++- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 24ea3f4cdd..14a9429c71 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -308,7 +308,11 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i textureId = d_ptr->textureId; } else { // Backingstore texture with the normal widgets. - textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &d_ptr->needsSwizzle); + TextureFlags flags = 0; + textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &flags); + d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0; + if (flags & TextureFlip) + origin = QOpenGLTextureBlitter::OriginBottomLeft; } if (textureId) { @@ -354,43 +358,55 @@ QImage QPlatformBackingStore::toImage() const backingstore as an OpenGL texture. \a dirtyRegion is the part of the backingstore which may have changed since the last call to this function. The caller of this function must ensure that there is a current context. + The size of the texture is returned in \a textureSize. The ownership of the texture is not transferred. The caller must not store the return value between calls, but instead call this function before each use. - The default implementation returns a cached texture if \a dirtyRegion is - empty and the window has not been resized, otherwise it retrieves the - content using toImage() and performs a texture upload. + The default implementation returns a cached texture if \a dirtyRegion is empty and + \a textureSize matches the backingstore size, otherwise it retrieves the content using + toImage() and performs a texture upload. This works only if the value of \a textureSize + is preserved between the calls to this function. + + If the red and blue components have to swapped, \a flags will be set to include \c + TextureSwizzle. This allows creating textures from images in formats like + QImage::Format_RGB32 without any further image conversion. Instead, the swizzling will + be done in the shaders when performing composition. Other formats, that do not need + such swizzling due to being already byte ordered RGBA, for example + QImage::Format_RGBA8888, must result in having \a needsSwizzle set to false. - If the red and blue components have to swapped, \a needsSwizzle will be set to \c true. - This allows creating textures from images in formats like QImage::Format_RGB32 without - any further image conversion. Instead, the swizzling will be done in the shaders when - performing composition. Other formats, that do not need such swizzling due to being - already byte ordered RGBA, for example QImage::Format_RGBA8888, must result in having \a - needsSwizzle set to false. + If the image has to be flipped (e.g. because the texture is attached to an FBO), \a + flags will be set to include \c TextureFlip. */ -GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, bool *needsSwizzle) const +GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const { + Q_ASSERT(textureSize); + Q_ASSERT(flags); + QImage image = toImage(); QSize imageSize = image.size(); - if (imageSize.isEmpty()) + + *flags = 0; + if (image.format() == QImage::Format_RGB32) + *flags |= TextureSwizzle; + + if (imageSize.isEmpty()) { + *textureSize = imageSize; return 0; + } - bool resized = d_ptr->textureSize != imageSize; + // Must rely on the input only, not d_ptr. + // With the default composeAndFlush() textureSize is &d_ptr->textureSize. + bool resized = *textureSize != imageSize; if (dirtyRegion.isEmpty() && !resized) return d_ptr->textureId; + *textureSize = imageSize; + // Fast path for RGB32 and RGBA8888, convert everything else to RGBA8888. - if (image.format() == QImage::Format_RGB32) { - if (needsSwizzle) - *needsSwizzle = true; - } else { - if (needsSwizzle) - *needsSwizzle = false; - if (image.format() != QImage::Format_RGBA8888) - image = image.convertToFormat(QImage::Format_RGBA8888); - } + if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_RGBA8888) + image = image.convertToFormat(QImage::Format_RGBA8888); QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); @@ -412,8 +428,6 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, const_cast(image.constBits())); - if (textureSize) - *textureSize = imageSize; } else { funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId); QRect imageRect = image.rect(); diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index df98ebf51b..ae7314b6d0 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -114,7 +114,12 @@ public: QPlatformTextureList *textures, QOpenGLContext *context, bool translucentBackground); virtual QImage toImage() const; - virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, bool *needsSwizzle) const; + enum TextureFlag { + TextureSwizzle = 0x01, + TextureFlip = 0x02 + }; + Q_DECLARE_FLAGS(TextureFlags, TextureFlag) + virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const; #endif virtual QPlatformGraphicsBuffer *graphicsBuffer() const; @@ -130,6 +135,10 @@ private: QPlatformBackingStorePrivate *d_ptr; }; +#ifndef QT_NO_OPENGL +Q_DECLARE_OPERATORS_FOR_FLAGS(QPlatformBackingStore::TextureFlags) +#endif + QT_END_NAMESPACE #endif // QPLATFORMBACKINGSTORE_H -- cgit v1.2.3 From 4ee087d0baa441ecf21b9154bf0c460edb44ad14 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 4 May 2015 12:34:48 +0200 Subject: xcb: Fix -no-opengl builds The GLX and EGL integrations are skipped correctly but the base class still contained createPlatformOpenGLContext() with OpenGL-specific types. Task-number: QTBUG-44998 Change-Id: I727ded7ca8589b163fc1271709dd718572b51c3e Reviewed-by: Gunnar Sletta --- src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h index c71c668f31..74c117582a 100644 --- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h +++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegration.h @@ -57,7 +57,9 @@ public: virtual bool handleXcbEvent(xcb_generic_event_t *event, uint responseType); virtual QXcbWindow *createWindow(QWindow *window) const = 0; +#ifndef QT_NO_OPENGL virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const = 0; +#endif virtual QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const = 0; virtual QXcbNativeInterfaceHandler *nativeInterfaceHandler() const { return Q_NULLPTR; } -- cgit v1.2.3 From f1687148af820121a4d5e0c99e9e34c92acc3405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Tue, 5 May 2015 21:30:44 +0100 Subject: docs: QFile doesn't support QUrl style qrc paths Change-Id: I2c5f90e7d1e64d652e920bdbf9da98ad8ac1e4f9 Reviewed-by: Giuseppe D'Angelo --- src/corelib/doc/snippets/code/doc_src_resources.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/doc/snippets/code/doc_src_resources.cpp b/src/corelib/doc/snippets/code/doc_src_resources.cpp index 430c0c92c1..ab97f609ac 100644 --- a/src/corelib/doc/snippets/code/doc_src_resources.cpp +++ b/src/corelib/doc/snippets/code/doc_src_resources.cpp @@ -48,7 +48,7 @@ MyClass::MyClass() : BaseClass() { Q_INIT_RESOURCE(resources); - QFile file("qrc:/myfile.dat"); + QFile file(":/myfile.dat"); ... } //! [5] @@ -60,7 +60,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); Q_INIT_RESOURCE(graphlib); - QFile file("qrc:/graph.png"); + QFile file(":/graph.png"); ... return app.exec(); } -- cgit v1.2.3 From 762d49399089821d1d7f13cedaab74dfa68e3357 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 5 May 2015 13:11:12 +0200 Subject: cocoa: ensure app don't crash when receiving drag from other app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change 939f21be53ef introduced a crash when dragging data from a 3rd party app into the app. Basically the current code assumed that we always have QCocoaIntegration::instance()->drag()->currentDrag() but this seems to only be the case if the drag was started by the app itself. The crash was found by testing the fridgemagnets example. Just drag text from other app into the example to see it crash. Also, refactored the cursor code into a separate method to simplify code reading. Change-Id: Ica611a4452a0dd02e01451111aeda14c879f8f1b Reviewed-by: Filipe Azevedo Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 71 ++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index cb8c6ec11a..ff6cd14bc7 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1844,41 +1844,9 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin return NO; } -- (NSDragOperation)draggingEntered:(id )sender +- (void)updateCursorFromDragResponse:(QPlatformDragQtResponse)response drag:(QCocoaDrag *)drag { - return [self handleDrag : sender]; -} - -- (NSDragOperation)draggingUpdated:(id )sender -{ - return [self handleDrag : sender]; -} - -// Sends drag update to Qt, return the action -- (NSDragOperation)handleDrag:(id )sender -{ - NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil]; - QPoint qt_windowPoint(windowPoint.x, windowPoint.y); - Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]); - - QWindow *target = findEventTargetWindow(m_window); - if (!target) - return NSDragOperationNone; - - // update these so selecting move/copy/link works - QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]]; - - QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect()); - if ([sender draggingSource] != nil) { - QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); - response = QWindowSystemInterface::handleDrag(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); - } else { - QCocoaDropData mimeData([sender draggingPasteboard]); - response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); - } - - QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); - const QPixmap pixmapCursor = nativeDrag->currentDrag()->dragCursor(response.acceptedAction()); + const QPixmap pixmapCursor = drag->currentDrag()->dragCursor(response.acceptedAction()); NSCursor *nativeCursor = nil; if (pixmapCursor.isNull()) { @@ -1918,6 +1886,41 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin )); CGEventPost(kCGHIDEventTap, moveEvent); CFRelease(moveEvent); +} + +- (NSDragOperation)draggingEntered:(id )sender +{ + return [self handleDrag : sender]; +} + +- (NSDragOperation)draggingUpdated:(id )sender +{ + return [self handleDrag : sender]; +} + +// Sends drag update to Qt, return the action +- (NSDragOperation)handleDrag:(id )sender +{ + NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil]; + QPoint qt_windowPoint(windowPoint.x, windowPoint.y); + Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]); + + QWindow *target = findEventTargetWindow(m_window); + if (!target) + return NSDragOperationNone; + + // update these so selecting move/copy/link works + QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]]; + + QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect()); + if ([sender draggingSource] != nil) { + QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); + response = QWindowSystemInterface::handleDrag(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); + [self updateCursorFromDragResponse:response drag:nativeDrag]; + } else { + QCocoaDropData mimeData([sender draggingPasteboard]); + response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed); + } return qt_mac_mapDropAction(response.acceptedAction()); } -- cgit v1.2.3 From 5d7858452377c50032654b6ab4d8f743e9f5068a Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 30 Mar 2015 17:12:02 +0200 Subject: QTextTable/QTextDocumentLayout: remove dead code Change-Id: I3eb72a43129c58574036b6ca8c8c8413ca24b43a Reviewed-by: Friedemann Kleint --- src/gui/text/qtextdocumentlayout.cpp | 2 -- src/gui/text/qtexttable.cpp | 6 ------ 2 files changed, 8 deletions(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index db8a792be7..5864ca0b1a 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -504,8 +504,6 @@ public: void layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat); void layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width = 0); - void pageBreakInsideTable(QTextTable *table, QTextLayoutStruct *layoutStruct); - void floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const; QFixed findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const; diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp index e5acccb55b..a75a1aae54 100644 --- a/src/gui/text/qtexttable.cpp +++ b/src/gui/text/qtexttable.cpp @@ -1264,12 +1264,6 @@ int QTextTable::columns() const return d->nCols; } -#if 0 -void QTextTable::mergeCells(const QTextCursor &selection) -{ -} -#endif - /*! \fn QTextCursor QTextTable::rowStart(const QTextCursor &cursor) const -- cgit v1.2.3 From 91efad8ef773ce93093e2a795fd389c50e7033f0 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 6 May 2015 11:31:04 +0200 Subject: doc: document how QFileDialog can be used to pick photos on iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iab4a0842f811cd26484123e6949c9b6a0ef0d524 Reviewed-by: Topi Reiniö --- src/widgets/dialogs/qfiledialog.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 8590467abc..a9d5574428 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -893,6 +893,12 @@ void QFileDialogPrivate::_q_goToUrl(const QUrl &url) /*! Sets the file dialog's current \a directory. + + \note On iOS, if you set \a directory to \l{QStandardPaths::standardLocations()} + {QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).last()}, + a native image picker dialog will be used for accessing the user's photo album. + The filename returned can be loaded using QFile and related APIs. + This feature was added in Qt 5.5. */ void QFileDialog::setDirectory(const QString &directory) { -- cgit v1.2.3 From ae050611b4004220071cc49e456bc444d9679ddc Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 6 May 2015 15:21:27 +0200 Subject: Mark QGraphicsScene::focusNextPrevChild as virtual in Qt 6 It's supposed to mirror QWidget's one, but this one isn't virtual, making it useless. Change-Id: I0dc531bd12b5e18fa11816c03ef5b3941851198f Task-number: QTBUG-45633 Reviewed-by: Andreas Aardal Hanssen --- src/widgets/graphicsview/qgraphicsscene.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/widgets/graphicsview/qgraphicsscene.h b/src/widgets/graphicsview/qgraphicsscene.h index b025730bb1..68382bf498 100644 --- a/src/widgets/graphicsview/qgraphicsscene.h +++ b/src/widgets/graphicsview/qgraphicsscene.h @@ -282,6 +282,10 @@ protected: QWidget *widget = 0); protected Q_SLOTS: + // ### Qt 6: make unconditional +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + virtual +#endif bool focusNextPrevChild(bool next); Q_SIGNALS: -- cgit v1.2.3 From fb5530cd691699c96aa035e430459faf00dfb513 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 15 Apr 2015 10:31:24 +0200 Subject: QSettings: use QStandardPath to resolve path on iOS The current solution hard-codes a settings path that on iOS will point to a write protected path inside the sandbox. So change the QSP fallback in QSettings to also include iOS. Note that changing settings path would normally be problematic since it would cause migration issues. However, since the current solution can never have worked on iOS, starting to use QSP now should be fine. Change-Id: Iecad7d84595aee24ca0e2446fa5997296ad8b5a8 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qsettings.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index afe68125d4..413f5693f0 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -104,6 +104,10 @@ using namespace ABI::Windows::Storage; #define Q_XDG_PLATFORM #endif +#if !defined(QT_NO_STANDARDPATHS) && (defined(Q_XDG_PLATFORM) || defined(Q_OS_IOS)) +#define QSETTINGS_USE_QSTANDARDPATHS +#endif + // ************************************************************************ // QConfFile @@ -1044,7 +1048,7 @@ static void initDefaultPaths(QMutexLocker *locker) windowsConfigPath(CSIDL_COMMON_APPDATA) + QDir::separator()); #else -#if defined(QT_NO_STANDARDPATHS) || !defined(Q_XDG_PLATFORM) +#ifndef QSETTINGS_USE_QSTANDARDPATHS // Non XDG platforms (OS X, iOS, Blackberry, Android...) have used this code path erroneously // for some time now. Moving away from that would require migrating existing settings. QString userPath; -- cgit v1.2.3 From 1665e0d105fd97bfa2c6cd459ba20aa87d8b2a81 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 20 Apr 2015 12:29:35 +0200 Subject: ios: add helper class for enumerating all available assets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for enumerating all available assets on the device. Trailing patches will use the class to fetch a list of all available assets for directory listing, and to search for assets that cannot be loaded by [ALAssetsLibrary assetForURL:]. Change-Id: I319721b536b14424fc8f54f683513aa7ca64e7f0 Reviewed-by: Tor Arne Vestbø --- .../platforms/ios/qiosfileengineassetslibrary.mm | 116 +++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index 43d40e9f56..5e73e615e2 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -38,6 +38,122 @@ #include #include +#include +#include + +static const int kBufferSize = 10; +static ALAsset *kNoAsset = 0; + +class QIOSAssetEnumerator +{ +public: + QIOSAssetEnumerator(ALAssetsLibrary *assetsLibrary, ALAssetsGroupType type) + : m_semWriteAsset(dispatch_semaphore_create(kBufferSize)) + , m_semReadAsset(dispatch_semaphore_create(0)) + , m_stop(false) + , m_assetsLibrary([assetsLibrary retain]) + , m_type(type) + , m_buffer(QVector(kBufferSize)) + , m_readIndex(0) + , m_writeIndex(0) + , m_nextAssetReady(false) + { + startEnumerate(); + } + + ~QIOSAssetEnumerator() + { + m_stop = true; + + // Flush and autorelease remaining assets in the buffer + while (hasNext()) + next(); + + // Documentation states that we need to balance out calls to 'wait' + // and 'signal'. Since the enumeration function always will be one 'wait' + // ahead, we need to signal m_semProceedToNextAsset one last time. + dispatch_semaphore_signal(m_semWriteAsset); + dispatch_release(m_semReadAsset); + dispatch_release(m_semWriteAsset); + + [m_assetsLibrary autorelease]; + } + + bool hasNext() + { + if (!m_nextAssetReady) { + dispatch_semaphore_wait(m_semReadAsset, DISPATCH_TIME_FOREVER); + m_nextAssetReady = true; + } + return m_buffer[m_readIndex] != kNoAsset; + } + + ALAsset *next() + { + Q_ASSERT(m_nextAssetReady); + Q_ASSERT(m_buffer[m_readIndex]); + + ALAsset *asset = [m_buffer[m_readIndex] autorelease]; + dispatch_semaphore_signal(m_semWriteAsset); + + m_readIndex = (m_readIndex + 1) % kBufferSize; + m_nextAssetReady = false; + return asset; + } + +private: + dispatch_semaphore_t m_semWriteAsset; + dispatch_semaphore_t m_semReadAsset; + std::atomic_bool m_stop; + + ALAssetsLibrary *m_assetsLibrary; + ALAssetsGroupType m_type; + QVector m_buffer; + int m_readIndex; + int m_writeIndex; + bool m_nextAssetReady; + + void writeAsset(ALAsset *asset) + { + dispatch_semaphore_wait(m_semWriteAsset, DISPATCH_TIME_FOREVER); + m_buffer[m_writeIndex] = [asset retain]; + dispatch_semaphore_signal(m_semReadAsset); + m_writeIndex = (m_writeIndex + 1) % kBufferSize; + } + + void startEnumerate() + { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [m_assetsLibrary enumerateGroupsWithTypes:m_type usingBlock:^(ALAssetsGroup *group, BOOL *stopEnumerate) { + + if (!group) { + writeAsset(kNoAsset); + return; + } + + if (m_stop) { + *stopEnumerate = true; + return; + } + + [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stopEnumerate) { + Q_UNUSED(index); + if (!asset || ![[asset valueForProperty:ALAssetPropertyType] isEqual:ALAssetTypePhoto]) + return; + + writeAsset(asset); + *stopEnumerate = m_stop; + }]; + } failureBlock:^(NSError *error) { + NSLog(@"QIOSFileEngine: %@", error); + writeAsset(kNoAsset); + }]; + }); + } + +}; + +// ------------------------------------------------------------------------- class QIOSAssetData : public QObject { -- cgit v1.2.3 From c4054ab1b7761c7a8c3ba9d5c6527eeae61da5b6 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 16 Apr 2015 13:14:19 +0200 Subject: ios: add fallback in QIOSFileEngineAssetsLibrary for loading assets from ALAssetsGroupPhotoStream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ALAssetsLibrary assetForUrl:] will not load assets coming from ALAssetsGroupPhotoStream. Such assets can be stored in the cloud and might need to be downloaded first. Unfortunately, forcing that to happen is hidden behind private APIs ([ALAsset requestDefaultRepresentation]). So if the user through QIOSFileDialog opens the photo stream folder and chooses a photo inside it, QIOSFileEngineAssetsLibrary will fail loading it. This patch implements a work-around that basically asks ALAssetLibrary to enumerate all assets in the photo library, and stop once we find an asset with the correct url. At that point we also have a pointer to a ALAsset that can be used for loading. This is off course a slow way of loading an asset, but at least better than not being able to load it at all. Change-Id: Ie50344974f043f909ee94fa12e7eb4a40a666c7f Reviewed-by: Tor Arne Vestbø --- .../platforms/ios/qiosfileengineassetslibrary.mm | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index 5e73e615e2..84a0b57e61 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -206,6 +206,26 @@ public: NSURL *url = [NSURL URLWithString:assetUrl.toNSString()]; m_assetLibrary = [[ALAssetsLibrary alloc] init]; [m_assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) { + + if (!asset) { + // When an asset couldn't be loaded, chances are that it belongs to ALAssetsGroupPhotoStream. + // Such assets can be stored in the cloud and might need to be downloaded first. Unfortunately, + // forcing that to happen is hidden behind private APIs ([ALAsset requestDefaultRepresentation]). + // As a work-around, we search for it instead, since that will give us a pointer to the asset. + QIOSAssetEnumerator e(m_assetLibrary, ALAssetsGroupPhotoStream); + while (e.hasNext()) { + ALAsset *a = e.next(); + QString url = QUrl::fromNSURL([a valueForProperty:ALAssetPropertyAssetURL]).toString(); + if (url == assetUrl) { + asset = a; + break; + } + } + } + + if (!asset) + engine->setError(QFile::OpenError, QLatin1String("could not open image")); + m_asset = [asset retain]; dispatch_semaphore_signal(semaphore); } failureBlock:^(NSError *error) { -- cgit v1.2.3 From 8628dd71584099a338e2985718668219f31509ce Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 14 Apr 2015 14:35:17 +0200 Subject: ios: add support for fetching entry list in QIOSFileEngineAssetsLibrary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch will implement support for listing all available pictures on the device by e.g doing: QDir dir(QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).last()); QStringList list = dir.entryList(); Change-Id: I52a07ba48e074bc6e509f2ed3afc3dfea17abc5d Reviewed-by: Tor Arne Vestbø --- .../platforms/ios/qiosfileengineassetslibrary.h | 6 ++ .../platforms/ios/qiosfileengineassetslibrary.mm | 76 ++++++++++++++++++++-- 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.h b/src/plugins/platforms/ios/qiosfileengineassetslibrary.h index 0f5eb1af8a..37bbc7bf23 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.h +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.h @@ -55,6 +55,12 @@ public: QString fileName(FileName file) const Q_DECL_OVERRIDE; void setFileName(const QString &file) Q_DECL_OVERRIDE; QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const Q_DECL_OVERRIDE; + +#ifndef QT_NO_FILESYSTEMITERATOR + Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) Q_DECL_OVERRIDE; + Iterator *endEntryList() Q_DECL_OVERRIDE; +#endif + void setError(QFile::FileError error, const QString &str) { QAbstractFileEngine::setError(error, str); } private: diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index 84a0b57e61..44766b0666 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -40,6 +40,9 @@ #include #include #include +#include + +static QThreadStorage g_iteratorCurrentUrl; static const int kBufferSize = 10; static ALAsset *kNoAsset = 0; @@ -265,6 +268,58 @@ QPointer QIOSAssetData::g_currentAssetData = 0; // ------------------------------------------------------------------------- +#ifndef QT_NO_FILESYSTEMITERATOR + +class QIOSFileEngineIteratorAssetsLibrary : public QAbstractFileEngineIterator +{ +public: + QIOSAssetEnumerator *m_enumerator; + + QIOSFileEngineIteratorAssetsLibrary( + QDir::Filters filters, const QStringList &nameFilters) + : QAbstractFileEngineIterator(filters, nameFilters) + , m_enumerator(new QIOSAssetEnumerator([[[ALAssetsLibrary alloc] init] autorelease], ALAssetsGroupAll)) + { + } + + ~QIOSFileEngineIteratorAssetsLibrary() + { + delete m_enumerator; + g_iteratorCurrentUrl.setLocalData(QString()); + } + + QString next() Q_DECL_OVERRIDE + { + // Cache the URL that we are about to return, since QDir will immediately create a + // new file engine on the file and ask if it exists. Unless we do this, we end up + // creating a new ALAsset just to verify its existence, which will be especially + // costly for assets belonging to ALAssetsGroupPhotoStream. + ALAsset *asset = m_enumerator->next(); + QString url = QUrl::fromNSURL([asset valueForProperty:ALAssetPropertyAssetURL]).toString(); + g_iteratorCurrentUrl.setLocalData(url); + return url; + } + + bool hasNext() const Q_DECL_OVERRIDE + { + return m_enumerator->hasNext(); + } + + QString currentFileName() const Q_DECL_OVERRIDE + { + return g_iteratorCurrentUrl.localData(); + } + + QFileInfo currentFileInfo() const + { + return QFileInfo(currentFileName()); + } +}; + +#endif + +// ------------------------------------------------------------------------- + QIOSFileEngineAssetsLibrary::QIOSFileEngineAssetsLibrary(const QString &fileName) : m_offset(0) , m_data(0) @@ -306,7 +361,7 @@ QAbstractFileEngine::FileFlags QIOSFileEngineAssetsLibrary::fileFlags(QAbstractF { QAbstractFileEngine::FileFlags flags = 0; const bool isDir = (m_assetUrl == QLatin1String("assets-library://")); - const bool exists = isDir || loadAsset(); + const bool exists = isDir || m_assetUrl == g_iteratorCurrentUrl.localData() || loadAsset(); if (!exists) return flags; @@ -389,7 +444,20 @@ void QIOSFileEngineAssetsLibrary::setFileName(const QString &file) QStringList QIOSFileEngineAssetsLibrary::entryList(QDir::Filters filters, const QStringList &filterNames) const { - Q_UNUSED(filters); - Q_UNUSED(filterNames); - return QStringList(); + return QAbstractFileEngine::entryList(filters, filterNames); } + +#ifndef QT_NO_FILESYSTEMITERATOR + +QAbstractFileEngine::Iterator *QIOSFileEngineAssetsLibrary::beginEntryList( + QDir::Filters filters, const QStringList &filterNames) +{ + return new QIOSFileEngineIteratorAssetsLibrary(filters, filterNames); +} + +QAbstractFileEngine::Iterator *QIOSFileEngineAssetsLibrary::endEntryList() +{ + return 0; +} + +#endif -- cgit v1.2.3 From 856debeec13d0ea19f97a627c9e7d6f6732be944 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 24 Apr 2015 12:14:49 +0200 Subject: ios: factor out authorization check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Factor out the check since it's needed both when loading assets and when creating an entry list. Note that the file flags returned from the file engine will report if the asset is not readable due to authorization status, so we don't need to check this again when trying to load. Change-Id: I77ebbc370f0a7a6020ed484e53ece32bc7fa51bd Reviewed-by: Tor Arne Vestbø --- .../platforms/ios/qiosfileengineassetslibrary.mm | 61 ++++++++++++---------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index 44766b0666..c7809c75e0 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -47,6 +47,24 @@ static QThreadStorage g_iteratorCurrentUrl; static const int kBufferSize = 10; static ALAsset *kNoAsset = 0; +static void ensureAuthorizationDialogNotBlocked() +{ + if ([ALAssetsLibrary authorizationStatus] != ALAuthorizationStatusNotDetermined) + return; + if (static_cast(QObjectPrivate::get(qApp))->in_exec) + return; + + // Since authorization status has not been determined, the user will be asked + // to authorize the app. But since main has not finished, the dialog will be held + // back until the launch completes. To avoid a dead-lock below, we start an event + // loop to complete the launch. + QEventLoop loop; + QTimer::singleShot(1, &loop, &QEventLoop::quit); + loop.exec(); +} + +// ------------------------------------------------------------------------- + class QIOSAssetEnumerator { public: @@ -61,6 +79,7 @@ public: , m_writeIndex(0) , m_nextAssetReady(false) { + ensureAuthorizationDialogNotBlocked(); startEnumerate(); } @@ -166,35 +185,19 @@ public: , m_assetUrl(assetUrl) , m_assetLibrary(0) { - switch ([ALAssetsLibrary authorizationStatus]) { - case ALAuthorizationStatusRestricted: - case ALAuthorizationStatusDenied: - engine->setError(QFile::PermissionsError, QLatin1String("Unauthorized access")); - return; - case ALAuthorizationStatusNotDetermined: - if (!static_cast(QObjectPrivate::get(qApp))->in_exec) { - // Since authorization status has not been determined, the user will be asked - // to authorize the app. But since main has not finished, the dialog will be held - // back until the launch completes. To avoid a dead-lock below, we start an event - // loop to complete the launch. - QEventLoop loop; - QTimer::singleShot(1, &loop, &QEventLoop::quit); - loop.exec(); - } - break; - default: - if (g_currentAssetData) { - // It's a common pattern that QFiles pointing to the same path are created and destroyed - // several times during a single event loop cycle. To avoid loading the same asset - // over and over, we check if the last loaded asset has not been destroyed yet, and try to - // reuse its data. Since QFile is (mostly) reentrant, we need to protect m_currentAssetData - // from being modified by several threads at the same time. - QMutexLocker lock(&g_mutex); - if (g_currentAssetData && g_currentAssetData->m_assetUrl == assetUrl) { - m_assetLibrary = [g_currentAssetData->m_assetLibrary retain]; - m_asset = [g_currentAssetData->m_asset retain]; - return; - } + ensureAuthorizationDialogNotBlocked(); + + if (g_currentAssetData) { + // It's a common pattern that QFiles pointing to the same path are created and destroyed + // several times during a single event loop cycle. To avoid loading the same asset + // over and over, we check if the last loaded asset has not been destroyed yet, and try to + // reuse its data. Since QFile is (mostly) reentrant, we need to protect m_currentAssetData + // from being modified by several threads at the same time. + QMutexLocker lock(&g_mutex); + if (g_currentAssetData && g_currentAssetData->m_assetUrl == assetUrl) { + m_assetLibrary = [g_currentAssetData->m_assetLibrary retain]; + m_asset = [g_currentAssetData->m_asset retain]; + return; } } -- cgit v1.2.3 From 41492b8b68785f277a24525f08daf82271c4a8bd Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 30 Apr 2015 14:49:13 +0200 Subject: ios: don't accept first responder if Qt::WindowDoesNotAcceptFocus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I01801648a1971444e0727e1bf0790cb3a0d0aad5 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 3 +++ src/plugins/platforms/ios/quiview.mm | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 777a3c12c5..daeebee3a1 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -145,6 +145,9 @@ void QIOSWindow::setVisible(bool visible) bool QIOSWindow::shouldAutoActivateWindow() const { + if (![m_view canBecomeFirstResponder]) + return false; + // We don't want to do automatic window activation for popup windows // that are unlikely to contain editable controls (to avoid hiding // the keyboard while the popup is showing) diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 8be3515cb5..e27495877c 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -194,7 +194,7 @@ - (BOOL)canBecomeFirstResponder { - return YES; + return !(m_qioswindow->window()->flags() & Qt::WindowDoesNotAcceptFocus); } - (BOOL)becomeFirstResponder -- cgit v1.2.3 From 63a46568bf927934027259486110f82f896105f7 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 30 Apr 2015 14:58:15 +0200 Subject: ios: don't autoactivate if _q_showWithoutActivating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Widgets can have the attribute Qt::WA_ShowWithoutActivating set, which is forwarded to QWindow as a property (_q_showWithoutActivating). Both The cocoa plugin and the windows plugin check for this property before activating a window upon setVisible, so lets do the same for the iOS plugin. Note that this is not the same as shouldAutoActivate, since the window should gain focus like normal if the user taps on it. Change-Id: Ie6c95d4044906d97f0a03d27009a23d462c6ca34 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qioswindow.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index daeebee3a1..80fba00ffb 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -119,7 +119,8 @@ void QIOSWindow::setVisible(bool visible) } if (visible && shouldAutoActivateWindow()) { - requestActivateWindow(); + if (!window()->property("_q_showWithoutActivating").toBool()) + requestActivateWindow(); } else if (!visible && [m_view isActiveWindow]) { // Our window was active/focus window but now hidden, so relinquish // focus to the next possible window in the stack. -- cgit v1.2.3 From 66bd144cf18d52ae5c7340e01fb69c48c37cda46 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 4 May 2015 13:02:40 +0200 Subject: ios: implement Qt::WindowTransparentForInput MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the flag is set, report to UIKit that it should continue searching for the touch target by returning 'NO' from [UIView pointInside:]. Change-Id: I723f64fd855284fa60d0be18b2535dfa61f31381 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/quiview.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index e27495877c..6f2664e708 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -280,6 +280,12 @@ // ------------------------------------------------------------------------- +-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event +{ + if (m_qioswindow->window()->flags() & Qt::WindowTransparentForInput) + return NO; + return [super pointInside:point withEvent:event]; +} - (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state { -- cgit v1.2.3 From 1f18f2c1c1918f5d8e622f94c0504459b0a36075 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Tue, 5 May 2015 16:18:46 +0300 Subject: Doc: Fix spelling errors in the QXcbWindowFunctions docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0fe7dab6e80876b0fd17f59559295feecfd8cf63 Reviewed-by: Topi Reiniö --- src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc index 9241e685eb..414d0795fc 100644 --- a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc +++ b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.qdoc @@ -32,7 +32,7 @@ \brief The QXcbWindowFunctions class is an inline class containing miscellaneous functionality for xcb window specific functionality. - A commen usage pattern is as follows: + A common usage pattern is as follows: \snippet qxcbwindowfunctions/main.cpp 0 \note There is no binary compatibility guarantee for this class, @@ -71,7 +71,7 @@ /*! \fn QByteArray QXcbWindowFunctions::setWmWindowTypeIdentifier() - This function returnes the bytearray that can be used to query + This function returns the byte array that can be used to query QGuiApplication::platformFunction to retrieve the SetWmWindowType function. */ -- cgit v1.2.3 From fe1fb593ae52fa3e4069826f123cc9fe6705e92d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 19 Mar 2015 13:09:00 +0100 Subject: Make it explicit that a few Qt::WindowFlags are overlapping Change-Id: Ia161fb9b7196d139e22fe7b3b576c5c72ee8a2f1 Reviewed-by: Oswald Buddenhagen Reviewed-by: Simon Hausmann --- src/corelib/global/qnamespace.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 79ddf81b38..82b383e69c 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -294,10 +294,13 @@ public: WindowCloseButtonHint = 0x08000000, MacWindowToolBarButtonHint = 0x10000000, BypassGraphicsProxyWidget = 0x20000000, - WindowOkButtonHint = 0x00080000, - WindowCancelButtonHint = 0x00100000, NoDropShadowWindowHint = 0x40000000, - WindowFullscreenButtonHint = 0x80000000 + WindowFullscreenButtonHint = 0x80000000, + + // The following enums have overlapping values with other enums. + // This was not intentional, but it's too late to change now. + WindowOkButtonHint = 0x00080000, // WindowTransparentForInput + WindowCancelButtonHint = 0x00100000 // WindowOverridesSystemGestures }; Q_DECLARE_FLAGS(WindowFlags, WindowType) -- cgit v1.2.3 From e46b6db98631804c4c2a79af764190c98c408fb7 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 4 May 2015 10:56:02 +0200 Subject: ios: Add support for QOpenGLWidget and QQuickWidget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The global shared context is now always enabled on iOS. This means that contexts used by QOpenGLWindow/Widget and QQuickWindow/Widget and the iOS backingstore will share with each other. [ChangeLog][QtGui] QOpenGLWidget and QQuickWidget are now supported on iOS. Task-number: QTBUG-40034 Change-Id: Ibfb99ffcb18f8f8d263662fbf237bc348fc730ee Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosbackingstore.h | 8 ++ src/plugins/platforms/ios/qiosbackingstore.mm | 109 ++++++++++++++++++++++++-- src/plugins/platforms/ios/qioscontext.mm | 6 +- src/plugins/platforms/ios/qiosintegration.mm | 11 +++ 4 files changed, 125 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h index 68c77d9900..5d2ae429f1 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.h +++ b/src/plugins/platforms/ios/qiosbackingstore.h @@ -39,6 +39,8 @@ QT_BEGIN_NAMESPACE class QOpenGLPaintDevice; +class QOpenGLFramebufferObject; +class QOffscreenSurface; class QIOSBackingStore : public QPlatformBackingStore { @@ -49,13 +51,19 @@ public: QPaintDevice *paintDevice(); void beginPaint(const QRegion &); + void endPaint(); void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); void resize(const QSize &size, const QRegion &staticContents); + GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const; + + void makeCurrent(); private: QOpenGLContext *m_context; QOpenGLPaintDevice *m_device; + QOpenGLFramebufferObject *m_fbo; + QOffscreenSurface *m_surface; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm index acec95b0d3..875d06dc80 100644 --- a/src/plugins/platforms/ios/qiosbackingstore.mm +++ b/src/plugins/platforms/ios/qiosbackingstore.mm @@ -36,41 +36,117 @@ #include #include +#include +#include +#include #include +class QIOSPaintDevice : public QOpenGLPaintDevice +{ +public: + QIOSPaintDevice(QIOSBackingStore *backingStore) : m_backingStore(backingStore) { } + void ensureActiveTarget() Q_DECL_OVERRIDE; + +private: + QIOSBackingStore *m_backingStore; +}; + +void QIOSPaintDevice::ensureActiveTarget() +{ + m_backingStore->makeCurrent(); +} + QIOSBackingStore::QIOSBackingStore(QWindow *window) : QPlatformBackingStore(window) , m_context(new QOpenGLContext) , m_device(0) + , m_fbo(0) + , m_surface(0) { QSurfaceFormat fmt = window->requestedFormat(); - fmt.setDepthBufferSize(16); - fmt.setStencilBufferSize(8); + // Due to sharing QIOSContext redirects our makeCurrent on window() attempts to + // the global share context. Hence it is essential to have a compatible format. + fmt.setDepthBufferSize(QSurfaceFormat::defaultFormat().depthBufferSize()); + fmt.setStencilBufferSize(QSurfaceFormat::defaultFormat().stencilBufferSize()); + + if (fmt.depthBufferSize() == 0) + qWarning("No depth in default format, expect rendering errors"); - // Needed to prevent QOpenGLContext::makeCurrent() from failing - window->setSurfaceType(QSurface::OpenGLSurface); + if (window->surfaceType() == QSurface::RasterSurface) + window->setSurfaceType(QSurface::OpenGLSurface); m_context->setFormat(fmt); m_context->setScreen(window->screen()); + Q_ASSERT(QOpenGLContext::globalShareContext()); + m_context->setShareContext(QOpenGLContext::globalShareContext()); m_context->create(); } QIOSBackingStore::~QIOSBackingStore() { + delete m_fbo; + delete m_surface; delete m_context; delete m_device; } +void QIOSBackingStore::makeCurrent() +{ + QSurface *surface = m_surface ? m_surface : static_cast(window()); + if (!m_context->makeCurrent(surface)) + qWarning("QIOSBackingStore: makeCurrent() failed"); + if (m_fbo) + m_fbo->bind(); +} + void QIOSBackingStore::beginPaint(const QRegion &) { - m_context->makeCurrent(window()); + if (qt_window_private(window())->compositing) { + if (!m_fbo) { + delete m_device; + m_device = 0; + } + if (!m_surface) { + m_surface = new QOffscreenSurface; + m_surface->setFormat(m_context->format()); + m_surface->create(); + } + if (!m_context->makeCurrent(m_surface)) + qWarning("QIOSBackingStore: Failed to make offscreen surface current"); + const QSize size = window()->size() * window()->devicePixelRatio(); + if (m_fbo && m_fbo->size() != size) { + delete m_fbo; + m_fbo = 0; + } + if (!m_fbo) + m_fbo = new QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::CombinedDepthStencil); + } else if (m_fbo) { + delete m_fbo; + m_fbo = 0; + delete m_surface; + m_surface = 0; + delete m_device; + m_device = 0; + } + + makeCurrent(); + + if (!m_device) + m_device = new QIOSPaintDevice(this); +} + +void QIOSBackingStore::endPaint() +{ + if (m_fbo) { + m_fbo->release(); + glFlush(); + } } QPaintDevice *QIOSBackingStore::paintDevice() { - if (!m_device) - m_device = new QOpenGLPaintDevice; + Q_ASSERT(m_device); // Keep paint device size and device pixel ratio in sync with window qreal devicePixelRatio = window()->devicePixelRatio(); @@ -82,6 +158,8 @@ QPaintDevice *QIOSBackingStore::paintDevice() void QIOSBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { + Q_ASSERT(!qt_window_private(window)->compositing); + Q_UNUSED(region); Q_UNUSED(offset); @@ -111,4 +189,21 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents) qWarning() << "QIOSBackingStore needs to have the same size as its window"; } +GLuint QIOSBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const +{ + Q_ASSERT(qt_window_private(window())->compositing); + Q_UNUSED(dirtyRegion); + + if (flags) + *flags = TextureFlip; + + if (!m_fbo) + return 0; + + if (textureSize) + *textureSize = m_fbo->size(); + + return m_fbo->texture(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index c7541fc51b..fe0ca33c13 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -116,7 +116,8 @@ static QString fboStatusString(GLenum status) bool QIOSContext::makeCurrent(QPlatformSurface *surface) { - Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(surface && (surface->surface()->surfaceType() == QSurface::OpenGLSurface + || surface->surface()->surfaceType() == QSurface::RasterGLSurface)); [EAGLContext setCurrentContext:m_eaglContext]; @@ -141,7 +142,8 @@ void QIOSContext::doneCurrent() void QIOSContext::swapBuffers(QPlatformSurface *surface) { - Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface); + Q_ASSERT(surface && (surface->surface()->surfaceType() == QSurface::OpenGLSurface + || surface->surface()->surfaceType() == QSurface::RasterGLSurface)); if (surface->surface()->surfaceClass() == QSurface::Offscreen) return; // Nothing to do diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 7cd4280f5e..837d0e9143 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -77,6 +77,15 @@ QIOSIntegration::QIOSIntegration() "'applicationDidFinishLaunching' inside your UIApplication delegate.\n"); } + // The backingstore needs a global share context in order to support composition in + // QPlatformBackingStore. + qApp->setAttribute(Qt::AA_ShareOpenGLContexts, true); + // And that context must match the format used for the backingstore's context. + QSurfaceFormat fmt; + fmt.setDepthBufferSize(16); + fmt.setStencilBufferSize(8); + QSurfaceFormat::setDefaultFormat(fmt); + // Set current directory to app bundle folder QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String])); @@ -137,6 +146,8 @@ bool QIOSIntegration::hasCapability(Capability cap) const return false; case ApplicationState: return true; + case RasterGLSurface: + return true; default: return QPlatformIntegration::hasCapability(cap); } -- cgit v1.2.3 From eb4bf7df60a95028e33c721f249ab328738ac462 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 22 Apr 2015 12:24:16 +0200 Subject: QStateMachine: Fix transition ordering. When there are conflicting transitions, a transition that is nested deeper (i.e. more specific) has priority. If two transitions have the same nesting level, the one that comes first in the document order gets priority. Before this patch, only the document order was considered. Change-Id: I58f188c270cabe2c386a783ceef7a0a955105425 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine.cpp | 37 +++++++++++-- .../qstatemachine/tst_qstatemachine.cpp | 64 ++++++++++++++++++++++ 2 files changed, 96 insertions(+), 5 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 7e9d99a416..25c9343943 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -299,6 +299,17 @@ static bool containsDecendantOf(const QSet &states, const QAbs return false; } +static int descendantDepth(const QAbstractState *state, const QAbstractState *ancestor) +{ + int depth = 0; + for (const QAbstractState *it = state; it != 0; it = it->parentState()) { + if (it == ancestor) + break; + ++depth; + } + return depth; +} + /* The function as described in http://www.w3.org/TR/2014/WD-scxml-20140529/ : function getProperAncestors(state1, state2) @@ -451,10 +462,25 @@ static int indexOfDescendant(QState *s, QAbstractState *desc) bool QStateMachinePrivate::transitionStateEntryLessThan(QAbstractTransition *t1, QAbstractTransition *t2) { QState *s1 = t1->sourceState(), *s2 = t2->sourceState(); - if (s1 == s2) - return QStatePrivate::get(s1)->transitions().indexOf(t1) < QStatePrivate::get(s2)->transitions().indexOf(t2); - else - return stateEntryLessThan(t1->sourceState(), t2->sourceState()); + if (s1 == s2) { + QList transitions = QStatePrivate::get(s1)->transitions(); + return transitions.indexOf(t1) < transitions.indexOf(t2); + } else if (isDescendant(s1, s2)) { + return true; + } else if (isDescendant(s2, s1)) { + return false; + } else { + Q_ASSERT(s1->machine() != 0); + QStateMachinePrivate *mach = QStateMachinePrivate::get(s1->machine()); + QState *lca = mach->findLCA(QList() << s1 << s2); + Q_ASSERT(lca != 0); + int s1Depth = descendantDepth(s1, lca); + int s2Depth = descendantDepth(s2, lca); + if (s1Depth == s2Depth) + return (indexOfDescendant(lca, s1) < indexOfDescendant(lca, s2)); + else + return s1Depth > s2Depth; + } } bool QStateMachinePrivate::stateEntryLessThan(QAbstractState *s1, QAbstractState *s2) @@ -594,7 +620,7 @@ void QStateMachinePrivate::removeConflictingTransitions(QList filteredTransitions; @@ -2081,6 +2107,7 @@ void QStateMachinePrivate::emitStateFinished(QState *forState, QFinalState *guil Q_ASSERT(guiltyState); #ifdef QSTATEMACHINE_DEBUG + Q_Q(QStateMachine); qDebug() << q << ": emitting finished signal for" << forState; #endif diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 6ddfb828e8..3718b07b33 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -248,6 +248,7 @@ private slots: void qtbug_44963(); void qtbug_44783(); void internalTransition(); + void conflictingTransition(); }; class TestState : public QState @@ -6382,5 +6383,68 @@ void tst_QStateMachine::internalTransition() TEST_ACTIVE_CHANGED(s, 1); } +void tst_QStateMachine::conflictingTransition() +{ + SignalEmitter emitter; + + QStateMachine machine; + QState b(QState::ParallelStates, &machine); + QState c(&b); + QState d(QState::ParallelStates, &b); + QState e(&d); + QState e1(&e); + QState e2(&e); + QState f(&d); + QState f1(&f); + QState f2(&f); + QState a1(&machine); + + machine.setInitialState(&b); + e.setInitialState(&e1); + f.setInitialState(&f1); + c.addTransition(&emitter, SIGNAL(signalWithNoArg()), &a1)->setObjectName("c->a1"); + e1.addTransition(&emitter, SIGNAL(signalWithNoArg()), &e2)->setObjectName("e1->e2"); + f1.addTransition(&emitter, SIGNAL(signalWithNoArg()), &f2)->setObjectName("f1->f2"); + + b.setObjectName("b"); + c.setObjectName("c"); + d.setObjectName("d"); + e.setObjectName("e"); + e1.setObjectName("e1"); + e2.setObjectName("e2"); + f.setObjectName("f"); + f1.setObjectName("f1"); + f2.setObjectName("f2"); + a1.setObjectName("a1"); + + machine.start(); + + QTRY_COMPARE(machine.configuration().contains(&b), true); + QTRY_COMPARE(machine.configuration().contains(&c), true); + QTRY_COMPARE(machine.configuration().contains(&d), true); + QTRY_COMPARE(machine.configuration().contains(&e), true); + QTRY_COMPARE(machine.configuration().contains(&e1), true); + QTRY_COMPARE(machine.configuration().contains(&e2), false); + QTRY_COMPARE(machine.configuration().contains(&f), true); + QTRY_COMPARE(machine.configuration().contains(&f1), true); + QTRY_COMPARE(machine.configuration().contains(&f2), false); + QTRY_COMPARE(machine.configuration().contains(&a1), false); + + emitter.emitSignalWithNoArg(); + + QTRY_COMPARE(machine.configuration().contains(&b), true); + QTRY_COMPARE(machine.configuration().contains(&c), true); + QTRY_COMPARE(machine.configuration().contains(&d), true); + QTRY_COMPARE(machine.configuration().contains(&e), true); + QTRY_COMPARE(machine.configuration().contains(&e1), false); + QTRY_COMPARE(machine.configuration().contains(&e2), true); + QTRY_COMPARE(machine.configuration().contains(&f), true); + QTRY_COMPARE(machine.configuration().contains(&f1), false); + QTRY_COMPARE(machine.configuration().contains(&f2), true); + QTRY_COMPARE(machine.configuration().contains(&a1), false); + + QVERIFY(machine.isRunning()); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" -- cgit v1.2.3 From 92c2783f7761be6709042b54b7183d2276a7174a Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 22 Apr 2015 14:17:13 +0200 Subject: QStateMachine: allow posting of events when starting. This allows subclasses to submit any queued events that have to be handled before normal operation starts. For example, if an error event got generated during initialization which has to be handled by the state machine, the startup hook in the private class can be used to post those events and have the state machine handle them appropriately. Change-Id: I62249a31d8840f47bc19920870ad5da9647e61f9 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine.cpp | 14 ++++++++++++-- src/corelib/statemachine/qstatemachine_p.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 25c9343943..bea6822ecc 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -1845,6 +1845,8 @@ void QStateMachinePrivate::_q_start() registerMultiThreadedSignalTransitions(); + startupHook(); + #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": starting"; #endif @@ -2114,6 +2116,10 @@ void QStateMachinePrivate::emitStateFinished(QState *forState, QFinalState *guil QStatePrivate::get(forState)->emitFinished(); } +void QStateMachinePrivate::startupHook() +{ +} + /* This function is called when the state machine is performing no microstep because no transition is enabled (i.e. an event is ignored). @@ -2726,14 +2732,18 @@ void QStateMachine::setRunning(bool running) event queue. Events are processed in the order posted. The state machine takes ownership of the event and deletes it once it has been processed. - You can only post events when the state machine is running. + You can only post events when the state machine is running or when it is starting up. \sa postDelayedEvent() */ void QStateMachine::postEvent(QEvent *event, EventPriority priority) { Q_D(QStateMachine); - if (d->state != QStateMachinePrivate::Running) { + switch (d->state) { + case QStateMachinePrivate::Running: + case QStateMachinePrivate::Starting: + break; + default: qWarning("QStateMachine::postEvent: cannot post event when the state machine is not running"); return; } diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 5584bc91ab..5db6489fa9 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -202,6 +202,7 @@ public: void cancelAllDelayedEvents(); virtual void emitStateFinished(QState *forState, QFinalState *guiltyState); + virtual void startupHook(); #ifndef QT_NO_PROPERTIES class RestorableId { -- cgit v1.2.3 From 07af5bfcea7f92b1cf309be5e22f3f0e53e83ca1 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 6 May 2015 13:59:37 +0200 Subject: Give QSizePolicy its own .cpp Previously, implementation was spread between qlayout.cpp and qlayoutitem.cpp and the docs between those two files and qsizepolicy.qdoc. Move everything into a new qsizepolicy.cpp. Change-Id: Id15c2c13572b7b8863be596603100f388eafea07 Reviewed-by: Friedemann Kleint Reviewed-by: Giuseppe D'Angelo --- src/widgets/kernel/kernel.pri | 1 + src/widgets/kernel/qlayout.cpp | 81 ------ src/widgets/kernel/qlayoutitem.cpp | 19 -- src/widgets/kernel/qsizepolicy.cpp | 498 ++++++++++++++++++++++++++++++++++++ src/widgets/kernel/qsizepolicy.h | 3 +- src/widgets/kernel/qsizepolicy.qdoc | 387 ---------------------------- 6 files changed, 500 insertions(+), 489 deletions(-) create mode 100644 src/widgets/kernel/qsizepolicy.cpp delete mode 100644 src/widgets/kernel/qsizepolicy.qdoc diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index 88c1e2595b..21a982f349 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -49,6 +49,7 @@ SOURCES += \ kernel/qlayoutengine.cpp \ kernel/qlayoutitem.cpp \ kernel/qshortcut.cpp \ + kernel/qsizepolicy.cpp \ kernel/qstackedlayout.cpp \ kernel/qtooltip.cpp \ kernel/qwhatsthis.cpp \ diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index 822690942e..d3e5986103 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -1471,85 +1471,4 @@ QSize QLayout::closestAcceptableSize(const QWidget *widget, const QSize &size) return result; } -void QSizePolicy::setControlType(ControlType type) -{ - /* - The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10, - etc. In memory, we pack it onto the available bits (CTSize) in - setControlType(), and unpack it here. - - Example: - - 0x00000001 maps to 0 - 0x00000002 maps to 1 - 0x00000004 maps to 2 - 0x00000008 maps to 3 - etc. - */ - - int i = 0; - while (true) { - if (type & (0x1 << i)) { - bits.ctype = i; - return; - } - ++i; - } -} - -QSizePolicy::ControlType QSizePolicy::controlType() const -{ - return QSizePolicy::ControlType(1 << bits.ctype); -} - -#ifndef QT_NO_DATASTREAM - -/*! - \relates QSizePolicy - \since 4.2 - - Writes the size \a policy to the data stream \a stream. - - \sa{Serializing Qt Data Types}{Format of the QDataStream operators} -*/ -QDataStream &operator<<(QDataStream &stream, const QSizePolicy &policy) -{ - // The order here is for historical reasons. (compatibility with Qt4) - quint32 data = (policy.bits.horPolicy | // [0, 3] - policy.bits.verPolicy << 4 | // [4, 7] - policy.bits.hfw << 8 | // [8] - policy.bits.ctype << 9 | // [9, 13] - policy.bits.wfh << 14 | // [14] - policy.bits.retainSizeWhenHidden << 15 | // [15] - policy.bits.verStretch << 16 | // [16, 23] - policy.bits.horStretch << 24); // [24, 31] - return stream << data; -} - -#define VALUE_OF_BITS(data, bitstart, bitcount) ((data >> bitstart) & ((1 << bitcount) -1)) - -/*! - \relates QSizePolicy - \since 4.2 - - Reads the size \a policy from the data stream \a stream. - - \sa{Serializing Qt Data Types}{Format of the QDataStream operators} -*/ -QDataStream &operator>>(QDataStream &stream, QSizePolicy &policy) -{ - quint32 data; - stream >> data; - policy.bits.horPolicy = VALUE_OF_BITS(data, 0, 4); - policy.bits.verPolicy = VALUE_OF_BITS(data, 4, 4); - policy.bits.hfw = VALUE_OF_BITS(data, 8, 1); - policy.bits.ctype = VALUE_OF_BITS(data, 9, 5); - policy.bits.wfh = VALUE_OF_BITS(data, 14, 1); - policy.bits.retainSizeWhenHidden = VALUE_OF_BITS(data, 15, 1); - policy.bits.verStretch = VALUE_OF_BITS(data, 16, 8); - policy.bits.horStretch = VALUE_OF_BITS(data, 24, 8); - return stream; -} -#endif // QT_NO_DATASTREAM - QT_END_NAMESPACE diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp index b21925e1d4..21f4c9a221 100644 --- a/src/widgets/kernel/qlayoutitem.cpp +++ b/src/widgets/kernel/qlayoutitem.cpp @@ -34,7 +34,6 @@ #include "qlayout.h" #include "qapplication.h" -#include "qdebug.h" #include "qlayoutengine_p.h" #include "qmenubar.h" #include "qtoolbar.h" @@ -67,14 +66,6 @@ inline static QSize toLayoutItemSize(QWidgetPrivate *priv, const QSize &size) return toLayoutItemRect(priv, QRect(QPoint(0, 0), size)).size(); } -/*! - Returns a QVariant storing this QSizePolicy. -*/ -QSizePolicy::operator QVariant() const -{ - return QVariant(QVariant::SizePolicy, this); -} - /*! \class QLayoutItem \brief The QLayoutItem class provides an abstract item that a @@ -847,14 +838,4 @@ int QWidgetItemV2::heightForWidth(int width) const return height; } -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug dbg, const QSizePolicy &p) -{ - QDebugStateSaver saver(dbg); - dbg.nospace() << "QSizePolicy(horizontalPolicy = " << p.horizontalPolicy() - << ", verticalPolicy = " << p.verticalPolicy() << ')'; - return dbg; -} -#endif - QT_END_NAMESPACE diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp new file mode 100644 index 0000000000..ba57a4f867 --- /dev/null +++ b/src/widgets/kernel/qsizepolicy.cpp @@ -0,0 +1,498 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsizepolicy.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QSizePolicy + \brief The QSizePolicy class is a layout attribute describing horizontal + and vertical resizing policy. + + \ingroup geomanagement + \inmodule QtWidgets + + The size policy of a widget is an expression of its willingness to + be resized in various ways, and affects how the widget is treated + by the \l{Layout Management}{layout engine}. Each widget returns a + QSizePolicy that describes the horizontal and vertical resizing + policy it prefers when being laid out. You can change this for + a specific widget by changing its QWidget::sizePolicy property. + + QSizePolicy contains two independent QSizePolicy::Policy values + and two stretch factors; one describes the widgets's horizontal + size policy, and the other describes its vertical size policy. It + also contains a flag to indicate whether the height and width of + its preferred size are related. + + The horizontal and vertical policies can be set in the + constructor, and altered using the setHorizontalPolicy() and + setVerticalPolicy() functions. The stretch factors can be set + using the setHorizontalStretch() and setVerticalStretch() + functions. The flag indicating whether the widget's + \l{QWidget::sizeHint()}{sizeHint()} is width-dependent (such as a + menu bar or a word-wrapping label) can be set using the + setHeightForWidth() function. + + The current size policies and stretch factors be retrieved using + the horizontalPolicy(), verticalPolicy(), horizontalStretch() and + verticalStretch() functions. Alternatively, use the transpose() + function to swap the horizontal and vertical policies and + stretches. The hasHeightForWidth() function returns the current + status of the flag indicating the size hint dependencies. + + Use the expandingDirections() function to determine whether the + associated widget can make use of more space than its + \l{QWidget::sizeHint()}{sizeHint()} function indicates, as well as + find out in which directions it can expand. + + Finally, the QSizePolicy class provides operators comparing this + size policy to a given policy, as well as a QVariant operator + storing this QSizePolicy as a QVariant object. + + \sa QSize, QWidget::sizeHint(), QWidget::sizePolicy, + QLayoutItem::sizeHint() +*/ + +/*! + \enum QSizePolicy::PolicyFlag + + These flags are combined together to form the various \l{Policy} + values: + + \value GrowFlag The widget can grow beyond its size hint if necessary. + \value ExpandFlag The widget should get as much space as possible. + \value ShrinkFlag The widget can shrink below its size hint if necessary. + \value IgnoreFlag The widget's size hint is ignored. The widget will get + as much space as possible. + + \sa Policy +*/ + +/*! + \enum QSizePolicy::Policy + + This enum describes the various per-dimension sizing types used + when constructing a QSizePolicy. + + \value Fixed The QWidget::sizeHint() is the only acceptable + alternative, so the widget can never grow or shrink (e.g. the + vertical direction of a push button). + + \value Minimum The sizeHint() is minimal, and sufficient. The + widget can be expanded, but there is no advantage to it being + larger (e.g. the horizontal direction of a push button). + It cannot be smaller than the size provided by sizeHint(). + + \value Maximum The sizeHint() is a maximum. The widget can be + shrunk any amount without detriment if other widgets need the + space (e.g. a separator line). + It cannot be larger than the size provided by sizeHint(). + + \value Preferred The sizeHint() is best, but the widget can be + shrunk and still be useful. The widget can be expanded, but there + is no advantage to it being larger than sizeHint() (the default + QWidget policy). + + \value Expanding The sizeHint() is a sensible size, but the + widget can be shrunk and still be useful. The widget can make use + of extra space, so it should get as much space as possible (e.g. + the horizontal direction of a horizontal slider). + + \value MinimumExpanding The sizeHint() is minimal, and sufficient. + The widget can make use of extra space, so it should get as much + space as possible (e.g. the horizontal direction of a horizontal + slider). + + \value Ignored The sizeHint() is ignored. The widget will get as + much space as possible. + + \sa PolicyFlag, setHorizontalPolicy(), setVerticalPolicy() +*/ + +/*! + \fn QSizePolicy::QSizePolicy() + + Constructs a QSizePolicy object with \l Fixed as its horizontal + and vertical policies. + + The policies can be altered using the setHorizontalPolicy() and + setVerticalPolicy() functions. Use the setHeightForWidth() + function if the preferred height of the widget is dependent on the + width of the widget (for example, a QLabel with line wrapping). + + \sa setHorizontalStretch(), setVerticalStretch() +*/ + +/*! + \fn QSizePolicy::QSizePolicy(Policy horizontal, Policy vertical, ControlType type) + \since 4.3 + + Constructs a QSizePolicy object with the given \a horizontal and + \a vertical policies, and the specified control \a type. + + Use setHeightForWidth() if the preferred height of the widget is + dependent on the width of the widget (for example, a QLabel with + line wrapping). + + \sa setHorizontalStretch(), setVerticalStretch(), controlType() +*/ + +/*! + \fn QSizePolicy::Policy QSizePolicy::horizontalPolicy() const + + Returns the horizontal component of the size policy. + + \sa setHorizontalPolicy(), verticalPolicy(), horizontalStretch() +*/ + +/*! + \fn QSizePolicy::Policy QSizePolicy::verticalPolicy() const + + Returns the vertical component of the size policy. + + \sa setVerticalPolicy(), horizontalPolicy(), verticalStretch() +*/ + +/*! + \fn void QSizePolicy::setHorizontalPolicy(Policy policy) + + Sets the horizontal component to the given \a policy. + + \sa horizontalPolicy(), setVerticalPolicy(), setHorizontalStretch() +*/ + +/*! + \fn void QSizePolicy::setVerticalPolicy(Policy policy) + + Sets the vertical component to the given \a policy. + + \sa verticalPolicy(), setHorizontalPolicy(), setVerticalStretch() +*/ + +/*! + \fn Qt::Orientations QSizePolicy::expandingDirections() const + + Returns whether a widget can make use of more space than the + QWidget::sizeHint() function indicates. + + A value of Qt::Horizontal or Qt::Vertical means that the widget + can grow horizontally or vertically (i.e., the horizontal or + vertical policy is \l Expanding or \l MinimumExpanding), whereas + Qt::Horizontal | Qt::Vertical means that it can grow in both + dimensions. + + \sa horizontalPolicy(), verticalPolicy() +*/ + +/*! + \since 4.3 + + Returns the control type associated with the widget for which + this size policy applies. +*/ +QSizePolicy::ControlType QSizePolicy::controlType() const +{ + return QSizePolicy::ControlType(1 << bits.ctype); +} + + +/*! + \since 4.3 + + Sets the control type associated with the widget for which this + size policy applies to \a type. + + The control type specifies the type of the widget for which this + size policy applies. It is used by some styles, notably + QMacStyle, to insert proper spacing between widgets. For example, + the Mac OS X Aqua guidelines specify that push buttons should be + separated by 12 pixels, whereas vertically stacked radio buttons + only require 6 pixels. + + \sa QStyle::layoutSpacing() +*/ +void QSizePolicy::setControlType(ControlType type) +{ + /* + The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10, + etc. In memory, we pack it onto the available bits (CTSize) in + setControlType(), and unpack it here. + + Example: + + 0x00000001 maps to 0 + 0x00000002 maps to 1 + 0x00000004 maps to 2 + 0x00000008 maps to 3 + etc. + */ + + int i = 0; + while (true) { + if (type & (0x1 << i)) { + bits.ctype = i; + return; + } + ++i; + } +} + +/*! + \fn void QSizePolicy::setHeightForWidth(bool dependent) + + Sets the flag determining whether the widget's preferred height + depends on its width, to \a dependent. + + \sa hasHeightForWidth(), setWidthForHeight() +*/ + +/*! + \fn bool QSizePolicy::hasHeightForWidth() const + + Returns \c true if the widget's preferred height depends on its + width; otherwise returns \c false. + + \sa setHeightForWidth() +*/ + +/*! + \fn void QSizePolicy::setWidthForHeight(bool dependent) + + Sets the flag determining whether the widget's width + depends on its height, to \a dependent. + + This is only supported for QGraphicsLayout's subclasses. + It is not possible to have a layout with both height-for-width + and width-for-height constraints at the same time. + + \sa hasWidthForHeight(), setHeightForWidth() +*/ + +/*! + \fn bool QSizePolicy::hasWidthForHeight() const + + Returns \c true if the widget's width depends on its + height; otherwise returns \c false. + + \sa setWidthForHeight() +*/ + +/*! + \fn bool QSizePolicy::operator==(const QSizePolicy &other) const + + Returns \c true if this policy is equal to \a other; otherwise + returns \c false. + + \sa operator!=() +*/ + +/*! + \fn bool QSizePolicy::operator!=(const QSizePolicy &other) const + + Returns \c true if this policy is different from \a other; otherwise + returns \c false. + + \sa operator==() +*/ + +/*! + \fn int QSizePolicy::horizontalStretch() const + + Returns the horizontal stretch factor of the size policy. + + \sa setHorizontalStretch(), verticalStretch(), horizontalPolicy() +*/ + +/*! + \fn int QSizePolicy::verticalStretch() const + + Returns the vertical stretch factor of the size policy. + + \sa setVerticalStretch(), horizontalStretch(), verticalPolicy() +*/ + +/*! + \fn void QSizePolicy::setHorizontalStretch(int stretchFactor) + + Sets the horizontal stretch factor of the size policy to the given \a + stretchFactor. \a stretchFactor must be in the range [0,255]. + + When two widgets are adjacent to each other in a horizontal layout, + setting the horizontal stretch factor of the widget on the left to 2 + and the factor of widget on the right to 1 will ensure that the widget + on the left will always be twice the size of the one on the right. + + \sa horizontalStretch(), setVerticalStretch(), setHorizontalPolicy() +*/ + +/*! + \fn void QSizePolicy::setVerticalStretch(int stretchFactor) + + Sets the vertical stretch factor of the size policy to the given + \a stretchFactor. \a stretchFactor must be in the range [0,255]. + + When two widgets are adjacent to each other in a vertical layout, + setting the vertical stretch factor of the widget on the top to 2 + and the factor of widget on the bottom to 1 will ensure that + the widget on the top will always be twice the size of the one + on the bottom. + + \sa verticalStretch(), setHorizontalStretch(), setVerticalPolicy() +*/ + +/*! + \fn void QSizePolicy::transpose() + + Swaps the horizontal and vertical policies and stretches. +*/ + +/*! + \fn void QSizePolicy::retainSizeWhenHidden() const + \since 5.2 + + Returns if the layout should retain the widgets size when it is hidden. This is by default false. + + \sa setRetainSizeWhenHidden() +*/ + +/*! + \fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize) + \since 5.2 + + Set if a layout should retain the widgets size when it is hidden. + If \a retainSize is true the layout will not be changed by hiding the widget. + + \sa retainSizeWhenHidden() +*/ + +/*! + \enum QSizePolicy::ControlType + \since 4.3 + + This enum specifies the different types of widgets in terms of + layout interaction: + + \value DefaultType The default type, when none is specified. + \value ButtonBox A QDialogButtonBox instance. + \value CheckBox A QCheckBox instance. + \value ComboBox A QComboBox instance. + \value Frame A QFrame instance. + \value GroupBox A QGroupBox instance. + \value Label A QLabel instance. + \value Line A QFrame instance with QFrame::HLine or QFrame::VLine. + \value LineEdit A QLineEdit instance. + \value PushButton A QPushButton instance. + \value RadioButton A QRadioButton instance. + \value Slider A QAbstractSlider instance. + \value SpinBox A QAbstractSpinBox instance. + \value TabWidget A QTabWidget instance. + \value ToolButton A QToolButton instance. + + \sa setControlType(), controlType() +*/ + +/*! + Returns a QVariant storing this QSizePolicy. +*/ +QSizePolicy::operator QVariant() const +{ + return QVariant(QVariant::SizePolicy, this); +} + +#ifndef QT_NO_DATASTREAM + +/*! + \relates QSizePolicy + \since 4.2 + + Writes the size \a policy to the data stream \a stream. + + \sa{Serializing Qt Data Types}{Format of the QDataStream operators} +*/ +QDataStream &operator<<(QDataStream &stream, const QSizePolicy &policy) +{ + // The order here is for historical reasons. (compatibility with Qt4) + quint32 data = (policy.bits.horPolicy | // [0, 3] + policy.bits.verPolicy << 4 | // [4, 7] + policy.bits.hfw << 8 | // [8] + policy.bits.ctype << 9 | // [9, 13] + policy.bits.wfh << 14 | // [14] + policy.bits.retainSizeWhenHidden << 15 | // [15] + policy.bits.verStretch << 16 | // [16, 23] + policy.bits.horStretch << 24); // [24, 31] + return stream << data; +} + +#define VALUE_OF_BITS(data, bitstart, bitcount) ((data >> bitstart) & ((1 << bitcount) -1)) + +/*! + \relates QSizePolicy + \since 4.2 + + Reads the size \a policy from the data stream \a stream. + + \sa{Serializing Qt Data Types}{Format of the QDataStream operators} +*/ +QDataStream &operator>>(QDataStream &stream, QSizePolicy &policy) +{ + quint32 data; + stream >> data; + policy.bits.horPolicy = VALUE_OF_BITS(data, 0, 4); + policy.bits.verPolicy = VALUE_OF_BITS(data, 4, 4); + policy.bits.hfw = VALUE_OF_BITS(data, 8, 1); + policy.bits.ctype = VALUE_OF_BITS(data, 9, 5); + policy.bits.wfh = VALUE_OF_BITS(data, 14, 1); + policy.bits.retainSizeWhenHidden = VALUE_OF_BITS(data, 15, 1); + policy.bits.verStretch = VALUE_OF_BITS(data, 16, 8); + policy.bits.horStretch = VALUE_OF_BITS(data, 24, 8); + return stream; +} +#endif // QT_NO_DATASTREAM + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug dbg, const QSizePolicy &p) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "QSizePolicy(horizontalPolicy = " << p.horizontalPolicy() + << ", verticalPolicy = " << p.verticalPolicy() << ')'; + return dbg; +} +#endif + +QT_END_NAMESPACE diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index 2376a2c644..6cd511f513 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -112,7 +112,7 @@ public: bool operator==(const QSizePolicy& s) const { return data == s.data; } bool operator!=(const QSizePolicy& s) const { return data != s.data; } - operator QVariant() const; // implemented in qlayoutitem.cpp + operator QVariant() const; int horizontalStretch() const { return static_cast(bits.horStretch); } int verticalStretch() const { return static_cast(bits.verStretch); } @@ -155,7 +155,6 @@ Q_DECLARE_TYPEINFO(QSizePolicy, Q_PRIMITIVE_TYPE); Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes) #ifndef QT_NO_DATASTREAM -// implemented in qlayout.cpp Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &, const QSizePolicy &); Q_WIDGETS_EXPORT QDataStream &operator>>(QDataStream &, QSizePolicy &); #endif diff --git a/src/widgets/kernel/qsizepolicy.qdoc b/src/widgets/kernel/qsizepolicy.qdoc deleted file mode 100644 index e84412bc46..0000000000 --- a/src/widgets/kernel/qsizepolicy.qdoc +++ /dev/null @@ -1,387 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QSizePolicy - \brief The QSizePolicy class is a layout attribute describing horizontal - and vertical resizing policy. - - \ingroup geomanagement - \inmodule QtWidgets - - The size policy of a widget is an expression of its willingness to - be resized in various ways, and affects how the widget is treated - by the \l{Layout Management}{layout engine}. Each widget returns a - QSizePolicy that describes the horizontal and vertical resizing - policy it prefers when being laid out. You can change this for - a specific widget by changing its QWidget::sizePolicy property. - - QSizePolicy contains two independent QSizePolicy::Policy values - and two stretch factors; one describes the widgets's horizontal - size policy, and the other describes its vertical size policy. It - also contains a flag to indicate whether the height and width of - its preferred size are related. - - The horizontal and vertical policies can be set in the - constructor, and altered using the setHorizontalPolicy() and - setVerticalPolicy() functions. The stretch factors can be set - using the setHorizontalStretch() and setVerticalStretch() - functions. The flag indicating whether the widget's - \l{QWidget::sizeHint()}{sizeHint()} is width-dependent (such as a - menu bar or a word-wrapping label) can be set using the - setHeightForWidth() function. - - The current size policies and stretch factors be retrieved using - the horizontalPolicy(), verticalPolicy(), horizontalStretch() and - verticalStretch() functions. Alternatively, use the transpose() - function to swap the horizontal and vertical policies and - stretches. The hasHeightForWidth() function returns the current - status of the flag indicating the size hint dependencies. - - Use the expandingDirections() function to determine whether the - associated widget can make use of more space than its - \l{QWidget::sizeHint()}{sizeHint()} function indicates, as well as - find out in which directions it can expand. - - Finally, the QSizePolicy class provides operators comparing this - size policy to a given policy, as well as a QVariant operator - storing this QSizePolicy as a QVariant object. - - \sa QSize, QWidget::sizeHint(), QWidget::sizePolicy, - QLayoutItem::sizeHint() -*/ - -/*! - \enum QSizePolicy::PolicyFlag - - These flags are combined together to form the various \l{Policy} - values: - - \value GrowFlag The widget can grow beyond its size hint if necessary. - \value ExpandFlag The widget should get as much space as possible. - \value ShrinkFlag The widget can shrink below its size hint if necessary. - \value IgnoreFlag The widget's size hint is ignored. The widget will get - as much space as possible. - - \sa Policy -*/ - -/*! - \enum QSizePolicy::Policy - - This enum describes the various per-dimension sizing types used - when constructing a QSizePolicy. - - \value Fixed The QWidget::sizeHint() is the only acceptable - alternative, so the widget can never grow or shrink (e.g. the - vertical direction of a push button). - - \value Minimum The sizeHint() is minimal, and sufficient. The - widget can be expanded, but there is no advantage to it being - larger (e.g. the horizontal direction of a push button). - It cannot be smaller than the size provided by sizeHint(). - - \value Maximum The sizeHint() is a maximum. The widget can be - shrunk any amount without detriment if other widgets need the - space (e.g. a separator line). - It cannot be larger than the size provided by sizeHint(). - - \value Preferred The sizeHint() is best, but the widget can be - shrunk and still be useful. The widget can be expanded, but there - is no advantage to it being larger than sizeHint() (the default - QWidget policy). - - \value Expanding The sizeHint() is a sensible size, but the - widget can be shrunk and still be useful. The widget can make use - of extra space, so it should get as much space as possible (e.g. - the horizontal direction of a horizontal slider). - - \value MinimumExpanding The sizeHint() is minimal, and sufficient. - The widget can make use of extra space, so it should get as much - space as possible (e.g. the horizontal direction of a horizontal - slider). - - \value Ignored The sizeHint() is ignored. The widget will get as - much space as possible. - - \sa PolicyFlag, setHorizontalPolicy(), setVerticalPolicy() -*/ - -/*! - \fn QSizePolicy::QSizePolicy() - - Constructs a QSizePolicy object with \l Fixed as its horizontal - and vertical policies. - - The policies can be altered using the setHorizontalPolicy() and - setVerticalPolicy() functions. Use the setHeightForWidth() - function if the preferred height of the widget is dependent on the - width of the widget (for example, a QLabel with line wrapping). - - \sa setHorizontalStretch(), setVerticalStretch() -*/ - -/*! - \fn QSizePolicy::QSizePolicy(Policy horizontal, Policy vertical, ControlType type) - \since 4.3 - - Constructs a QSizePolicy object with the given \a horizontal and - \a vertical policies, and the specified control \a type. - - Use setHeightForWidth() if the preferred height of the widget is - dependent on the width of the widget (for example, a QLabel with - line wrapping). - - \sa setHorizontalStretch(), setVerticalStretch(), controlType() -*/ - -/*! - \fn QSizePolicy::Policy QSizePolicy::horizontalPolicy() const - - Returns the horizontal component of the size policy. - - \sa setHorizontalPolicy(), verticalPolicy(), horizontalStretch() -*/ - -/*! - \fn QSizePolicy::Policy QSizePolicy::verticalPolicy() const - - Returns the vertical component of the size policy. - - \sa setVerticalPolicy(), horizontalPolicy(), verticalStretch() -*/ - -/*! - \fn void QSizePolicy::setHorizontalPolicy(Policy policy) - - Sets the horizontal component to the given \a policy. - - \sa horizontalPolicy(), setVerticalPolicy(), setHorizontalStretch() -*/ - -/*! - \fn void QSizePolicy::setVerticalPolicy(Policy policy) - - Sets the vertical component to the given \a policy. - - \sa verticalPolicy(), setHorizontalPolicy(), setVerticalStretch() -*/ - -/*! - \fn Qt::Orientations QSizePolicy::expandingDirections() const - - Returns whether a widget can make use of more space than the - QWidget::sizeHint() function indicates. - - A value of Qt::Horizontal or Qt::Vertical means that the widget - can grow horizontally or vertically (i.e., the horizontal or - vertical policy is \l Expanding or \l MinimumExpanding), whereas - Qt::Horizontal | Qt::Vertical means that it can grow in both - dimensions. - - \sa horizontalPolicy(), verticalPolicy() -*/ - -/*! - \fn ControlType QSizePolicy::controlType() const - \since 4.3 - - Returns the control type associated with the widget for which - this size policy applies. -*/ - -/*! - \fn void QSizePolicy::setControlType(ControlType type) - \since 4.3 - - Sets the control type associated with the widget for which this - size policy applies to \a type. - - The control type specifies the type of the widget for which this - size policy applies. It is used by some styles, notably - QMacStyle, to insert proper spacing between widgets. For example, - the Mac OS X Aqua guidelines specify that push buttons should be - separated by 12 pixels, whereas vertically stacked radio buttons - only require 6 pixels. - - \sa QStyle::layoutSpacing() -*/ - -/*! - \fn void QSizePolicy::setHeightForWidth(bool dependent) - - Sets the flag determining whether the widget's preferred height - depends on its width, to \a dependent. - - \sa hasHeightForWidth(), setWidthForHeight() -*/ - -/*! - \fn bool QSizePolicy::hasHeightForWidth() const - - Returns \c true if the widget's preferred height depends on its - width; otherwise returns \c false. - - \sa setHeightForWidth() -*/ - -/*! - \fn void QSizePolicy::setWidthForHeight(bool dependent) - - Sets the flag determining whether the widget's width - depends on its height, to \a dependent. - - This is only supported for QGraphicsLayout's subclasses. - It is not possible to have a layout with both height-for-width - and width-for-height constraints at the same time. - - \sa hasWidthForHeight(), setHeightForWidth() -*/ - -/*! - \fn bool QSizePolicy::hasWidthForHeight() const - - Returns \c true if the widget's width depends on its - height; otherwise returns \c false. - - \sa setWidthForHeight() -*/ - -/*! - \fn bool QSizePolicy::operator==(const QSizePolicy &other) const - - Returns \c true if this policy is equal to \a other; otherwise - returns \c false. - - \sa operator!=() -*/ - -/*! - \fn bool QSizePolicy::operator!=(const QSizePolicy &other) const - - Returns \c true if this policy is different from \a other; otherwise - returns \c false. - - \sa operator==() -*/ - -/*! - \fn int QSizePolicy::horizontalStretch() const - - Returns the horizontal stretch factor of the size policy. - - \sa setHorizontalStretch(), verticalStretch(), horizontalPolicy() -*/ - -/*! - \fn int QSizePolicy::verticalStretch() const - - Returns the vertical stretch factor of the size policy. - - \sa setVerticalStretch(), horizontalStretch(), verticalPolicy() -*/ - -/*! - \fn void QSizePolicy::setHorizontalStretch(int stretchFactor) - - Sets the horizontal stretch factor of the size policy to the given \a - stretchFactor. \a stretchFactor must be in the range [0,255]. - - When two widgets are adjacent to each other in a horizontal layout, - setting the horizontal stretch factor of the widget on the left to 2 - and the factor of widget on the right to 1 will ensure that the widget - on the left will always be twice the size of the one on the right. - - \sa horizontalStretch(), setVerticalStretch(), setHorizontalPolicy() -*/ - -/*! - \fn void QSizePolicy::setVerticalStretch(int stretchFactor) - - Sets the vertical stretch factor of the size policy to the given - \a stretchFactor. \a stretchFactor must be in the range [0,255]. - - When two widgets are adjacent to each other in a vertical layout, - setting the vertical stretch factor of the widget on the top to 2 - and the factor of widget on the bottom to 1 will ensure that - the widget on the top will always be twice the size of the one - on the bottom. - - \sa verticalStretch(), setHorizontalStretch(), setVerticalPolicy() -*/ - -/*! - \fn void QSizePolicy::transpose() - - Swaps the horizontal and vertical policies and stretches. -*/ - -/*! - \fn void QSizePolicy::retainSizeWhenHidden() const - \since 5.2 - - Returns if the layout should retain the widgets size when it is hidden. This is by default false. - - \sa setRetainSizeWhenHidden() -*/ - -/*! - \fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize) - \since 5.2 - - Set if a layout should retain the widgets size when it is hidden. - If \a retainSize is true the layout will not be changed by hiding the widget. - - \sa retainSizeWhenHidden() -*/ - -/*! - \enum QSizePolicy::ControlType - \since 4.3 - - This enum specifies the different types of widgets in terms of - layout interaction: - - \value DefaultType The default type, when none is specified. - \value ButtonBox A QDialogButtonBox instance. - \value CheckBox A QCheckBox instance. - \value ComboBox A QComboBox instance. - \value Frame A QFrame instance. - \value GroupBox A QGroupBox instance. - \value Label A QLabel instance. - \value Line A QFrame instance with QFrame::HLine or QFrame::VLine. - \value LineEdit A QLineEdit instance. - \value PushButton A QPushButton instance. - \value RadioButton A QRadioButton instance. - \value Slider A QAbstractSlider instance. - \value SpinBox A QAbstractSpinBox instance. - \value TabWidget A QTabWidget instance. - \value ToolButton A QToolButton instance. - - \sa setControlType(), controlType() -*/ - -- cgit v1.2.3 From e374ffc29c67493a51527117b55a53dfa5dd4267 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 6 May 2015 15:56:28 +0200 Subject: QSizePolicy: improve docs of retainSizeWhenHidden Fixed markup and grammar. Change-Id: Ie2427965f905135572fd1f81e4a6d7514dea7022 Reviewed-by: Friedemann Kleint Reviewed-by: Giuseppe D'Angelo --- src/widgets/kernel/qsizepolicy.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp index ba57a4f867..1476b4c5d7 100644 --- a/src/widgets/kernel/qsizepolicy.cpp +++ b/src/widgets/kernel/qsizepolicy.cpp @@ -386,7 +386,8 @@ void QSizePolicy::setControlType(ControlType type) \fn void QSizePolicy::retainSizeWhenHidden() const \since 5.2 - Returns if the layout should retain the widgets size when it is hidden. This is by default false. + Returns whether the layout should retain the widget's size when it is hidden. + This is \c false by default. \sa setRetainSizeWhenHidden() */ @@ -395,8 +396,8 @@ void QSizePolicy::setControlType(ControlType type) \fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize) \since 5.2 - Set if a layout should retain the widgets size when it is hidden. - If \a retainSize is true the layout will not be changed by hiding the widget. + Sets whether a layout should retain the widget's size when it is hidden. + If \a retainSize is \c true, the layout will not be changed by hiding the widget. \sa retainSizeWhenHidden() */ -- cgit v1.2.3 From b64e87f2ed6457b11594e9f4fc522860caa737ab Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 7 May 2015 13:10:13 +0200 Subject: Blacklist task256322_highlight on OS X The test keeps failing. The approach of sending mouse move events is inherently fragile due to the use of QCursor::setPos and the expectation that that produces the correct sequence of mouse move events. Change-Id: I07ec75460b70c27152e8775deffcb77fa9328d0c Reviewed-by: Simon Hausmann --- tests/auto/widgets/widgets/qmenubar/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/auto/widgets/widgets/qmenubar/BLACKLIST diff --git a/tests/auto/widgets/widgets/qmenubar/BLACKLIST b/tests/auto/widgets/widgets/qmenubar/BLACKLIST new file mode 100644 index 0000000000..e8b4945495 --- /dev/null +++ b/tests/auto/widgets/widgets/qmenubar/BLACKLIST @@ -0,0 +1,2 @@ +[task256322_highlight] +osx -- cgit v1.2.3 From ace86dca159d50886be5bcff7abe72383cad9fde Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 7 May 2015 08:34:19 +0200 Subject: Revert "configure: Change default of CFG_REDUCE_RELOCATIONS to "no"." This reverts commit d0eba497c1c34d35ddda2b5d44902ebd636d4f9e. A better fix is to use -fPIC instead of just -fPIE fo -reduce-relocations. Task-number: QTBUG-45755 Change-Id: I1759291b684fd76d4009e4be9ba1354eb056e659 Reviewed-by: Simon Hausmann Reviewed-by: Thiago Macieira --- configure | 2 +- tools/configure/configureapp.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 15a75bbccd..6ce6753e3f 100755 --- a/configure +++ b/configure @@ -674,7 +674,7 @@ CFG_SSE4_1=auto CFG_SSE4_2=auto CFG_AVX=auto CFG_AVX2=auto -CFG_REDUCE_RELOCATIONS=no +CFG_REDUCE_RELOCATIONS=auto CFG_ACCESSIBILITY=auto CFG_ACCESSIBILITY_ATSPI_BRIDGE=no # will be enabled depending on dbus and accessibility being enabled CFG_NEON=auto diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index db0791b75c..6e9d4aa80b 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -1696,7 +1696,7 @@ void Configure::applySpecSpecifics() dictionary[ "LARGE_FILE" ] = "no"; dictionary[ "ANGLE" ] = "no"; dictionary[ "DYNAMICGL" ] = "no"; - dictionary[ "REDUCE_RELOCATIONS" ] = "no"; + dictionary[ "REDUCE_RELOCATIONS" ] = "yes"; dictionary[ "QT_GETIFADDRS" ] = "no"; dictionary[ "QT_XKBCOMMON" ] = "no"; dictionary["ANDROID_STYLE_ASSETS"] = "yes"; -- cgit v1.2.3 From 36d6eb721e7d5997ade75e289d4088dc48678d0d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 5 May 2015 08:43:42 -0700 Subject: Require -fPIC instead of just -fPIE for -reduce-relocations GCC 5 combined with a recent binutils have a new optimization that allows them to generate copy relocations even in -fPIE code. Clang has the same functionality when compiling an executable with -flto. We need to let the compilers know that they cannot use copy relocations, so they need to use really position-independent code. Position independent code throughout is not really required. We just need the compilers to use position-independent access to symbols coming from the Qt libraries, but there's currently no other way of doing that. Task-number: QTBUG-45755 Change-Id: I0d4913955e3745b69672ffff13db5df7377398c5 Reviewed-by: Simon Hausmann Reviewed-by: Oswald Buddenhagen --- mkspecs/common/gcc-base.conf | 2 +- mkspecs/common/qcc-base.conf | 2 +- mkspecs/linux-icc/qmake.conf | 2 +- src/corelib/Qt5CoreConfigExtras.cmake.in | 2 +- src/corelib/global/qglobal.h | 4 ++-- tests/auto/tools/moc/tst_moc.cpp | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf index a149f4d907..e4ccbd7156 100644 --- a/mkspecs/common/gcc-base.conf +++ b/mkspecs/common/gcc-base.conf @@ -42,7 +42,7 @@ QMAKE_CFLAGS_RELEASE += $$QMAKE_CFLAGS_OPTIMIZE QMAKE_CFLAGS_DEBUG += -g QMAKE_CFLAGS_SHLIB += -fPIC QMAKE_CFLAGS_STATIC_LIB += -fPIC -QMAKE_CFLAGS_APP += -fPIE +QMAKE_CFLAGS_APP += -fPIC QMAKE_CFLAGS_ISYSTEM = -isystem QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden diff --git a/mkspecs/common/qcc-base.conf b/mkspecs/common/qcc-base.conf index f529d7fc7b..8276316c3f 100644 --- a/mkspecs/common/qcc-base.conf +++ b/mkspecs/common/qcc-base.conf @@ -23,7 +23,7 @@ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_OPTIMIZE -g QMAKE_CFLAGS_DEBUG += -g QMAKE_CFLAGS_SHLIB += -fPIC -shared QMAKE_CFLAGS_STATIC_LIB += -fPIC -QMAKE_CFLAGS_APP += -fPIE +QMAKE_CFLAGS_APP += -fPIC QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden QMAKE_CFLAGS_SSE2 += -msse2 diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf index 8119c8aa09..9190aa9f28 100644 --- a/mkspecs/linux-icc/qmake.conf +++ b/mkspecs/linux-icc/qmake.conf @@ -12,7 +12,7 @@ QMAKE_LEXFLAGS = QMAKE_YACC = yacc QMAKE_YACCFLAGS = -d QMAKE_CFLAGS = -QMAKE_CFLAGS_APP = -fPIE +QMAKE_CFLAGS_APP = -fPIC QMAKE_CFLAGS_DEPS = -M QMAKE_CFLAGS_WARN_ON = -w1 -Wall -Wcheck -wd1572,873,2259,2261 QMAKE_CFLAGS_WARN_OFF = -w diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 7213a844f5..48d5f21447 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -71,7 +71,7 @@ set(_qt5_corelib_extra_includes) # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") -set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIE\") +set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 455582e310..ef84662036 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1047,9 +1047,9 @@ Q_CORE_EXPORT int qrand(); # define QT_NO_SHAREDMEMORY #endif -#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) && !defined(__PIE__) +#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) # error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ - "Compile your code with -fPIC or -fPIE." + "Compile your code with -fPIC." #endif namespace QtPrivate { diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index edb6488eaa..748cb82989 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -662,7 +662,7 @@ void tst_Moc::oldStyleCasts() QStringList args; args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "." - << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIE" << "-"; + << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-"; proc.start("gcc", args); QVERIFY(proc.waitForStarted()); proc.write(mocOut); @@ -732,7 +732,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension() QStringList args; args << "-c" << "-x" << "c++" << "-I" << ".." - << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIE" << "-"; + << "-I" << qtIncludePath << "-o" << "/dev/null" << "-fPIC" << "-"; proc.start("gcc", args); QVERIFY(proc.waitForStarted()); proc.write(mocOut); @@ -1011,7 +1011,7 @@ void tst_Moc::ignoreOptionClashes() // If -pthread wasn't ignored, it was parsed as a prefix of "thread/", which breaks compilation. QStringList gccArgs; gccArgs << "-c" << "-x" << "c++" << "-I" << ".." - << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null" << "-fPIE" << "-"; + << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null" << "-fPIC" << "-"; proc.start("gcc", gccArgs); QVERIFY(proc.waitForStarted()); proc.write(mocOut); -- cgit v1.2.3 From ea17cc07685575fd1c00c0fc7c4aaa5d87ce72e8 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 6 May 2015 14:02:48 +0200 Subject: QColumnView: re-enable scrolling of the preview widget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason, each column in a QColumnView is a QAbstractItemView, *including* the preview widget's column. Unfortunately, the preview widget's column class was not overriding scrollContentsBy, so scrolling it had no effect. A more comprehensive solution would be a major refactoring of the code to make that column a plain Q(Abstract)ScrollArea, as it doesn't need QAIV's APIs at all, but I don't want to change code and risk breaking behavior. Change-Id: Ice500a8eaef13c295df4cc274b9f80d9a24c65f4 Task-number: QTBUG-11392 Reviewed-by: Friedemann Kleint Reviewed-by: Alexander Volkov Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qcolumnview_p.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/widgets/itemviews/qcolumnview_p.h b/src/widgets/itemviews/qcolumnview_p.h index ed30b5f085..0c0bdb5d1f 100644 --- a/src/widgets/itemviews/qcolumnview_p.h +++ b/src/widgets/itemviews/qcolumnview_p.h @@ -89,6 +89,16 @@ public: QAbstractScrollArea::resizeEvent(event); } + void scrollContentsBy(int dx, int dy) Q_DECL_OVERRIDE + { + if (!previewWidget) + return; + scrollDirtyRegion(dx, dy); + viewport()->scroll(dx, dy); + + QAbstractItemView::scrollContentsBy(dx, dy); + } + QRect visualRect(const QModelIndex &) const Q_DECL_OVERRIDE { return QRect(); -- cgit v1.2.3 From a34e9ebc1b908d31ba645688a8b0e9e53c2d3c6e Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 6 May 2015 17:00:21 +0200 Subject: QLineEdit: show the clear button if it gets enabled after setting a text We were fetching "lastText" too late, and setting the opacity of the clear button to 0. Change-Id: I82c2aea7dab4af4424fb57e12f78d07a0374457e Task-number: QTBUG-45518 Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qlineedit_p.cpp | 8 ++-- src/widgets/widgets/qlineedit_p.h | 2 +- .../widgets/widgets/qlineedit/tst_qlineedit.cpp | 45 ++++++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 6a41c3791f..ad3a92d35a 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -440,6 +440,10 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE Q_Q(QLineEdit); if (!newAction) return 0; + if (!hasSideWidgets()) { // initial setup. + QObject::connect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString))); + lastTextSize = q->text().size(); + } QWidget *w = 0; // Store flags about QWidgetAction here since removeAction() may be called from ~QAction, // in which a qobject_cast<> no longer works. @@ -456,10 +460,6 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE toolButton->setDefaultAction(newAction); w = toolButton; } - if (!hasSideWidgets()) { // initial setup. - QObject::connect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString))); - lastTextSize = q->text().size(); - } // If there is a 'before' action, it takes preference PositionIndexPair positionIndex = before ? findSideWidget(before) : PositionIndexPair(position, -1); SideWidgetEntryList &list = positionIndex.first == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets; diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 1ede07e4cb..4654262ea7 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE // QLineEditIconButton: This is a simple helper class that represents clickable icons that fade in with text -class QLineEditIconButton : public QToolButton +class Q_AUTOTEST_EXPORT QLineEditIconButton : public QToolButton { Q_OBJECT Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index 9417541040..adedc601a9 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -304,6 +304,7 @@ private slots: void undoRedoAndEchoModes(); void clearButton(); + void clearButtonVisibleAfterSettingText_QTBUG_45518(); void sideWidgets(); void shouldShowPlaceholderText_data(); @@ -4273,6 +4274,50 @@ void tst_QLineEdit::clearButton() QVERIFY(!clearButton->isEnabled()); } +void tst_QLineEdit::clearButtonVisibleAfterSettingText_QTBUG_45518() +{ +#ifndef QT_BUILD_INTERNAL + QSKIP("This test requires a developer build"); +#else + QLineEdit edit; + edit.setMinimumWidth(200); + centerOnScreen(&edit); + QLineEditIconButton *clearButton; + clearButton = edit.findChild(); + QVERIFY(!clearButton); + + edit.setText(QStringLiteral("some text")); + edit.show(); + QVERIFY(QTest::qWaitForWindowActive(&edit)); + + QVERIFY(!edit.isClearButtonEnabled()); + + clearButton = edit.findChild(); + QVERIFY(!clearButton); + + edit.setClearButtonEnabled(true); + QVERIFY(edit.isClearButtonEnabled()); + + clearButton = edit.findChild(); + QVERIFY(clearButton); + QVERIFY(clearButton->isVisible()); + + QTRY_VERIFY(clearButton->opacity() > 0); + QTRY_COMPARE(clearButton->cursor().shape(), Qt::ArrowCursor); + + QTest::mouseClick(clearButton, Qt::LeftButton, 0, clearButton->rect().center()); + QTRY_COMPARE(edit.text(), QString()); + + QTRY_COMPARE(clearButton->opacity(), qreal(0)); + QTRY_COMPARE(clearButton->cursor().shape(), clearButton->parentWidget()->cursor().shape()); + + edit.setClearButtonEnabled(false); + QVERIFY(!edit.isClearButtonEnabled()); + clearButton = edit.findChild(); + QVERIFY(!clearButton); +#endif // QT_BUILD_INTERNAL +} + void tst_QLineEdit::sideWidgets() { QWidget testWidget; -- cgit v1.2.3 From 00a341daa7c55926ce4d1c1f0290520b5e6c22a5 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Sun, 3 May 2015 20:52:15 +0300 Subject: winrt: Use ANGLE sub-buffer swap on Windows Phone This allows the plugin to communicate the swap region to ANGLE and avoid glitches when the orientation changes. Task-number: QTBUG-44333 Change-Id: I40240cbcb3aaec92dbf4a82f4957965e92b9c3da Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrteglcontext.cpp | 14 ++++++++++++++ src/plugins/platforms/winrt/qwinrteglcontext.h | 1 + 2 files changed, 15 insertions(+) diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index fd90582119..0832fbb586 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -33,6 +33,9 @@ #include "qwinrteglcontext.h" +#define EGL_EGLEXT_PROTOTYPES +#include "EGL/eglext.h" + QT_BEGIN_NAMESPACE QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config) @@ -40,6 +43,17 @@ QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGL { } +void QWinRTEGLContext::swapBuffers(QPlatformSurface *surface) +{ +#ifdef Q_OS_WINPHONE + const QSize size = surface->surface()->size(); + eglPostSubBufferNV(eglDisplay(), eglSurfaceForPlatformSurface(surface), + 0, 0, size.width(), size.height()); +#else + eglSwapBuffers(eglDisplay(), eglSurfaceForPlatformSurface(surface)); +#endif +} + EGLSurface QWinRTEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) { if (surface->surface()->surfaceClass() == QSurface::Window) { diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h index bec9c19089..9b1ef37d1b 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.h +++ b/src/plugins/platforms/winrt/qwinrteglcontext.h @@ -43,6 +43,7 @@ class QWinRTEGLContext : public QEGLPlatformContext public: explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface, EGLConfig config); + void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE; QFunctionPointer getProcAddress(const QByteArray &procName) Q_DECL_OVERRIDE; protected: -- cgit v1.2.3 From 916cfede0536ce63a1a5851bc675f5082e3c641c Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Sun, 3 May 2015 20:56:04 +0300 Subject: ANGLE: Allow Windows Phone to communicate swap region eglPostSubBufferNV is used to communicate the size of the window, as otherwise there is no way for the renderer to know if the last frame was rendered in landscape or portrait, causing rendering glitches when the orientation changes. The rotation flags are utilized in a few additional places now to fix some corner cases where the rotation was not applied. This patch should be squashed into "ANGLE-Improve-Windows-Phone-Support" during the next ANGLE rebase. Task-number: QTBUG-44333 Task-number: QTBUG-43502 Change-Id: Iec37f7531854184819c30c87eab82d96d56ff133 Reviewed-by: Oliver Wolff --- .../angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 2 + .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 28 ++-- .../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 5 +- .../angle/src/libGLESv2/entry_points_egl_ext.cpp | 2 + ...-Windows-Phone-to-communicate-swap-region.patch | 145 +++++++++++++++++++++ 5 files changed, 169 insertions(+), 13 deletions(-) create mode 100644 src/angle/patches/0006-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp index 4fde295443..4a87488014 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp @@ -189,6 +189,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) return egl::Error(EGL_SUCCESS); } +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: eglPostSubBufferNV comes here if (x + width > mWidth) { width = mWidth - x; @@ -198,6 +199,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) { height = mHeight - y; } +#endif if (width == 0 || height == 0) { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp index 298f3ccbd2..dc539cf66e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp @@ -552,18 +552,18 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); +#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // Create a quad in homogeneous coordinates - float x1 = (x / float(mWidth)) * 2.0f - 1.0f; - float y1 = (y / float(mHeight)) * 2.0f - 1.0f; - float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; - float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; + float x1 = -1.0f; + float y1 = -1.0f; + float x2 = 1.0f; + float y2 = 1.0f; -#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) const float dim = std::max(mWidth, mHeight); - float u1 = x / dim; - float v1 = y / dim; - float u2 = (x + width) / dim; - float v2 = (y + height) / dim; + float u1 = 0; + float v1 = 0; + float u2 = float(width) / dim; + float v2 = float(height) / dim; const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags(); const bool rotateL = flags == NativeWindow::RotateLeft; @@ -573,6 +573,12 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1); d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2); #else + // Create a quad in homogeneous coordinates + float x1 = (x / float(mWidth)) * 2.0f - 1.0f; + float y1 = (y / float(mHeight)) * 2.0f - 1.0f; + float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; + float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; + float u1 = x / float(mWidth); float v1 = y / float(mHeight); float u2 = (x + width) / float(mWidth); @@ -613,8 +619,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) viewport.TopLeftX = 0; viewport.TopLeftY = 0; #if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - viewport.Width = (rotateL || rotateR) ? mHeight : mWidth; - viewport.Height = (rotateL || rotateR) ? mWidth : mHeight; + viewport.Width = (rotateL || rotateR) ? height : width; + viewport.Height = (rotateL || rotateR) ? width : height; #else viewport.Width = mWidth; viewport.Height = mHeight; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp index 350526c867..fa9a69c5a1 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp @@ -100,6 +100,7 @@ bool CoreWindowNativeWindow::registerForSizeChangeEvents() if (SUCCEEDED(result)) { result = mDisplayInformation->add_OrientationChanged(orientationChangedHandler.Get(), &mOrientationChangedEventToken); + orientationChangedHandler->Invoke(mDisplayInformation.Get(), nullptr); } #endif @@ -135,8 +136,8 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor } DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; - swapChainDesc.Width = width; - swapChainDesc.Height = height; + swapChainDesc.Width = mRotationFlags ? height : width; + swapChainDesc.Height = mRotationFlags ? width : height; swapChainDesc.Format = format; swapChainDesc.Stereo = FALSE; swapChainDesc.SampleDesc.Count = 1; diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp index ded73dbb48..62f3ca1207 100644 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp @@ -101,12 +101,14 @@ EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLin return EGL_FALSE; } +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: Allow this entry point as a workaround if (!display->getExtensions().postSubBuffer) { // Spec is not clear about how this should be handled. SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } +#endif error = eglSurface->postSubBuffer(x, y, width, height); if (error.isError()) diff --git a/src/angle/patches/0006-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch b/src/angle/patches/0006-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch new file mode 100644 index 0000000000..5c6ef7b036 --- /dev/null +++ b/src/angle/patches/0006-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch @@ -0,0 +1,145 @@ +From f0fb8d75bd2c7a894df1cb7e7d3dcd1ad0fd88d0 Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Sun, 3 May 2015 20:55:04 +0300 +Subject: [PATCH] ANGLE: Allow Windows Phone to communicate swap region + +eglPostSubBufferNV is used to communicate the size of the window, as +otherwise there is no way for the renderer to know if the last frame was +rendered in landscape or portrait, causing rendering glitches when the +orientation changes. The rotation flags are utilized in a few additional +places now to fix some corner cases where the rotation was not applied. + +This patch should be squashed into "ANGLE-Improve-Windows-Phone-Support" +during the next ANGLE rebase. + +Task-number: QTBUG-44333 +Task-number: QTBUG-43502 +Change-Id: Iec37f7531854184819c30c87eab82d96d56ff133 +--- + .../angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 2 ++ + .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 28 +++++++++++++--------- + .../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 5 ++-- + .../angle/src/libGLESv2/entry_points_egl_ext.cpp | 2 ++ + 4 files changed, 24 insertions(+), 13 deletions(-) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp +index 4fde295..4a87488 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp +@@ -189,6 +189,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + return egl::Error(EGL_SUCCESS); + } + ++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: eglPostSubBufferNV comes here + if (x + width > mWidth) + { + width = mWidth - x; +@@ -198,6 +199,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + { + height = mHeight - y; + } ++#endif + + if (width == 0 || height == 0) + { +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +index 298f3cc..dc539cf 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +@@ -552,18 +552,18 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + + d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); + ++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + // Create a quad in homogeneous coordinates +- float x1 = (x / float(mWidth)) * 2.0f - 1.0f; +- float y1 = (y / float(mHeight)) * 2.0f - 1.0f; +- float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; +- float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; ++ float x1 = -1.0f; ++ float y1 = -1.0f; ++ float x2 = 1.0f; ++ float y2 = 1.0f; + +-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + const float dim = std::max(mWidth, mHeight); +- float u1 = x / dim; +- float v1 = y / dim; +- float u2 = (x + width) / dim; +- float v2 = (y + height) / dim; ++ float u1 = 0; ++ float v1 = 0; ++ float u2 = float(width) / dim; ++ float v2 = float(height) / dim; + + const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags(); + const bool rotateL = flags == NativeWindow::RotateLeft; +@@ -573,6 +573,12 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1); + d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2); + #else ++ // Create a quad in homogeneous coordinates ++ float x1 = (x / float(mWidth)) * 2.0f - 1.0f; ++ float y1 = (y / float(mHeight)) * 2.0f - 1.0f; ++ float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; ++ float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; ++ + float u1 = x / float(mWidth); + float v1 = y / float(mHeight); + float u2 = (x + width) / float(mWidth); +@@ -613,8 +619,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + #if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +- viewport.Width = (rotateL || rotateR) ? mHeight : mWidth; +- viewport.Height = (rotateL || rotateR) ? mWidth : mHeight; ++ viewport.Width = (rotateL || rotateR) ? height : width; ++ viewport.Height = (rotateL || rotateR) ? width : height; + #else + viewport.Width = mWidth; + viewport.Height = mHeight; +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +index 350526c..fa9a69c 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +@@ -100,6 +100,7 @@ bool CoreWindowNativeWindow::registerForSizeChangeEvents() + if (SUCCEEDED(result)) + { + result = mDisplayInformation->add_OrientationChanged(orientationChangedHandler.Get(), &mOrientationChangedEventToken); ++ orientationChangedHandler->Invoke(mDisplayInformation.Get(), nullptr); + } + #endif + +@@ -135,8 +136,8 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor + } + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; +- swapChainDesc.Width = width; +- swapChainDesc.Height = height; ++ swapChainDesc.Width = mRotationFlags ? height : width; ++ swapChainDesc.Height = mRotationFlags ? width : height; + swapChainDesc.Format = format; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; +diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp +index ded73db..62f3ca1 100644 +--- a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp ++++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp +@@ -101,12 +101,14 @@ EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLin + return EGL_FALSE; + } + ++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: Allow this entry point as a workaround + if (!display->getExtensions().postSubBuffer) + { + // Spec is not clear about how this should be handled. + SetGlobalError(Error(EGL_SUCCESS)); + return EGL_TRUE; + } ++#endif + + error = eglSurface->postSubBuffer(x, y, width, height); + if (error.isError()) +-- +1.9.5.msysgit.0 + -- cgit v1.2.3 From 201bf9e6736a32e5740430dc053916e042a605ea Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Mon, 27 Apr 2015 09:20:42 +0200 Subject: Tests: Remove EXPECT_FAIL in tst_QWidget::widgetAt() The test is always marked as XPASS in CI. Change-Id: I629bdec6f038cd8b6208fc4db61c67a9ea003b2e Task-number: QTBUG-22326 Reviewed-by: Frederik Gladhorn --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 5e00ca9450..f623c0ab00 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -3335,8 +3335,6 @@ void tst_QWidget::widgetAt() #if defined(Q_OS_WINCE) QEXPECT_FAIL("", "Windows CE does only support rectangular regions", Continue); //See also task 147191 #endif - if (!QGuiApplication::platformName().compare(QLatin1String("cocoa"), Qt::CaseInsensitive)) - QEXPECT_FAIL("", "Window mask not implemented on Mac QTBUG-22326", Continue); QTRY_VERIFY((wr = QApplication::widgetAt(testPos))); QTRY_COMPARE(wr->objectName(), w1->objectName()); -- cgit v1.2.3 From e6ffb36b5517d1d4025718b56423db9bdf0a63f8 Mon Sep 17 00:00:00 2001 From: Niclas Rosenvik Date: Tue, 5 May 2015 11:04:11 +0200 Subject: Use kqueue on NetBSD in qfilesystemwatcher. Enable kqueue on NetBSD in qfilesystemwatcher. NetBSD has kqueue. http://netbsd.gw.com/cgi-bin/man-cgi?kqueue Change-Id: I6305a37df079c35b9a9b1f70c75ec00e05d25b47 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/io.pri | 2 +- src/corelib/io/qfilesystemwatcher.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 4c189bfe57..207de2a85b 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -187,7 +187,7 @@ win32 { } !nacl { - freebsd-*|mac|darwin-*|openbsd-*:{ + freebsd-*|mac|darwin-*|openbsd-*|netbsd-*:{ SOURCES += io/qfilesystemwatcher_kqueue.cpp HEADERS += io/qfilesystemwatcher_kqueue_p.h } diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index 0bd46400d3..3a8f7bd0a9 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -52,7 +52,7 @@ # include "qfilesystemwatcher_win_p.h" #elif defined(USE_INOTIFY) # include "qfilesystemwatcher_inotify_p.h" -#elif defined(Q_OS_FREEBSD) || defined(Q_OS_IOS) +#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_IOS) # include "qfilesystemwatcher_kqueue_p.h" #elif defined(Q_OS_OSX) # include "qfilesystemwatcher_fsevents_p.h" @@ -68,7 +68,7 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject // there is a chance that inotify may fail on Linux pre-2.6.13 (August // 2005), so we can't just new inotify directly. return QInotifyFileSystemWatcherEngine::create(parent); -#elif defined(Q_OS_FREEBSD) || defined(Q_OS_IOS) +#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_IOS) return QKqueueFileSystemWatcherEngine::create(parent); #elif defined(Q_OS_OSX) return QFseventsFileSystemWatcherEngine::create(parent); -- cgit v1.2.3 From 00fe833189e79be3f8f00d1972d1f54b7f384dde Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 6 May 2015 12:57:58 +0200 Subject: QNAM: Fix compiler warning Change-Id: I2ae6493e13c9b168c64c458e42ea90d4ec2d8628 Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/network/access/qnetworkreplyhttpimpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 974a101e9c..a4f677efab 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1280,7 +1280,7 @@ void QNetworkReplyHttpImplPrivate::sentUploadDataSlot(qint64 pos, qint64 amount) { if (uploadByteDevicePosition + amount != pos) { // Sanity check, should not happen. - error(QNetworkReply::UnknownNetworkError, ""); + error(QNetworkReply::UnknownNetworkError, QString()); return; } uploadByteDevice->advanceReadPointer(amount); -- cgit v1.2.3 From 3545ef41217e3ce4d1bea2b07793fa7a8c1058a6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 4 May 2015 18:20:07 -0700 Subject: Autotest: Check if this D-Bus library knows about file descriptors Because if it doesn't, then calling dbus_type_is_fixed or is_basic may result in a failed assertion. process 16304: arguments to dbus_type_is_fixed() were incorrect, assertion "_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID" failed in file dbus-signature.c line 345. Change-Id: Idf715b895bac4d56b4afffff13db2ed71b1516a5 Reviewed-by: Allan Sandfeld Jensen --- tests/auto/dbus/qdbustype/tst_qdbustype.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/auto/dbus/qdbustype/tst_qdbustype.cpp b/tests/auto/dbus/qdbustype/tst_qdbustype.cpp index e674b6d686..a054db877d 100644 --- a/tests/auto/dbus/qdbustype/tst_qdbustype.cpp +++ b/tests/auto/dbus/qdbustype/tst_qdbustype.cpp @@ -87,8 +87,19 @@ static void addFixedTypes() QTest::newRow("int64") << DBUS_TYPE_INT64_AS_STRING << true << true; QTest::newRow("uint64") << DBUS_TYPE_UINT64_AS_STRING << true << true; QTest::newRow("double") << DBUS_TYPE_DOUBLE_AS_STRING << true << true; + #ifdef DBUS_TYPE_UNIX_FD_AS_STRING - QTest::newRow("unixfd") << DBUS_TYPE_UNIX_FD_AS_STRING << true << true; +# ifndef QT_LINKED_LIBDBUS + // We have got the macro from dbus_minimal_p.h, so we need to check if + // the library recognizes this as valid type first. + // The following function was added for Unix FD support, so if it is + // present, so is support for Unix FDs. + bool supportsUnixFds = qdbus_resolve_conditionally("dbus_connection_can_send_type"); +# else + bool supportsUnixFds = true; +# endif + if (supportsUnixFds) + QTest::newRow("unixfd") << DBUS_TYPE_UNIX_FD_AS_STRING << true << true; #endif } -- cgit v1.2.3 From 3a726628f13c8f46b447cf0844eb8a5b740a1993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 6 May 2015 18:15:03 +0200 Subject: Android: Store and use the class names as key when caching. Previously the jclass handle was part of the key used for caching the class' methods and fields. Using the jclass handle is not ideal, but it meant that we could easily create a key when the only identifier we had was the jobject or jclass handle. However, in Android 5.1, the re-use of handles seems to be more aggressive and therefore increasing the chance of a collision in the cache look-up. This change removes caching for all calls where we don't know the class name, as that is the only thing that guarantees that we create unique keys for each class. The consequence of this is that only calls that provide a class name will benefit from the internal caching. Task-number: QTBUG-45748 Change-Id: I0039d04e7c068debc9e3b3983632c45dc8e52309 Reviewed-by: Frank Meerkoetter Reviewed-by: Alex Blasche --- src/corelib/kernel/qjni.cpp | 472 +++++++++++++++++++++++++++----------------- src/corelib/kernel/qjni_p.h | 1 + 2 files changed, 293 insertions(+), 180 deletions(-) diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 8431ee3b67..344f7725a0 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE static inline QString keyBase() { - return QStringLiteral("%1%2%3"); + return QStringLiteral("%1%2:%3"); } static QString qt_convertJString(jstring string) @@ -72,15 +72,15 @@ typedef QHash JClassHash; Q_GLOBAL_STATIC(JClassHash, cachedClasses) Q_GLOBAL_STATIC(QReadWriteLock, cachedClassesLock) -static QString toDotEncodedClassName(const char *className) +static QByteArray toBinaryEncClassName(const QByteArray &className) { - return QString::fromLatin1(className).replace(QLatin1Char('/'), QLatin1Char('.')); + return QByteArray(className).replace('/', '.'); } -static jclass getCachedClass(const QString &classDotEnc, bool *isCached = 0) +static jclass getCachedClass(const QByteArray &classBinEnc, bool *isCached = 0) { QReadLocker locker(cachedClassesLock); - const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + const QHash::const_iterator &it = cachedClasses->constFind(QString::fromLatin1(classBinEnc)); const bool found = (it != cachedClasses->constEnd()); if (isCached != 0) @@ -89,10 +89,12 @@ static jclass getCachedClass(const QString &classDotEnc, bool *isCached = 0) return found ? it.value() : 0; } -static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) +inline static jclass loadClass(const QByteArray &className, JNIEnv *env, bool binEncoded = false) { + const QByteArray &binEncClassName = binEncoded ? className : toBinaryEncClassName(className); + bool isCached = false; - jclass clazz = getCachedClass(classDotEnc, &isCached); + jclass clazz = getCachedClass(binEncClassName, &isCached); if (clazz != 0 || isCached) return clazz; @@ -102,11 +104,12 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) QWriteLocker locker(cachedClassesLock); // did we lose the race? - const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + const QLatin1String key(binEncClassName); + const QHash::const_iterator &it = cachedClasses->constFind(key); if (it != cachedClasses->constEnd()) return it.value(); - QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(classDotEnc); + QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(key); QJNIObjectPrivate classObject = classLoader.callObjectMethod("loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", stringName.object()); @@ -114,27 +117,40 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) if (!exceptionCheckAndClear(env) && classObject.isValid()) clazz = static_cast(env->NewGlobalRef(classObject.object())); - cachedClasses->insert(classDotEnc, clazz); + cachedClasses->insert(key, clazz); return clazz; } -inline static jclass loadClass(const char *className, JNIEnv *env) -{ - return loadClassDotEnc(toDotEncodedClassName(className), env); -} - typedef QHash JMethodIDHash; Q_GLOBAL_STATIC(JMethodIDHash, cachedMethodID) Q_GLOBAL_STATIC(QReadWriteLock, cachedMethodIDLock) +static inline jmethodID getMethodID(JNIEnv *env, + jclass clazz, + const char *name, + const char *sig, + bool isStatic = false) +{ + jmethodID id = isStatic ? env->GetStaticMethodID(clazz, name, sig) + : env->GetMethodID(clazz, name, sig); + + if (exceptionCheckAndClear(env)) + return 0; + + return id; +} + static jmethodID getCachedMethodID(JNIEnv *env, jclass clazz, + const QByteArray &className, const char *name, const char *sig, bool isStatic = false) { - // TODO: We need to use something else then the ref. from clazz to avoid collisions. - const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + if (className.isEmpty()) + return getMethodID(env, clazz, name, sig, isStatic); + + const QString key = keyBase().arg(QLatin1String(className)).arg(QLatin1String(name)).arg(QLatin1String(sig)); QHash::const_iterator it; { @@ -150,14 +166,7 @@ static jmethodID getCachedMethodID(JNIEnv *env, if (it != cachedMethodID->constEnd()) return it.value(); - jmethodID id = 0; - if (isStatic) - id = env->GetStaticMethodID(clazz, name, sig); - else - id = env->GetMethodID(clazz, name, sig); - - if (exceptionCheckAndClear(env)) - id = 0; + jmethodID id = getMethodID(env, clazz, name, sig, isStatic); cachedMethodID->insert(key, id); return id; @@ -168,13 +177,32 @@ typedef QHash JFieldIDHash; Q_GLOBAL_STATIC(JFieldIDHash, cachedFieldID) Q_GLOBAL_STATIC(QReadWriteLock, cachedFieldIDLock) +static inline jfieldID getFieldID(JNIEnv *env, + jclass clazz, + const char *name, + const char *sig, + bool isStatic = false) +{ + jfieldID id = isStatic ? env->GetStaticFieldID(clazz, name, sig) + : env->GetFieldID(clazz, name, sig); + + if (exceptionCheckAndClear(env)) + return 0; + + return id; +} + static jfieldID getCachedFieldID(JNIEnv *env, jclass clazz, + const QByteArray &className, const char *name, const char *sig, bool isStatic = false) { - const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + if (className.isNull()) + return getFieldID(env, clazz, name, sig, isStatic); + + const QString key = keyBase().arg(QLatin1String(className)).arg(QLatin1String(name)).arg(QLatin1String(sig)); QHash::const_iterator it; { @@ -190,14 +218,7 @@ static jfieldID getCachedFieldID(JNIEnv *env, if (it != cachedFieldID->constEnd()) return it.value(); - jfieldID id = 0; - if (isStatic) - id = env->GetStaticFieldID(clazz, name, sig); - else - id = env->GetFieldID(clazz, name, sig); - - if (exceptionCheckAndClear(env)) - id = 0; + jfieldID id = getFieldID(env, clazz, name, sig, isStatic); cachedFieldID->insert(key, id); return id; @@ -241,7 +262,7 @@ JNIEnv *QJNIEnvironmentPrivate::operator->() jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) { - const QString &classDotEnc = toDotEncodedClassName(className); + const QByteArray &classDotEnc = toBinaryEncClassName(className); bool isCached = false; jclass clazz = getCachedClass(classDotEnc, &isCached); @@ -250,9 +271,10 @@ jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) if (found) return clazz; + const QLatin1String key(classDotEnc); if (env != 0) { // We got an env. pointer (We expect this to be the right env. and call FindClass()) QWriteLocker locker(cachedClassesLock); - const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + const QHash::const_iterator &it = cachedClasses->constFind(key); // Did we lose the race? if (it != cachedClasses->constEnd()) return it.value(); @@ -264,11 +286,11 @@ jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) } if (clazz != 0) - cachedClasses->insert(classDotEnc, clazz); + cachedClasses->insert(key, clazz); } if (clazz == 0) // We didn't get an env. pointer or we got one with the WRONG class loader... - clazz = loadClassDotEnc(classDotEnc, QJNIEnvironmentPrivate()); + clazz = loadClass(classDotEnc, QJNIEnvironmentPrivate(), true); return clazz; } @@ -309,11 +331,12 @@ QJNIObjectPrivate::QJNIObjectPrivate(const char *className) : d(new QJNIObjectData()) { QJNIEnvironmentPrivate env; - d->m_jclass = loadClass(className, env); + d->m_className = toBinaryEncClassName(className); + d->m_jclass = loadClass(d->m_className, env, true); d->m_own_jclass = false; if (d->m_jclass) { // get default constructor - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", "()V"); + jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "", "()V"); if (constructorId) { jobject obj = env->NewObject(d->m_jclass, constructorId); if (obj) { @@ -328,10 +351,11 @@ QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, ... : d(new QJNIObjectData()) { QJNIEnvironmentPrivate env; - d->m_jclass = loadClass(className, env); + d->m_className = toBinaryEncClassName(className); + d->m_jclass = loadClass(d->m_className, env, true); d->m_own_jclass = false; if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "", sig); if (constructorId) { va_list args; va_start(args, sig); @@ -349,10 +373,11 @@ QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, con : d(new QJNIObjectData()) { QJNIEnvironmentPrivate env; - d->m_jclass = loadClass(className, env); + d->m_className = toBinaryEncClassName(className); + d->m_jclass = loadClass(d->m_className, env, true); d->m_own_jclass = false; if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "", sig); if (constructorId) { jobject obj = env->NewObjectV(d->m_jclass, constructorId, args); if (obj) { @@ -370,7 +395,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz) d->m_jclass = static_cast(env->NewGlobalRef(clazz)); if (d->m_jclass) { // get default constructor - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", "()V"); + jmethodID constructorId = getMethodID(env, d->m_jclass, "", "()V"); if (constructorId) { jobject obj = env->NewObject(d->m_jclass, constructorId); if (obj) { @@ -388,7 +413,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, ...) if (clazz) { d->m_jclass = static_cast(env->NewGlobalRef(clazz)); if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getMethodID(env, d->m_jclass, "", sig); if (constructorId) { va_list args; va_start(args, sig); @@ -410,7 +435,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, const QVaLis if (clazz) { d->m_jclass = static_cast(env->NewGlobalRef(clazz)); if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getMethodID(env, d->m_jclass, "", sig); if (constructorId) { jobject obj = env->NewObjectV(d->m_jclass, constructorId, args); if (obj) { @@ -430,15 +455,15 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj) QJNIEnvironmentPrivate env; d->m_jobject = env->NewGlobalRef(obj); - jclass objectClass = env->GetObjectClass(d->m_jobject); - d->m_jclass = static_cast(env->NewGlobalRef(objectClass)); - env->DeleteLocalRef(objectClass); + jclass cls = env->GetObjectClass(obj); + d->m_jclass = static_cast(env->NewGlobalRef(cls)); + env->DeleteLocalRef(cls); } template <> void QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { env->CallVoidMethodV(d->m_jobject, id, args); } @@ -458,7 +483,7 @@ jboolean QJNIObjectPrivate::callMethodV(const char *methodName, const { QJNIEnvironmentPrivate env; jboolean res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallBooleanMethodV(d->m_jobject, id, args); } @@ -480,7 +505,7 @@ jbyte QJNIObjectPrivate::callMethodV(const char *methodName, const char * { QJNIEnvironmentPrivate env; jbyte res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallByteMethodV(d->m_jobject, id, args); } @@ -502,7 +527,7 @@ jchar QJNIObjectPrivate::callMethodV(const char *methodName, const char * { QJNIEnvironmentPrivate env; jchar res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallCharMethodV(d->m_jobject, id, args); } @@ -524,7 +549,7 @@ jshort QJNIObjectPrivate::callMethodV(const char *methodName, const char { QJNIEnvironmentPrivate env; jshort res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallShortMethodV(d->m_jobject, id, args); } @@ -546,7 +571,7 @@ jint QJNIObjectPrivate::callMethodV(const char *methodName, const char *si { QJNIEnvironmentPrivate env; jint res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallIntMethodV(d->m_jobject, id, args); } @@ -568,7 +593,7 @@ jlong QJNIObjectPrivate::callMethodV(const char *methodName, const char * { QJNIEnvironmentPrivate env; jlong res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallLongMethodV(d->m_jobject, id, args); } @@ -590,7 +615,7 @@ jfloat QJNIObjectPrivate::callMethodV(const char *methodName, const char { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallFloatMethodV(d->m_jobject, id, args); } @@ -612,7 +637,7 @@ jdouble QJNIObjectPrivate::callMethodV(const char *methodName, const ch { QJNIEnvironmentPrivate env; jdouble res = 0.; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallDoubleMethodV(d->m_jobject, id, args); } @@ -692,7 +717,7 @@ void QJNIObjectPrivate::callStaticMethodV(const char *className, QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { env->CallStaticVoidMethodV(clazz, id, args); } @@ -718,7 +743,7 @@ void QJNIObjectPrivate::callStaticMethodV(jclass clazz, va_list args) { QJNIEnvironmentPrivate env; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { env->CallStaticVoidMethodV(clazz, id, args); } @@ -746,7 +771,7 @@ jboolean QJNIObjectPrivate::callStaticMethodV(const char *className, jboolean res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticBooleanMethodV(clazz, id, args); } @@ -776,7 +801,7 @@ jboolean QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jboolean res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticBooleanMethodV(clazz, id, args); } @@ -807,7 +832,7 @@ jbyte QJNIObjectPrivate::callStaticMethodV(const char *className, jbyte res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticByteMethodV(clazz, id, args); } @@ -837,7 +862,7 @@ jbyte QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jbyte res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticByteMethodV(clazz, id, args); } @@ -868,7 +893,7 @@ jchar QJNIObjectPrivate::callStaticMethodV(const char *className, jchar res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticCharMethodV(clazz, id, args); } @@ -898,7 +923,7 @@ jchar QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jchar res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticCharMethodV(clazz, id, args); } @@ -929,7 +954,7 @@ jshort QJNIObjectPrivate::callStaticMethodV(const char *className, jshort res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticShortMethodV(clazz, id, args); } @@ -959,7 +984,7 @@ jshort QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jshort res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticShortMethodV(clazz, id, args); } @@ -990,7 +1015,7 @@ jint QJNIObjectPrivate::callStaticMethodV(const char *className, jint res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticIntMethodV(clazz, id, args); } @@ -1020,7 +1045,7 @@ jint QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jint res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticIntMethodV(clazz, id, args); } @@ -1051,7 +1076,7 @@ jlong QJNIObjectPrivate::callStaticMethodV(const char *className, jlong res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticLongMethodV(clazz, id, args); } @@ -1081,7 +1106,7 @@ jlong QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jlong res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticLongMethodV(clazz, id, args); } @@ -1112,7 +1137,7 @@ jfloat QJNIObjectPrivate::callStaticMethodV(const char *className, jfloat res = 0.f; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticFloatMethodV(clazz, id, args); } @@ -1142,7 +1167,7 @@ jfloat QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticFloatMethodV(clazz, id, args); } @@ -1173,7 +1198,7 @@ jdouble QJNIObjectPrivate::callStaticMethodV(const char *className, jdouble res = 0.; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticDoubleMethodV(clazz, id, args); } @@ -1203,7 +1228,7 @@ jdouble QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jdouble res = 0.; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticDoubleMethodV(clazz, id, args); } @@ -1338,7 +1363,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethodV(const char *methodName, { QJNIEnvironmentPrivate env; jobject res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallObjectMethodV(d->m_jobject, id, args); if (res && env->ExceptionCheck()) @@ -1418,7 +1443,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethodV(const char *classNa jobject res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticObjectMethodV(clazz, id, args); if (res && env->ExceptionCheck()) @@ -1450,7 +1475,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jobject res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticObjectMethodV(clazz, id, args); if (res && env->ExceptionCheck()) @@ -1479,7 +1504,7 @@ jboolean QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jboolean res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "Z"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Z"); if (id) res = env->GetBooleanField(d->m_jobject, id); @@ -1491,7 +1516,7 @@ jbyte QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jbyte res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "B"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "B"); if (id) res = env->GetByteField(d->m_jobject, id); @@ -1503,7 +1528,7 @@ jchar QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jchar res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "C"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "C"); if (id) res = env->GetCharField(d->m_jobject, id); @@ -1515,7 +1540,7 @@ jshort QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jshort res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "S"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "S"); if (id) res = env->GetShortField(d->m_jobject, id); @@ -1527,7 +1552,7 @@ jint QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jint res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "I"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "I"); if (id) res = env->GetIntField(d->m_jobject, id); @@ -1539,7 +1564,7 @@ jlong QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jlong res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "J"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "J"); if (id) res = env->GetLongField(d->m_jobject, id); @@ -1551,7 +1576,7 @@ jfloat QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "F"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "F"); if (id) res = env->GetFloatField(d->m_jobject, id); @@ -1563,7 +1588,7 @@ jdouble QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jdouble res = 0.; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "D"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "D"); if (id) res = env->GetDoubleField(d->m_jobject, id); @@ -1575,7 +1600,7 @@ jboolean QJNIObjectPrivate::getStaticField(jclass clazz, const char *f { QJNIEnvironmentPrivate env; jboolean res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "Z", true); + jfieldID id = getFieldID(env, clazz, fieldName, "Z", true); if (id) res = env->GetStaticBooleanField(clazz, id); @@ -1586,12 +1611,15 @@ template <> jboolean QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jboolean res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "Z", true); + if (id == 0) + return 0; + + return env->GetStaticBooleanField(clazz, id); } template <> @@ -1599,7 +1627,7 @@ jbyte QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa { QJNIEnvironmentPrivate env; jbyte res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "B", true); + jfieldID id = getFieldID(env, clazz, fieldName, "B", true); if (id) res = env->GetStaticByteField(clazz, id); @@ -1610,12 +1638,15 @@ template <> jbyte QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jbyte res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "B", true); + if (id == 0) + return 0; + + return env->GetStaticByteField(clazz, id); } template <> @@ -1623,7 +1654,7 @@ jchar QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa { QJNIEnvironmentPrivate env; jchar res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "C", true); + jfieldID id = getFieldID(env, clazz, fieldName, "C", true); if (id) res = env->GetStaticCharField(clazz, id); @@ -1634,12 +1665,15 @@ template <> jchar QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jchar res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "C", true); + if (id == 0) + return 0; + + return env->GetStaticCharField(clazz, id); } template <> @@ -1647,7 +1681,7 @@ jshort QJNIObjectPrivate::getStaticField(jclass clazz, const char *field { QJNIEnvironmentPrivate env; jshort res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "S", true); + jfieldID id = getFieldID(env, clazz, fieldName, "S", true); if (id) res = env->GetStaticShortField(clazz, id); @@ -1658,12 +1692,15 @@ template <> jshort QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jshort res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "S", true); + if (id == 0) + return 0; + + return env->GetStaticShortField(clazz, id); } template <> @@ -1671,7 +1708,7 @@ jint QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName { QJNIEnvironmentPrivate env; jint res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "I", true); + jfieldID id = getFieldID(env, clazz, fieldName, "I", true); if (id) res = env->GetStaticIntField(clazz, id); @@ -1682,12 +1719,15 @@ template <> jint QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jint res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "I", true); + if (id == 0) + return 0; + + return env->GetStaticIntField(clazz, id); } template <> @@ -1695,7 +1735,7 @@ jlong QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa { QJNIEnvironmentPrivate env; jlong res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "J", true); + jfieldID id = getFieldID(env, clazz, fieldName, "J", true); if (id) res = env->GetStaticLongField(clazz, id); @@ -1706,12 +1746,15 @@ template <> jlong QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jlong res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "J", true); + if (id == 0) + return 0; + + return env->GetStaticLongField(clazz, id); } template <> @@ -1719,7 +1762,7 @@ jfloat QJNIObjectPrivate::getStaticField(jclass clazz, const char *field { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "F", true); + jfieldID id = getFieldID(env, clazz, fieldName, "F", true); if (id) res = env->GetStaticFloatField(clazz, id); @@ -1730,12 +1773,15 @@ template <> jfloat QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jfloat res = 0.f; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0.f; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "F", true); + if (id == 0) + return 0.f; + + return env->GetStaticFloatField(clazz, id); } template <> @@ -1743,7 +1789,7 @@ jdouble QJNIObjectPrivate::getStaticField(jclass clazz, const char *fie { QJNIEnvironmentPrivate env; jdouble res = 0.; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "D", true); + jfieldID id = getFieldID(env, clazz, fieldName, "D", true); if (id) res = env->GetStaticDoubleField(clazz, id); @@ -1754,12 +1800,15 @@ template <> jdouble QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jdouble res = 0.; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0.; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "D", true); + if (id == 0) + return 0.; + + return env->GetStaticDoubleField(clazz, id); } QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName, @@ -1767,7 +1816,7 @@ QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName, { QJNIEnvironmentPrivate env; jobject res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, sig); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig); if (id) { res = env->GetObjectField(d->m_jobject, id); if (res && env->ExceptionCheck()) @@ -1784,12 +1833,21 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(const char *className, const char *sig) { QJNIEnvironmentPrivate env; - QJNIObjectPrivate res; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticObjectField(clazz, fieldName, sig); + if (clazz == 0) + return QJNIObjectPrivate(); - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, sig, true); + if (id == 0) + return QJNIObjectPrivate(); + + jobject res = env->GetStaticObjectField(clazz, id); + if (res && env->ExceptionCheck()) + res = 0; + + QJNIObjectPrivate obj(res); + env->DeleteLocalRef(res); + return obj; } QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz, @@ -1798,7 +1856,7 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz, { QJNIEnvironmentPrivate env; jobject res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, sig, true); + jfieldID id = getFieldID(env, clazz, fieldName, sig, true); if (id) { res = env->GetStaticObjectField(clazz, id); if (res && env->ExceptionCheck()) @@ -1814,7 +1872,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jboolean value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "Z"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Z"); if (id) env->SetBooleanField(d->m_jobject, id, value); @@ -1824,7 +1882,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jbyte value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "B"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "B"); if (id) env->SetByteField(d->m_jobject, id, value); @@ -1834,7 +1892,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jchar value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "C"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "C"); if (id) env->SetCharField(d->m_jobject, id, value); @@ -1844,7 +1902,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jshort value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "S"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "S"); if (id) env->SetShortField(d->m_jobject, id, value); @@ -1854,7 +1912,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jint value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "I"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "I"); if (id) env->SetIntField(d->m_jobject, id, value); @@ -1864,7 +1922,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jlong value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "J"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "J"); if (id) env->SetLongField(d->m_jobject, id, value); @@ -1874,7 +1932,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jfloat value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "F"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "F"); if (id) env->SetFloatField(d->m_jobject, id, value); @@ -1884,7 +1942,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jdouble value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "D"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "D"); if (id) env->SetDoubleField(d->m_jobject, id, value); @@ -1894,7 +1952,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jbooleanArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[Z"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[Z"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1904,7 +1962,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jbyteArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[B"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[B"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1914,7 +1972,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jcharArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[C"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[C"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1924,7 +1982,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jshortArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[S"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[S"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1934,7 +1992,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jintArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[I"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[I"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1944,7 +2002,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jlongArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[J"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[J"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1954,7 +2012,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jfloatArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[F"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[F"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1964,7 +2022,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jdoubleArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[D"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[D"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1974,7 +2032,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jstring value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "Ljava/lang/String;"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Ljava/lang/String;"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1986,7 +2044,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jobject value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, sig); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1998,7 +2056,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jobjectArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, sig); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -2010,7 +2068,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jboolean value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "Z", true); + jfieldID id = getFieldID(env, clazz, fieldName, "Z", true); if (id) env->SetStaticBooleanField(clazz, id, value); } @@ -2022,8 +2080,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "Z", true); + if (id == 0) + return; + + env->SetStaticBooleanField(clazz, id, value); } template <> @@ -2032,7 +2096,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jbyte value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "B", true); + jfieldID id = getFieldID(env, clazz, fieldName, "B", true); if (id) env->SetStaticByteField(clazz, id, value); } @@ -2044,8 +2108,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "B", true); + if (id == 0) + return; + + env->SetStaticByteField(clazz, id, value); } template <> @@ -2054,7 +2124,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jchar value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "C", true); + jfieldID id = getFieldID(env, clazz, fieldName, "C", true); if (id) env->SetStaticCharField(clazz, id, value); } @@ -2066,8 +2136,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "C", true); + if (id == 0) + return; + + env->SetStaticCharField(clazz, id, value); } template <> @@ -2076,7 +2152,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jshort value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "S", true); + jfieldID id = getFieldID(env, clazz, fieldName, "S", true); if (id) env->SetStaticShortField(clazz, id, value); } @@ -2088,8 +2164,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "S", true); + if (id == 0) + return; + + env->SetStaticShortField(clazz, id, value); } template <> @@ -2098,7 +2180,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jint value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "I", true); + jfieldID id = getFieldID(env, clazz, fieldName, "I", true); if (id) env->SetStaticIntField(clazz, id, value); } @@ -2110,8 +2192,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "I", true); + if (id == 0) + return; + + env->SetStaticIntField(clazz, id, value); } template <> @@ -2120,7 +2208,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jlong value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "J", true); + jfieldID id = getFieldID(env, clazz, fieldName, "J", true); if (id) env->SetStaticLongField(clazz, id, value); } @@ -2132,8 +2220,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "J", true); + if (id == 0) + return; + + env->SetStaticLongField(clazz, id, value); } template <> @@ -2142,7 +2236,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jfloat value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "F", true); + jfieldID id = getFieldID(env, clazz, fieldName, "F", true); if (id) env->SetStaticFloatField(clazz, id, value); } @@ -2154,8 +2248,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "F", true); + if (id == 0) + return; + + env->SetStaticFloatField(clazz, id, value); } template <> @@ -2164,7 +2264,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jdouble value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "D", true); + jfieldID id = getFieldID(env, clazz, fieldName, "D", true); if (id) env->SetStaticDoubleField(clazz, id, value); } @@ -2176,8 +2276,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "D", true); + if (id == 0) + return; + + env->SetStaticDoubleField(clazz, id, value); } template <> @@ -2187,7 +2293,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jobject value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, sig, true); + jfieldID id = getFieldID(env, clazz, fieldName, sig, true); if (id) env->SetStaticObjectField(clazz, id, value); } @@ -2200,8 +2306,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, sig, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, sig, true); + if (id == 0) + return; + + env->SetStaticObjectField(clazz, id, value); } QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string) diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h index fb1982dc74..a62e9ee056 100644 --- a/src/corelib/kernel/qjni_p.h +++ b/src/corelib/kernel/qjni_p.h @@ -74,6 +74,7 @@ public: jobject m_jobject; jclass m_jclass; bool m_own_jclass; + QByteArray m_className; }; class Q_CORE_EXPORT QJNIObjectPrivate -- cgit v1.2.3 From 4fe68ffbe5c93244562f2b56292d4ecf5ce39f56 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 10 Apr 2015 13:55:10 +0200 Subject: Add GPU_BLACKLIST support to QTestLib In addition to BLACKLIST, Qt will now look for GPU_BLACKLIST too. Test cases that are specified as disabled in the GPU blacklist will be skipped. This is particularly relevant when running tests on Embedded Linux devices. For example, the following JSON would configure the test case glxContextWrap to be skipped on drivers where GL_VENDOR contains UnstableDriverVendor: { "entries": [ { "gl_vendor": "UnstableDriverVendor", "features": [ "disable_glxContextWrap" ] } ] } In contrast to the regular blacklist, GPU-blacklisted test cases are not run at all. This is because driver problems and instabilities often lead to crashes. Change-Id: I340cf5c0261a206109b78409774408981bba5c68 Reviewed-by: Friedemann Kleint Reviewed-by: Simon Hausmann --- src/gui/opengl/qopengl.cpp | 11 +++++++++++ src/testlib/qtest.h | 20 ++++++++++++++++++++ src/testlib/qtestblacklist.cpp | 27 ++++++++++++++++++++++++++- src/testlib/qtestblacklist_p.h | 3 ++- src/testlib/qtestcase.cpp | 3 ++- 5 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index 622e014746..1c008ccb42 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -47,6 +47,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE #if defined(QT_OPENGL_3) @@ -474,4 +476,13 @@ QOpenGLConfig::Gpu QOpenGLConfig::Gpu::fromContext() return gpu; } +Q_GUI_EXPORT std::set *qgpu_features(const QString &filename) +{ + const QSet features = QOpenGLConfig::gpuFeatures(QOpenGLConfig::Gpu::fromContext(), filename); + std::set *result = new std::set; + foreach (const QString &feature, features) + result->insert(feature.toUtf8()); + return result; +} + QT_END_NAMESPACE diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 70e923927b..994179958b 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -289,6 +289,18 @@ int main(int argc, char *argv[]) \ } #include +#include + +#ifndef QT_NO_OPENGL +# define QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \ + extern Q_TESTLIB_EXPORT std::set *(*qgpu_features_ptr)(const QString &); \ + extern Q_GUI_EXPORT std::set *qgpu_features(const QString &); +# define QTEST_ADD_GPU_BLACKLIST_SUPPORT \ + qgpu_features_ptr = qgpu_features; +#else +# define QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS +# define QTEST_ADD_GPU_BLACKLIST_SUPPORT +#endif #if defined(QT_WIDGETS_LIB) @@ -301,11 +313,15 @@ int main(int argc, char *argv[]) \ #endif #define QTEST_MAIN(TestObject) \ +QT_BEGIN_NAMESPACE \ +QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \ +QT_END_NAMESPACE \ int main(int argc, char *argv[]) \ { \ QApplication app(argc, argv); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ QTEST_DISABLE_KEYPAD_NAVIGATION \ + QTEST_ADD_GPU_BLACKLIST_SUPPORT \ TestObject tc; \ QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ @@ -316,10 +332,14 @@ int main(int argc, char *argv[]) \ #include #define QTEST_MAIN(TestObject) \ +QT_BEGIN_NAMESPACE \ +QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \ +QT_END_NAMESPACE \ int main(int argc, char *argv[]) \ { \ QGuiApplication app(argc, argv); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ + QTEST_ADD_GPU_BLACKLIST_SUPPORT \ TestObject tc; \ QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index f8285c3ea9..28a2878b32 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -34,6 +34,7 @@ #include "qtestresult_p.h" #include +#include #include #include #include @@ -154,6 +155,9 @@ static bool checkCondition(const QByteArray &condition) static bool ignoreAll = false; static std::set *ignoredTests = 0; +static std::set *gpuFeatures = 0; + +Q_TESTLIB_EXPORT std::set *(*qgpu_features_ptr)(const QString &) = 0; namespace QTestPrivate { @@ -189,7 +193,18 @@ void parseBlackList() } } -void checkBlackList(const char *slot, const char *data) +void parseGpuBlackList() +{ + if (!qgpu_features_ptr) + return; + QString filename = QTest::qFindTestData(QStringLiteral("GPU_BLACKLIST")); + if (filename.isEmpty()) + return; + if (!gpuFeatures) + gpuFeatures = qgpu_features_ptr(filename); +} + +void checkBlackLists(const char *slot, const char *data) { bool ignore = ignoreAll; @@ -204,6 +219,16 @@ void checkBlackList(const char *slot, const char *data) } QTestResult::setBlacklistCurrentTest(ignore); + + // Tests blacklisted in GPU_BLACKLIST are to be skipped. Just ignoring the result is + // not sufficient since these are expected to crash or behave in undefined ways. + if (!ignore && gpuFeatures) { + const QByteArray disableKey = QByteArrayLiteral("disable_") + QByteArray(slot); + if (gpuFeatures->find(disableKey) != gpuFeatures->end()) { + const QByteArray msg = QByteArrayLiteral("Skipped due to GPU blacklist: ") + disableKey; + QTest::qSkip(msg.constData(), __FILE__, __LINE__); + } + } } } diff --git a/src/testlib/qtestblacklist_p.h b/src/testlib/qtestblacklist_p.h index 158d99593e..0107e5d282 100644 --- a/src/testlib/qtestblacklist_p.h +++ b/src/testlib/qtestblacklist_p.h @@ -51,7 +51,8 @@ QT_BEGIN_NAMESPACE namespace QTestPrivate { void parseBlackList(); - void checkBlackList(const char *slot, const char *data); + void parseGpuBlackList(); + void checkBlackLists(const char *slot, const char *data); } QT_END_NAMESPACE diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index b76e5544ba..e3c543671b 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2074,7 +2074,7 @@ static bool qInvokeTestMethod(const char *slotName, const char *data=0) if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) { foundFunction = true; - QTestPrivate::checkBlackList(slot, dataCount ? table.testData(curDataIndex)->dataTag() : 0); + QTestPrivate::checkBlackLists(slot, dataCount ? table.testData(curDataIndex)->dataTag() : 0); QTestDataSetter s(curDataIndex >= dataCount ? static_cast(0) : table.testData(curDataIndex)); @@ -2583,6 +2583,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) #endif QTestPrivate::parseBlackList(); + QTestPrivate::parseGpuBlackList(); QTestResult::reset(); -- cgit v1.2.3 From 82449d725168b4afb5c4178647ee35bd04f4ca41 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 May 2015 19:01:14 +0200 Subject: fix (un-)installation for TEMPLATE = aux don't try to install the primary target, as it obviously doesn't exist. however, we must not disarm bundle installation. Change-Id: I3074150f749220d77c1210a4978e71aff9c9a3a9 Reviewed-by: Joerg Bornemann --- qmake/generators/unix/unixmake.cpp | 24 ++++++++++++++---------- qmake/generators/win32/winmakefile.cpp | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index efea807209..723eea80d3 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -699,6 +699,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t) return QString(); enum { NoBundle, SolidBundle, SlicedBundle } bundle = NoBundle; + bool isAux = (project->first("TEMPLATE") == "aux"); const QString root = "$(INSTALL_ROOT)"; ProStringList &uninst = project->values(ProKey(t + ".uninstall")); QString ret, destdir = project->first("DESTDIR").toQString(); @@ -773,21 +774,21 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } src_targ = escapeFilePath(src_targ); dst_targ = escapeFilePath(dst_targ); - if(!ret.isEmpty()) - ret += "\n\t"; - QString copy_cmd("-"); + QString copy_cmd; if (bundle == SolidBundle) { - copy_cmd += "$(INSTALL_DIR) " + src_targ + ' ' + plain_targ; + copy_cmd += "-$(INSTALL_DIR) " + src_targ + ' ' + plain_targ; } else if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) { - copy_cmd += "$(INSTALL_FILE) " + src_targ + ' ' + dst_targ; - } else { + copy_cmd += "-$(INSTALL_FILE) " + src_targ + ' ' + dst_targ; + } else if (!isAux) { if (bundle == SlicedBundle) ret += mkdir_p_asstring("\"`dirname " + dst_targ + "`\"", false) + "\n\t"; - copy_cmd += "$(INSTALL_PROGRAM) " + src_targ + ' ' + dst_targ; + copy_cmd += "-$(INSTALL_PROGRAM) " + src_targ + ' ' + dst_targ; } if(project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && project->values(ProKey(t + ".CONFIG")).indexOf("fix_rpath") != -1) { + if (!ret.isEmpty()) + ret += "\n\t"; if(!project->isEmpty("QMAKE_FIX_RPATH")) { ret += copy_cmd; ret += "\n\t-" + var("QMAKE_FIX_RPATH") + ' ' + dst_targ + ' ' + dst_targ; @@ -797,11 +798,14 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } else { ret += copy_cmd; } - } else { + } else if (!copy_cmd.isEmpty()) { + if (!ret.isEmpty()) + ret += "\n\t"; ret += copy_cmd; } - if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) { + if (isAux) { + } else if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) { if(!project->isEmpty("QMAKE_RANLIB")) ret += QString("\n\t$(RANLIB) ") + dst_targ; } else if (!project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") @@ -820,7 +824,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t) uninst.append("\n\t"); if (bundle == SolidBundle) uninst.append("-$(DEL_FILE) -r " + plain_targ); - else + else if (!isAux) uninst.append("-$(DEL_FILE) " + dst_targ); if (bundle == SlicedBundle) { int dstlen = project->first("DESTDIR").length(); diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 6ea129f82c..8a60c44032 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -784,7 +784,7 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t) { if((t != "target" && t != "dlltarget") || (t == "dlltarget" && (project->first("TEMPLATE") != "lib" || !project->isActiveConfig("shared"))) || - project->first("TEMPLATE") == "subdirs") + project->first("TEMPLATE") == "subdirs" || project->first("TEMPLATE") == "aux") return QString(); const QString root = "$(INSTALL_ROOT)"; -- cgit v1.2.3 From d4efd4b004bf58c6843d10aa205bdd608ca7a3bd Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 May 2015 18:16:00 +0200 Subject: change approach to requesting headers-only modules there is no need to make exceptions for install targets now, so instead of abusing qt_no_install_library, introduce a new header_module flag. Change-Id: I4ad7e301d1b60938b17e1dea732b1dbe3ff88a1a Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_module.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 66a7598597..bfa17807aa 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -60,7 +60,7 @@ MODULE_DEFINES = $$MODULE_DEFINE $$MODULE_DEFINES load(qt_build_paths) -qt_no_install_library { +header_module { TEMPLATE = aux CONFIG += force_qt # Needed for the headers_clean tests. } else { @@ -104,7 +104,7 @@ mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) { QMAKE_TARGET_BUNDLE_PREFIX = org.qt-project #QMAKE_FRAMEWORK_VERSION = 4.0 CONFIG += sliced_bundle qt_framework - qt_no_install_library { + header_module { CONFIG += bundle QMAKE_BUNDLE_EXTENSION = .framework QMAKE_INFO_PLIST = $$QMAKESPEC/Info.plist.lib -- cgit v1.2.3 From 93f581e1f270401dd7a39575cd8151f41f290a7c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 6 May 2015 16:25:15 +0200 Subject: fix wrong path separators in extra compiler commands Change-Id: I19a2c53c301becbbe5b70e47067f9a3355f7b04a Reviewed-by: Simon Hausmann --- qmake/generators/makefile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index f5e8248af5..728be67acc 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2019,7 +2019,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) for(int i = 0; i < pre_deps.size(); ++i) deps << replaceExtraCompilerVariables(pre_deps.at(i), inpf, out, NoShell); } - QString cmd = replaceExtraCompilerVariables(tmp_cmd, inpf, out, LocalShell); + QString cmd = replaceExtraCompilerVariables(tmp_cmd, inpf, out, TargetShell); // NOTE: The var -> QMAKE_COMP_var replace feature is unsupported, do not use! for (ProStringList::ConstIterator it3 = vars.constBegin(); it3 != vars.constEnd(); ++it3) cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); -- cgit v1.2.3 From 4b7d70886f710767c2b163a08da44d3a7b80479c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 6 May 2015 15:30:33 +0200 Subject: fix ANGLE build with VS2015 ... by making the conditional future-proof by inverting it. Task-number: QTBUG-45972 Change-Id: I0bf8eac1b1095b9bf4dec0b82fc42e5a58d0499a Reviewed-by: Andrew Knight Reviewed-by: Gunnar Roth --- 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 63b80347d1..735c841ad8 100644 --- a/src/angle/src/common/common.pri +++ b/src/angle/src/common/common.pri @@ -13,7 +13,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. -win32-msvc2012|win32-msvc2013|winrt { +winrt|if(msvc:!win32-msvc2005:!win32-msvc2008:!win32-msvc2010) { FXC = fxc.exe } else { DX_DIR = $$(DXSDK_DIR) -- cgit v1.2.3 From 1ac1ae05f551d45772ff2a840dba128abf04171e Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 8 May 2015 13:49:54 +0200 Subject: QDialogButtonBox: prevent crashes on deletions in slots As usual, user code connected to signals emitted from Qt may destroy an object's internal status while a signal is being emitted. Guard a bit QDialogButtonBox signal emissions to prevent crashes in case the button or a dialog get deleted from a slot connected to clicked(). Also, be sure to emit the corresponding accepted/rejected/etc. signal. Change-Id: I7b1888070a8f2f56aa60923a17f90fb5efef145c Task-number: QTBUG-45835 Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Marc Mutz --- src/widgets/widgets/qdialogbuttonbox.cpp | 12 +++- .../qdialogbuttonbox/tst_qdialogbuttonbox.cpp | 66 ++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 237eb775b9..3e8c08f923 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -852,9 +852,19 @@ void QDialogButtonBoxPrivate::_q_handleButtonClicked() { Q_Q(QDialogButtonBox); if (QAbstractButton *button = qobject_cast(q->sender())) { + // Can't fetch this *after* emitting clicked, as clicked may destroy the button + // or change its role. Now changing the role is not possible yet, but arguably + // both clicked and accepted/rejected/etc. should be emitted "atomically" + // depending on whatever role the button had at the time of the click. + const QDialogButtonBox::ButtonRole buttonRole = q->buttonRole(button); + QPointer guard(q); + emit q->clicked(button); - switch (q->buttonRole(button)) { + if (!guard) + return; + + switch (buttonRole) { case QPlatformDialogHelper::AcceptRole: case QPlatformDialogHelper::YesRole: emit q->accepted(); diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp index 9c549365ff..38b473e5ae 100644 --- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp @@ -90,6 +90,7 @@ private slots: // void buttons(); void testDelete(); + void testSignalEmissionAfterDelete_QTBUG_45835(); void testRemove(); void testMultipleAdd(); void testStandardButtonMapping_data(); @@ -111,6 +112,7 @@ private: tst_QDialogButtonBox::tst_QDialogButtonBox() { + qRegisterMetaType(); } tst_QDialogButtonBox::~tst_QDialogButtonBox() @@ -414,6 +416,70 @@ void tst_QDialogButtonBox::testDelete() QCOMPARE(buttonBox.buttons().count(), 0); } +class ObjectDeleter : public QObject +{ + Q_OBJECT +public slots: + void deleteButton(QAbstractButton *button) + { + delete button; + } + + void deleteSender() + { + delete sender(); + } +}; + +void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835() +{ + { + QDialogButtonBox buttonBox; + QCOMPARE(buttonBox.buttons().count(), 0); + + QSignalSpy buttonClickedSpy(&buttonBox, &QDialogButtonBox::clicked); + QVERIFY(buttonClickedSpy.isValid()); + + QSignalSpy buttonBoxAcceptedSpy(&buttonBox, &QDialogButtonBox::accepted); + QVERIFY(buttonBoxAcceptedSpy.isValid()); + + QPushButton *button = buttonBox.addButton("Test", QDialogButtonBox::AcceptRole); + QCOMPARE(buttonBox.buttons().count(), 1); + + ObjectDeleter objectDeleter; + connect(&buttonBox, &QDialogButtonBox::clicked, &objectDeleter, &ObjectDeleter::deleteButton); + + button->click(); + + QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonClickedSpy.count(), 1); + QCOMPARE(buttonBoxAcceptedSpy.count(), 1); + } + + { + QPointer buttonBox(new QDialogButtonBox); + QCOMPARE(buttonBox->buttons().count(), 0); + + QSignalSpy buttonClickedSpy(buttonBox.data(), &QDialogButtonBox::clicked); + QVERIFY(buttonClickedSpy.isValid()); + + QSignalSpy buttonBoxAcceptedSpy(buttonBox.data(), &QDialogButtonBox::accepted); + QVERIFY(buttonBoxAcceptedSpy.isValid()); + + QPushButton *button = buttonBox->addButton("Test", QDialogButtonBox::AcceptRole); + QCOMPARE(buttonBox->buttons().count(), 1); + + ObjectDeleter objectDeleter; + connect(buttonBox.data(), &QDialogButtonBox::clicked, &objectDeleter, &ObjectDeleter::deleteSender); + + button->click(); + + QVERIFY(buttonBox.isNull()); + QCOMPARE(buttonClickedSpy.count(), 1); + QCOMPARE(buttonBoxAcceptedSpy.count(), 0); + } +} + void tst_QDialogButtonBox::testMultipleAdd() { // Add a button into the thing multiple times. -- cgit v1.2.3 From f1bfc4266bb0b4a3269d79f6ed34eaa8a1cadbca Mon Sep 17 00:00:00 2001 From: David Faure Date: Sun, 29 Mar 2015 22:09:56 +0200 Subject: Don't overwrite applicationName if already set. My commit 6c973dee2cb1686ea32657 broke the case where setApplicationName is called before the QCoreApplication constructor. Fixed and added autotest. Task-number: QTBUG-45283 Change-Id: If7bdb0d82be50b50a95a04027f5f9d7143c1a7ac Reviewed-by: Oswald Buddenhagen Reviewed-by: Shawn Rutledge Reviewed-by: Giuseppe D'Angelo --- src/corelib/kernel/qcoreapplication.cpp | 10 ++++++---- .../kernel/qcoreapplication/tst_qcoreapplication.cpp | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index fffecbfb55..b6f839d554 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -326,6 +326,7 @@ struct QCoreApplicationData { #ifndef QT_NO_LIBRARY app_libpaths = 0; #endif + applicationNameSet = false; } ~QCoreApplicationData() { #ifndef QT_NO_LIBRARY @@ -370,8 +371,8 @@ struct QCoreApplicationData { QString orgName, orgDomain; QString application; // application name, initially from argv[0], can then be modified. - QString applicationNameCompat; // for QDesktopServices. Only set explicitly. QString applicationVersion; + bool applicationNameSet; // true if setApplicationName was called #ifndef QT_NO_LIBRARY QStringList *app_libpaths; @@ -753,7 +754,8 @@ void QCoreApplication::init() QCoreApplication::self = this; // Store app name (so it's still available after QCoreApplication is destroyed) - coreappdata()->application = d_func()->appName(); + if (!coreappdata()->applicationNameSet) + coreappdata()->application = d_func()->appName(); QLoggingRegistry::instance()->init(); @@ -2350,13 +2352,13 @@ QString QCoreApplication::organizationDomain() */ void QCoreApplication::setApplicationName(const QString &application) { + coreappdata()->applicationNameSet = !application.isEmpty(); QString newAppName = application; if (newAppName.isEmpty() && QCoreApplication::self) newAppName = QCoreApplication::self->d_func()->appName(); if (coreappdata()->application == newAppName) return; coreappdata()->application = newAppName; - coreappdata()->applicationNameCompat = newAppName; #ifndef QT_NO_QOBJECT if (QCoreApplication::self) emit QCoreApplication::self->applicationNameChanged(); @@ -2374,7 +2376,7 @@ QString QCoreApplication::applicationName() // Exported for QDesktopServices (Qt4 behavior compatibility) Q_CORE_EXPORT QString qt_applicationName_noFallback() { - return coreappdata()->applicationNameCompat; + return coreappdata()->applicationNameSet ? coreappdata()->application : QString(); } /*! diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index ff4963a960..924db17c04 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -112,6 +112,22 @@ void tst_QCoreApplication::qAppName() // The application name should still be available after destruction; // global statics often rely on this. QCOMPARE(QCoreApplication::applicationName(), QString::fromLatin1(appName)); + + // Setting the appname before creating the application should work (QTBUG-45283) + const QString wantedAppName("my app name"); + { + int argc = 1; + char *argv[] = { const_cast(appName) }; + QCoreApplication::setApplicationName(wantedAppName); + TestApplication app(argc, argv); + QCOMPARE(::qAppName(), QString::fromLatin1(appName)); + QCOMPARE(QCoreApplication::applicationName(), wantedAppName); + } + QCOMPARE(QCoreApplication::applicationName(), wantedAppName); + + // Restore to initial value + QCoreApplication::setApplicationName(QString()); + QCOMPARE(QCoreApplication::applicationName(), QString()); } void tst_QCoreApplication::argc() -- cgit v1.2.3 From cca5cce205df1a7faefb3828af960326ba1ab846 Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 6 May 2015 17:00:59 +0200 Subject: Use ItemIsUserTristate instead of ItemIsTristate in table & list tests. ItemIsTristate only makes sense in tree widgets, where it triggers the auto-tristate behavior between parents and children. Change-Id: Idfa8bb5d0b9c63fe450115fb58d088929e11c7ff Reviewed-by: Jarek Kobus --- tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp | 8 ++++---- tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp index 6786ae9aa2..dcbdbe824a 100644 --- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp @@ -605,21 +605,21 @@ void tst_QListWidget::insertItems() void tst_QListWidget::itemAssignment() { QListWidgetItem itemInWidget("inWidget", testWidget); - itemInWidget.setFlags(itemInWidget.flags() | Qt::ItemIsTristate); + itemInWidget.setFlags(itemInWidget.flags() | Qt::ItemIsUserTristate); QListWidgetItem itemOutsideWidget("outsideWidget"); QVERIFY(itemInWidget.listWidget()); QCOMPARE(itemInWidget.text(), QString("inWidget")); - QVERIFY(itemInWidget.flags() & Qt::ItemIsTristate); + QVERIFY(itemInWidget.flags() & Qt::ItemIsUserTristate); QVERIFY(!itemOutsideWidget.listWidget()); QCOMPARE(itemOutsideWidget.text(), QString("outsideWidget")); - QVERIFY(!(itemOutsideWidget.flags() & Qt::ItemIsTristate)); + QVERIFY(!(itemOutsideWidget.flags() & Qt::ItemIsUserTristate)); itemOutsideWidget = itemInWidget; QVERIFY(!itemOutsideWidget.listWidget()); QCOMPARE(itemOutsideWidget.text(), QString("inWidget")); - QVERIFY(itemOutsideWidget.flags() & Qt::ItemIsTristate); + QVERIFY(itemOutsideWidget.flags() & Qt::ItemIsUserTristate); } void tst_QListWidget::item_data() diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp index a4c6e13979..36bc23910c 100644 --- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp @@ -281,21 +281,21 @@ void tst_QTableWidget::itemAssignment() { QTableWidgetItem itemInWidget("inWidget"); testWidget->setItem(0, 0, &itemInWidget); - itemInWidget.setFlags(itemInWidget.flags() | Qt::ItemIsTristate); + itemInWidget.setFlags(itemInWidget.flags() | Qt::ItemIsUserTristate); QTableWidgetItem itemOutsideWidget("outsideWidget"); QVERIFY(itemInWidget.tableWidget()); QCOMPARE(itemInWidget.text(), QString("inWidget")); - QVERIFY(itemInWidget.flags() & Qt::ItemIsTristate); + QVERIFY(itemInWidget.flags() & Qt::ItemIsUserTristate); QVERIFY(!itemOutsideWidget.tableWidget()); QCOMPARE(itemOutsideWidget.text(), QString("outsideWidget")); - QVERIFY(!(itemOutsideWidget.flags() & Qt::ItemIsTristate)); + QVERIFY(!(itemOutsideWidget.flags() & Qt::ItemIsUserTristate)); itemOutsideWidget = itemInWidget; QVERIFY(!itemOutsideWidget.tableWidget()); QCOMPARE(itemOutsideWidget.text(), QString("inWidget")); - QVERIFY(itemOutsideWidget.flags() & Qt::ItemIsTristate); + QVERIFY(itemOutsideWidget.flags() & Qt::ItemIsUserTristate); } void tst_QTableWidget::item_data() -- cgit v1.2.3 From 52c122e616f389bdeeffd3eedcd17c49e7e437c2 Mon Sep 17 00:00:00 2001 From: Christoph Schleifenbaum Date: Wed, 22 Apr 2015 13:06:32 +0200 Subject: Improve QListView scroll bar calculation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When both scroll bar's policies are set to ScrollBarAsNeeded, make sure the scroll bars are shown if needed and not show if not. Even the corner case, where one scroll bar's visibility depends on the other, is handled properly. Task-number: QTBUG-45470 Change-Id: I11d6ccf7c0b51644a5ce2d5c3fc59e2e4812755d Reviewed-by: Giuseppe D'Angelo Reviewed-by: Thorbjørn Lund Martsum Reviewed-by: Thorbjørn Lindeijer --- src/widgets/itemviews/qlistview.cpp | 26 +++++++-- .../widgets/itemviews/qlistview/tst_qlistview.cpp | 62 ++++++++++++++++++++++ 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index b7a4ec3925..f3fd3e75a1 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1846,8 +1846,17 @@ void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step) const bool bothScrollBarsAuto = qq->verticalScrollBarPolicy() == Qt::ScrollBarAsNeeded && qq->horizontalScrollBarPolicy() == Qt::ScrollBarAsNeeded; - if (bothScrollBarsAuto && contentsSize.width() - qq->verticalScrollBar()->width() <= viewport()->width() - && contentsSize.height() - qq->horizontalScrollBar()->height() <= viewport()->height()) { + const QSize viewportSize(viewport()->width() + (qq->verticalScrollBar()->maximum() > 0 ? qq->verticalScrollBar()->width() : 0), + viewport()->height() + (qq->horizontalScrollBar()->maximum() > 0 ? qq->horizontalScrollBar()->height() : 0)); + + bool verticalWantsToShow = contentsSize.height() > viewportSize.height(); + bool horizontalWantsToShow; + if (verticalWantsToShow) + horizontalWantsToShow = contentsSize.width() > viewportSize.width() - qq->verticalScrollBar()->width(); + else + horizontalWantsToShow = contentsSize.width() > viewportSize.width(); + + if (bothScrollBarsAuto && !horizontalWantsToShow) { // break the infinite loop described above by setting the range to 0, 0. // QAbstractScrollArea will then hide the scroll bar for us horizontalScrollBar()->setRange(0, 0); @@ -1868,8 +1877,17 @@ void QCommonListViewBase::updateVerticalScrollBar(const QSize &step) const bool bothScrollBarsAuto = qq->verticalScrollBarPolicy() == Qt::ScrollBarAsNeeded && qq->horizontalScrollBarPolicy() == Qt::ScrollBarAsNeeded; - if (bothScrollBarsAuto && contentsSize.width() - qq->verticalScrollBar()->width() <= viewport()->width() - && contentsSize.height() - qq->horizontalScrollBar()->height() <= viewport()->height()) { + const QSize viewportSize(viewport()->width() + (qq->verticalScrollBar()->maximum() > 0 ? qq->verticalScrollBar()->width() : 0), + viewport()->height() + (qq->horizontalScrollBar()->maximum() > 0 ? qq->horizontalScrollBar()->height() : 0)); + + bool horizontalWantsToShow = contentsSize.width() > viewportSize.width(); + bool verticalWantsToShow; + if (horizontalWantsToShow) + verticalWantsToShow = contentsSize.height() > viewportSize.height() - qq->horizontalScrollBar()->height(); + else + verticalWantsToShow = contentsSize.height() > viewportSize.height(); + + if (bothScrollBarsAuto && !verticalWantsToShow) { // break the infinite loop described above by setting the range to 0, 0. // QAbstractScrollArea will then hide the scroll bar for us verticalScrollBar()->setRange(0, 0); diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index cea08435c9..32ca5ea7b7 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #if defined(Q_OS_WIN) || defined(Q_OS_WINCE) # include @@ -2348,11 +2349,34 @@ void tst_QListView::testViewOptions() QCOMPARE(options.decorationPosition, QStyleOptionViewItem::Top); } +// make sure we have no transient scroll bars +class TempStyleSetter +{ +public: + TempStyleSetter() + : m_oldStyle(qApp->style()) + { + m_oldStyle->setParent(0); + QListView tempView; + if (QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, tempView.horizontalScrollBar())) + QApplication::setStyle(QStyleFactory::create("Fusion")); + } + + ~TempStyleSetter() + { + QApplication::setStyle(m_oldStyle); + } +private: + QStyle* m_oldStyle; +}; + void tst_QListView::taskQTBUG_39902_mutualScrollBars() { QWidget window; window.resize(400, 300); QListView *view = new QListView(&window); + // make sure we have no transient scroll bars + TempStyleSetter styleSetter; QStandardItemModel model(200, 1); const QSize itemSize(100, 20); for (int i = 0; i < model.rowCount(); ++i) @@ -2370,6 +2394,44 @@ void tst_QListView::taskQTBUG_39902_mutualScrollBars() view->resize(itemSize.width() + view->frameWidth() * 2, model.rowCount() * itemSize.height() + view->frameWidth() * 2); // this will end up in a stack overflow, if QTBUG-39902 is not fixed QTest::qWait(100); + + // these tests do not apply with transient scroll bars enabled + QVERIFY (!view->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, view->horizontalScrollBar())); + + // make it double as large, no scroll bars should be visible + view->resize((itemSize.width() + view->frameWidth() * 2) * 2, (model.rowCount() * itemSize.height() + view->frameWidth() * 2) * 2); + QTRY_VERIFY(!view->horizontalScrollBar()->isVisible()); + QTRY_VERIFY(!view->verticalScrollBar()->isVisible()); + + // make it half the size, both scroll bars should be visible + view->resize((itemSize.width() + view->frameWidth() * 2) / 2, (model.rowCount() * itemSize.height() + view->frameWidth() * 2) / 2); + QTRY_VERIFY(view->horizontalScrollBar()->isVisible()); + QTRY_VERIFY(view->verticalScrollBar()->isVisible()); + + // make it double as large, no scroll bars should be visible + view->resize((itemSize.width() + view->frameWidth() * 2) * 2, (model.rowCount() * itemSize.height() + view->frameWidth() * 2) * 2); + QTRY_VERIFY(!view->horizontalScrollBar()->isVisible()); + QTRY_VERIFY(!view->verticalScrollBar()->isVisible()); + + // now, coming from the double size, resize it to the exactly matching size, still no scroll bars should be visible again + view->resize(itemSize.width() + view->frameWidth() * 2, model.rowCount() * itemSize.height() + view->frameWidth() * 2); + QTRY_VERIFY(!view->horizontalScrollBar()->isVisible()); + QTRY_VERIFY(!view->verticalScrollBar()->isVisible()); + + // now remove just one single pixel in height -> both scroll bars will show up since they depend on each other + view->resize(itemSize.width() + view->frameWidth() * 2, model.rowCount() * itemSize.height() + view->frameWidth() * 2 - 1); + QTRY_VERIFY(view->horizontalScrollBar()->isVisible()); + QTRY_VERIFY(view->verticalScrollBar()->isVisible()); + + // now remove just one single pixel in with -> both scroll bars will show up since they depend on each other + view->resize(itemSize.width() + view->frameWidth() * 2 - 1, model.rowCount() * itemSize.height() + view->frameWidth() * 2); + QTRY_VERIFY(view->horizontalScrollBar()->isVisible()); + QTRY_VERIFY(view->verticalScrollBar()->isVisible()); + + // finally, coming from a size being to small, resize back to the exactly matching size -> both scroll bars should disappear again + view->resize(itemSize.width() + view->frameWidth() * 2, model.rowCount() * itemSize.height() + view->frameWidth() * 2); + QTRY_VERIFY(!view->horizontalScrollBar()->isVisible()); + QTRY_VERIFY(!view->verticalScrollBar()->isVisible()); } QTEST_MAIN(tst_QListView) -- cgit v1.2.3 From 6eaee855c7e2da8ed9385f0c68c8823b103d5195 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 27 Apr 2015 13:41:40 +0200 Subject: ios: change file engine caching logic for loading assets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current caching strategy had a flaw in that it tried to lazy-lock the mutex only if g_currentAssetData was non-zero. For this to be somewhat reliable, g_currentAssetData would have to be volatile. But that would still not be enough since thread-unaware code optimizations might also happen on the CPU level. Instead of complicating the current logic more, change it to only do caching per thread. Since QThreadStorage will take ownership of its data, we can't let it store a pointer to QIOSAssetData directly since we need to control the life time of QIOSAssetData using deleteLater. Change-Id: I2c3ffb3257ec2bdec8be71a3d63f666ab33b5277 Reviewed-by: Tor Arne Vestbø --- .../platforms/ios/qiosfileengineassetslibrary.mm | 27 ++++++++-------------- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index c7809c75e0..44a7901160 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -43,6 +43,7 @@ #include static QThreadStorage g_iteratorCurrentUrl; +static QThreadStorage > g_assetDataCache; static const int kBufferSize = 10; static ALAsset *kNoAsset = 0; @@ -187,16 +188,14 @@ public: { ensureAuthorizationDialogNotBlocked(); - if (g_currentAssetData) { + if (QIOSAssetData *assetData = g_assetDataCache.localData()) { // It's a common pattern that QFiles pointing to the same path are created and destroyed // several times during a single event loop cycle. To avoid loading the same asset // over and over, we check if the last loaded asset has not been destroyed yet, and try to - // reuse its data. Since QFile is (mostly) reentrant, we need to protect m_currentAssetData - // from being modified by several threads at the same time. - QMutexLocker lock(&g_mutex); - if (g_currentAssetData && g_currentAssetData->m_assetUrl == assetUrl) { - m_assetLibrary = [g_currentAssetData->m_assetLibrary retain]; - m_asset = [g_currentAssetData->m_asset retain]; + // reuse its data. + if (assetData->m_assetUrl == assetUrl) { + m_assetLibrary = [assetData->m_assetLibrary retain]; + m_asset = [assetData->m_asset retain]; return; } } @@ -243,17 +242,15 @@ public: dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); dispatch_release(semaphore); - QMutexLocker lock(&g_mutex); - g_currentAssetData = this; + g_assetDataCache.setLocalData(this); } ~QIOSAssetData() { - QMutexLocker lock(&g_mutex); [m_assetLibrary release]; [m_asset release]; - if (this == g_currentAssetData) - g_currentAssetData = 0; + if (g_assetDataCache.localData() == this) + g_assetDataCache.setLocalData(0); } ALAsset *m_asset; @@ -261,14 +258,8 @@ public: private: QString m_assetUrl; ALAssetsLibrary *m_assetLibrary; - - static QBasicMutex g_mutex; - static QPointer g_currentAssetData; }; -QBasicMutex QIOSAssetData::g_mutex; -QPointer QIOSAssetData::g_currentAssetData = 0; - // ------------------------------------------------------------------------- #ifndef QT_NO_FILESYSTEMITERATOR -- cgit v1.2.3 From e5eb36feb27500b43f694df3ac1619d36fe8e7ec Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 7 May 2015 13:25:57 +0200 Subject: qstandardpaths_ios: allow empty strings to be returned for undefined locations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the documentation for QStandardPaths::standardLocations() and QStandardPaths::writableLocation, they should return empty lists / strings if the location cannot be determined. So remove the section in qstandardpath_ios.mm that always sets a default path for undefined locations. Change-Id: I0c7fc0a1a0bbe2a5e0fb4e79e0f96f0280a647e2 Reviewed-by: Tor Arne Vestbø --- src/corelib/io/qstandardpaths_ios.mm | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm index 6e53b75df4..eb85e2fd23 100644 --- a/src/corelib/io/qstandardpaths_ios.mm +++ b/src/corelib/io/qstandardpaths_ios.mm @@ -103,18 +103,9 @@ QString QStandardPaths::writableLocation(StandardLocation type) // NSDownloadsDirectory points to a non-existing write-protected path. location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/Download"); break; - default: - break; - } - - switch (type) { case RuntimeLocation: break; default: - // All other types must return something, so use the document directory - // as a reasonable fall-back (which will always exist). - if (location.isEmpty()) - location = pathForDirectory(NSDocumentDirectory); break; } -- cgit v1.2.3 From dad54e794f8e5ebf19883399a2481098b2043639 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 13 Apr 2015 15:50:45 +0200 Subject: MSVC: Silence compiler warning about INFINITY Contrary to the comment, MSVC does support INFINITY, but always prints a warning when it's used: qpainterpath.cpp(3066) : warning C4756: overflow in constant arithmetic Avoid this by using numeric_limits::infinity. Change-Id: Ie925b036b807378da5298a275fa108347c24519e Reviewed-by: Friedemann Kleint --- src/gui/painting/qpainterpath.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 88cf05c646..e2f267d7ee 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -3057,20 +3057,19 @@ qreal QPainterPath::slopeAtPercent(qreal t) const //tangent line qreal slope = 0; -#define SIGN(x) ((x < 0)?-1:1) if (m1) slope = m2/m1; else { - //windows doesn't define INFINITY :( -#ifdef INFINITY - slope = INFINITY*SIGN(m2); -#else - if (sizeof(qreal) == sizeof(double)) { - return 1.79769313486231570e+308; + if (std::numeric_limits::has_infinity) { + slope = (m2 < 0) ? -std::numeric_limits::infinity() + : std::numeric_limits::infinity(); } else { - return ((qreal)3.40282346638528860e+38); + if (sizeof(qreal) == sizeof(double)) { + return 1.79769313486231570e+308; + } else { + return ((qreal)3.40282346638528860e+38); + } } -#endif } return slope; -- cgit v1.2.3 From a1ada382ff00a8e1599aba22ee06ff53ce478666 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 30 Apr 2015 15:09:59 +0200 Subject: Handle parsing of GL_VERSION as reported by Nexus 6 The Nexus 6 device reports a GL_VERSION which is strictly not conformant to what is expected from GL_VERSION, so a check is added for this case so that it correctly detects the right OpenGL ES version. Change-Id: I00297dd7c1e505dd7f9ab8a7fa480f514162b488 Reviewed-by: Laszlo Agocs --- src/gui/kernel/qplatformopenglcontext.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/kernel/qplatformopenglcontext.cpp b/src/gui/kernel/qplatformopenglcontext.cpp index 527bfdd983..364c1a5c0e 100644 --- a/src/gui/kernel/qplatformopenglcontext.cpp +++ b/src/gui/kernel/qplatformopenglcontext.cpp @@ -121,6 +121,10 @@ bool QPlatformOpenGLContext::parseOpenGLVersion(const QByteArray &versionString, if (versionParts.size() >= 2) { major = versionParts.at(0).toInt(&majorOk); minor = versionParts.at(1).toInt(&minorOk); + // Nexus 6 has "OpenGL ES 3.0V@95.0 (GIT@I86da836d38)" + if (!minorOk) + if (int idx = versionParts.at(1).indexOf('V')) + minor = versionParts.at(1).left(idx).toInt(&minorOk); } else { qWarning("Unrecognized OpenGL ES version"); } -- cgit v1.2.3 From ada8f1985d1f04440fca97894192748d98e47441 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 8 May 2015 16:17:00 +0300 Subject: Check the maximum size of a QByteArray more precisely Also document that the QByteArrray::MaxSize takes a trailing '\0' into account. Change-Id: I89e9a0d1a80a49b33efbac16ff7aa2a98f0e5670 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/io/qiodevice.cpp | 4 ++-- src/corelib/tools/qbytearray.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index e73a200fb4..d68f33287d 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -989,7 +989,7 @@ QByteArray QIODevice::readAll() // Size is unknown, read incrementally. qint64 readResult; do { - if (quint64(readBytes) + QIODEVICE_BUFFERSIZE > QByteArray::MaxSize) { + if (quint64(readBytes) + QIODEVICE_BUFFERSIZE >= QByteArray::MaxSize) { // If resize would fail, don't read more, return what we have. break; } @@ -1001,7 +1001,7 @@ QByteArray QIODevice::readAll() } else { // Read it all in one go. // If resize fails, don't read anything. - if (quint64(readBytes + theSize - d->pos) > QByteArray::MaxSize) + if (quint64(readBytes + theSize - d->pos) >= QByteArray::MaxSize) return QByteArray(); result.resize(int(readBytes + theSize - d->pos)); readBytes += read(result.data() + readBytes, result.size() - readBytes); diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index da5d00311a..36c1f42995 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -124,7 +124,7 @@ int qFindByteArray( int qAllocMore(int alloc, int extra) Q_DECL_NOTHROW { Q_ASSERT(alloc >= 0 && extra >= 0); - Q_ASSERT_X(uint(alloc) < QByteArray::MaxSize, "qAllocMore", "Requested size is too large!"); + Q_ASSERT_X(uint(alloc) <= QByteArray::MaxSize, "qAllocMore", "Requested size is too large!"); unsigned nalloc = qNextPowerOfTwo(alloc + extra); @@ -842,8 +842,9 @@ static inline char qToLower(char c) \internal \since 5.4 - The maximum size of a QByteArray, in bytes. Also applies to a the maximum - storage size of QString and QVector, though not the number of elements. + The maximum size of a QByteArray (including a '\0' terminator), in bytes. + Also applies to the maximum storage size of QString and QVector, though + not the number of elements. */ /*! -- cgit v1.2.3 From 5891f90846738e732b88e0eebfc4fa1eeae7e2c0 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 8 May 2015 10:03:23 +0200 Subject: qdoc: Update documentation of \qmlabstract The \qmlabstract command was missing from the qdoc user manual, and qdoc was still allowing the \abstract command to be used for marking up the abstract of a scientific paper. The \abstract command is now made a synonym of \qmlabstract, and they are both added to the qdoc user manual. Change-Id: I003ac50b8dabbf037f18d9ea3e6d88a12d69bf5f Task-number: QTBUG-46003 Reviewed-by: Venugopal Shivashankar Reviewed-by: Martin Smith --- src/tools/qdoc/atom.cpp | 4 --- src/tools/qdoc/atom.h | 2 -- src/tools/qdoc/cppcodeparser.cpp | 5 ++-- src/tools/qdoc/cppcodeparser.h | 1 + src/tools/qdoc/doc.cpp | 23 -------------- src/tools/qdoc/doc/qdoc-manual-cmdindex.qdoc | 1 + src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc | 40 +++++++++++++++++++------ src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc | 14 --------- src/tools/qdoc/htmlgenerator.cpp | 8 ----- src/tools/qdoc/qmlcodeparser.cpp | 2 ++ src/tools/qdoc/qmlvisitor.cpp | 3 +- 11 files changed, 40 insertions(+), 63 deletions(-) diff --git a/src/tools/qdoc/atom.cpp b/src/tools/qdoc/atom.cpp index ebbe685985..f50f401c5b 100644 --- a/src/tools/qdoc/atom.cpp +++ b/src/tools/qdoc/atom.cpp @@ -66,8 +66,6 @@ QT_BEGIN_NAMESPACE /*! \enum Atom::AtomType - \value AbstractLeft - \value AbstractRight \value AnnotatedList \value AutoLink \value BaseName @@ -149,8 +147,6 @@ static const struct { const char *english; int no; } atms[] = { - { "AbstractLeft", Atom::AbstractLeft }, - { "AbstractRight", Atom::AbstractRight }, { "AnnotatedList", Atom::AnnotatedList }, { "AutoLink", Atom::AutoLink }, { "BaseName", Atom::BaseName }, diff --git a/src/tools/qdoc/atom.h b/src/tools/qdoc/atom.h index dae106a742..86b8ba7b3c 100644 --- a/src/tools/qdoc/atom.h +++ b/src/tools/qdoc/atom.h @@ -47,8 +47,6 @@ class Atom { public: enum AtomType { - AbstractLeft, - AbstractRight, AnnotatedList, AutoLink, BaseName, diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index 552fb6a4ba..90f91c5f06 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -870,7 +870,8 @@ const QSet& CppCodeParser::otherMetaCommands() << COMMAND_QMLINSTANTIATES << COMMAND_QMLDEFAULT << COMMAND_QMLREADONLY - << COMMAND_QMLABSTRACT; + << COMMAND_QMLABSTRACT + << COMMAND_ABSTRACT; } return otherMetaCommands_; } @@ -1014,7 +1015,7 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, } } } - else if (command == COMMAND_QMLABSTRACT) { + else if ((command == COMMAND_QMLABSTRACT) || (command == COMMAND_ABSTRACT)) { if (node->isQmlType() || node->isJsType()) node->setAbstract(true); } diff --git a/src/tools/qdoc/cppcodeparser.h b/src/tools/qdoc/cppcodeparser.h index 4acd370541..31964699a2 100644 --- a/src/tools/qdoc/cppcodeparser.h +++ b/src/tools/qdoc/cppcodeparser.h @@ -177,6 +177,7 @@ protected: QString exampleImageFilter; }; +#define COMMAND_ABSTRACT Doc::alias("abstract") #define COMMAND_CLASS Doc::alias("class") #define COMMAND_CONTENTSPAGE Doc::alias("contentspage") #define COMMAND_DITAMAP Doc::alias("ditamap") diff --git a/src/tools/qdoc/doc.cpp b/src/tools/qdoc/doc.cpp index bfe9cbe935..f322bd9360 100644 --- a/src/tools/qdoc/doc.cpp +++ b/src/tools/qdoc/doc.cpp @@ -69,7 +69,6 @@ struct Macro enum { CMD_A, - CMD_ABSTRACT, CMD_ANNOTATEDLIST, CMD_B, CMD_BADCODE, @@ -85,7 +84,6 @@ enum { CMD_DOTS, CMD_E, CMD_ELSE, - CMD_ENDABSTRACT, CMD_ENDCHAPTER, CMD_ENDCODE, CMD_ENDDIV, @@ -187,7 +185,6 @@ static struct { QString *alias; } cmds[] = { { "a", CMD_A, 0 }, - { "abstract", CMD_ABSTRACT, 0 }, { "annotatedlist", CMD_ANNOTATEDLIST, 0 }, { "b", CMD_B, 0 }, { "badcode", CMD_BADCODE, 0 }, @@ -203,7 +200,6 @@ static struct { { "dots", CMD_DOTS, 0 }, { "e", CMD_E, 0 }, { "else", CMD_ELSE, 0 }, - { "endabstract", CMD_ENDABSTRACT, 0 }, { "endchapter", CMD_ENDCHAPTER, 0 }, { "endcode", CMD_ENDCODE, 0 }, { "enddiv", CMD_ENDDIV, 0 }, @@ -631,12 +627,6 @@ void DocParser::parse(const QString& source, append(Atom::FormattingRight,ATOM_FORMATTING_PARAMETER); priv->params.insert(p1); break; - case CMD_ABSTRACT: - if (openCommand(cmd)) { - leavePara(); - append(Atom::AbstractLeft); - } - break; case CMD_BADCODE: leavePara(); append(Atom::CodeBad,getCode(CMD_BADCODE, marker)); @@ -748,12 +738,6 @@ void DocParser::parse(const QString& source, location().warning(tr("Unexpected '\\%1'").arg(cmdName(CMD_ELSE))); } break; - case CMD_ENDABSTRACT: - if (closeCommand(cmd)) { - leavePara(); - append(Atom::AbstractRight); - } - break; case CMD_ENDCHAPTER: endSection(Doc::Chapter, cmd); break; @@ -1830,11 +1814,6 @@ bool DocParser::openCommand(int cmd) if (outer == CMD_LIST) { ok = (cmd == CMD_FOOTNOTE || cmd == CMD_LIST); } - else if (outer == CMD_ABSTRACT) { - ok = (cmd == CMD_LIST || - cmd == CMD_QUOTATION || - cmd == CMD_TABLE); - } else if (outer == CMD_SIDEBAR) { ok = (cmd == CMD_LIST || cmd == CMD_QUOTATION || @@ -2674,8 +2653,6 @@ void DocParser::skipToNextPreprocessorCommand() int DocParser::endCmdFor(int cmd) { switch (cmd) { - case CMD_ABSTRACT: - return CMD_ENDABSTRACT; case CMD_BADCODE: return CMD_ENDCODE; case CMD_CHAPTER: diff --git a/src/tools/qdoc/doc/qdoc-manual-cmdindex.qdoc b/src/tools/qdoc/doc/qdoc-manual-cmdindex.qdoc index 87416fcd14..63fcee6469 100644 --- a/src/tools/qdoc/doc/qdoc-manual-cmdindex.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-cmdindex.qdoc @@ -106,6 +106,7 @@ \li \l {printto-command} {\\printto} \li \l {printuntil-command} {\\printuntil} \li \l {property-command} {\\property} + \li \l {qmlabstract-command} {\\qmlabstract} \li \l {qmlattachedproperty-command} {\\qmlattachedproperty} \li \l {qmlattachedsignal-command} {\\qmlattachedsignal} \li \l {qmlbasictype-command} {\\qmlbasictype} diff --git a/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc index 700b1a09c7..3bf63214ad 100644 --- a/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-contextcmds.qdoc @@ -46,6 +46,7 @@ below the \l {Topic Commands} {topic} command. \list + \li \l {abstract-command} {\\abstract} \li \l {compat-command}{\\compat}, \li \l {contentspage-command}{\\contentspage}, \li \l {indexpage-command}{\\indexpage}, @@ -59,6 +60,7 @@ \li \l {overload-command}{\\overload}, \li \l {preliminary-command}{\\preliminary}, \li \l {previouspage-command}{\\previouspage}, + \li \l {qmlabstract-command} {\\qmlabstract} \li \l {reentrant-command}{\\reentrant}, \li \l {reimp-command}{\\reimp}, \li \l {relates-command}{\\relates}, @@ -199,21 +201,41 @@ index page of the collection. */ - /*! \page 16-qdoc-commands-status.html \previouspage Document Navigation \contentspage QDoc Manual \nextpage Thread Support - \title Reporting Status - - These commands are for indicating that a documented element is - still under development, is becoming obsolete, is provided for - compatibility reasons, or is simply not to be included in the - public interface. The \l {since-command}{\\since} command is for - including information about the version when a function or class - first appeared. + \title Status + + These commands are for indicating that a documented element has + some special status. The element could be marked as about to be + made obsolete, or that it is provided for compatibility with an + earlier version, or is simply not to be included in the public + interface. The \l {since-command}{\\since} command is for + specifying the version number in which a function or class first + appeared. The \l {qmlabstract-command} {\\qmlabstract} command is + for marking a QML type as an abstract base class. + + \target abstract-command + \target qmlabstract-command + \section1 \\abstract and \\qmlabstract + + \\abstract is a synonym for the \\qmlabstract command. Add this + command to the \l {qmltype-command} {\\qmltype} comment for a QML + type when that type is meant to be used \e {only} as an abstract + base type. When a QML type is abstract, it means that the QML type + that can't be instantiated. Instead, the properties in its public + API are included in the public properties list on the reference + page for each QML type that inherits the abstract QML type. The + properties are documented as if they are properties of the + inheriting QML type. + + Normally, when a QML type is marked with \e{\\qmlabstract}, it is + also marked with \e{\\internal} so that its reference page is not + generated. It the abstract QML type is not marked internal, it + will have a reference page in the documentation. \target compat-command \section1 \\compat diff --git a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc index d9b5a6f659..9458d96045 100644 --- a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc @@ -38,7 +38,6 @@ \list \li \l {a-command} {\\a} - \li \l {abstract-command} {\\abstract} \li \l {annotatedlist-command} {\\annotatedlist} \li \l {b-command} {\\b} \span {class="newStuff"} \li \l {b-command} {\\bold} {(deprecated, use \\b)} @@ -2886,19 +2885,6 @@ parts with a special rendering, conceptual meaning or function. - \target abstract-command - \section1 \\abstract - - The \\abstract and \\endabstract commands delimit a - document's abstract section. - - The abstract section is rendered as an indented italicized - paragraph. - - \warning The \b{\\abstract} and \b{\\endabstract} commands - have not been implemented. The abstract section is rendered as a - regular HTML paragraph. - \target quotation-command \section1 \\quotation diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 3fb6acf72b..18e538ef7b 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -474,14 +474,6 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark static bool in_para = false; switch (atom->type()) { - case Atom::AbstractLeft: - if (relative) - relative->doc().location().warning(tr("\abstract is not implemented.")); - else - Location::information(tr("\abstract is not implemented.")); - break; - case Atom::AbstractRight: - break; case Atom::AutoLink: case Atom::NavAutoLink: if (!inLink_ && !inContents_ && !inSectionHeading_) { diff --git a/src/tools/qdoc/qmlcodeparser.cpp b/src/tools/qdoc/qmlcodeparser.cpp index 4f5720a94d..f485255b8e 100644 --- a/src/tools/qdoc/qmlcodeparser.cpp +++ b/src/tools/qdoc/qmlcodeparser.cpp @@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE #define COMMAND_SINCE Doc::alias("since") #define COMMAND_WRAPPER Doc::alias("wrapper") +#define COMMAND_ABSTRACT Doc::alias("abstract") #define COMMAND_QMLABSTRACT Doc::alias("qmlabstract") #define COMMAND_QMLCLASS Doc::alias("qmlclass") #define COMMAND_QMLTYPE Doc::alias("qmltype") @@ -251,6 +252,7 @@ const QSet& QmlCodeParser::otherMetaCommands() << COMMAND_OBSOLETE << COMMAND_PRELIMINARY << COMMAND_SINCE + << COMMAND_ABSTRACT << COMMAND_QMLABSTRACT << COMMAND_INQMLMODULE << COMMAND_INJSMODULE diff --git a/src/tools/qdoc/qmlvisitor.cpp b/src/tools/qdoc/qmlvisitor.cpp index 4803a1d63a..360af5adf6 100644 --- a/src/tools/qdoc/qmlvisitor.cpp +++ b/src/tools/qdoc/qmlvisitor.cpp @@ -55,6 +55,7 @@ QT_BEGIN_NAMESPACE #define COMMAND_SINCE Doc::alias(QLatin1String("since")) #define COMMAND_WRAPPER Doc::alias(QLatin1String("wrapper")) +#define COMMAND_ABSTRACT Doc::alias(QLatin1String("abstract")) #define COMMAND_QMLABSTRACT Doc::alias(QLatin1String("qmlabstract")) #define COMMAND_QMLCLASS Doc::alias(QLatin1String("qmlclass")) #define COMMAND_QMLTYPE Doc::alias(QLatin1String("qmltype")) @@ -497,7 +498,7 @@ void QmlDocVisitor::applyMetacommands(QQmlJS::AST::SourceLocation, while (i != metacommands.end()) { QString command = *i; ArgList args = doc.metaCommandArgs(command); - if (command == COMMAND_QMLABSTRACT) { + if ((command == COMMAND_QMLABSTRACT) || (command == COMMAND_ABSTRACT)) { if (node->isQmlType() || node->isJsType()) { node->setAbstract(true); } -- cgit v1.2.3 From 1f03520a20eb8d2a7236075c71b354b21a32b2a2 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Wed, 22 Apr 2015 13:39:39 +0300 Subject: Add a way to filter window system events This change introduces the class QWindowSystemEventHandler which can be used to hook into QWindowSystemInterfacePrivate to filter and dispatch window system events. One use case is to intercept key events from the underlying system in QtCompositor and feed them into the xkbcommon state, and to modify the events based on the resulting state. Change-Id: I829eb7d960420135990fb0f6db54c14eea3e8e48 Reviewed-by: Laszlo Agocs Reviewed-by: Gunnar Sletta --- src/gui/kernel/qwindowsysteminterface.cpp | 34 +++++++++++++++++++++++++++++-- src/gui/kernel/qwindowsysteminterface_p.h | 13 ++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 8fa9a177ac..629bd02cd2 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -48,6 +48,7 @@ QElapsedTimer QWindowSystemInterfacePrivate::eventTime; bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false; QWaitCondition QWindowSystemInterfacePrivate::eventsFlushed; QMutex QWindowSystemInterfacePrivate::flushEventMutex; +QWindowSystemEventHandler *QWindowSystemInterfacePrivate::eventHandler; //------------------------------------------------------------ // @@ -605,14 +606,32 @@ bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFla QWindowSystemInterfacePrivate::getWindowSystemEvent(); if (!event) break; - nevents++; - QGuiApplicationPrivate::processWindowSystemEvent(event); + + if (QWindowSystemInterfacePrivate::eventHandler) { + if (QWindowSystemInterfacePrivate::eventHandler->sendEvent(event)) + nevents++; + } else { + nevents++; + QGuiApplicationPrivate::processWindowSystemEvent(event); + } delete event; } return (nevents > 0); } +void QWindowSystemInterfacePrivate::installWindowSystemEventHandler(QWindowSystemEventHandler *handler) +{ + if (!eventHandler) + eventHandler = handler; +} + +void QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(QWindowSystemEventHandler *handler) +{ + if (eventHandler == handler) + eventHandler = 0; +} + void QWindowSystemInterface::setSynchronousWindowSystemEvents(bool enable) { QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = enable; @@ -836,4 +855,15 @@ Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device, QWindowSystemInterface::handleTouchEvent(w, device, touchPointList(points), mods); } +QWindowSystemEventHandler::~QWindowSystemEventHandler() +{ + QWindowSystemInterfacePrivate::removeWindowSystemEventhandler(this); +} + +bool QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) +{ + QGuiApplicationPrivate::processWindowSystemEvent(e); + return true; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 8841ba95c8..7160971305 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -54,6 +54,8 @@ QT_BEGIN_NAMESPACE +class QWindowSystemEventHandler; + class Q_GUI_EXPORT QWindowSystemInterfacePrivate { public: enum EventType { @@ -487,6 +489,17 @@ public: static QMutex flushEventMutex; static QList convertTouchPoints(const QList &points, QEvent::Type *type); + + static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler); + static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler); + static QWindowSystemEventHandler *eventHandler; +}; + +class Q_GUI_EXPORT QWindowSystemEventHandler +{ +public: + virtual ~QWindowSystemEventHandler(); + virtual bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *event); }; QT_END_NAMESPACE -- cgit v1.2.3 From 62f24f04bf2b3a254faccc35fc7f673ef76a9345 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 6 May 2015 21:53:55 +0200 Subject: xcb: Skip EGL integration with -no-opengl When EGL is autodetected but -no-opengl is specified the backend must be skipped, just like the GLX one. Task-number: QTBUG-44998 Change-Id: I1ccbaf540f3777a1fc39aaf12bded4febf20faa0 Reviewed-by: Gunnar Sletta --- src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro b/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro index 29b6d1d2f7..9de0476810 100644 --- a/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro +++ b/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs -contains(QT_CONFIG, egl):contains(QT_CONFIG, egl_x11) { +contains(QT_CONFIG, egl): contains(QT_CONFIG, egl_x11): contains(QT_CONFIG, opengl) { SUBDIRS += xcb_egl } -- cgit v1.2.3 From 1adedb7baad717bd6f41796ccc717ba93e2f3738 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 11 May 2015 14:29:17 +0200 Subject: Make the windowcontainer example more robust The QWindow tends to get mouse releases on Windows when maximizing the window for example. This is likely a problem in the platform, but the example should be improved too to be more robust and ignore such unwanted events. Task-number: QTBUG-42842 Change-Id: Iecf916a2f753ed1b37d644721ee212ca7c728c49 Reviewed-by: Friedemann Kleint --- examples/widgets/windowcontainer/windowcontainer.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/examples/widgets/windowcontainer/windowcontainer.cpp b/examples/widgets/windowcontainer/windowcontainer.cpp index 022b6dafc4..a38a10e6f6 100644 --- a/examples/widgets/windowcontainer/windowcontainer.cpp +++ b/examples/widgets/windowcontainer/windowcontainer.cpp @@ -92,10 +92,12 @@ public: } void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE { - m_mouseDown = true; - m_polygon.clear(); - m_polygon.append(e->pos()); - renderLater(); + if (!m_mouseDown) { + m_mouseDown = true; + m_polygon.clear(); + m_polygon.append(e->pos()); + renderLater(); + } } void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE { @@ -106,9 +108,11 @@ public: } void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE { - m_mouseDown = false; - m_polygon.append(e->pos()); - renderLater(); + if (m_mouseDown) { + m_mouseDown = false; + m_polygon.append(e->pos()); + renderLater(); + } } void focusInEvent(QFocusEvent *) Q_DECL_OVERRIDE { -- cgit v1.2.3 From d33edcfe379fe4d86c8a4a0a2b02e8c6af104a71 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 7 May 2015 18:05:00 +0200 Subject: Fix the qscreen manual test for separate X screens It is fully possible to show a window on all the connected screens even when the screens are not virtual siblings, i.e. they do not form one big desktop. When X is configured to use a separate screen for each physical screen, it becomes essential to do setScreen() either directly or via QDesktopWidget in case of widgets. The original code attempting to call QWindow::setScreen() cannot succeed since there is no QWindow available before the widget is shown. This is easy to work around. The app now works identically in all cases. Change-Id: I519ca0c0109c68aac2f2d4e6972d14b55767b403 Reviewed-by: Gunnar Sletta --- tests/manual/qscreen/README | 12 ++++-------- tests/manual/qscreen/main.cpp | 21 ++++++++++----------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/tests/manual/qscreen/README b/tests/manual/qscreen/README index 5f5da17293..cd1324276d 100644 --- a/tests/manual/qscreen/README +++ b/tests/manual/qscreen/README @@ -20,14 +20,10 @@ create two windows, and will center one each screen, by setting the geometry. Alternatively you can configure xorg.conf to create separate screens for each graphics card; then the mouse cursor can move between the screens, but -application windows cannot: each app needs to be started up on the screen that -you want to run it on. In either case, ideally this test app ought to create -two windows, one on each screen; but in fact, it can do that only if the -screens are virtual siblings. If they are on different Displays, the second -Display is not accessible to the QXcbConnection instance which was createad on -the first Display. It can be considered a known bug that the API appears to -make this possible (you would think QWindow::setScreen might work) but it -isn't possible. +application windows cannot: each app needs to be started on the screen that +you want to run it on (by specifying e.g. DISPLAY=:0.1 for the second screen), +or the application has to set the desired screen via QWindow::setScreen() before +showing the window. The physical size of the screen is considered to be a constant. This can create discrepancies in DPI when orientation is changed, or when the screen is diff --git a/tests/manual/qscreen/main.cpp b/tests/manual/qscreen/main.cpp index 6f672ee422..1047ffcdfc 100644 --- a/tests/manual/qscreen/main.cpp +++ b/tests/manual/qscreen/main.cpp @@ -38,6 +38,7 @@ #include #include #include +#include int i = 0; @@ -66,19 +67,17 @@ void screenAdded(QScreen* screen) w->layout()->insertRow(0, "virtualSiblings", siblingsField); updateSiblings(w); - // This doesn't work. If the multiple screens are part of - // a virtual desktop (i.e. they are virtual siblings), then - // setScreen has no effect, and we need the code below to - // change the window geometry. If on the other hand the - // screens are really separate, so that windows are not - // portable between them, XCreateWindow needs to have not just - // a different root Window but also a different Display, in order to - // put the window on the other screen. That would require a - // different QXcbConnection. So this setScreen call doesn't seem useful. - //w->windowHandle()->setScreen(screen); + // Set the screen via QDesktopWidget. This corresponds to setScreen() for the underlying + // QWindow. This is essential when having separate X screens since the the positioning below is + // not sufficient to get the windows show up on the desired screen. + QList screens = QGuiApplication::screens(); + int screenNumber = screens.indexOf(screen); + Q_ASSERT(screenNumber >= 0); + w->setParent(qApp->desktop()->screen(screenNumber)); - // But this works as long as the screens are all virtual siblings w->show(); + + // Position the windows so that they end up at the center of the corresponding screen. QRect geom = w->geometry(); geom.setSize(w->sizeHint()); if (geom.height() > screen->geometry().height()) -- cgit v1.2.3 From 55225948a97ed3c405f894c617da375e6e89e9f0 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 7 May 2015 18:51:42 +0200 Subject: Create context with the correct screen in QOpenGLWindow Targeting a non-primary screen with a QOpenGLWindow requires (at least with GLX) that the context is created with the same screen. Otherwise the context cannot be used with the window (BadMatch due to different X screens) Change-Id: I64f38ad7317d39a164bb69bb1430692319fc49d4 Reviewed-by: Gunnar Sletta --- src/gui/kernel/qopenglwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index a7ba57e85e..7113345a75 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -206,6 +206,7 @@ public: context.reset(new QOpenGLContext); context->setShareContext(shareContext); context->setFormat(q->requestedFormat()); + context->setScreen(q->screen()); if (!context->create()) qWarning("QOpenGLWindow::beginPaint: Failed to create context"); if (!context->makeCurrent(q)) -- cgit v1.2.3 From 6ea636b0bd73f067c08217aa4e0ccc3f0209ede0 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 7 May 2015 19:00:11 +0200 Subject: Create contexts and pbuffers with the correct screen in QOpenGLWidget It won't be functional otherwise with GLX when the QOpenGLWidget is targeting a separate X screen. Change-Id: Ibe5b89023f833039bb67d94b78b173de2e021ac9 Reviewed-by: Gunnar Sletta --- src/widgets/kernel/qopenglwidget.cpp | 2 ++ src/widgets/kernel/qwidget.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index d4d23604a3..b8df25b38f 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -739,6 +739,7 @@ void QOpenGLWidgetPrivate::initialize() QScopedPointer ctx(new QOpenGLContext); ctx->setShareContext(shareContext); ctx->setFormat(requestedFormat); + ctx->setScreen(shareContext->screen()); if (!ctx->create()) { qWarning("QOpenGLWidget: Failed to create context"); return; @@ -762,6 +763,7 @@ void QOpenGLWidgetPrivate::initialize() // in QQuickWidget, use a dedicated QOffscreenSurface. surface = new QOffscreenSurface; surface->setFormat(ctx->format()); + surface->setScreen(ctx->screen()); surface->create(); if (!ctx->makeCurrent(surface)) { diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b2ea83c991..c7b141e700 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -12074,6 +12074,7 @@ QOpenGLContext *QWidgetPrivate::shareContext() const QOpenGLContext *ctx = new QOpenGLContext; ctx->setShareContext(qt_gl_global_share_context()); ctx->setFormat(extra->topextra->window->format()); + ctx->setScreen(extra->topextra->window->screen()); ctx->create(); that->extra->topextra->shareContext = ctx; } -- cgit v1.2.3 From 03ae6ad8e9aa73d77ce3caa89d9cebc2179e199a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 7 May 2015 11:54:17 +0200 Subject: remove $INCLUDE/$LIB hack for mingw mingw is not msvc, and nobody in their right mind would expect it to behave like it. [ChangeLog][Important Behavior Changes][qmake] Qt configure and qmake used with a MinGW spec will no longer emulate MSVC by picking up the INCLUDE and LIB environment variables. Use the -I/-L configure options to pass additional paths, as you would under Unix. Change-Id: I533bb97de34d14dcbd45e0416283a79f44096c67 Reviewed-by: Joerg Bornemann --- tools/configure/configureapp.cpp | 10 ---------- tools/configure/environment.cpp | 8 ++++---- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 8ea5b2ed3b..08ec943563 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3042,16 +3042,6 @@ void Configure::generateOutputVars() if (!qmakeStylePlugins.isEmpty()) qmakeVars += QString("style-plugins += ") + qmakeStylePlugins.join(' '); - if (dictionary["QMAKESPEC"].endsWith("-g++")) { - QString includepath = qgetenv("INCLUDE"); - const bool hasSh = !QStandardPaths::findExecutable(QStringLiteral("sh.exe")).isEmpty(); - QChar separator = (!includepath.contains(":\\") && hasSh ? QChar(':') : QChar(';')); - qmakeVars += QString("TMPPATH = $$quote($$(INCLUDE))"); - qmakeVars += QString("QMAKE_INCDIR_POST += $$split(TMPPATH,\"%1\")").arg(separator); - qmakeVars += QString("TMPPATH = $$quote($$(LIB))"); - qmakeVars += QString("QMAKE_LIBDIR_POST += $$split(TMPPATH,\"%1\")").arg(separator); - } - if (!dictionary[ "QMAKESPEC" ].length()) { cout << "Configure could not detect your compiler. QMAKESPEC must either" << endl << "be defined as an environment variable, or specified as an" << endl diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp index 63c1e8a1f0..11064a757d 100644 --- a/tools/configure/environment.cpp +++ b/tools/configure/environment.cpp @@ -611,9 +611,9 @@ QStringList Environment::headerPaths(Compiler compiler) foreach (const QFileInfo &version, mingwLibDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) headerPaths += version.absoluteFilePath() + QLatin1String("/include"); } + } else { + headerPaths = splitPathList(QString::fromLocal8Bit(getenv("INCLUDE"))); } - // MinGW: Although gcc doesn't care about INCLUDE, qmake automatically adds it via -I - headerPaths += splitPathList(QString::fromLocal8Bit(getenv("INCLUDE"))); // Add Direct X SDK for ANGLE const QString directXSdk = detectDirectXSdk(); @@ -627,9 +627,9 @@ QStringList Environment::libraryPaths(Compiler compiler) QStringList libraryPaths; if (compiler == CC_MINGW) { libraryPaths = mingwPaths(detectMinGW(), "lib"); + } else { + libraryPaths = splitPathList(QString::fromLocal8Bit(qgetenv("LIB"))); } - // MinGW: Although gcc doesn't care about LIB, qmake automatically adds it via -L - libraryPaths += splitPathList(QString::fromLocal8Bit(qgetenv("LIB"))); // Add Direct X SDK for ANGLE const QString directXSdk = detectDirectXSdk(); -- cgit v1.2.3 From 84be950e98fe44cc62a352de082f2c2d76915128 Mon Sep 17 00:00:00 2001 From: Bjoern Breitmeyer Date: Thu, 30 Apr 2015 11:24:20 +0200 Subject: Fixing the build of the SIMD support for WEC2013. Change-Id: Ib0dd8d34f0a5d68acb1efbc37680165e7d7933bd Reviewed-by: Friedemann Kleint Reviewed-by: Gunnar Roth Reviewed-by: Thiago Macieira --- src/corelib/tools/qsimd.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 52ffc161bf..d572dd209c 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -39,7 +39,9 @@ #if defined(Q_OS_WIN) # if defined(Q_OS_WINCE) # include -# include +# if _WIN32_WCE < 0x800 +# include +# endif # endif # if !defined(Q_CC_GNU) # ifndef Q_OS_WINCE -- cgit v1.2.3 From 12dd4ff7e7b4fae33fb74def603ce880eee0c16b Mon Sep 17 00:00:00 2001 From: Bjoern Breitmeyer Date: Tue, 28 Apr 2015 14:15:31 +0200 Subject: Remove effectless statement. The UNDER_NT define is useless as the include already happens before in qfunctions... Change-Id: I25fc23e169ce91d787331a7a86023aa7b424d687 Reviewed-by: Friedemann Kleint --- src/gui/image/qpixmap_win.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index 0de47f55af..12e19440dc 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -40,11 +40,6 @@ #include #include -#ifdef Q_OS_WINCE -#define UNDER_NT -#include -#endif - QT_BEGIN_NAMESPACE #ifdef Q_OS_WINCE -- cgit v1.2.3 From ba323b04cd78fb43e9e63b891e973d24b08250af Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 4 May 2015 13:32:32 +0200 Subject: Optionally apply orientation on QImage read Make it possible to read images with EXIF orientation automatically applied. This was originally implemented without opt-out in Qt 5.4, but reverted. Here it is implemented as opt-in for JPEG, and opt-out for TIFF to keep behavioral consistency. The EXIF support for JPEG was written by Rainer Keller. [ChangeLog][QtGui][Image plugins] An option has been added to QImageReader to enable automatic application of EXIF orientation. This behavior was default in Qt 5.4.1, but reverted in Qt 5.4.2. Task-number: QTBUG-37946 Task-number: QTBUG-43563 Task-number: QTBUG-45552 Task-number: QTBUG-45865 Change-Id: Iaafd2519b63ede66ecc1f8aa4c7118081312b8f5 Reviewed-by: Gunnar Sletta --- src/gui/image/qimage.cpp | 14 ++ src/gui/image/qimageiohandler.cpp | 37 +++++ src/gui/image/qimageiohandler.h | 19 ++- src/gui/image/qimagereader.cpp | 63 +++++++++ src/gui/image/qimagereader.h | 5 + src/gui/image/qimagewriter.cpp | 39 +++++- src/gui/image/qimagewriter.h | 3 + src/gui/image/qjpeghandler.cpp | 152 ++++++++++++++++++++- .../image/qimage/images/jpeg_exif_QTBUG-45865.jpg | Bin 0 -> 27540 bytes .../images/jpeg_exif_orientation_value_1.jpg | Bin 0 -> 910 bytes .../images/jpeg_exif_orientation_value_2.jpg | Bin 0 -> 910 bytes .../images/jpeg_exif_orientation_value_3.jpg | Bin 0 -> 988 bytes .../images/jpeg_exif_orientation_value_4.jpg | Bin 0 -> 995 bytes .../images/jpeg_exif_orientation_value_5.jpg | Bin 0 -> 912 bytes .../images/jpeg_exif_orientation_value_6.jpg | Bin 0 -> 911 bytes .../jpeg_exif_orientation_value_6_motorola.jpg | Bin 0 -> 911 bytes .../images/jpeg_exif_orientation_value_7.jpg | Bin 0 -> 987 bytes .../images/jpeg_exif_orientation_value_8.jpg | Bin 0 -> 991 bytes tests/auto/gui/image/qimage/tst_qimage.cpp | 60 ++++++++ 19 files changed, 388 insertions(+), 4 deletions(-) create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_QTBUG-45865.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6_motorola.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg create mode 100644 tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 8a0f570f47..cd0cbf7f49 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -5048,4 +5048,18 @@ QImage::Format QImage::toImageFormat(QPixelFormat format) Q_DECL_NOTHROW return Format_Invalid; } +Q_GUI_EXPORT void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient) +{ + if (orient == QImageIOHandler::TransformationNone) + return; + if (orient == QImageIOHandler::TransformationRotate270) { + src = rotated270(src); + } else { + src = qMove(src).mirrored(orient & QImageIOHandler::TransformationMirror, + orient & QImageIOHandler::TransformationFlip); + if (orient & QImageIOHandler::TransformationRotate90) + src = rotated90(src); + } +} + QT_END_NAMESPACE diff --git a/src/gui/image/qimageiohandler.cpp b/src/gui/image/qimageiohandler.cpp index cc9a6ae2a1..22b4bcf560 100644 --- a/src/gui/image/qimageiohandler.cpp +++ b/src/gui/image/qimageiohandler.cpp @@ -159,6 +159,43 @@ \value ProgressiveScanWrite. A handler which supports this option is expected to write the image as a progressive scan image. + + \value ImageTransformation. A handler which supports this option can read + the transformation metadata of an image. A handler that supports this option + should not apply the transformation itself. + + \value TransformedByDefault. A handler that reports support for this feature + will have image transformation metadata applied by default on read. +*/ + +/*! \enum QImageIOHandler::Transformation + \since 5.5 + + This enum describes the different transformations or orientations + supported by some image formats, usually through EXIF. + + \value TransformationNone No transformation should be applied. + + \value TransformationMirror Mirror the image horizontally. + + \value TransformationFlip Mirror the image vertically. + + \value TransformationRotate180 Rotate the image 180 degrees. + This is the same as mirroring it both horizontally and vertically. + + \value TransformationRotate90 Rotate the image 90 degrees. + + \value TransformationMirrorAndRotate90 Mirror the image horizontally + and then rotate it 90 degrees. + + \value TransformationFlipAndRotate90 Mirror the image vertically + and then rotate it 90 degrees. + + \value TransformationRotate270 Rotate the image 270 degrees. + This is the same as mirroring it both horizontally, vertically and + then rotating it 90 degrees. + + \sa QImageReader::transformation(), QImageReader::setAutoTransform(), QImageWriter::setTransformation() */ /*! diff --git a/src/gui/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h index b48226f619..80cd87c4c3 100644 --- a/src/gui/image/qimageiohandler.h +++ b/src/gui/image/qimageiohandler.h @@ -86,8 +86,25 @@ public: ImageFormat, SupportedSubTypes, OptimizedWrite, - ProgressiveScanWrite + ProgressiveScanWrite, + ImageTransformation +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + , TransformedByDefault +#endif }; + + enum Transformation { + TransformationNone = 0, + TransformationMirror = 1, + TransformationFlip = 2, + TransformationRotate180 = TransformationMirror | TransformationFlip, + TransformationRotate90 = 4, + TransformationMirrorAndRotate90 = TransformationMirror | TransformationRotate90, + TransformationFlipAndRotate90 = TransformationFlip | TransformationRotate90, + TransformationRotate270 = TransformationRotate180 | TransformationRotate90 + }; + Q_DECLARE_FLAGS(Transformations, Transformation) + virtual QVariant option(ImageOption option) const; virtual void setOption(ImageOption option, const QVariant &value); virtual bool supportsOption(ImageOption option) const; diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index c2795cc38d..ba79bf40e5 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -533,6 +533,11 @@ public: int quality; QMap text; void getText(); + enum { + UsePluginDefault, + ApplyTransform, + DoNotApplyTransform + } autoTransform; // error QImageReader::ImageReaderError imageReaderError; @@ -552,6 +557,7 @@ QImageReaderPrivate::QImageReaderPrivate(QImageReader *qq) handler = 0; quality = -1; imageReaderError = QImageReader::UnknownError; + autoTransform = UsePluginDefault; q = qq; } @@ -1143,6 +1149,59 @@ QList QImageReader::supportedSubTypes() const return QList(); } +/*! + \since 5.5 + + Returns the transformation metadata of the image, including image orientation. If the format + does not support transformation metadata \c QImageIOHandler::Transformation_None is returned. + + \sa setAutoTransform(), autoTransform() +*/ +QImageIOHandler::Transformations QImageReader::transformation() const +{ + int option = QImageIOHandler::TransformationNone; + if (d->initHandler() && d->handler->supportsOption(QImageIOHandler::ImageTransformation)) + option = d->handler->option(QImageIOHandler::ImageTransformation).toInt(); + return QImageIOHandler::Transformations(option); +} + +/*! + \since 5.5 + + Sets if images returned by read() should have transformation metadata automatically applied. + + \sa autoTransform(), transform(), read() +*/ +void QImageReader::setAutoTransform(bool enabled) +{ + d->autoTransform = enabled ? QImageReaderPrivate::ApplyTransform + : QImageReaderPrivate::DoNotApplyTransform; +} + +/*! + \since 5.5 + + Returns \c true if the image handler will apply transformation metadata on read(). + + \sa setAutoTransform(), transformation(), read() +*/ +bool QImageReader::autoTransform() const +{ + switch (d->autoTransform) { + case QImageReaderPrivate::ApplyTransform: + return true; + case QImageReaderPrivate::DoNotApplyTransform: + return false; + case QImageReaderPrivate::UsePluginDefault: + if (d->initHandler()) + return d->handler->supportsOption(QImageIOHandler::TransformedByDefault); + // no break + default: + break; + } + return false; +} + /*! Returns \c true if an image can be read for the device (i.e., the image format is supported, and the device seems to contain valid @@ -1185,6 +1244,8 @@ QImage QImageReader::read() return read(&image) ? image : QImage(); } +extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient); + /*! \overload @@ -1294,6 +1355,8 @@ bool QImageReader::read(QImage *image) if (!disable2xImageLoading && QFileInfo(fileName()).baseName().endsWith(QLatin1String("@2x"))) { image->setDevicePixelRatio(2.0); } + if (autoTransform()) + qt_imageTransform(*image, transformation()); return true; } diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h index 34191ed657..27a29bed49 100644 --- a/src/gui/image/qimagereader.h +++ b/src/gui/image/qimagereader.h @@ -105,6 +105,11 @@ public: bool supportsAnimation() const; + QImageIOHandler::Transformations transformation() const; + + void setAutoTransform(bool enabled); + bool autoTransform() const; + QByteArray subType() const; QList supportedSubTypes() const; diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index b418101163..e9de1db4b2 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -91,6 +91,7 @@ #include #include #include +#include #include #include #include @@ -254,6 +255,7 @@ public: QByteArray subType; bool optimizedWrite; bool progressiveScanWrite; + QImageIOHandler::Transformations transformation; // error QImageWriter::ImageWriterError imageWriterError; @@ -277,6 +279,7 @@ QImageWriterPrivate::QImageWriterPrivate(QImageWriter *qq) progressiveScanWrite = false; imageWriterError = QImageWriter::UnknownError; errorString = QImageWriter::tr("Unknown error"); + transformation = QImageIOHandler::TransformationNone; q = qq; } @@ -615,6 +618,33 @@ bool QImageWriter::progressiveScanWrite() const return d->progressiveScanWrite; } +/*! + \since 5.5 + + Sets the image transformations metadata including orientation. + + If transformation metadata is not supported by the image format, + the transform is applied before writing. + + \sa transformation(), write() +*/ +void QImageWriter::setTransformation(QImageIOHandler::Transformations transform) +{ + d->transformation = transform; +} + +/*! + \since 5.5 + + Returns the transformation and orientation the image has been set to written with. + + \sa setTransformation() +*/ +QImageIOHandler::Transformations QImageWriter::transformation() const +{ + return d->transformation; +} + /*! \obsolete @@ -694,6 +724,8 @@ bool QImageWriter::canWrite() const return d->canWriteHelper(); } +extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient); + /*! Writes the image \a image to the assigned device or file name. Returns \c true on success; otherwise returns \c false. If the @@ -708,6 +740,7 @@ bool QImageWriter::write(const QImage &image) if (!canWrite()) return false; + QImage img = image; if (d->handler->supportsOption(QImageIOHandler::Quality)) d->handler->setOption(QImageIOHandler::Quality, d->quality); if (d->handler->supportsOption(QImageIOHandler::CompressionRatio)) @@ -722,8 +755,12 @@ bool QImageWriter::write(const QImage &image) d->handler->setOption(QImageIOHandler::OptimizedWrite, d->optimizedWrite); if (d->handler->supportsOption(QImageIOHandler::ProgressiveScanWrite)) d->handler->setOption(QImageIOHandler::ProgressiveScanWrite, d->progressiveScanWrite); + if (d->handler->supportsOption(QImageIOHandler::ImageTransformation)) + d->handler->setOption(QImageIOHandler::ImageTransformation, int(d->transformation)); + else + qt_imageTransform(img, d->transformation); - if (!d->handler->write(image)) + if (!d->handler->write(img)) return false; if (QFile *file = qobject_cast(d->device)) file->flush(); diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h index 96d8f51b3a..7f92595c53 100644 --- a/src/gui/image/qimagewriter.h +++ b/src/gui/image/qimagewriter.h @@ -89,6 +89,9 @@ public: void setProgressiveScanWrite(bool progressive); bool progressiveScanWrite() const; + QImageIOHandler::Transformations transformation() const; + void setTransformation(QImageIOHandler::Transformations orientation); + // Obsolete as of 4.1 void setDescription(const QString &description); QString description() const; diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 2014b7440c..4ff3917fe6 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -714,7 +714,7 @@ public: }; QJpegHandlerPrivate(QJpegHandler *qq) - : quality(75), iod_src(0), + : quality(75), transformation(QImageIOHandler::TransformationNone), iod_src(0), rgb888ToRgb32ConverterPtr(qt_convert_rgb888_to_rgb32), state(Ready), optimize(false), progressive(false), q(qq) {} @@ -732,6 +732,7 @@ public: bool read(QImage *image); int quality; + QImageIOHandler::Transformations transformation; QVariant size; QImage::Format format; QSize scaledSize; @@ -754,6 +755,122 @@ public: QJpegHandler *q; }; +static bool readExifHeader(QDataStream &stream) +{ + char prefix[6]; + if (stream.readRawData(prefix, sizeof(prefix)) != sizeof(prefix)) + return false; + static const char exifMagic[6] = {'E', 'x', 'i', 'f', 0, 0}; + return memcmp(prefix, exifMagic, 6) == 0; +} + +/* + * Returns -1 on error + * Returns 0 if no Exif orientation was found + * Returns 1 orientation is horizontal (normal) + * Returns 2 mirror horizontal + * Returns 3 rotate 180 + * Returns 4 mirror vertical + * Returns 5 mirror horizontal and rotate 270 CCW + * Returns 6 rotate 90 CW + * Returns 7 mirror horizontal and rotate 90 CW + * Returns 8 rotate 270 CW + */ +static int getExifOrientation(QByteArray &exifData) +{ + QDataStream stream(&exifData, QIODevice::ReadOnly); + + if (!readExifHeader(stream)) + return -1; + + quint16 val; + quint32 offset; + const qint64 headerStart = stream.device()->pos(); + + // read byte order marker + stream >> val; + if (val == 0x4949) // 'II' == Intel + stream.setByteOrder(QDataStream::LittleEndian); + else if (val == 0x4d4d) // 'MM' == Motorola + stream.setByteOrder(QDataStream::BigEndian); + else + return -1; // unknown byte order + + // read size + stream >> val; + if (val != 0x2a) + return -1; + + stream >> offset; + + // read IFD + while (!stream.atEnd()) { + quint16 numEntries; + + // skip offset bytes to get the next IFD + const qint64 bytesToSkip = offset - (stream.device()->pos() - headerStart); + + if (stream.skipRawData(bytesToSkip) != bytesToSkip) + return -1; + + stream >> numEntries; + + for (; numEntries > 0; --numEntries) { + quint16 tag; + quint16 type; + quint32 components; + quint16 value; + quint16 dummy; + + stream >> tag >> type >> components >> value >> dummy; + if (tag == 0x0112) { // Tag Exif.Image.Orientation + if (components != 1) + return -1; + if (type != 3) // we are expecting it to be an unsigned short + return -1; + if (value < 1 || value > 8) // check for valid range + return -1; + + // It is possible to include the orientation multiple times. + // Right now the first value is returned. + return value; + } + } + + // read offset to next IFD + stream >> offset; + if (offset == 0) // this is the last IFD + break; + } + + // No Exif orientation was found + return 0; +} + +static QImageIOHandler::Transformations exif2Qt(int exifOrientation) +{ + switch (exifOrientation) { + case 1: // normal + return QImageIOHandler::TransformationNone; + case 2: // mirror horizontal + return QImageIOHandler::TransformationMirror; + case 3: // rotate 180 + return QImageIOHandler::TransformationRotate180; + case 4: // mirror vertical + return QImageIOHandler::TransformationFlip; + case 5: // mirror horizontal and rotate 270 CW + return QImageIOHandler::TransformationFlipAndRotate90; + case 6: // rotate 90 CW + return QImageIOHandler::TransformationRotate90; + case 7: // mirror horizontal and rotate 90 CW + return QImageIOHandler::TransformationMirrorAndRotate90; + case 8: // rotate 270 CW + return QImageIOHandler::TransformationRotate270; + } + qWarning("Invalid EXIF orientation"); + return QImageIOHandler::TransformationNone; +} + /*! \internal */ @@ -773,6 +890,7 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) if (!setjmp(err.setjmp_buffer)) { jpeg_save_markers(&info, JPEG_COM, 0xFFFF); + jpeg_save_markers(&info, JPEG_APP0 + 1, 0xFFFF); // Exif uses APP1 marker (void) jpeg_read_header(&info, TRUE); @@ -784,6 +902,8 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) format = QImage::Format_Invalid; read_jpeg_format(format, &info); + QByteArray exifData; + for (jpeg_saved_marker_ptr marker = info.marker_list; marker != NULL; marker = marker->next) { if (marker->marker == JPEG_COM) { QString key, value; @@ -801,9 +921,20 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) description += key + QLatin1String(": ") + value.simplified(); readTexts.append(key); readTexts.append(value); + } else if (marker->marker == JPEG_APP0 + 1) { + exifData.append((const char*)marker->data, marker->data_length); } } + if (!exifData.isEmpty()) { + // Exif data present + int exifOrientation = getExifOrientation(exifData); + if (exifOrientation == -1) + return false; + if (exifOrientation > 0) + transformation = exif2Qt(exifOrientation); + } + state = ReadHeader; return true; } @@ -905,8 +1036,16 @@ bool QJpegHandler::read(QImage *image) return d->read(image); } +extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient); + bool QJpegHandler::write(const QImage &image) { + if (d->transformation != QImageIOHandler::TransformationNone) { + // We don't support writing EXIF headers so apply the transform to the data. + QImage img = image; + qt_imageTransform(img, d->transformation); + return write_jpeg_image(img, device(), d->quality, d->description, d->optimize, d->progressive); + } return write_jpeg_image(image, device(), d->quality, d->description, d->optimize, d->progressive); } @@ -920,7 +1059,8 @@ bool QJpegHandler::supportsOption(ImageOption option) const || option == Size || option == ImageFormat || option == OptimizedWrite - || option == ProgressiveScanWrite; + || option == ProgressiveScanWrite + || option == ImageTransformation; } QVariant QJpegHandler::option(ImageOption option) const @@ -947,6 +1087,9 @@ QVariant QJpegHandler::option(ImageOption option) const return d->optimize; case ProgressiveScanWrite: return d->progressive; + case ImageTransformation: + d->readJpegHeader(device()); + return int(d->transformation); default: break; } @@ -978,6 +1121,11 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value) case ProgressiveScanWrite: d->progressive = value.toBool(); break; + case ImageTransformation: { + int transformation = value.toInt(); + if (transformation > 0 && transformation < 8) + d->transformation = QImageIOHandler::Transformations(transformation); + } default: break; } diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_QTBUG-45865.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_QTBUG-45865.jpg new file mode 100644 index 0000000000..97deae3e25 Binary files /dev/null and b/tests/auto/gui/image/qimage/images/jpeg_exif_QTBUG-45865.jpg differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg new file mode 100644 index 0000000000..aaa4ac4e10 Binary files /dev/null and b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_1.jpg differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg new file mode 100644 index 0000000000..a61d2723d7 Binary files /dev/null and b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_2.jpg differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg new file mode 100644 index 0000000000..43e56dcef7 Binary files /dev/null and b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_3.jpg differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg new file mode 100644 index 0000000000..d5d06f7409 Binary files /dev/null and b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_4.jpg differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg new file mode 100644 index 0000000000..1886f3775e Binary files /dev/null and b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_5.jpg differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg new file mode 100644 index 0000000000..5cec757354 Binary files /dev/null and b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6.jpg differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6_motorola.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6_motorola.jpg new file mode 100644 index 0000000000..0aa164b78b Binary files /dev/null and b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_6_motorola.jpg differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg new file mode 100644 index 0000000000..b3dcc466a9 Binary files /dev/null and b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_7.jpg differ diff --git a/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg new file mode 100644 index 0000000000..8bc390e2b9 Binary files /dev/null and b/tests/auto/gui/image/qimage/images/jpeg_exif_orientation_value_8.jpg differ diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 62a9f19f36..da29a57f98 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -181,6 +181,11 @@ private slots: void invertPixelsRGB_data(); void invertPixelsRGB(); + void exifOrientation_data(); + void exifOrientation(); + + void exif_QTBUG45865(); + void cleanupFunctions(); void devicePixelRatio(); @@ -2810,6 +2815,61 @@ void tst_QImage::invertPixelsRGB() QCOMPARE(qBlue(pixel) >> 4, (255 - 96) >> 4); } +void tst_QImage::exifOrientation_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("orientation"); + QTest::newRow("Orientation 1, Intel format") << m_prefix + "jpeg_exif_orientation_value_1.jpg" << (int)QImageIOHandler::TransformationNone; + QTest::newRow("Orientation 2, Intel format") << m_prefix + "jpeg_exif_orientation_value_2.jpg" << (int)QImageIOHandler::TransformationMirror; + QTest::newRow("Orientation 3, Intel format") << m_prefix + "jpeg_exif_orientation_value_3.jpg" << (int)QImageIOHandler::TransformationRotate180; + QTest::newRow("Orientation 4, Intel format") << m_prefix + "jpeg_exif_orientation_value_4.jpg" << (int)QImageIOHandler::TransformationFlip; + QTest::newRow("Orientation 5, Intel format") << m_prefix + "jpeg_exif_orientation_value_5.jpg" << (int)QImageIOHandler::TransformationFlipAndRotate90; + QTest::newRow("Orientation 6, Intel format") << m_prefix + "jpeg_exif_orientation_value_6.jpg" << (int)QImageIOHandler::TransformationRotate90; + QTest::newRow("Orientation 6, Motorola format") << m_prefix + "jpeg_exif_orientation_value_6_motorola.jpg" << (int)QImageIOHandler::TransformationRotate90; + QTest::newRow("Orientation 7, Intel format") << m_prefix + "jpeg_exif_orientation_value_7.jpg" << (int)QImageIOHandler::TransformationMirrorAndRotate90; + QTest::newRow("Orientation 8, Intel format") << m_prefix + "jpeg_exif_orientation_value_8.jpg" << (int)QImageIOHandler::TransformationRotate270; +} + +QT_BEGIN_NAMESPACE +extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient); +QT_END_NAMESPACE +QT_USE_NAMESPACE + +void tst_QImage::exifOrientation() +{ + QFETCH(QString, fileName); + QFETCH(int, orientation); + + QImageReader imageReader(fileName); + imageReader.setAutoTransform(true); + QCOMPARE(imageReader.transformation(), orientation); + QImage img = imageReader.read(); + QRgb px; + QVERIFY(!img.isNull()); + + px = img.pixel(0, 0); + QVERIFY(qRed(px) > 250 && qGreen(px) < 5 && qBlue(px) < 5); + + px = img.pixel(img.width() - 1, 0); + QVERIFY(qRed(px) < 5 && qGreen(px) < 5 && qBlue(px) > 250); + + QImageReader imageReader2(fileName); + QCOMPARE(imageReader2.autoTransform(), false); + QCOMPARE(imageReader2.transformation(), orientation); + QImage img2 = imageReader2.read(); + qt_imageTransform(img2, imageReader2.transformation()); + QCOMPARE(img, img2); +} + +void tst_QImage::exif_QTBUG45865() +{ + QFile file(m_prefix + "jpeg_exif_QTBUG-45865.jpg"); + QVERIFY(file.open(QIODevice::ReadOnly)); + QByteArray byteArray = file.readAll(); + QImage image = QImage::fromData(byteArray); + QCOMPARE(image.size(), QSize(5, 8)); +} + static void cleanupFunction(void* info) { bool *called = static_cast(info); -- cgit v1.2.3 From ac1b6c01454b8969e59becf066bba14f9ed0d310 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 5 Mar 2015 11:00:53 +0100 Subject: Add QMainWindow::GroupedDragging DockOption If this setting is enabled, the entire group of docked tabs will be draggable by the title bar of the group and and individual dock can be dragged by dragging the tab. When tabs are detached, the docks that are contained are reparented to a QDockWidgetGroupWindow. [ChangeLog][QtWidgets][QMainWindow] Added GroupedDragging as a DockOption which allow users to drag all the tabs together when dragging the title of a QDockWidget which is tabbed with others. Change-Id: I5285685b129770498eb3e4fd5f4556e41225a595 Reviewed-by: Friedemann Kleint Reviewed-by: Paul Olav Tvete --- .../widgets/mainwindows/mainwindow/colorswatch.cpp | 8 +- .../widgets/mainwindows/mainwindow/colorswatch.h | 4 +- .../widgets/mainwindows/mainwindow/mainwindow.cpp | 7 + src/widgets/widgets/qdockarealayout.cpp | 82 +++- src/widgets/widgets/qdockarealayout_p.h | 4 +- src/widgets/widgets/qdockwidget.cpp | 153 ++++-- src/widgets/widgets/qdockwidget_p.h | 3 +- src/widgets/widgets/qmainwindow.cpp | 7 + src/widgets/widgets/qmainwindow.h | 3 +- src/widgets/widgets/qmainwindowlayout.cpp | 519 ++++++++++++++++++++- src/widgets/widgets/qmainwindowlayout_p.h | 24 +- 11 files changed, 717 insertions(+), 97 deletions(-) diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp index 408f6c4b0f..7499389dc3 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp @@ -248,8 +248,8 @@ void ColorDock::setCustomSizeHint(const QSize &size) updateGeometry(); } -ColorSwatch::ColorSwatch(const QString &colorName, QWidget *parent, Qt::WindowFlags flags) - : QDockWidget(parent, flags) +ColorSwatch::ColorSwatch(const QString &colorName, QMainWindow *parent, Qt::WindowFlags flags) + : QDockWidget(parent, flags), mainWindow(parent) { setObjectName(colorName + QLatin1String(" Dock Widget")); setWindowTitle(objectName() + QLatin1String(" [*]")); @@ -390,7 +390,6 @@ ColorSwatch::ColorSwatch(const QString &colorName, QWidget *parent, Qt::WindowFl void ColorSwatch::updateContextMenu() { - QMainWindow *mainWindow = qobject_cast(parentWidget()); const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(this); const Qt::DockWidgetAreas areas = allowedAreas(); @@ -458,7 +457,6 @@ void ColorSwatch::updateContextMenu() void ColorSwatch::splitInto(QAction *action) { - QMainWindow *mainWindow = qobject_cast(parentWidget()); QList dock_list = mainWindow->findChildren(); ColorSwatch *target = 0; foreach (ColorSwatch *dock, dock_list) { @@ -477,7 +475,6 @@ void ColorSwatch::splitInto(QAction *action) void ColorSwatch::tabInto(QAction *action) { - QMainWindow *mainWindow = qobject_cast(parentWidget()); QList dock_list = mainWindow->findChildren(); ColorSwatch *target = 0; foreach (ColorSwatch *dock, dock_list) { @@ -525,7 +522,6 @@ void ColorSwatch::place(Qt::DockWidgetArea area, bool p) { if (!p) return; - QMainWindow *mainWindow = qobject_cast(parentWidget()); mainWindow->addDockWidget(area, this); if (allowedAreasActions->isEnabled()) { diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.h b/examples/widgets/mainwindows/mainwindow/colorswatch.h index 6d02592b22..78f267c320 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.h +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.h @@ -70,8 +70,10 @@ class ColorSwatch : public QDockWidget QAction *windowModifiedAction; + QMainWindow *mainWindow; + public: - explicit ColorSwatch(const QString &colorName, QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit ColorSwatch(const QString &colorName, QMainWindow *parent = 0, Qt::WindowFlags flags = 0); QMenu *menu; void setCustomSizeHint(const QSize &size); diff --git a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp index 70a8644b47..ea557c7aa9 100644 --- a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp +++ b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp @@ -156,6 +156,11 @@ void MainWindow::setupMenuBar() action->setChecked(dockOptions() & VerticalTabs); connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + action = mainWindowMenu->addAction(tr("Grouped dragging")); + action->setCheckable(true); + action->setChecked(dockOptions() & GroupedDragging); + connect(action, SIGNAL(toggled(bool)), this, SLOT(setDockOptions())); + QMenu *toolBarMenu = menuBar()->addMenu(tr("Tool bars")); for (int i = 0; i < toolBars.count(); ++i) toolBarMenu->addMenu(toolBars.at(i)->menu); @@ -187,6 +192,8 @@ void MainWindow::setDockOptions() opts |= ForceTabbedDocks; if (actions.at(4)->isChecked()) opts |= VerticalTabs; + if (actions.at(5)->isChecked()) + opts |= GroupedDragging; QMainWindow::setDockOptions(opts); } diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index af0f2515fe..bc2259ce90 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Olivier Goffart ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWidgets module of the Qt Toolkit. @@ -1854,20 +1855,6 @@ static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos) return Qt::NoDockWidgetArea; } -static QRect constrainedRect(QRect rect, const QRect &desktop) -{ - if (desktop.isValid()) { - rect.setWidth(qMin(rect.width(), desktop.width())); - rect.setHeight(qMin(rect.height(), desktop.height())); - rect.moveLeft(qMax(rect.left(), desktop.left())); - rect.moveTop(qMax(rect.top(), desktop.top())); - rect.moveRight(qMin(rect.right(), desktop.right())); - rect.moveBottom(qMin(rect.bottom(), desktop.bottom())); - } - - return rect; -} - bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList &widgets, bool testing) { uchar marker; @@ -1958,11 +1945,7 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList #endif if (!testing) { QRect r(x, y, w, h); - QDesktopWidget *desktop = QApplication::desktop(); - if (desktop->isVirtualDesktop()) - r = constrainedRect(r, desktop->screenGeometry(desktop->screenNumber(r.topLeft()))); - else - r = constrainedRect(r, desktop->screenGeometry(widget)); + r = QDockAreaLayout::constrainedRect(r, widget); widget->move(r.topLeft()); widget->resize(r.size()); } @@ -2075,6 +2058,36 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const #endif //QT_NO_TABBAR #ifndef QT_NO_TABBAR +/*! \internal + reparent all the widgets contained in this layout portion to the + specified parent. This is used to reparent dock widgets and tabbars + to the floating window or the main window + */ +void QDockAreaLayoutInfo::reparentWidgets(QWidget *parent) +{ + if (tabBar) + tabBar->setParent(parent); + + for (int i = 0; i < item_list.count(); ++i) { + const QDockAreaLayoutItem &item = item_list.at(i); + if (item.flags & QDockAreaLayoutItem::GapItem) + continue; + if (item.skip()) + continue; + if (item.subinfo) + item.subinfo->reparentWidgets(parent); + if (item.widgetItem) { + QWidget *w = item.widgetItem->widget(); + if (w->parent() != parent) { + bool hidden = w->isHidden(); + w->setParent(parent); + if (!hidden) + w->show(); + } + } + } +} + //returns whether the tabbar is visible or not bool QDockAreaLayoutInfo::updateTabBar() const { @@ -2981,6 +2994,33 @@ QSize QDockAreaLayout::minimumSize() const return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3)); } +/*! \internal + Try to fit the given rectangle \a rect on the screen which contains + the window \a widget. + Used to compute the geometry of a dragged a dock widget that should + be shown with \a rect, but needs to be visible on the screen + */ +QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget) +{ + QRect desktop; + QDesktopWidget *desktopW = QApplication::desktop(); + if (desktopW->isVirtualDesktop()) + desktop = desktopW->screenGeometry(rect.topLeft()); + else + desktop = desktopW->screenGeometry(widget); + + if (desktop.isValid()) { + rect.setWidth(qMin(rect.width(), desktop.width())); + rect.setHeight(qMin(rect.height(), desktop.height())); + rect.moveLeft(qMax(rect.left(), desktop.left())); + rect.moveTop(qMax(rect.top(), desktop.top())); + rect.moveRight(qMin(rect.right(), desktop.right())); + rect.moveBottom(qMin(rect.bottom(), desktop.bottom())); + } + + return rect; +} + bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) { QList index = indexOfPlaceHolder(dockWidget->objectName()); @@ -2994,9 +3034,7 @@ bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) item.widgetItem = new QDockWidgetItem(dockWidget); if (placeHolder->window) { - const QRect screenGeometry = - QApplication::desktop()->screenGeometry(placeHolder->topLevelRect.center()); - const QRect r = constrainedRect(placeHolder->topLevelRect, screenGeometry); + const QRect r = constrainedRect(placeHolder->topLevelRect, dockWidget); dockWidget->d_func()->setWindowState(true, true, r); } dockWidget->setVisible(!placeHolder->hidden); diff --git a/src/widgets/widgets/qdockarealayout_p.h b/src/widgets/widgets/qdockarealayout_p.h index 64fae7ebf6..93b005f64f 100644 --- a/src/widgets/widgets/qdockarealayout_p.h +++ b/src/widgets/widgets/qdockarealayout_p.h @@ -202,6 +202,7 @@ public: QTabBar *tabBar; int tabBarShape; + void reparentWidgets(QWidget *p); bool updateTabBar() const; void setTabBarShape(int shape); QSize tabBarMinimumSize() const; @@ -232,7 +233,8 @@ public: bool isValid() const; - enum { DockWidgetStateMarker = 0xfd }; + enum { DockWidgetStateMarker = 0xfd, FloatingDockWidgetTabMarker = 0xf9 }; + static QRect constrainedRect(QRect rect, QWidget *widget); void saveState(QDataStream &stream) const; bool restoreState(QDataStream &stream, const QList &widgets, bool testing = false); diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 21b0904cc0..1b7473fbd7 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -65,6 +65,18 @@ extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); / // qmainwindow.cpp extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window); +static inline QMainWindowLayout *qt_mainwindow_layout_from_dock(const QDockWidget *dock) +{ + const QWidget *p = dock->parentWidget(); + while (p) { + const QMainWindow *window = qobject_cast(p); + if (window) + return qt_mainwindow_layout(window); + p = p->parentWidget(); + } + return Q_NULLPTR; +} + static inline bool hasFeature(const QDockWidgetPrivate *priv, QDockWidget::DockWidgetFeature feature) { return (priv->features & feature) == feature; } @@ -194,25 +206,40 @@ QDockWidgetLayout::~QDockWidgetLayout() qDeleteAll(item_list); } +/*! \internal + Returns true if the dock widget managed by this layout should have a native + window decoration or if Qt needs to draw it. + */ bool QDockWidgetLayout::nativeWindowDeco() const { - return nativeWindowDeco(parentWidget()->isWindow()); + bool floating = parentWidget()->isWindow(); + if (!floating && qobject_cast(parentWidget()->parentWidget())) + return wmSupportsNativeWindowDeco(); + return nativeWindowDeco(floating); } -static bool isXcb() +/*! \internal + Returns true if the window manager can draw natively the windows decoration + of a dock widget + */ +bool QDockWidgetLayout::wmSupportsNativeWindowDeco() { +#if defined(Q_OS_WINCE) || defined(Q_OS_ANDROID) + return false; +#else static const bool xcb = !QGuiApplication::platformName().compare(QLatin1String("xcb"), Qt::CaseInsensitive); - return xcb; + return !xcb; +#endif } +/*! \internal + Returns true if the dock widget managed by this layout should have a native + window decoration or if Qt needs to draw it. The \a floating parameter + overrides the floating current state of the dock widget. + */ bool QDockWidgetLayout::nativeWindowDeco(bool floating) const { -#if defined(Q_OS_WINCE) || defined(Q_OS_ANDROID) - Q_UNUSED(floating) - return false; -#else - return !isXcb() && (floating && item_list[QDockWidgetLayout::TitleBar] == 0); -#endif + return wmSupportsNativeWindowDeco() && floating && item_list.at(QDockWidgetLayout::TitleBar) == 0; } @@ -611,7 +638,10 @@ void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const return; QDockWidgetLayout *dwlayout = qobject_cast(layout()); - option->initFrom(this); + QDockWidgetGroupWindow *floatingTab = qobject_cast(parent()); + // If we are in a floating tab, init from the parent because the attributes and the geometry + // of the title bar should be taken from the floating window. + option->initFrom(floatingTab && !isFloating() ? parentWidget() : this); option->rect = dwlayout->titleArea(); option->title = d->fixedWindowTitle; option->closable = hasFeature(this, QDockWidget::DockWidgetClosable); @@ -681,14 +711,20 @@ void QDockWidgetPrivate::_q_toggleTopLevel() q->setFloating(!q->isFloating()); } +/*! \internal + Initialize the drag state structure and remember the position of the click. + This is called when the mouse is pressed, but the dock is not yet dragged out. + + \a nca specify that the event comes from NonClientAreaMouseButtonPress + */ void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca) { + Q_Q(QDockWidget); + if (state != 0) return; - QMainWindow *win = qobject_cast(parent); - Q_ASSERT(win != 0); - QMainWindowLayout *layout = qt_mainwindow_layout(win); + QMainWindowLayout *layout = qt_mainwindow_layout_from_dock(q); Q_ASSERT(layout != 0); if (layout->pluggingWidget != 0) // the main window is animating a docking operation return; @@ -702,17 +738,23 @@ void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca) state->ctrlDrag = false; } -void QDockWidgetPrivate::startDrag() +/*! \internal + Actually start the drag and detach the dockwidget. + The \a group parameter is true when we should potentially drag a group of + tabbed widgets, and false if the dock widget should always be dragged + alone. + */ +void QDockWidgetPrivate::startDrag(bool group) { Q_Q(QDockWidget); if (state == 0 || state->dragging) return; - QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast(q->parentWidget())); + QMainWindowLayout *layout = qt_mainwindow_layout_from_dock(q); Q_ASSERT(layout != 0); - state->widgetItem = layout->unplug(q); + state->widgetItem = layout->unplug(q, group); if (state->widgetItem == 0) { /* I have a QMainWindow parent, but I was never inserted with QMainWindow::addDockWidget, so the QMainWindowLayout has no @@ -728,6 +770,11 @@ void QDockWidgetPrivate::startDrag() state->dragging = true; } +/*! \internal + Ends the drag end drop operation of the QDockWidget. + The \a abort parameter specifies that it ends because of programmatic state + reset rather than mouse release event. + */ void QDockWidgetPrivate::endDrag(bool abort) { Q_Q(QDockWidget); @@ -736,29 +783,31 @@ void QDockWidgetPrivate::endDrag(bool abort) q->releaseMouse(); if (state->dragging) { - QMainWindowLayout *mwLayout = qt_mainwindow_layout(qobject_cast(q->parentWidget())); + QMainWindowLayout *mwLayout = qt_mainwindow_layout_from_dock(q); Q_ASSERT(mwLayout != 0); if (abort || !mwLayout->plug(state->widgetItem)) { if (hasFeature(this, QDockWidget::DockWidgetFloatable)) { + // This QDockWidget will now stay in the floating state. if (state->ownWidgetItem) delete state->widgetItem; mwLayout->restore(); - if (isXcb()) { + QDockWidgetLayout *dwLayout = qobject_cast(layout); + if (!dwLayout->nativeWindowDeco()) { // get rid of the X11BypassWindowManager window flag and activate the resizer Qt::WindowFlags flags = q->windowFlags(); flags &= ~Qt::X11BypassWindowManagerHint; q->setWindowFlags(flags); - setResizerActive(true); + setResizerActive(q->isFloating()); q->show(); } else { - QDockWidgetLayout *myLayout - = qobject_cast(layout); - setResizerActive(myLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0); + setResizerActive(false); } undockedGeometry = q->geometry(); q->activateWindow(); } else { + // The tab was not plugged back in the QMainWindow but the QDockWidget cannot + // stay floating, revert to the previous state. mwLayout->revert(state->widgetItem); } } @@ -782,11 +831,7 @@ bool QDockWidgetPrivate::isAnimating() const { Q_Q(const QDockWidget); - QMainWindow *mainWin = qobject_cast(parent); - if (mainWin == 0) - return false; - - QMainWindowLayout *mainWinLayout = qt_mainwindow_layout(mainWin); + QMainWindowLayout *mainWinLayout = qt_mainwindow_layout_from_dock(q); if (mainWinLayout == 0) return false; @@ -804,12 +849,14 @@ bool QDockWidgetPrivate::mousePressEvent(QMouseEvent *event) if (!dwLayout->nativeWindowDeco()) { QRect titleArea = dwLayout->titleArea(); + QDockWidgetGroupWindow *floatingTab = qobject_cast(parent); + if (event->button() != Qt::LeftButton || !titleArea.contains(event->pos()) || // check if the tool window is movable... do nothing if it // is not (but allow moving if the window is floating) (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) || - qobject_cast(parent) == 0 || + (qobject_cast(parent) == 0 && !floatingTab) || isAnimating() || state != 0) { return false; } @@ -853,7 +900,7 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event) QDockWidgetLayout *dwlayout = qobject_cast(layout); - QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast(q->parentWidget())); + QMainWindowLayout *mwlayout = qt_mainwindow_layout_from_dock(q); if (!dwlayout->nativeWindowDeco()) { if (!state->dragging && mwlayout->pluggingWidget == 0 @@ -871,7 +918,12 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event) if (state->dragging && !state->nca) { QPoint pos = event->globalPos() - state->pressPos; - q->move(pos); + + QDockWidgetGroupWindow *floatingTab = qobject_cast(parent); + if (floatingTab && !q->isFloating()) + floatingTab->move(pos); + else + q->move(pos); if (state && !state->ctrlDrag) mwlayout->hover(state->widgetItem, event->globalPos()); @@ -902,8 +954,9 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event) int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q); - QRect geo = q->geometry(); - QRect titleRect = q->frameGeometry(); + QWidget *tl = q->topLevelWidget(); + QRect geo = tl->geometry(); + QRect titleRect = tl->frameGeometry(); #ifdef Q_DEAD_CODE_FROM_QT4_MAC if ((features & QDockWidget::DockWidgetVerticalTitleBar)) { titleRect.setTop(geo.top()); @@ -924,7 +977,7 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event) break; if (state != 0) break; - if (qobject_cast(parent) == 0) + if (qobject_cast(parent) == 0 && qobject_cast(parent) == 0) break; if (isAnimating()) break; @@ -958,11 +1011,17 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event) } } +/*! \internal + Called when the QDockWidget or the QDockWidgetGroupWindow is moved + */ void QDockWidgetPrivate::moveEvent(QMoveEvent *event) { Q_Q(QDockWidget); - if (state == 0 || !state->dragging || !state->nca || !q->isWindow()) + if (state == 0 || !state->dragging || !state->nca) + return; + + if (!q->isWindow() && qobject_cast(parent) == 0) return; // When the native window frame is being dragged, all we get is these mouse @@ -971,7 +1030,7 @@ void QDockWidgetPrivate::moveEvent(QMoveEvent *event) if (state->ctrlDrag) return; - QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast(q->parentWidget())); + QMainWindowLayout *layout = qt_mainwindow_layout_from_dock(q); Q_ASSERT(layout != 0); QPoint globalMousePos = event->pos() + state->pressPos; @@ -999,8 +1058,9 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect Q_Q(QDockWidget); if (!floating && parent) { - QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast(q->parentWidget())); - if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea) + QMainWindowLayout *mwlayout = qt_mainwindow_layout_from_dock(q); + if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea + && !qobject_cast(parent)) return; // this dockwidget can't be redocked } @@ -1048,7 +1108,7 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect if (floating != wasFloating) { emit q->topLevelChanged(floating); if (!floating && parent) { - QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast(q->parentWidget())); + QMainWindowLayout *mwlayout = qt_mainwindow_layout_from_dock(q); if (mwlayout) emit q->dockLocationChanged(mwlayout->dockWidgetArea(q)); } @@ -1230,8 +1290,11 @@ void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features) emit featuresChanged(d->features); update(); if (closableChanged && layout->nativeWindowDeco()) { - //this ensures the native decoration is drawn - d->setWindowState(true /*floating*/, true /*unplug*/); + QDockWidgetGroupWindow *floatingTab = qobject_cast(parent()); + if (floatingTab && !isFloating()) + floatingTab->adjustFlags(); + else + d->setWindowState(true /*floating*/, true /*unplug*/); //this ensures the native decoration is drawn } } @@ -1323,11 +1386,12 @@ void QDockWidget::changeEvent(QEvent *event) #endif #ifndef QT_NO_TABBAR { - QMainWindow *win = qobject_cast(parentWidget()); - if (QMainWindowLayout *winLayout = qt_mainwindow_layout(win)) { + if (QMainWindowLayout *winLayout = qt_mainwindow_layout_from_dock(this)) { if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this)) info->updateTabBar(); } + if (QDockWidgetGroupWindow *p = qobject_cast(parent())) + p->adjustFlags(); } #endif // QT_NO_TABBAR break; @@ -1380,7 +1444,7 @@ bool QDockWidget::event(QEvent *event) Q_D(QDockWidget); QMainWindow *win = qobject_cast(parentWidget()); - QMainWindowLayout *layout = qt_mainwindow_layout(win); + QMainWindowLayout *layout = qt_mainwindow_layout_from_dock(this); switch (event->type()) { #ifndef QT_NO_ACTION @@ -1417,6 +1481,9 @@ bool QDockWidget::event(QEvent *event) } if (!isFloating() && layout != 0 && onTop) layout->raise(this); + if (QDockWidgetGroupWindow *p = qobject_cast(parent())) + p->adjustFlags(); + break; } case QEvent::WindowActivate: diff --git a/src/widgets/widgets/qdockwidget_p.h b/src/widgets/widgets/qdockwidget_p.h index 752d6519e5..9c68bc5fb1 100644 --- a/src/widgets/widgets/qdockwidget_p.h +++ b/src/widgets/widgets/qdockwidget_p.h @@ -108,7 +108,7 @@ public: void setWindowState(bool floating, bool unplug = false, const QRect &rect = QRect()); void nonClientAreaMouseEvent(QMouseEvent *event); void initDrag(const QPoint &pos, bool nca); - void startDrag(); + void startDrag(bool group = true); void endDrag(bool abort = false); void moveEvent(QMoveEvent *event); @@ -151,6 +151,7 @@ public: int minimumTitleWidth() const; int titleHeight() const; void updateMaxSize(); + static bool wmSupportsNativeWindowDeco(); bool nativeWindowDeco() const; bool nativeWindowDeco(bool floating) const; diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index 2a1e8428ab..8eb9050528 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -420,6 +420,13 @@ QMainWindow::~QMainWindow() at the bottom. Implies AllowTabbedDocks. See also \l setTabPosition(). + \value GroupedDragging When dragging the titlebar of a dock, all the tabs + that are tabbed with it are going to be dragged. + Implies AllowTabbedDocks. Does not work well if + some QDockWidgets have restrictions in which area + they are allowed. (This enum value was added in Qt + 5.6.) + These options only control how dock widgets may be dropped in a QMainWindow. They do not re-arrange the dock widgets to conform with the specified options. For this reason they should be set before any dock widgets diff --git a/src/widgets/widgets/qmainwindow.h b/src/widgets/widgets/qmainwindow.h index cbbea74b9b..0bd70c87a6 100644 --- a/src/widgets/widgets/qmainwindow.h +++ b/src/widgets/widgets/qmainwindow.h @@ -77,7 +77,8 @@ public: AllowNestedDocks = 0x02, AllowTabbedDocks = 0x04, ForceTabbedDocks = 0x08, // implies AllowTabbedDocks, !AllowNestedDocks - VerticalTabs = 0x10 // implies AllowTabbedDocks + VerticalTabs = 0x10, // implies AllowTabbedDocks + GroupedDragging = 0x20 // implies AllowTabbedDocks }; Q_ENUM(DockOption) Q_DECLARE_FLAGS(DockOptions, DockOption) diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 3620aa04fc..d41f3bad19 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Olivier Goffart ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWidgets module of the Qt Toolkit. @@ -49,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +63,7 @@ #include #include +#include #ifdef Q_DEAD_CODE_FROM_QT4_MAC # include # include @@ -68,9 +71,7 @@ QT_BEGIN_NAMESPACE -#ifdef QT_NO_DOCKWIDGET extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window); -#endif /****************************************************************************** ** debug @@ -164,6 +165,242 @@ QDebug operator<<(QDebug debug, const QMainWindowLayout *layout) #endif // !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_DEBUG) +/****************************************************************************** + ** QDockWidgetGroupWindow + */ +// QDockWidgetGroupWindow is the floating window containing the tabbed dockwidgets in case several +// dockwidgets are dragged together (QMainWindow::GroupedDragging feature). +// QDockWidgetGroupLayout is the layout of that window and use a QDockAreaLayoutInfo to layout +// the tabs inside it. +#ifndef QT_NO_DOCKWIDGET +class QDockWidgetGroupLayout : public QLayout { + QDockAreaLayoutInfo info; + QWidgetResizeHandler *resizer; +public: + QDockWidgetGroupLayout(QWidget* parent) : QLayout(parent) { + setSizeConstraint(QLayout::SetMinAndMaxSize); + resizer = new QWidgetResizeHandler(parent); + resizer->setMovingEnabled(false); + } + ~QDockWidgetGroupLayout() { + info.deleteAllLayoutItems(); + } + + void addItem(QLayoutItem*) Q_DECL_OVERRIDE { Q_UNREACHABLE(); } + int count() const Q_DECL_OVERRIDE { return 0; } + QLayoutItem* itemAt(int index) const Q_DECL_OVERRIDE + { + int x = 0; + return info.itemAt(&x, index); + } + QLayoutItem* takeAt(int index) Q_DECL_OVERRIDE + { + int x = 0; + return info.takeAt(&x, index); + } + QSize sizeHint() const Q_DECL_OVERRIDE + { + int fw = frameWidth(); + return info.sizeHint() + QSize(fw, fw); + } + QSize minimumSize() const Q_DECL_OVERRIDE + { + int fw = frameWidth(); + return info.minimumSize() + QSize(fw, fw); + } + QSize maximumSize() const Q_DECL_OVERRIDE + { + int fw = frameWidth(); + return info.maximumSize() + QSize(fw, fw); + } + void setGeometry(const QRect&r) Q_DECL_OVERRIDE + { + QDockAreaLayoutInfo *li = layoutInfo(); + if (li->isEmpty()) { + static_cast(parent())->destroyIfEmpty(); + return; + } + int fw = frameWidth(); + li->reparentWidgets(parentWidget()); + li->rect = r.adjusted(fw, fw, -fw, -fw); + li->fitItems(); + li->apply(false); + resizer->setActive(QWidgetResizeHandler::Resize, !nativeWindowDeco()); + } + + QDockAreaLayoutInfo *layoutInfo() { + return &info; + } + + bool nativeWindowDeco() const + { + return QDockWidgetLayout::wmSupportsNativeWindowDeco(); + } + + int frameWidth() const + { + return nativeWindowDeco() ? 0 : + parentWidget()->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, parentWidget()); + } +}; + +// This item will be used in the layout for the gap item. We cannot use QWidgetItem directly +// because QWidgetItem functions return an empty size for widgets are are floating. +class QDockWidgetGroupWindowItem : public QWidgetItem +{ +public: + QDockWidgetGroupWindowItem(QDockWidgetGroupWindow *parent) : QWidgetItem(parent) {} + QSize minimumSize() const Q_DECL_OVERRIDE { return lay()->minimumSize(); } + QSize maximumSize() const Q_DECL_OVERRIDE { return lay()->maximumSize(); } + QSize sizeHint() const Q_DECL_OVERRIDE { return lay()->sizeHint(); } + +private: + QLayout *lay() const { return const_cast(this)->widget()->layout(); } +}; + +bool QDockWidgetGroupWindow::event(QEvent *e) +{ + switch (e->type()) { + case QEvent::Close: + // Forward the close to the QDockWidget just as if its close button was pressed + if (QDockWidget *dw = topDockWidget()) { + e->ignore(); + dw->close(); + adjustFlags(); + } + return true; + case QEvent::Move: + // Let QDockWidgetPrivate::moseEvent handle the dragging + if (QDockWidget *dw = topDockWidget()) + static_cast(QObjectPrivate::get(dw))->moveEvent(static_cast(e)); + return true; + case QEvent::NonClientAreaMouseMove: + case QEvent::NonClientAreaMouseButtonPress: + case QEvent::NonClientAreaMouseButtonRelease: + case QEvent::NonClientAreaMouseButtonDblClick: + // Let the QDockWidgetPrivate of the currently visible dock widget handle the drag and drop + if (QDockWidget *dw = topDockWidget()) + static_cast(QObjectPrivate::get(dw))->nonClientAreaMouseEvent(static_cast(e)); + return true; + case QEvent::ChildAdded: + if (qobject_cast(static_cast(e)->child())) + adjustFlags(); + break; + default: + break; + } + return QWidget::event(e); +} + +void QDockWidgetGroupWindow::paintEvent(QPaintEvent *) +{ + QDockWidgetGroupLayout *lay = static_cast(layout()); + bool nativeDeco = lay->nativeWindowDeco(); + + if (!nativeDeco) { + QStyleOptionFrame framOpt; + framOpt.init(this); + QStylePainter p(this); + p.drawPrimitive(QStyle::PE_FrameDockWidget, framOpt); + } +} + +QDockAreaLayoutInfo *QDockWidgetGroupWindow::layoutInfo() const +{ + return static_cast(layout())->layoutInfo(); +} + +/*! \internal + \returns the currently active QDockWidget + */ +QDockWidget *QDockWidgetGroupWindow::topDockWidget() const +{ + QDockAreaLayoutInfo *info = layoutInfo(); + QDockWidget *dw = 0; + if (info->tabBar && info->tabBar->currentIndex() >= 0) { + int i = info->tabIndexToListIndex(info->tabBar->currentIndex()); + if (i >= 0) { + const QDockAreaLayoutItem &item = info->item_list.at(i); + if (item.widgetItem) + dw = qobject_cast(item.widgetItem->widget()); + } + } + if (!dw) { + for (int i = 0; !dw && i < info->item_list.count(); ++i) { + const QDockAreaLayoutItem &item = info->item_list.at(i); + if (item.skip()) + continue; + if (!item.widgetItem) + continue; + dw = qobject_cast(item.widgetItem->widget()); + } + } + return dw; +} + +/*! \internal + Destroy this window if there is no more QDockWidget in it. + */ +void QDockWidgetGroupWindow::destroyIfEmpty() +{ + if (layoutInfo()->isEmpty()) { + // Make sure to reparent the possibly floating or hidden QDockWidgets to the parent + foreach (QDockWidget *dw, + findChildren(QString(), Qt::FindDirectChildrenOnly)) { + bool wasFloating = dw->isFloating(); + bool wasHidden = dw->isHidden(); + dw->setParent(parentWidget()); + if (wasFloating) { + dw->setFloating(true); + } else { + // maybe it was hidden, we still have to put it back in the main layout. + QMainWindowLayout *ml = qt_mainwindow_layout(static_cast(parentWidget())); + Qt::DockWidgetArea area = ml->dockWidgetArea(this); + if (area == Qt::NoDockWidgetArea) + area = Qt::LeftDockWidgetArea; + static_cast(parentWidget())->addDockWidget(area, dw); + } + if (!wasHidden) + dw->show(); + } + foreach (QTabBar *tb, findChildren(QString(), Qt::FindDirectChildrenOnly)) + tb->setParent(parentWidget()); + deleteLater(); + } +} + +/*! \internal + Sets the flags of this window in accordence to the capabilities of the dock widgets + */ +void QDockWidgetGroupWindow::adjustFlags() +{ + QDockWidget *top = topDockWidget(); + if (!top) + return; + const bool nativeDeco = static_cast(layout())->nativeWindowDeco(); + + Qt::WindowFlags oldFlags = windowFlags(); + Qt::WindowFlags flags = oldFlags; + if (nativeDeco) { + flags |= Qt::CustomizeWindowHint | Qt::WindowTitleHint; + if (top->features() & QDockWidget::DockWidgetClosable) + flags |= Qt::WindowCloseButtonHint; + else + flags &= ~Qt::WindowCloseButtonHint; + flags &= ~Qt::FramelessWindowHint; + } else { + flags |= Qt::FramelessWindowHint; + } + if (oldFlags != flags) { + setWindowFlags(flags); + show(); // setWindowFlags hides the window + } + + setWindowTitle(top->windowTitle()); + setWindowIcon(top->windowIcon()); +} +#endif + /****************************************************************************** ** QMainWindowLayoutState */ @@ -335,8 +572,8 @@ QList QMainWindowLayoutState::indexOf(QWidget *widget) const #ifndef QT_NO_DOCKWIDGET // is it a dock widget? - if (QDockWidget *dockWidget = qobject_cast(widget)) { - result = dockAreaLayout.indexOf(dockWidget); + if (qobject_cast(widget) || qobject_cast(widget)) { + result = dockAreaLayout.indexOf(widget); if (!result.isEmpty()) result.prepend(1); return result; @@ -413,7 +650,8 @@ QList QMainWindowLayoutState::gapIndex(QWidget *widget, #ifndef QT_NO_DOCKWIDGET // is it a dock widget? - if (qobject_cast(widget) != 0) { + if (qobject_cast(widget) != 0 + || qobject_cast(widget)) { result = dockAreaLayout.gapIndex(pos); if (!result.isEmpty()) result.prepend(1); @@ -440,7 +678,7 @@ bool QMainWindowLayoutState::insertGap(const QList &path, QLayoutItem *item #ifndef QT_NO_DOCKWIDGET if (i == 1) { - Q_ASSERT(qobject_cast(item->widget()) != 0); + Q_ASSERT(qobject_cast(item->widget()) || qobject_cast(item->widget())); return dockAreaLayout.insertGap(path.mid(1), item); } #endif //QT_NO_DOCKWIDGET @@ -593,6 +831,17 @@ void QMainWindowLayoutState::saveState(QDataStream &stream) const { #ifndef QT_NO_DOCKWIDGET dockAreaLayout.saveState(stream); +#ifndef QT_NO_TABBAR + QList floatingTabs = + mainWindow->findChildren(QString(), Qt::FindDirectChildrenOnly); + + foreach (QDockWidgetGroupWindow *floating, floatingTabs) { + if (floating->layoutInfo()->isEmpty()) + continue; + stream << uchar(QDockAreaLayout::FloatingDockWidgetTabMarker) << floating->geometry(); + floating->layoutInfo()->saveState(stream); + } +#endif #endif #ifndef QT_NO_TOOLBAR toolBarAreaLayout.saveState(stream); @@ -638,12 +887,28 @@ bool QMainWindowLayoutState::checkFormat(QDataStream &stream) case QDockAreaLayout::DockWidgetStateMarker: { QList dockWidgets = findChildrenHelper(mainWindow); + foreach (QDockWidgetGroupWindow *floating, findChildrenHelper(mainWindow)) + dockWidgets += findChildrenHelper(floating); if (!dockAreaLayout.restoreState(stream, dockWidgets, true /*testing*/)) { return false; } } break; -#endif +#ifndef QT_NO_TABBAR + case QDockAreaLayout::FloatingDockWidgetTabMarker: + { + QRect geom; + stream >> geom; + QDockAreaLayoutInfo info; + QList dockWidgets = findChildrenHelper(mainWindow); + foreach (QDockWidgetGroupWindow *floating, findChildrenHelper(mainWindow)) + dockWidgets += findChildrenHelper(floating); + if (!info.restoreState(stream, dockWidgets, true /* testing*/)) + return false; + } + break; +#endif // QT_NO_TABBAR +#endif // QT_NO_DOCKWIDGET default: //there was an error during the parsing return false; @@ -682,6 +947,8 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream, case QDockAreaLayout::DockWidgetStateMarker: { QList dockWidgets = findChildrenHelper(mainWindow); + foreach (QDockWidgetGroupWindow *floating, findChildrenHelper(mainWindow)) + dockWidgets += findChildrenHelper(floating); if (!dockAreaLayout.restoreState(stream, dockWidgets)) return false; @@ -702,6 +969,26 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream, } } break; +#ifndef QT_NO_TABBAR + case QDockAreaLayout::FloatingDockWidgetTabMarker: + { + QList dockWidgets = findChildrenHelper(mainWindow); + foreach (QDockWidgetGroupWindow *floating, findChildrenHelper(mainWindow)) + dockWidgets += findChildrenHelper(floating); + QDockWidgetGroupWindow* floatingTab = qt_mainwindow_layout(mainWindow)->createTabbedDockWindow(); + *floatingTab->layoutInfo() = QDockAreaLayoutInfo(&dockAreaLayout.sep, QInternal::LeftDock, + Qt::Horizontal, QTabBar::RoundedSouth, mainWindow); + QRect geometry; + stream >> geometry; + if (!floatingTab->layoutInfo()->restoreState(stream, dockWidgets, false)) + return false; + geometry = QDockAreaLayout::constrainedRect(geometry, floatingTab); + floatingTab->move(geometry.topLeft()); + floatingTab->resize(geometry.size()); + floatingTab->show(); + } + break; +#endif // QT_NO_TABBAR #endif // QT_NO_DOCKWIDGET #ifndef QT_NO_TOOLBAR @@ -1223,7 +1510,7 @@ void QMainWindowLayout::splitDockWidget(QDockWidget *after, invalidate(); } -Qt::DockWidgetArea QMainWindowLayout::dockWidgetArea(QDockWidget *widget) const +Qt::DockWidgetArea QMainWindowLayout::dockWidgetArea(QWidget *widget) const { QList pathToWidget = layoutState.dockAreaLayout.indexOf(widget); if (pathToWidget.isEmpty()) @@ -1238,20 +1525,88 @@ void QMainWindowLayout::keepSize(QDockWidget *w) #ifndef QT_NO_TABBAR +// Handle custom tooltip, and allow to drag tabs away. class QMainWindowTabBar : public QTabBar { + QMainWindow *mainWindow; + QDockWidget *draggingDock; // Currently dragging (detached) dock widget public: - QMainWindowTabBar(QWidget *parent); + QMainWindowTabBar(QMainWindow *parent); protected: bool event(QEvent *e) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent*) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent*) Q_DECL_OVERRIDE; + }; -QMainWindowTabBar::QMainWindowTabBar(QWidget *parent) - : QTabBar(parent) +QMainWindowTabBar::QMainWindowTabBar(QMainWindow *parent) + : QTabBar(parent), mainWindow(parent), draggingDock(0) { setExpanding(false); } +void QMainWindowTabBar::mouseMoveEvent(QMouseEvent *e) +{ + // The QTabBar handles the moving (reordering) of tabs. + // When QTabBarPrivate::dragInProgress is true, and that the mouse is outside of a region + // around the QTabBar, we will consider the user wants to drag that QDockWidget away from this + // tab area. + + QTabBarPrivate *d = static_cast(d_ptr.data()); + if (!draggingDock && (mainWindow->dockOptions() & QMainWindow::GroupedDragging)) { + int offset = QApplication::startDragDistance() + 1; + offset *= 3; + QRect r = rect().adjusted(-offset, -offset, offset, offset); + if (d->dragInProgress && !r.contains(e->pos()) && d->validIndex(d->pressedIndex)) { + QMainWindowLayout* mlayout = qt_mainwindow_layout(mainWindow); + QDockAreaLayoutInfo *info = mlayout->dockInfo(this); + Q_ASSERT(info); + int idx = info->tabIndexToListIndex(d->pressedIndex); + const QDockAreaLayoutItem &item = info->item_list.at(idx); + if (item.widgetItem + && (draggingDock = qobject_cast(item.widgetItem->widget()))) { + // We should drag this QDockWidget away by unpluging it. + // First cancel the QTabBar's internal move + d->moveTabFinished(d->pressedIndex); + d->pressedIndex = -1; + if (d->movingTab) + d->movingTab->setVisible(false); + d->dragStartPosition = QPoint(); + + // Then starts the drag using QDockWidgetPrivate's API + QDockWidgetPrivate *dockPriv = static_cast(QObjectPrivate::get(draggingDock)); + QDockWidgetLayout *dwlayout = static_cast(draggingDock->layout()); + dockPriv->initDrag(dwlayout->titleArea().center(), true); + dockPriv->startDrag(false); + if (dockPriv->state) + dockPriv->state->ctrlDrag = e->modifiers() & Qt::ControlModifier; + } + } + } + + if (draggingDock) { + QDockWidgetPrivate *dockPriv = static_cast(QObjectPrivate::get(draggingDock)); + if (dockPriv->state && dockPriv->state->dragging) { + QPoint pos = e->globalPos() - dockPriv->state->pressPos; + draggingDock->move(pos); + // move will call QMainWindowLayout::hover + } + } + QTabBar::mouseMoveEvent(e); +} + +void QMainWindowTabBar::mouseReleaseEvent(QMouseEvent *e) +{ + if (draggingDock && e->button() == Qt::LeftButton) { + QDockWidgetPrivate *dockPriv = static_cast(QObjectPrivate::get(draggingDock)); + if (dockPriv->state && dockPriv->state->dragging) { + dockPriv->endDrag(); + } + draggingDock = 0; + } + QTabBar::mouseReleaseEvent(e); +} + bool QMainWindowTabBar::event(QEvent *e) { // show the tooltip if tab is too small to fit label @@ -1276,7 +1631,7 @@ QTabBar *QMainWindowLayout::getTabBar() if (!unusedTabBars.isEmpty()) { result = unusedTabBars.takeLast(); } else { - result = new QMainWindowTabBar(parentWidget()); + result = new QMainWindowTabBar(static_cast(parentWidget())); result->setDrawBase(true); result->setElideMode(Qt::ElideRight); result->setDocumentMode(_documentMode); @@ -1305,12 +1660,30 @@ QWidget *QMainWindowLayout::getSeparatorWidget() return result; } +/*! \internal + Returns a pointer QDockAreaLayoutInfo which contains this \a widget directly + (in its internal list) + */ +QDockAreaLayoutInfo *QMainWindowLayout::dockInfo(QWidget *widget) +{ + QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget); + if (info) + return info; + foreach (QDockWidgetGroupWindow *dwgw, + parent()->findChildren(QString(), Qt::FindDirectChildrenOnly)) { + info = dwgw->layoutInfo()->info(widget); + if (info) + return info; + } + return 0; +} + void QMainWindowLayout::tabChanged() { QTabBar *tb = qobject_cast(sender()); if (tb == 0) return; - QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(tb); + QDockAreaLayoutInfo *info = dockInfo(tb); if (info == 0) return; info->apply(false); @@ -1323,7 +1696,7 @@ void QMainWindowLayout::tabMoved(int from, int to) { QTabBar *tb = qobject_cast(sender()); Q_ASSERT(tb); - QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(tb); + QDockAreaLayoutInfo *info = dockInfo(tb); Q_ASSERT(info); info->moveTab(from, to); @@ -1365,7 +1738,7 @@ bool QMainWindowLayout::endSeparatorMove(const QPoint&) void QMainWindowLayout::raise(QDockWidget *widget) { - QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget); + QDockAreaLayoutInfo *info = dockInfo(widget); if (info == 0) return; #ifndef QT_NO_TABBAR @@ -1549,6 +1922,8 @@ void QMainWindowLayout::revert(QLayoutItem *widgetItem) QWidget *widget = widgetItem->widget(); layoutState = savedState; currentGapPos = layoutState.indexOf(widget); + if (currentGapPos.isEmpty()) + return; fixToolBarOrientation(widgetItem, currentGapPos.at(1)); layoutState.unplug(currentGapPos); layoutState.fitLayout(); @@ -1613,6 +1988,42 @@ void QMainWindowLayout::animationFinished(QWidget *widget) if (widget == pluggingWidget) { #ifndef QT_NO_DOCKWIDGET + if (QDockWidgetGroupWindow *dwgw = qobject_cast(widget)) { + // When the animated widget was a QDockWidgetGroupWindow, it means each of the + // embedded QDockWidget needs to be plugged back into the QMainWindow layout. + savedState.clear(); + QDockAreaLayoutInfo* info = dwgw->layoutInfo(); + QList path = layoutState.dockAreaLayout.indexOf(widget); + Q_ASSERT(path.size() >= 2); + + QDockAreaLayoutInfo* parentInfo = layoutState.dockAreaLayout.info(path); + Q_ASSERT(parentInfo); + if (parentInfo->tabbed) { + // merge the two tab widgets + int idx = path.last(); + Q_ASSERT(parentInfo->item_list[idx].widgetItem->widget() == dwgw); + delete parentInfo->item_list[idx].widgetItem; + parentInfo->item_list.removeAt(idx); + std::copy(info->item_list.cbegin(), info->item_list.cend(), + std::inserter(parentInfo->item_list, parentInfo->item_list.begin() + idx)); + quintptr currentId = info->currentTabId(); + *info = QDockAreaLayoutInfo(); + parentInfo->reparentWidgets(parentWidget()); + parentInfo->updateTabBar(); + parentInfo->setCurrentTabId(currentId); + } else { + QDockAreaLayoutItem &item = layoutState.dockAreaLayout.item(path); + Q_ASSERT(item.widgetItem->widget() == dwgw); + delete item.widgetItem; + item.widgetItem = 0; + item.subinfo = new QDockAreaLayoutInfo(qMove(*info)); + *info = QDockAreaLayoutInfo(); + item.subinfo->reparentWidgets(parentWidget()); + item.subinfo->setTabBarShape(parentInfo->tabBarShape); + } + dwgw->destroyIfEmpty(); + } + if (QDockWidget *dw = qobject_cast(widget)) dw->d_func()->plug(currentGapRect); #endif @@ -1633,7 +2044,7 @@ void QMainWindowLayout::animationFinished(QWidget *widget) if (qobject_cast(widget) != 0) { // info() might return null if the widget is destroyed while // animating but before the animationFinished signal is received. - if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget)) + if (QDockAreaLayoutInfo *info = dockInfo(widget)) info->setCurrentTab(widget); } #endif @@ -1777,8 +2188,33 @@ void QMainWindowLayout::setCentralWidget(QWidget *widget) invalidate(); } -QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) -{ +/*! \internal + Unplug \a widget (QDockWidget or QToolBar) from it's parent container. + + If \a group is true we might actually unplug the group of tabs this + widget is part if QMainWindow::GroupedDragging is set. When \a group + is false, the widget itself is always unplugged alone + + \returns the QLayoutItem of the dragged element. + The layout item is kept in the layout but set as a gap item. + */ +QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group) +{ +#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_TABBAR) + QDockWidgetGroupWindow *floatingParent = qobject_cast(widget->parentWidget()); + if (group && floatingParent && !widget->isWindow()) { + // We are just dragging a floating window as it, not need to do anything, we just have to + // look up the corresponding QWidgetItem* if it exists + QList tabbedWindowPath = layoutState.indexOf(widget->parentWidget()); + return tabbedWindowPath.isEmpty() ? 0 : layoutState.item(tabbedWindowPath); + } else if (floatingParent) { + // We are unplugging a dock widget from a floating window. + if (QDockWidget *dw = qobject_cast(widget)) { + dw->d_func()->unplug(widget->geometry()); + return 0; + } + } +#endif QList path = layoutState.indexOf(widget); if (path.isEmpty()) return 0; @@ -1792,9 +2228,35 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) #ifndef QT_NO_DOCKWIDGET if (QDockWidget *dw = qobject_cast(widget)) { - dw->d_func()->unplug(r); + Q_ASSERT(path.first() == 1); + bool actualGroup = false; +#ifndef QT_NO_TABBAR + if (group && (dockOptions & QMainWindow::GroupedDragging) && path.size() > 3) { + QDockAreaLayoutItem &parentItem = layoutState.dockAreaLayout.item(path.mid(1, path.size() - 2)); + if (parentItem.subinfo && parentItem.subinfo->tabbed) { + // The QDockWidget is part of a group of tab and we need to unplug them all. + actualGroup = true; + path.removeLast(); + + QDockWidgetGroupWindow* floatingTabs = createTabbedDockWindow(); + QDockAreaLayoutInfo* info = floatingTabs->layoutInfo(); + *info = qMove(*parentItem.subinfo); + delete parentItem.subinfo; + parentItem.subinfo = 0; + floatingTabs->setGeometry(info->rect.translated(parentWidget()->pos())); + floatingTabs->show(); + floatingTabs->raise(); + item = new QDockWidgetGroupWindowItem(floatingTabs); + parentItem.widgetItem = item; + savedState = layoutState; + } + } +#endif // QT_NO_TABBAR + if (!actualGroup) { + dw->d_func()->unplug(r); + } } -#endif +#endif // QT_NO_DOCKWIDGET #ifndef QT_NO_TOOLBAR if (QToolBar *tb = qobject_cast(widget)) { tb->d_func()->unplug(r); @@ -1841,6 +2303,9 @@ QList QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse #ifndef QT_NO_DOCKWIDGET if (QDockWidget *dw = qobject_cast(widget)) allowed = dw->isAreaAllowed(toDockWidgetArea(path.at(1))); + + if (qobject_cast(widget)) + allowed = true; #endif #ifndef QT_NO_TOOLBAR if (QToolBar *tb = qobject_cast(widget)) @@ -1893,11 +2358,23 @@ QList QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse return path; } +QDockWidgetGroupWindow *QMainWindowLayout::createTabbedDockWindow() +{ + QDockWidgetGroupWindow* f = new QDockWidgetGroupWindow(parentWidget(), Qt::Tool); + new QDockWidgetGroupLayout(f); + return f; +} + void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animate) { #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR QSet used = newState.dockAreaLayout.usedTabBars(); + foreach (QDockWidgetGroupWindow *dwgw, + parent()->findChildren(QString(), Qt::FindDirectChildrenOnly)) { + used += dwgw->layoutInfo()->usedTabBars(); + } + QSet retired = usedTabBars - used; usedTabBars = used; foreach (QTabBar *tab_bar, retired) { @@ -1916,6 +2393,8 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat } } + for (int i = 0; i < QInternal::DockCount; ++i) + newState.dockAreaLayout.docks[i].reparentWidgets(parentWidget()); #endif // QT_NO_TABBAR #endif // QT_NO_DOCKWIDGET diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h index 8ccb4d303f..9155c5fb23 100644 --- a/src/widgets/widgets/qmainwindowlayout_p.h +++ b/src/widgets/widgets/qmainwindowlayout_p.h @@ -77,6 +77,23 @@ QT_BEGIN_NAMESPACE class QToolBar; class QRubberBand; +#ifndef QT_NO_DOCKWIDGET +class QDockWidgetGroupWindow : public QWidget +{ + Q_OBJECT +public: + explicit QDockWidgetGroupWindow(QWidget* parent = 0, Qt::WindowFlags f = 0) + : QWidget(parent, f) {} + QDockAreaLayoutInfo *layoutInfo() const; + QDockWidget *topDockWidget() const; + void destroyIfEmpty(); + void adjustFlags(); +protected: + bool event(QEvent *) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent*) Q_DECL_OVERRIDE; +}; +#endif + /* This data structure represents the state of all the tool-bars and dock-widgets. It's value based so it can be easilly copied into a temporary variable. All operations are performed without moving any widgets. Only when we are sure we have the desired state, we call apply(), which moves the @@ -196,10 +213,11 @@ public: QDockWidget *dockwidget, Qt::Orientation orientation); void tabifyDockWidget(QDockWidget *first, QDockWidget *second); - Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const; + Qt::DockWidgetArea dockWidgetArea(QWidget* widget) const; void raise(QDockWidget *widget); void setVerticalTabsEnabled(bool enabled); bool restoreDockWidget(QDockWidget *dockwidget); + QDockAreaLayoutInfo *dockInfo(QWidget *w); #ifndef QT_NO_TABBAR bool _documentMode; @@ -224,6 +242,8 @@ public: void setTabShape(QTabWidget::TabShape tabShape); QTabWidget::TabPosition tabPosition(Qt::DockWidgetArea area) const; void setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition); + + QDockWidgetGroupWindow *createTabbedDockWindow(); #endif // QT_NO_TABWIDGET #endif // QT_NO_TABBAR @@ -273,7 +293,7 @@ public: QList hover(QLayoutItem *widgetItem, const QPoint &mousePos); bool plug(QLayoutItem *widgetItem); - QLayoutItem *unplug(QWidget *widget); + QLayoutItem *unplug(QWidget *widget, bool group = false); void revert(QLayoutItem *widgetItem); void updateGapIndicator(); void paintDropIndicator(QPainter *p, QWidget *widget, const QRegion &clip); -- cgit v1.2.3 From 77e00909951f9274bccec20be950425ba9dbe744 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 22 Apr 2015 18:43:33 +0300 Subject: QMouseEvent: add constructor which takes the source as a parameter Simplify the code by passing the source of a mouse event directly to the constructor instead of setting it by QGuiApplicationPrivate::setMouseEventSource(). Change-Id: I1774cf39a211d36d3adf0ff30f3bd2fb7c5fb429 Reviewed-by: Laszlo Agocs --- src/gui/kernel/qevent.cpp | 30 +++++++++++++++++++++++ src/gui/kernel/qevent.h | 3 +++ src/gui/kernel/qguiapplication.cpp | 6 ++--- src/widgets/graphicsview/qgraphicsproxywidget.cpp | 3 +-- src/widgets/itemviews/qabstractitemview.cpp | 3 +-- src/widgets/kernel/qapplication.cpp | 5 ++-- src/widgets/kernel/qwidgetwindow.cpp | 11 ++++----- src/widgets/util/qflickgesture.cpp | 14 +++++------ src/widgets/widgets/qmenu.cpp | 3 +-- 9 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 11f7f13552..006f4d6245 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -262,6 +262,36 @@ QMouseEvent::QMouseEvent(Type type, const QPointF &localPos, const QPointF &wind : QInputEvent(type, modifiers), l(localPos), w(windowPos), s(screenPos), b(button), mouseState(buttons), caps(0) {} +/*! + \since 5.6 + + Constructs a mouse event object. + + The \a type parameter must be QEvent::MouseButtonPress, + QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick, + or QEvent::MouseMove. + + The points \a localPos, \a windowPos and \a screenPos specify the + mouse cursor's position relative to the receiving widget or item, + window, and screen, respectively. + + The \a button that caused the event is given as a value from the + \l Qt::MouseButton enum. If the event \a type is \l MouseMove, + the appropriate button for this event is Qt::NoButton. \a buttons + is the state of all buttons at the time of the event, \a modifiers + is the state of all keyboard modifiers. + + The source of the event is specified by \a source. + +*/ +QMouseEvent::QMouseEvent(QEvent::Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos, + Qt::MouseButton button, Qt::MouseButtons buttons, + Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source) + : QInputEvent(type, modifiers), l(localPos), w(windowPos), s(screenPos), b(button), mouseState(buttons), caps(0) +{ + QGuiApplicationPrivate::setMouseEventSource(this, source); +} + /*! \internal */ diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index e931e28a2e..0cf0601db9 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -106,6 +106,9 @@ public: QMouseEvent(Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers); + QMouseEvent(Type type, const QPointF &localPos, const QPointF &windowPos, const QPointF &screenPos, + Qt::MouseButton button, Qt::MouseButtons buttons, + Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source); ~QMouseEvent(); #ifndef QT_NO_INTEGER_EVENT_COORDINATES diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 926ec16f19..af93a93cfe 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1766,9 +1766,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo if (!window) return; - QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers); + QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers, e->source); ev.setTimestamp(e->timestamp); - setMouseEventSource(&ev, e->source); #ifndef QT_NO_CURSOR if (!e->synthetic()) { if (const QScreen *screen = window->screen()) @@ -1827,9 +1826,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo if (!e->window.isNull() || e->nullWindow()) { // QTBUG-36364, check if window closed in response to press const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick; QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint, - button, buttons, e->modifiers); + button, buttons, e->modifiers, e->source); dblClickEvent.setTimestamp(e->timestamp); - setMouseEventSource(&dblClickEvent, e->source); QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent); } } diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp index db4d18299b..08ea1ea0e3 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp +++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp @@ -269,8 +269,7 @@ void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneMouseEvent // Send mouse event. QMouseEvent mouseEvent(type, pos, receiver->mapTo(receiver->topLevelWidget(), pos.toPoint()), receiver->mapToGlobal(pos.toPoint()), - event->button(), event->buttons(), event->modifiers()); - QGuiApplicationPrivate::setMouseEventSource(&mouseEvent, event->source()); + event->button(), event->buttons(), event->modifiers(), event->source()); QWidget *embeddedMouseGrabberPtr = (QWidget *)embeddedMouseGrabber; QApplicationPrivate::sendMouseEvent(receiver, &mouseEvent, alienWidget, widget, diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 2caf5d1eb3..5b955a6e14 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -1882,8 +1882,7 @@ void QAbstractItemView::mouseDoubleClickEvent(QMouseEvent *event) || (d->pressedIndex != index)) { QMouseEvent me(QEvent::MouseButtonPress, event->localPos(), event->windowPos(), event->screenPos(), - event->button(), event->buttons(), event->modifiers()); - QGuiApplicationPrivate::setMouseEventSource(&me, event->source()); + event->button(), event->buttons(), event->modifiers(), event->source()); mousePressEvent(&me); return; } diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index dd7474b930..401fb47dc8 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3250,12 +3250,11 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QPointer pw = w; while (w) { - QMouseEvent me(mouse->type(), relpos, mouse->windowPos(), mouse->globalPos(), mouse->button(), mouse->buttons(), - mouse->modifiers()); + QMouseEvent me(mouse->type(), relpos, mouse->windowPos(), mouse->globalPos(), + mouse->button(), mouse->buttons(), mouse->modifiers(), mouse->source()); me.spont = mouse->spontaneous(); me.setTimestamp(mouse->timestamp()); QGuiApplicationPrivate::setMouseEventFlags(&me, mouse->flags()); - QGuiApplicationPrivate::setMouseEventSource(&me, mouse->source()); // throw away any mouse-tracking-only mouse events if (!w->hasMouseTracking() && mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) { diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index efe7d9415b..d715438bfe 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -446,8 +446,8 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) if (receiver != popup) widgetPos = receiver->mapFromGlobal(event->globalPos()); QWidget *alien = m_widget->childAt(m_widget->mapFromGlobal(event->globalPos())); - QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers()); - QGuiApplicationPrivate::setMouseEventSource(&e, QGuiApplicationPrivate::mouseEventSource(event)); + QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(), + event->button(), event->buttons(), event->modifiers(), event->source()); e.setTimestamp(event->timestamp()); QApplicationPrivate::sendMouseEvent(receiver, &e, alien, m_widget, &qt_button_down, qt_last_mouse_receiver); qt_last_mouse_receiver = receiver; @@ -489,9 +489,9 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) if (globalGeometry.contains(event->globalPos())) { // Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec() const QPoint localPos = win->mapFromGlobal(event->globalPos()); - QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers()); + QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), + event->button(), event->buttons(), event->modifiers(), event->source()); QCoreApplicationPrivate::setEventSpontaneous(e, true); - QGuiApplicationPrivate::setMouseEventSource(e, QGuiApplicationPrivate::mouseEventSource(event)); e->setTimestamp(event->timestamp()); QCoreApplication::postEvent(win, e); } @@ -548,8 +548,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) // The preceding statement excludes MouseButtonPress events which caused // creation of a MouseButtonDblClick event. QTBUG-25831 QMouseEvent translated(event->type(), mapped, event->windowPos(), event->screenPos(), - event->button(), event->buttons(), event->modifiers()); - QGuiApplicationPrivate::setMouseEventSource(&translated, QGuiApplicationPrivate::mouseEventSource(event)); + event->button(), event->buttons(), event->modifiers(), event->source()); translated.setTimestamp(event->timestamp()); QApplicationPrivate::sendMouseEvent(receiver, &translated, widget, m_widget, &qt_button_down, qt_last_mouse_receiver); diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp index 0e598717c8..8eadc42625 100644 --- a/src/widgets/util/qflickgesture.cpp +++ b/src/widgets/util/qflickgesture.cpp @@ -66,8 +66,8 @@ static QMouseEvent *copyMouseEvent(QEvent *e) case QEvent::MouseButtonRelease: case QEvent::MouseMove: { QMouseEvent *me = static_cast(e); - QMouseEvent *cme = new QMouseEvent(me->type(), QPoint(0, 0), me->windowPos(), me->screenPos(), me->button(), me->buttons(), me->modifiers()); - QGuiApplicationPrivate::setMouseEventSource(cme, me->source()); + QMouseEvent *cme = new QMouseEvent(me->type(), QPoint(0, 0), me->windowPos(), me->screenPos(), + me->button(), me->buttons(), me->modifiers(), me->source()); return cme; } #ifndef QT_NO_GRAPHICSVIEW @@ -78,8 +78,8 @@ static QMouseEvent *copyMouseEvent(QEvent *e) #if 1 QEvent::Type met = me->type() == QEvent::GraphicsSceneMousePress ? QEvent::MouseButtonPress : (me->type() == QEvent::GraphicsSceneMouseRelease ? QEvent::MouseButtonRelease : QEvent::MouseMove); - QMouseEvent *cme = new QMouseEvent(met, QPoint(0, 0), QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers()); - QGuiApplicationPrivate::setMouseEventSource(cme, me->source()); + QMouseEvent *cme = new QMouseEvent(met, QPoint(0, 0), QPoint(0, 0), me->screenPos(), + me->button(), me->buttons(), me->modifiers(), me->source()); return cme; #else QGraphicsSceneMouseEvent *copy = new QGraphicsSceneMouseEvent(me->type()); @@ -240,8 +240,7 @@ public: qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget; QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway, farFarAway, mouseButton, QApplication::mouseButtons() & ~mouseButton, - QApplication::keyboardModifiers()); - QGuiApplicationPrivate::setMouseEventSource(&re, mouseEventSource); + QApplication::keyboardModifiers(), mouseEventSource); sendMouseEvent(&re, RegrabMouseAfterwards); // don't clear the mouseTarget just yet, since we need to explicitly ungrab the mouse on release! } @@ -291,8 +290,7 @@ protected: if (me) { QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()), mouseTarget->topLevelWidget()->mapFromGlobal(me->globalPos()), me->screenPos(), - me->button(), me->buttons(), me->modifiers()); - QGuiApplicationPrivate::setMouseEventSource(©, me->source()); + me->button(), me->buttons(), me->modifiers(), me->source()); qt_sendSpontaneousEvent(mouseTarget, ©); } diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 1749f9d8c7..19f6b78853 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -1110,8 +1110,7 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) handleEnterLeaveEvents(&previousMouseMenu,qobject_cast(caused)); if(e->type() != QEvent::MouseButtonRelease || mouseDown == caused) { QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(), - e->button(), e->buttons(), e->modifiers()); - QGuiApplicationPrivate::setMouseEventSource(&new_e, e->source()); + e->button(), e->buttons(), e->modifiers(), e->source()); QApplication::sendEvent(caused, &new_e); return true; } -- cgit v1.2.3 From 49107dd53bdb35d05db14d99a46e77a963987678 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 8 May 2015 16:41:40 +0200 Subject: cocoa: Do not access the integration instance when shutting down MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-46016 Change-Id: Icb7f0c73d5fe944538e2b9abf50c2532037e932f Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index e817287a46..739a2b105a 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -435,7 +435,9 @@ QCocoaWindow::~QCocoaWindow() // While it is unlikely that this window will be in the popup stack // during deletetion we clear any pointers here to make sure. - QCocoaIntegration::instance()->popupWindowStack()->removeAll(this); + if (QCocoaIntegration::instance()) { + QCocoaIntegration::instance()->popupWindowStack()->removeAll(this); + } foreach (QCocoaWindow *child, m_childWindows) { [m_nsWindow removeChildWindow:child->m_nsWindow]; -- cgit v1.2.3 From 8567cfd9f022dd5971a000c4a38d7a3f7181a96b Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 28 Apr 2015 16:01:36 +0200 Subject: Update PCRE to 8.37 Change-Id: I0668a8ccdebc1a6b5f1cb8bbb74d91b44ac937f8 Reviewed-by: Konstantin Ritt Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/3rdparty/pcre/AUTHORS | 6 +-- src/3rdparty/pcre/LICENCE | 9 +++-- src/3rdparty/pcre/pcre.h | 4 +- src/3rdparty/pcre/pcre_compile.c | 10 +---- src/3rdparty/pcre/pcre_internal.h | 9 ++++- src/3rdparty/pcre/pcre_jit_compile.c | 7 ++++ src/3rdparty/pcre/pcre_study.c | 60 +++++++++++++++++++++++------ src/3rdparty/pcre/sljit/sljitNativeARM_64.c | 37 +++++++++++------- 8 files changed, 97 insertions(+), 45 deletions(-) diff --git a/src/3rdparty/pcre/AUTHORS b/src/3rdparty/pcre/AUTHORS index 5eee1af4c6..d33723f198 100644 --- a/src/3rdparty/pcre/AUTHORS +++ b/src/3rdparty/pcre/AUTHORS @@ -8,7 +8,7 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2014 University of Cambridge +Copyright (c) 1997-2015 University of Cambridge All rights reserved @@ -19,7 +19,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2010-2014 Zoltan Herczeg +Copyright(c) 2010-2015 Zoltan Herczeg All rights reserved. @@ -30,7 +30,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2009-2014 Zoltan Herczeg +Copyright(c) 2009-2015 Zoltan Herczeg All rights reserved. diff --git a/src/3rdparty/pcre/LICENCE b/src/3rdparty/pcre/LICENCE index 602e4ae680..9f6f98e477 100644 --- a/src/3rdparty/pcre/LICENCE +++ b/src/3rdparty/pcre/LICENCE @@ -6,7 +6,8 @@ and semantics are as close as possible to those of the Perl 5 language. Release 8 of PCRE is distributed under the terms of the "BSD" licence, as specified below. The documentation for PCRE, supplied in the "doc" -directory, is distributed under the same terms as the software itself. +directory, is distributed under the same terms as the software itself. The data +in the testdata directory is not copyrighted and is in the public domain. The basic library functions are written in C and are freestanding. Also included in the distribution is a set of C++ wrapper functions, and a @@ -24,7 +25,7 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2014 University of Cambridge +Copyright (c) 1997-2015 University of Cambridge All rights reserved. @@ -35,7 +36,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2010-2014 Zoltan Herczeg +Copyright(c) 2010-2015 Zoltan Herczeg All rights reserved. @@ -46,7 +47,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2009-2014 Zoltan Herczeg +Copyright(c) 2009-2015 Zoltan Herczeg All rights reserved. diff --git a/src/3rdparty/pcre/pcre.h b/src/3rdparty/pcre/pcre.h index 20f04ebed4..58ed46a2a3 100644 --- a/src/3rdparty/pcre/pcre.h +++ b/src/3rdparty/pcre/pcre.h @@ -43,8 +43,8 @@ POSSIBILITY OF SUCH DAMAGE. #define PCRE_MAJOR 8 #define PCRE_MINOR 37 -#define PCRE_PRERELEASE -RC1 -#define PCRE_DATE 2015-02-03 +#define PCRE_PRERELEASE +#define PCRE_DATE 2015-04-28 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate diff --git a/src/3rdparty/pcre/pcre_compile.c b/src/3rdparty/pcre/pcre_compile.c index 6510835c17..0efad2645d 100644 --- a/src/3rdparty/pcre/pcre_compile.c +++ b/src/3rdparty/pcre/pcre_compile.c @@ -866,14 +866,6 @@ static const pcre_uint8 opcode_possessify[] = { }; -/* Structure for mutual recursion detection. */ - -typedef struct recurse_check { - struct recurse_check *prev; - const pcre_uchar *group; -} recurse_check; - - /************************************************* * Find an error text * @@ -5532,13 +5524,13 @@ for (;; ptr++) PUT(previous, 1, (int)(code - previous)); break; /* End of class handling */ } -#endif /* Even though any XCLASS list is now discarded, we must allow for its memory. */ if (lengthptr != NULL) *lengthptr += (int)(class_uchardata - class_uchardata_base); +#endif /* If there are no characters > 255, or they are all to be included or excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the diff --git a/src/3rdparty/pcre/pcre_internal.h b/src/3rdparty/pcre/pcre_internal.h index 1c5f4cefd6..dd0ac7fc91 100644 --- a/src/3rdparty/pcre/pcre_internal.h +++ b/src/3rdparty/pcre/pcre_internal.h @@ -2446,7 +2446,7 @@ typedef struct compile_data { BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ BOOL check_lookbehind; /* Lookbehinds need later checking */ BOOL dupnames; /* Duplicate names exist */ - BOOL iscondassert; /* Next assert is a condition */ + BOOL iscondassert; /* Next assert is a condition */ int nltype; /* Newline type */ int nllen; /* Newline string length */ pcre_uchar nl[4]; /* Newline string when fixed length */ @@ -2460,6 +2460,13 @@ typedef struct branch_chain { pcre_uchar *current_branch; } branch_chain; +/* Structure for mutual recursion detection. */ + +typedef struct recurse_check { + struct recurse_check *prev; + const pcre_uchar *group; +} recurse_check; + /* Structure for items in a linked list that represents an explicit recursive call within the pattern; used by pcre_exec(). */ diff --git a/src/3rdparty/pcre/pcre_jit_compile.c b/src/3rdparty/pcre/pcre_jit_compile.c index dd378e097b..debdf6ef45 100644 --- a/src/3rdparty/pcre/pcre_jit_compile.c +++ b/src/3rdparty/pcre/pcre_jit_compile.c @@ -1533,7 +1533,11 @@ while (cc < ccend) { case OP_KET: if (PRIVATE_DATA(cc) != 0) + { private_data_length++; + SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0); + cc += PRIVATE_DATA(cc + 1); + } cc += 1 + LINK_SIZE; break; @@ -1548,6 +1552,7 @@ while (cc < ccend) case OP_SBRAPOS: case OP_SCOND: private_data_length++; + SLJIT_ASSERT(PRIVATE_DATA(cc) != 0); cc += 1 + LINK_SIZE; break; @@ -1710,6 +1715,8 @@ do { count = 1; srcw[0] = PRIVATE_DATA(cc); + SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0); + cc += PRIVATE_DATA(cc + 1); } cc += 1 + LINK_SIZE; break; diff --git a/src/3rdparty/pcre/pcre_study.c b/src/3rdparty/pcre/pcre_study.c index a2458c4c96..998fe2325e 100644 --- a/src/3rdparty/pcre/pcre_study.c +++ b/src/3rdparty/pcre/pcre_study.c @@ -70,7 +70,7 @@ Arguments: code pointer to start of group (the bracket) startcode pointer to start of the whole pattern's code options the compiling options - int RECURSE depth + recurses chain of recurse_check to catch mutual recursion Returns: the minimum length -1 if \C in UTF-8 mode or (*ACCEPT) was encountered @@ -80,12 +80,13 @@ Returns: the minimum length static int find_minlength(const REAL_PCRE *re, const pcre_uchar *code, - const pcre_uchar *startcode, int options, int recurse_depth) + const pcre_uchar *startcode, int options, recurse_check *recurses) { int length = -1; /* PCRE_UTF16 has the same value as PCRE_UTF8. */ BOOL utf = (options & PCRE_UTF8) != 0; BOOL had_recurse = FALSE; +recurse_check this_recurse; register int branchlength = 0; register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE; @@ -130,7 +131,7 @@ for (;;) case OP_SBRAPOS: case OP_ONCE: case OP_ONCE_NC: - d = find_minlength(re, cc, startcode, options, recurse_depth); + d = find_minlength(re, cc, startcode, options, recurses); if (d < 0) return d; branchlength += d; do cc += GET(cc, 1); while (*cc == OP_ALT); @@ -393,7 +394,7 @@ for (;;) ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(slot, 0)); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); - if ((cc > cs && cc < ce) || recurse_depth > 10) + if (cc > cs && cc < ce) /* Simple recursion */ { d = 0; had_recurse = TRUE; @@ -401,8 +402,22 @@ for (;;) } else { - int dd = find_minlength(re, cs, startcode, options, recurse_depth+1); - if (dd < d) d = dd; + recurse_check *r = recurses; + for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; + if (r != NULL) /* Mutual recursion */ + { + d = 0; + had_recurse = TRUE; + break; + } + else + { + int dd; + this_recurse.prev = recurses; + this_recurse.group = cs; + dd = find_minlength(re, cs, startcode, options, &this_recurse); + if (dd < d) d = dd; + } } slot += re->name_entry_size; } @@ -418,14 +433,26 @@ for (;;) ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1)); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); - if ((cc > cs && cc < ce) || recurse_depth > 10) + if (cc > cs && cc < ce) /* Simple recursion */ { d = 0; had_recurse = TRUE; } else { - d = find_minlength(re, cs, startcode, options, recurse_depth + 1); + recurse_check *r = recurses; + for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; + if (r != NULL) /* Mutual recursion */ + { + d = 0; + had_recurse = TRUE; + } + else + { + this_recurse.prev = recurses; + this_recurse.group = cs; + d = find_minlength(re, cs, startcode, options, &this_recurse); + } } } else d = 0; @@ -474,12 +501,21 @@ for (;;) case OP_RECURSE: cs = ce = (pcre_uchar *)startcode + GET(cc, 1); do ce += GET(ce, 1); while (*ce == OP_ALT); - if ((cc > cs && cc < ce) || recurse_depth > 10) + if (cc > cs && cc < ce) /* Simple recursion */ had_recurse = TRUE; else { - branchlength += find_minlength(re, cs, startcode, options, - recurse_depth + 1); + recurse_check *r = recurses; + for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; + if (r != NULL) /* Mutual recursion */ + had_recurse = TRUE; + else + { + this_recurse.prev = recurses; + this_recurse.group = cs; + branchlength += find_minlength(re, cs, startcode, options, + &this_recurse); + } } cc += 1 + LINK_SIZE; break; @@ -1503,7 +1539,7 @@ if ((re->options & PCRE_ANCHORED) == 0 && /* Find the minimum length of subject string. */ -switch(min = find_minlength(re, code, code, re->options, 0)) +switch(min = find_minlength(re, code, code, re->options, NULL)) { case -2: *errorptr = "internal error: missing capturing bracket"; return NULL; case -3: *errorptr = "internal error: opcode not recognized"; return NULL; diff --git a/src/3rdparty/pcre/sljit/sljitNativeARM_64.c b/src/3rdparty/pcre/sljit/sljitNativeARM_64.c index c5251be53d..b66455f756 100644 --- a/src/3rdparty/pcre/sljit/sljitNativeARM_64.c +++ b/src/3rdparty/pcre/sljit/sljitNativeARM_64.c @@ -1081,12 +1081,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); offs = (local_size - saved_regs_size) << (15 - 3); } else { - compiler->local_size += 2 * sizeof(sljit_sw); - local_size -= saved_regs_size; - saved_regs_size += 2 * sizeof(sljit_sw); - FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) - | RN(TMP_SP) | ((-(saved_regs_size >> 3) & 0x7f) << 15))); - offs = 2 << 15; + offs = 0 << 15; + if (saved_regs_size & 0x8) { + offs = 1 << 15; + saved_regs_size += sizeof(sljit_sw); + } + local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); } tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; @@ -1122,6 +1123,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil } if (local_size) FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); + FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) + | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15))); FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); } @@ -1145,8 +1148,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET; local_size = (local_size + 15) & ~0xf; - if (local_size > (63 * sizeof(sljit_sw))) - local_size += 2 * sizeof(sljit_sw); compiler->local_size = local_size; return SLJIT_SUCCESS; } @@ -1167,16 +1168,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi if (local_size <= (63 * sizeof(sljit_sw))) offs = (local_size - saved_regs_size) << (15 - 3); else { - saved_regs_size += 2 * sizeof(sljit_sw); - local_size -= saved_regs_size; + FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) + | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15))); + offs = 0 << 15; + if (saved_regs_size & 0x8) { + offs = 1 << 15; + saved_regs_size += sizeof(sljit_sw); + } + local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; if (local_size > 0xfff) { FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); local_size &= 0xfff; } if (local_size) FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); - local_size = saved_regs_size; - offs = 2 << 15; } tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; @@ -1204,8 +1209,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi if (prev != -1) FAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(TMP_SP) | (offs >> 5))); - FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) - | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15))); + if (compiler->local_size <= (63 * sizeof(sljit_sw))) { + FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) + | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15))); + } else { + FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); + } FAIL_IF(push_inst(compiler, RET | RN(TMP_LR))); return SLJIT_SUCCESS; -- cgit v1.2.3 From d66de0f51b5df812cc31499250a3c629880302ec Mon Sep 17 00:00:00 2001 From: Kati Kankaanpaa Date: Thu, 7 May 2015 13:56:41 -0700 Subject: Fix compile error in XCB when XInput version < 2.2 Add version guards to prevent compiler error: 'XITouchClass' was not declared in this scope in systems having XInput version < 2.2. Change-Id: Ib1308f29ef97288eb994ab8bdd668199ca2ee1d7 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index d1b3ead11c..2895a2762a 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -175,9 +175,11 @@ void QXcbConnection::xi2SetupDevices() case XIKeyClass: qCDebug(lcQpaXInputDevices) << " it's a keyboard"; break; +#ifdef XCB_USE_XINPUT22 case XITouchClass: // will be handled in deviceForId() break; +#endif default: qCDebug(lcQpaXInputDevices) << " has class" << devices[i].classes[c]->type; break; -- cgit v1.2.3 From 994a7476ef6a6c1dce7a4044a7e64fc1b60846f8 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 1 May 2015 08:14:04 +0400 Subject: [QFontDatabase::findFont] Get rid of the refactoring leftovers The logic this code was aimed for has been covered by a more complete solution in QFontDatabase::load() years ago; simply drop the dead code. Change-Id: Id8860353ff4f4d2f1529aa89810d6c5725e97d24 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 126f0bf3ec..c1c1f04513 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2536,24 +2536,14 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, int index = match(script, request, family_name, foundry_name, &desc, blackListed); if (index >= 0) { engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size); - if (!engine) + if (engine) + initFontDef(desc, request, &engine->fontDef, engine->type() == QFontEngine::Multi); + else blackListed.append(index); } else { FM_DEBUG(" NO MATCH FOUND\n"); } - if (engine && engine->type() != QFontEngine::TestFontEngine) { - initFontDef(desc, request, &engine->fontDef, engine->type() == QFontEngine::Multi); - - if (fp) { - QFontDef def = request; - if (def.family.isEmpty()) { - def.family = fp->request.family; - def.family = def.family.left(def.family.indexOf(QLatin1Char(','))); - } - } - } - if (!engine) { if (!request.family.isEmpty()) { QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint); -- cgit v1.2.3 From c874e10cbcf67fa5fdddafc4dcbf8a54d7f36b2d Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Fri, 1 May 2015 08:18:36 +0400 Subject: Simplify QFontDatabase::findFont() QFontDatabase::load() is the only caller that passes non-null QFontPrivate* to QFontDatabase::findFont(), to adjust the pointSize with regards to the font's dpi; do that right in QFontDatabase::load(). The `multi` param's meaning is, in fact, an absence of the QFont::NoFontMerging flag, so prefer the latter and prevent ambiguity in the future. Change-Id: Icc7751044e454ca438e7627364faa415287bf1ae Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.cpp | 37 ++++++++++++++++++++----------------- src/gui/text/qfontdatabase.h | 2 +- src/gui/text/qfontengine.cpp | 2 +- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index c1c1f04513..d07b1c5628 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -630,6 +630,7 @@ static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDe } else { fontDef->pixelSize = desc.size->pixelSize; } + fontDef->pointSize = request.pointSize; fontDef->styleHint = request.styleHint; fontDef->styleStrategy = request.styleStrategy; @@ -2505,9 +2506,7 @@ bool QFontDatabase::supportsThreadedFontRendering() /*! \internal */ -QFontEngine * -QFontDatabase::findFont(int script, const QFontPrivate *fp, - const QFontDef &request, bool multi) +QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) { QMutexLocker locker(fontDatabaseMutex()); @@ -2515,6 +2514,11 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, initializeDb(); QFontEngine *engine; + + // Until we specifically asked not to, try looking for Multi font engine + // first, the last '1' indicates that we want Multi font engine instead + // of single ones + bool multi = !(request.styleStrategy & QFont::NoFontMerging); QFontCache::Key key(request, script, multi ? 1 : 0); engine = QFontCache::instance()->findEngine(key); if (engine) { @@ -2529,6 +2533,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, if (qt_enable_test_font && request.family == QLatin1String("__Qt__Box__Engine__")) { engine =new QTestFontEngine(request.pixelSize); engine->fontDef = request; + return engine; } QtFontDesc desc; @@ -2537,7 +2542,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, if (index >= 0) { engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size); if (engine) - initFontDef(desc, request, &engine->fontDef, engine->type() == QFontEngine::Multi); + initFontDef(desc, request, &engine->fontDef, multi); else blackListed.append(index); } else { @@ -2573,7 +2578,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, loadDef.family = desc.family->name; engine = loadEngine(script, loadDef, desc.family, desc.foundry, desc.style, desc.size); if (engine) - initFontDef(desc, loadDef, &engine->fontDef, engine->type() == QFontEngine::Multi); + initFontDef(desc, loadDef, &engine->fontDef, multi); else blackListed.append(index); } @@ -2588,12 +2593,6 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, FM_DEBUG("returning box engine"); } - if (fp && fp->dpi > 0) { - engine->fontDef.pointSize = qreal(double((engine->fontDef.pixelSize * 72) / fp->dpi)); - } else { - engine->fontDef.pointSize = request.pointSize; - } - return engine; } @@ -2661,12 +2660,16 @@ void QFontDatabase::load(const QFontPrivate *d, int script) for (; !fe && it != end; ++it) { req.family = *it; - fe = QFontDatabase::findFont(script, d, req, multi); - if (fe && (fe->type()==QFontEngine::Box) && !req.family.isEmpty()) { - if (fe->ref.load() == 0) - delete fe; - - fe = 0; + fe = QFontDatabase::findFont(req, script); + if (fe) { + if (fe->type() == QFontEngine::Box && !req.family.isEmpty()) { + if (fe->ref.load() == 0) + delete fe; + fe = 0; + } else { + if (d->dpi > 0) + fe->fontDef.pointSize = qreal(double((fe->fontDef.pixelSize * 72) / d->dpi)); + } } // No need to check requested fallback families again diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h index 6d738d96be..02bc8e8a08 100644 --- a/src/gui/text/qfontdatabase.h +++ b/src/gui/text/qfontdatabase.h @@ -153,7 +153,7 @@ private: static void createDatabase(); static void parseFontName(const QString &name, QString &foundry, QString &family); static QString resolveFontFamilyAlias(const QString &family); - static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request, bool multi = false); + static QFontEngine *findFont(const QFontDef &request, int script); static void load(const QFontPrivate *d, int script); friend struct QFontDef; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index b028d868b9..87e6c30afe 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1641,7 +1641,7 @@ QFontEngine *QFontEngineMulti::loadEngine(int at) request.styleStrategy |= QFont::NoFontMerging; request.family = fallbackFamilyAt(at - 1); - if (QFontEngine *engine = QFontDatabase::findFont(m_script, /*fontprivate = */0, request, /*multi = */false)) { + if (QFontEngine *engine = QFontDatabase::findFont(request, m_script)) { engine->fontDef = request; return engine; } -- cgit v1.2.3 From 43cab86802fb5a7447e6fd2d451f97a37b53f13c Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 22 Apr 2015 06:27:16 +0400 Subject: Fix overcaching the fallback families list for a requested family The cached list didn't take fontStyle, styleHint and script into account. As long as QFontCache isn't explicitly disabled, loadEngine() rarely called for the same family, foundry, style and size - so avoid caching anything here at all. Change-Id: I7779bf33fc074edc00799f9a39d67327f8c88ccc Reviewed-by: Simon Hausmann --- src/gui/text/qfontdatabase.cpp | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index d07b1c5628..e77856c8d1 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -346,7 +346,6 @@ struct QtFontFamily populated(false), fixedPitch(false), name(n), count(0), foundries(0) - , askedForFallback(false) { memset(writingSystems, 0, sizeof(writingSystems)); } @@ -364,8 +363,6 @@ struct QtFontFamily int count; QtFontFoundry **foundries; - QStringList fallbackFamilies; - bool askedForFallback; unsigned char writingSystems[QFontDatabase::WritingSystemsCount]; bool matchesFamilyName(const QString &familyName) const; @@ -759,6 +756,7 @@ QString qt_resolveFontFamilyAlias(const QString &alias) static QStringList fallbackFamilies(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) { + // make sure that the db has all fallback families QStringList retList = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script); QFontDatabasePrivate *db = privateDb(); @@ -884,20 +882,13 @@ QFontEngine *loadEngine(int script, const QFontDef &request, QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size); Q_ASSERT(!engine || engine->type() != QFontEngine::Multi); if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) { - // make sure that the db has all fallback families - if (family && !family->askedForFallback) { - QFont::Style fontStyle = QFont::Style(style->key.style); - QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint); - if (styleHint == QFont::AnyStyle && request.fixedPitch) - styleHint = QFont::TypeWriter; - family->fallbackFamilies = fallbackFamilies(family->name, fontStyle, styleHint, QChar::Script(script)); + QStringList fallbacks = request.fallBackFamilies; - family->askedForFallback = true; - } + QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint); + if (styleHint == QFont::AnyStyle && request.fixedPitch) + styleHint = QFont::TypeWriter; - QStringList fallbacks = request.fallBackFamilies; - if (family) - fallbacks += family->fallbackFamilies; + fallbacks += fallbackFamilies(family->name, QFont::Style(style->key.style), styleHint, QChar::Script(script)); QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script)); -- cgit v1.2.3 From 237e73df945ad9a82a658647a28706d04b63a6a6 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 6 May 2015 22:24:46 +0400 Subject: Don't assume QLocale::codecForLocale always returns non-null It may return null during program exit, due to QCoreGlobalData global static already having been destroyed, or due to the codec name/mib being unsupported by ICU. If that's the case, QTextStream needs to fall back to Latin 1, like QString::toLocal8Bit and fromLocal8Bit already do. Change-Id: Ia888243669e051e78e0dbe0bb1bc55a1c4f519d8 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qtextstream.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 5fe4cfef9d..47b96d708f 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -464,7 +464,7 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes) } #if defined (QTEXTSTREAM_DEBUG) qDebug("QTextStreamPrivate::fillReadBuffer(), using %s codec", - codec->name().constData()); + codec ? codec->name().constData() : "no"); #endif #endif @@ -476,9 +476,10 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes) int oldReadBufferSize = readBuffer.size(); #ifndef QT_NO_TEXTCODEC // convert to unicode - readBuffer += codec->toUnicode(buf, bytesRead, &readConverterState); + readBuffer += Q_LIKELY(codec) ? codec->toUnicode(buf, bytesRead, &readConverterState) + : QString::fromLatin1(buf, bytesRead); #else - readBuffer += QString::fromLatin1(QByteArray(buf, bytesRead).constData()); + readBuffer += QString::fromLatin1(buf, bytesRead); #endif // reset the Text flag. @@ -564,7 +565,8 @@ void QTextStreamPrivate::flushWriteBuffer() codec = QTextCodec::codecForLocale(); #if defined (QTEXTSTREAM_DEBUG) qDebug("QTextStreamPrivate::flushWriteBuffer(), using %s codec (%s generating BOM)", - codec->name().constData(), writeConverterState.flags & QTextCodec::IgnoreHeader ? "not" : ""); + codec ? codec->name().constData() : "no", + !codec || (writeConverterState.flags & QTextCodec::IgnoreHeader) ? "not" : ""); #endif // convert from unicode to raw data @@ -572,7 +574,7 @@ void QTextStreamPrivate::flushWriteBuffer() QByteArray data = Q_LIKELY(codec) ? codec->fromUnicode(writeBuffer.data(), writeBuffer.size(), &writeConverterState) : writeBuffer.toLatin1(); #else - QByteArray data = writeBuffer.toLocal8Bit(); + QByteArray data = writeBuffer.toLatin1(); #endif writeBuffer.clear(); -- cgit v1.2.3 From 2a2e7ec20aba6064649d25b622ec34df7fb436a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sun, 3 May 2015 20:03:00 +0100 Subject: QQuaternion: Deprecate conjugate() and introduce conjugated() Change-Id: I9aa835138e1e33448fea920f7a5ba99b26a95ebf Reviewed-by: Thiago Macieira Reviewed-by: Konstantin Ritt Reviewed-by: Giuseppe D'Angelo Reviewed-by: Sean Harmer Reviewed-by: Marc Mutz --- src/gui/math3d/qquaternion.cpp | 14 +++++++++++--- src/gui/math3d/qquaternion.h | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 4b35ee4e79..0e73f79ac0 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -301,12 +301,20 @@ void QQuaternion::normalize() */ /*! - \fn QQuaternion QQuaternion::conjugate() const + \fn QQuaternion QQuaternion::conjugated() const + \since 5.5 Returns the conjugate of this quaternion, which is (-x, -y, -z, scalar). */ +/*! + \fn QQuaternion QQuaternion::conjugate() const + \obsolete + + Use conjugated() instead. +*/ + /*! Rotates \a vector with this quaternion to produce a new vector in 3D space. The following code: @@ -318,12 +326,12 @@ void QQuaternion::normalize() is equivalent to the following: \code - QVector3D result = (q * QQuaternion(0, vector) * q.conjugate()).vector(); + QVector3D result = (q * QQuaternion(0, vector) * q.conjugated()).vector(); \endcode */ QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const { - return (*this * QQuaternion(0, vector) * conjugate()).vector(); + return (*this * QQuaternion(0, vector) * conjugated()).vector(); } /*! diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index 95ce5ce6d0..1fbd8b826c 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -88,7 +88,10 @@ public: inline QQuaternion inverted() const; - QQuaternion conjugate() const Q_REQUIRED_RESULT; + QQuaternion conjugated() const Q_REQUIRED_RESULT; +#if QT_DEPRECATED_SINCE(5, 5) + QT_DEPRECATED QQuaternion conjugate() const Q_REQUIRED_RESULT; +#endif QVector3D rotatedVector(const QVector3D& vector) const; @@ -196,11 +199,18 @@ inline QQuaternion QQuaternion::inverted() const return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f); } -inline QQuaternion QQuaternion::conjugate() const +inline QQuaternion QQuaternion::conjugated() const { return QQuaternion(wp, -xp, -yp, -zp); } +#if QT_DEPRECATED_SINCE(5, 5) +inline QQuaternion QQuaternion::conjugate() const +{ + return conjugated(); +} +#endif + inline QQuaternion &QQuaternion::operator+=(const QQuaternion &quaternion) { xp += quaternion.xp; -- cgit v1.2.3 From 894a81a1fbb12fbde923015a517a7fcdcae923b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Tue, 12 May 2015 11:37:17 +0100 Subject: Fix hidden detach The methods are const but the member is mutable. Spotted being detached a few times at app startup. Strings were a few hundred chars big. Change-Id: Iaa3dc42a4f01f819a3fc4f8d756e35d38ce0aa1b Reviewed-by: David Faure --- src/corelib/io/qfilesystementry.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index faaf7a00af..79f16a0839 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -255,15 +255,15 @@ QString QFileSystemEntry::completeSuffix() const bool QFileSystemEntry::isRelative() const { resolveFilePath(); - return (m_filePath.isEmpty() || (!m_filePath.isEmpty() && (m_filePath[0].unicode() != '/') - && (!(m_filePath.length() >= 2 && m_filePath[1].unicode() == ':')))); + return (m_filePath.isEmpty() || (!m_filePath.isEmpty() && (m_filePath.at(0).unicode() != '/') + && (!(m_filePath.length() >= 2 && m_filePath.at(1).unicode() == ':')))); } bool QFileSystemEntry::isAbsolute() const { resolveFilePath(); return (!m_filePath.isEmpty() && ((m_filePath.length() >= 3 - && (m_filePath[0].isLetter() && m_filePath[1].unicode() == ':' && m_filePath[2].unicode() == '/')) + && (m_filePath.at(0).isLetter() && m_filePath.at(1).unicode() == ':' && m_filePath.at(2).unicode() == '/')) || (m_filePath.length() >= 2 && (m_filePath.at(0) == QLatin1Char('/') && m_filePath.at(1) == QLatin1Char('/'))) )); } @@ -276,7 +276,7 @@ bool QFileSystemEntry::isRelative() const bool QFileSystemEntry::isAbsolute() const { resolveFilePath(); - return (!m_filePath.isEmpty() && (m_filePath[0].unicode() == '/')); + return (!m_filePath.isEmpty() && (m_filePath.at(0).unicode() == '/')); } #endif @@ -337,10 +337,10 @@ void QFileSystemEntry::findFileNameSeparators() const int i = m_filePath.size() - 1; for (; i >= stop; --i) { - if (m_filePath[i].unicode() == '.') { + if (m_filePath.at(i).unicode() == '.') { firstDotInFileName = lastDotInFileName = i; break; - } else if (m_filePath[i].unicode() == '/') { + } else if (m_filePath.at(i).unicode() == '/') { lastSeparator = i; break; } @@ -348,9 +348,9 @@ void QFileSystemEntry::findFileNameSeparators() const if (lastSeparator != i) { for (--i; i >= stop; --i) { - if (m_filePath[i].unicode() == '.') + if (m_filePath.at(i).unicode() == '.') firstDotInFileName = i; - else if (m_filePath[i].unicode() == '/') { + else if (m_filePath.at(i).unicode() == '/') { lastSeparator = i; break; } -- cgit v1.2.3 From ce9ad30c78fe0c9ada7cde579f4f9945821f8e5f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 4 May 2015 13:43:02 +0200 Subject: QQuaternion: optimize op* Swap subexpressions around so the expressions involving w (the first member in memory order) execute first. And no, compilers don't do that automatically. Well, GCC 4.9 doesn't. Change-Id: I918ecc27a9ac9775fa91968c0548d182d7ad28e3 Reviewed-by: Sean Harmer --- src/gui/math3d/qquaternion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index 1fbd8b826c..5b0006ac56 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -240,9 +240,9 @@ inline QQuaternion &QQuaternion::operator*=(float factor) inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2) { - float ww = (q1.zp + q1.xp) * (q2.xp + q2.yp); float yy = (q1.wp - q1.yp) * (q2.wp + q2.zp); float zz = (q1.wp + q1.yp) * (q2.wp - q2.zp); + float ww = (q1.zp + q1.xp) * (q2.xp + q2.yp); float xx = ww + yy + zz; float qq = 0.5 * (xx + (q1.zp - q1.xp) * (q2.xp - q2.yp)); -- cgit v1.2.3 From af6c52522b1afc56c5acf30253aaa89ee9c99934 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 12 May 2015 12:05:01 +0200 Subject: Fix MSVC 64 bit compiler warnings in 3rdparty code Make casts from size_t to int explicit to avoid warnings like warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data Change-Id: Ib69c25519dadf8732b0c08412cc97887df00a2d4 Reviewed-by: Konstantin Ritt --- src/3rdparty/harfbuzz/src/harfbuzz-thai.c | 4 ++-- src/3rdparty/md4/md4.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-thai.c b/src/3rdparty/harfbuzz/src/harfbuzz-thai.c index 7438d5994c..2d4627e4f7 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-thai.c +++ b/src/3rdparty/harfbuzz/src/harfbuzz-thai.c @@ -241,7 +241,7 @@ static HB_Bool HB_ThaiConvertStringToGlyphIndices (HB_ShaperItem *item) int lgn = 0; HB_Bool haveSaraAm = false; - cell_length = th_next_cell ((const unsigned char *)cstr + i, len - i, &tis_cell, true); /* !item->fixedPitch); */ + cell_length = (int)(th_next_cell ((const unsigned char *)cstr + i, len - i, &tis_cell, true)); /* !item->fixedPitch); */ haveSaraAm = (cstr[i + cell_length - 1] == (char)0xd3); /* set shaper item's log_clusters */ @@ -432,7 +432,7 @@ static void HB_ThaiAssignAttributes(const HB_UChar16 *string, hb_uint32 len, HB_ /* manage grapheme boundaries */ i = 0; while (i < len) { - cell_length = th_next_cell((const unsigned char *)cstr + i, len - i, &tis_cell, true); + cell_length = (hb_uint32)(th_next_cell((const unsigned char *)cstr + i, len - i, &tis_cell, true)); attributes[i].graphemeBoundary = true; for (j = 1; j < cell_length; j++) diff --git a/src/3rdparty/md4/md4.cpp b/src/3rdparty/md4/md4.cpp index 94ac6adf58..ec74958d69 100644 --- a/src/3rdparty/md4/md4.cpp +++ b/src/3rdparty/md4/md4.cpp @@ -180,7 +180,7 @@ static void md4_update(struct md4_context *ctx, const unsigned char *data, size_ saved_lo = ctx->lo; if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) ctx->hi++; - ctx->hi += size >> 29; + ctx->hi += (quint32)(size >> 29); used = saved_lo & 0x3f; -- cgit v1.2.3 From 3eca75de67b3fd2c890715b30c7899cebc096fe9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 11 May 2015 18:30:00 +0900 Subject: Make qglobal.h complain if you use -fPIE Prior to Qt 5.4.2 (commit 36d6eb721e7d5997ade75e289d4088dc48678d0d), we allowed it, but now we need to enforce that it is not used. Note that -fPIE does define __PIC__, so we need this to catch the use of -fPIE. [ChangeLog][Important Behavior Changes] On x86 and x86-64 systems with ELF binaries (especially Linux), due to a new optimization in GCC 5.x in combination with a recent version of GNU binutils, compiling Qt applications with -fPIE is no longer enough. Applications now need to be compiled with the -fPIC option if Qt's option "reduce relocations" is active. Note that Clang is known to generate incompatible code even with -fPIC if the -flto option is active. Task-number: QTBUG-45755 Change-Id: I66a35ce5f88941f29aa6ffff13dd210e0aa2728f Reviewed-by: Dmitry Shachnev Reviewed-by: Simon Hausmann --- dist/changes-5.4.2 | 7 +++++++ src/corelib/global/qglobal.h | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/dist/changes-5.4.2 b/dist/changes-5.4.2 index e1ad9b6846..5827187e9e 100644 --- a/dist/changes-5.4.2 +++ b/dist/changes-5.4.2 @@ -34,6 +34,13 @@ information about a particular change. common EXIF-format (big-endian) was not working until 5.4.1. 5.4.2 restores the behavior of 5.4.0 and earlier for most EXIF-tagged JPEGs. EXIF orientation will be an opt-in starting with Qt 5.5. +- On x86 and x86-64 systems with ELF binaries (especially Linux), due to + a new optimization in GCC 5.x in combination with a recent version of + GNU binutils, compiling Qt applications with -fPIE is no longer + enough. Applications now need to be compiled with the -fPIC option if + Qt's option "reduce relocations" is active. Note that Clang is known + to generate incompatible code even with -fPIC if the -flto option is + active. **************************************************************************** * Library * diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index ef84662036..4547877da6 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1047,9 +1047,9 @@ Q_CORE_EXPORT int qrand(); # define QT_NO_SHAREDMEMORY #endif -#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) +#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && (!defined(__PIC__) || defined(__PIE__)) # error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ - "Compile your code with -fPIC." + "Compile your code with -fPIC (-fPIE is not enough)." #endif namespace QtPrivate { -- cgit v1.2.3 From 6e18f57a9c6810115ad7fba133bd53e7d460a265 Mon Sep 17 00:00:00 2001 From: Adam Strzelecki Date: Thu, 7 Aug 2014 13:04:48 +0200 Subject: Build Qt for OS X and iOS with relative rpath. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Defaulting to absolute_library_soname on configure -rpath is no longer necessary as now we support @rpath install name ids on OS X and iOS. This also sets QMAKE_SONAME_PREFIX to @rpath for Qt modules when built with rpath configuration. This makes Qt libraries relocatable on OS X. Qt SDK is not yet relocatable though, because plugin locations (including cocoa plugin) are still resolved using absolute path (see QTBUG-14150). Also, there are several absolute paths hardcoded in qmake mkspecs pri files. Task-number: QTBUG-31814 Change-Id: I36b9384cd69ac609608acbe2b3d5e0512317e0d6 Reviewed-by: Tor Arne Vestbø --- configure | 6 +----- mkspecs/features/qt_build_config.prf | 6 ------ mkspecs/features/qt_module.prf | 3 +++ 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/configure b/configure index 8116d731e2..4a8ef14ccf 100755 --- a/configure +++ b/configure @@ -6205,11 +6205,7 @@ fi [ '!' -z "$INCLUDES" ] && QMakeVar add INCLUDEPATH "$INCLUDES" [ '!' -z "$L_FLAGS" ] && QMakeVar add LIBS "$L_FLAGS" -if [ "$XPLATFORM_MAC" = "yes" ] && [ "$QT_CROSS_COMPILE" = "no" ]; then - if [ "$CFG_RPATH" = "yes" ]; then - QMAKE_CONFIG="$QMAKE_CONFIG absolute_library_soname" - fi -elif [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then +if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then if [ -n "$RPATH_FLAGS" ]; then echo echo "ERROR: -R cannot be used on this platform as \$QMAKE_LFLAGS_RPATH is" diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf index 42046c238a..7197f84c9a 100644 --- a/mkspecs/features/qt_build_config.prf +++ b/mkspecs/features/qt_build_config.prf @@ -52,12 +52,6 @@ QMAKE_DIR_REPLACE_SANE = PRECOMPILED_DIR OBJECTS_DIR MOC_DIR RCC_DIR UI_DIR unset(modpath) } -mac { - !isEmpty(QMAKE_RPATHDIR){ - CONFIG += absolute_library_soname - } -} - cross_compile: \ CONFIG += force_bootstrap diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index bfa17807aa..5412f3778a 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -132,6 +132,9 @@ mac { QMAKE_CFLAGS += -fconstant-cfstrings QMAKE_CXXFLAGS += -fconstant-cfstrings } + + contains(QT_CONFIG, rpath): \ + QMAKE_SONAME_PREFIX = @rpath } DEFINES += QT_BUILDING_QT -- cgit v1.2.3 From c8db55970fecd5ee934c81bad12268c1760bfda7 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 12 May 2015 09:37:52 +0300 Subject: Consider "assets" scheme as a local file on Android Task-number: QTBUG-46010 Change-Id: Icb6c5c2529b77e3967f6d23217e63e7773a5d706 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/io/qfileselector.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp index 4ca07ba41d..cddd70f908 100644 --- a/src/corelib/io/qfileselector.cpp +++ b/src/corelib/io/qfileselector.cpp @@ -225,9 +225,13 @@ QString QFileSelector::select(const QString &filePath) const return d->select(filePath); } -static QString qrcScheme() +static bool isLocalScheme(const QString &file) { - return QStringLiteral("qrc"); + bool local = file == QStringLiteral("qrc"); +#ifdef Q_OS_ANDROID + local |= file == QStringLiteral("assets"); +#endif + return local; } /*! @@ -240,10 +244,10 @@ static QString qrcScheme() QUrl QFileSelector::select(const QUrl &filePath) const { Q_D(const QFileSelector); - if (filePath.scheme() != qrcScheme() && !filePath.isLocalFile()) + if (!isLocalScheme(filePath.scheme()) && !filePath.isLocalFile()) return filePath; QUrl ret(filePath); - if (filePath.scheme() == qrcScheme()) { + if (isLocalScheme(filePath.scheme())) { QString equivalentPath = QLatin1Char(':') + filePath.path(); QString selectedPath = d->select(equivalentPath); ret.setPath(selectedPath.remove(0, 1)); -- cgit v1.2.3 From ec93ea4a6fcf0fb4db1c0526bdfef6edace99b13 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 13 May 2015 00:27:08 +0200 Subject: Fix building tst_QPluginLoader on OS X, non-devel builds QMachOParser is defined in the private header that only gets included in developer-builds. Thus ifdef its usage out, not just the header inclusion. Change-Id: I1e0059787be6eb70bd1661c7814e69eee7c5b2ee Reviewed-by: Simon Hausmann --- tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp index cd77b188cc..72bd38d116 100644 --- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp @@ -312,7 +312,7 @@ void tst_QPluginLoader::loadCorruptElf() void tst_QPluginLoader::loadMachO_data() { -#ifdef Q_OF_MACH_O +#if defined(QT_BUILD_INTERNAL) && defined(Q_OF_MACH_O) QTest::addColumn("parseResult"); QTest::newRow("/dev/null") << int(QMachOParser::NotSuitable); @@ -348,7 +348,7 @@ void tst_QPluginLoader::loadMachO_data() void tst_QPluginLoader::loadMachO() { -#ifdef Q_OF_MACH_O +#if defined(QT_BUILD_INTERNAL) && defined(Q_OF_MACH_O) QFile f(QFINDTESTDATA(QTest::currentDataTag())); QVERIFY(f.open(QIODevice::ReadOnly)); QByteArray data = f.readAll(); -- cgit v1.2.3 From fd9a51bf56e05212371888ab83d8acb2ecbf68f8 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Mon, 11 May 2015 11:01:53 +0200 Subject: Build qtconnectivity for iOS. Starting with Qt 5.5 qtconnectivity on iOS is supported Change-Id: I30430ce351b7e2fc8031c5719bed5354ed234cc7 Task-number: QTBUG-45988 Reviewed-by: Timur Pocheptsov --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 4a8ef14ccf..dddb40f485 100755 --- a/configure +++ b/configure @@ -3306,7 +3306,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then CFG_RPATH="no" CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples" CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store - CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtmacextras qtserialport qtwebkit qtwebkit-examples" + CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtdoc qtmacextras qtserialport qtwebkit qtwebkit-examples" CFG_PRECOMPILE="no" # Precompiled headers not supported with multiple -arch arguments # If the user passes -sdk on the command line we build a SDK-specific Qt build. -- cgit v1.2.3 From 5a3251a0324d65d688c3702a327d7a71a0de5ab9 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 22 Apr 2015 15:43:50 +0200 Subject: Doc: fix QSystemSemaphore example acquire() doesn't take arguments. Change-Id: I16f0169c40433cc3cbfcb577bd8386d217cccb12 Task-number: QTBUG-40055 Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- .../doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp index bc03770f16..9cded446d1 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp @@ -51,8 +51,9 @@ sem.release(2); // resources available == 3 //! [1] QSystemSemaphore sem("market", 5, QSystemSemaphore::Create); -sem.acquire(5); // acquire all 5 resources -sem.release(5); // release the 5 resources +for (int i = 0; i < 5; ++i) // acquire all 5 resources + sem.acquire(); +sem.release(5); // release the 5 resources //! [1] -- cgit v1.2.3 From 2023b9e76baf8d8a3b1ea59748624e16f3297ac3 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 22 Apr 2015 14:18:20 +0200 Subject: Doc: clarify ownership after QStackedWidget::removeWidget Change-Id: Ia14b72cdac3205a3896c47ecc81b31adb508181b Task-number: QTBUG-44891 Reviewed-by: Leena Miettinen --- src/widgets/widgets/qstackedwidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qstackedwidget.cpp b/src/widgets/widgets/qstackedwidget.cpp index fd1bf57321..411651f480 100644 --- a/src/widgets/widgets/qstackedwidget.cpp +++ b/src/widgets/widgets/qstackedwidget.cpp @@ -182,7 +182,9 @@ int QStackedWidget::insertWidget(int index, QWidget *widget) not deleted but simply removed from the stacked layout, causing it to be hidden. - \b{Note:} Ownership of \a widget reverts to the application. + \note Parent object and parent widget of \a widget will remain the + QStackedWidget. If the application wants to reuse the removed + \a widget, then it is recommended to re-parent it. \sa addWidget(), insertWidget(), currentWidget() */ -- cgit v1.2.3 From d14397b7298879e260bc7218a5f7539b6b94a2cf Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 12 May 2015 17:11:00 +0200 Subject: Windows: Fix exit crash of GUI applications when deleting argv[]. When passing Qt arguments followed by normal arguments, a double deletion may occur due to Qt shifting argv. For example: argv[] = app -qwindowgeometry +50+50 some_arg becomes: argv[] = app some_arg some_arg Terminate deletion when encountering the null pointer. Change-Id: I5279955b6bd463f5858d6e5e8e16a1f5d0945652 Reviewed-by: Joerg Bornemann --- src/winmain/qtmain_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/winmain/qtmain_win.cpp b/src/winmain/qtmain_win.cpp index 25b79543ba..459ca114a6 100644 --- a/src/winmain/qtmain_win.cpp +++ b/src/winmain/qtmain_win.cpp @@ -111,7 +111,7 @@ extern "C" int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR /*cmdParamarg*/, int argv[argc] = Q_NULLPTR; LocalFree(argvW); const int exitCode = main(argc, argv); - for (int i = 0; i < argc; ++i) + for (int i = 0; i < argc && argv[i]; ++i) delete [] argv[i]; delete [] argv; return exitCode; -- cgit v1.2.3 From cf5e55707365ce0da33a2602191cb0f95bd12eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 13 May 2015 10:18:44 +0200 Subject: Remove init() function declaration. Fix doc error. This function is not used in Qt 5 and there is no definition for it. Change-Id: Id7e4fe1ada54005f65a559ae1ab393d011c37480 Reviewed-by: Timur Pocheptsov --- src/widgets/widgets/qmacnativewidget_mac.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/widgets/widgets/qmacnativewidget_mac.h b/src/widgets/widgets/qmacnativewidget_mac.h index b27d877e8f..761e55656b 100644 --- a/src/widgets/widgets/qmacnativewidget_mac.h +++ b/src/widgets/widgets/qmacnativewidget_mac.h @@ -52,7 +52,6 @@ public: NSView *nativeView() const; protected: - void init(NSView *parentView); bool event(QEvent *ev); private: -- cgit v1.2.3 From 2ca1253b13e77643b3d2dd993a038ae2df882311 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 8 Apr 2015 14:46:32 +0200 Subject: Cocoa: Upgrade default surface format to include an alpha channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default surface format on OS X is changed to RGBA since this is most performant. You can request a different surface format to change this. You can not request the default format without alpha channel, though. Change-Id: I4f44d0abe01515c98ba699c76a0dd5e37b873766 Reviewed-by: Laszlo Agocs Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 739a2b105a..3db3fc3547 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -451,7 +451,13 @@ QCocoaWindow::~QCocoaWindow() QSurfaceFormat QCocoaWindow::format() const { - return window()->requestedFormat(); + QSurfaceFormat format = window()->requestedFormat(); + + // Upgrade the default surface format to include an alpha channel. The default RGB format + // causes Cocoa to spend an unreasonable amount of time converting it to RGBA internally. + if (format == QSurfaceFormat()) + format.setAlphaBufferSize(8); + return format; } void QCocoaWindow::setGeometry(const QRect &rectIn) -- cgit v1.2.3 From 50c41bc8efb52b2b3f2aad66d79167320e9b2b31 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 24 Nov 2014 14:53:05 +0100 Subject: Doc: corrected autolink issues statemachine.qdoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-40362 Change-Id: Ia686ebdfd722f448aa30fb1f1f266b6148df4026 Reviewed-by: Topi Reiniö --- src/corelib/doc/src/statemachine.qdoc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/corelib/doc/src/statemachine.qdoc b/src/corelib/doc/src/statemachine.qdoc index 846eb7d1f0..4b50174b88 100644 --- a/src/corelib/doc/src/statemachine.qdoc +++ b/src/corelib/doc/src/statemachine.qdoc @@ -63,7 +63,7 @@ used to effectively embed the elements and semantics of statecharts in Qt applications. The framework integrates tightly with Qt's meta-object system; for example, transitions between states can be triggered by signals, and - states can be configured to set properties and invoke methods on QObjects. + states can be configured to set properties and invoke methods on {QObject}s. Qt's event system is used to drive the state machines. The state graph in the State Machine framework is hierarchical. States can be nested inside of @@ -126,9 +126,9 @@ The QState::entered() signal is emitted when the state is entered, and the QState::exited() signal is emitted when the state is exited. In the - following snippet, the button's showMaximized() slot will be called when - state \c s3 is entered, and the button's showMinimized() slot will be called - when \c s3 is exited: + following snippet, the button's \l {QPushButton::}{showMaximized()} slot + will be called when state \c s3 is entered, and the button's \l {QPushButton::}{showMinimized()} + slot will be called when \c s3 is exited: \snippet statemachine/main.cpp 5 @@ -151,7 +151,7 @@ Assume we wanted the user to be able to quit the application at any time by clicking a Quit button. In order to achieve this, we need to create a final state and make it the target of a transition associated with the Quit - button's clicked() signal. We could add a transition from each of \c s1, \c + button's \l{QPushButton::}{clicked()} signal. We could add a transition from each of \c s1, \c s2 and \c s3; however, this seems redundant, and one would also have to remember to add such a transition from every new state that is added in the future. @@ -184,8 +184,8 @@ \snippet statemachine/main2.cpp 1 In this case we want the application to quit when the state machine is - finished, so the machine's finished() signal is connected to the - application's quit() slot. + finished, so the machine's \l {QStateMachine::}{finished()} signal is connected to the + application's \l {QCoreApplication::}{quit()} slot. A child state can override an inherited transition. For example, the following code adds a transition that effectively causes the Quit button to @@ -290,7 +290,7 @@ \endomit When \c s1 's final state is entered, \c s1 will automatically emit - finished(). We use a signal transition to cause this event to trigger a + \l {QState::}{finished()}. We use a signal transition to cause this event to trigger a state change: \snippet statemachine/main3.cpp 1 @@ -302,7 +302,7 @@ encapsulation mechanism when building complex (deeply nested) state machines. (In the above example, you could of course create a transition directly from \c s1 's \c done state rather than relying on \c s1 's - finished() signal, but with the consequence that implementation details of + \l {QState::}{finished()} signal, but with the consequence that implementation details of \c s1 are exposed and depended on). For parallel state groups, the QState::finished() signal is emitted when \e @@ -365,8 +365,8 @@ \snippet statemachine/main4.cpp 1 - In the eventTest() reimplementation, we first check if the event type is the - desired one; if so, we cast the event to a StringEvent and perform the + In the \l {QAbstractTransition::}{eventTest()} reimplementation, we first check if the event type is the + desired one; if so, we cast the event to a \c StringEvent and perform the string comparison. The following is a statechart that uses the custom event and transition: @@ -486,7 +486,7 @@ message box will pop up before the geometry of the button has actually been set. To ensure that the message box does not pop up until the geometry actually reaches its final - value, we can use the state's propertiesAssigned() signal. The propertiesAssigned() signal will be + value, we can use the state's \l {QState::}{propertiesAssigned()} signal. The \l {QState::}{propertiesAssigned()} signal will be emitted when the property is assigned its final value, whether this is done immediately or after the animation has finished playing. @@ -503,14 +503,14 @@ has been assigned the defined value. If the global restore policy is set to QStateMachine::RestoreProperties, the state will not emit - the propertiesAssigned() signal until these have been executed as well. + the \l {QState::}{propertiesAssigned()} signal until these have been executed as well. \section1 What Happens If A State Is Exited Before The Animation Has Finished If a state has property assignments, and the transition into the state has animations for the properties, the state can potentially be exited before the properties have been assigned to the values defines by the state. This is true in particular when there are transitions out from the - state that do not depend on the propertiesAssigned signal, as described in the previous section. + state that do not depend on the \l {QState::}{propertiesAssigned()} signal, as described in the previous section. The State Machine API guarantees that a property assigned by the state machine either: \list @@ -563,13 +563,13 @@ The parent state machine treats the child machine as an \e atomic state in the state machine algorithm. The child state machine is self-contained; it maintains its own event queue and - configuration. In particular, note that the \l{QStateMachine::configuration()}{configuration} + configuration. In particular, note that the \l{QStateMachine::}{configuration()} of the child machine is not part of the parent machine's configuration (only the child machine itself is). States of the child state machine cannot be specified as targets of transitions in the parent state machine; only the child state machine itself can. Conversely, states of the parent state machine cannot be specified as targets of transitions in the child state machine. The child - state machine's \l{QState::finished()}{finished}() signal can be used to trigger a transition + state machine's \l{QState::}{finished}() signal can be used to trigger a transition in the parent machine. */ -- cgit v1.2.3 From 21e6c7ae4745a76b676dfaa9fe17a2dd40fc0c5c Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 24 Apr 2015 16:48:14 +0200 Subject: Cocoa integration - implement Qt::WindowModal file dialogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, for Qt::WindowModal dialogs we were creating modal sheet with beginSheetModalForWindow: and later (from exec) calling -runModal, essentially making a window modal dialog into (now) application modal sheet, which is not right- it's centered relative to desktop and the jump from window modal sheet's position (centered relative to a window) to application modal was quite visible. Now, instead of [panel runModal] (== [NSApp runModalForWindow:panel]) we call [NSApp runModalForWindow:theRequiredWindow]. Change-Id: I793dc72c7d1fe96497bb35754f4d0eac9a5e00e5 Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qplatformdialoghelper.cpp | 6 +++++ src/gui/kernel/qplatformdialoghelper.h | 1 + .../platforms/cocoa/qcocoafiledialoghelper.h | 1 + .../platforms/cocoa/qcocoafiledialoghelper.mm | 28 ++++++++++++++++------ src/widgets/dialogs/qdialog.cpp | 5 +++- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp index 3d37088182..3d7c2f7bf0 100644 --- a/src/gui/kernel/qplatformdialoghelper.cpp +++ b/src/gui/kernel/qplatformdialoghelper.cpp @@ -137,6 +137,12 @@ QVariant QPlatformDialogHelper::defaultStyleHint(QPlatformDialogHelper::StyleHi return QVariant(); } +void QPlatformDialogHelper::execModalForWindow(QWindow *parent) +{ + Q_UNUSED(parent); + exec(); +} + // Font dialog class QFontDialogOptionsPrivate : public QSharedData diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h index 8b2b9881b7..6d3a367e60 100644 --- a/src/gui/kernel/qplatformdialoghelper.h +++ b/src/gui/kernel/qplatformdialoghelper.h @@ -145,6 +145,7 @@ public: virtual QVariant styleHint(StyleHint hint) const; virtual void exec() = 0; + virtual void execModalForWindow(QWindow *parent); virtual bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) = 0; diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h index 48d7efe174..36943a563e 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h @@ -51,6 +51,7 @@ public: virtual ~QCocoaFileDialogHelper(); void exec(); + void execModalForWindow(QWindow *parent); bool defaultNameFilterDisables() const; diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 4ece1b5a22..19f81c72a1 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -254,17 +254,22 @@ static QString strippedText(QString s) || [self panel:nil shouldShowFilename:filepath]; [self updateProperties]; - QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder(); [mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]]; [mSavePanel setNameFieldStringValue:selectable ? QCFString::toNSString(info.fileName()) : @""]; NSWindow *nsparent = static_cast(qGuiApp->platformNativeInterface()->nativeResourceForWindow("nswindow", parent)); + qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); + QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder(); + [mSavePanel beginSheetModalForWindow:nsparent completionHandler:^(NSInteger result){ - mReturnCode = result; - if (mHelper) - mHelper->QNSOpenSavePanelDelegate_panelClosed(result == NSOKButton); + [[NSApplication sharedApplication] stopModalWithCode:result]; }]; + + mReturnCode = [[NSApplication sharedApplication] runModalForWindow:nsparent]; + QAbstractEventDispatcher::instance()->interrupt(); + if (mHelper) + mHelper->QNSOpenSavePanelDelegate_panelClosed(mReturnCode == NSOKButton); } - (BOOL)isHiddenFile:(NSString *)filename isDir:(BOOL)isDir @@ -706,14 +711,15 @@ void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate() bool QCocoaFileDialogHelper::showCocoaFilePanel(Qt::WindowModality windowModality, QWindow *parent) { + Q_UNUSED(parent) + createNSOpenSavePanelDelegate(); if (!mDelegate) return false; if (windowModality == Qt::NonModal) [mDelegate showModelessPanel]; - else if (windowModality == Qt::WindowModal && parent) - [mDelegate showWindowModalSheet:parent]; - // no need to show a Qt::ApplicationModal dialog here, since it will be done in _q_platformRunNativeAppModalPanel() + // no need to show a Qt::ApplicationModal dialog here, since it will be done in exec; + // Qt::WindowModal will be done in execModalForWindow. return true; } @@ -745,6 +751,14 @@ void QCocoaFileDialogHelper::exec() } +void QCocoaFileDialogHelper::execModalForWindow(QWindow *parent) +{ + if (!parent) + return exec(); + + [mDelegate showWindowModalSheet:parent]; +} + bool QCocoaFileDialogHelper::defaultNameFilterDisables() const { return true; diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 65def6d4b8..6676a3ccba 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -534,7 +534,10 @@ int QDialog::exec() QPointer guard = this; if (d->nativeDialogInUse) { - d->platformHelper()->exec(); + if (windowModality() == Qt::WindowModal) + d->platformHelper()->execModalForWindow(d->parentWindow()); + else + d->platformHelper()->exec(); } else { QEventLoop eventLoop; d->eventLoop = &eventLoop; -- cgit v1.2.3 From 78a10908211ed604c0f7c7b6bbc6dcace4f01bd0 Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Wed, 29 Apr 2015 10:05:09 +0200 Subject: Tests: Remove tst_QHostInfo::abortHostLookupInDifferentThread() test This test has been initially blacklisted. However it is racy by design and cannot be fixed. Removing it. Change-Id: I6c386a12e54d8a382f17c4fc033428f56eb03f02 Task-number: QTBUG-23837 Reviewed-by: Thiago Macieira Reviewed-by: Frederik Gladhorn --- tests/auto/network/kernel/qhostinfo/BLACKLIST | 3 --- .../auto/network/kernel/qhostinfo/tst_qhostinfo.cpp | 21 --------------------- 2 files changed, 24 deletions(-) delete mode 100644 tests/auto/network/kernel/qhostinfo/BLACKLIST diff --git a/tests/auto/network/kernel/qhostinfo/BLACKLIST b/tests/auto/network/kernel/qhostinfo/BLACKLIST deleted file mode 100644 index ea4b64d7c2..0000000000 --- a/tests/auto/network/kernel/qhostinfo/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -# QTBUG-23837 -[abortHostLookupInDifferentThread] -opensuse-13.1 64bit diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp index 9762e8244c..599e475beb 100644 --- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp @@ -126,7 +126,6 @@ private slots: void cache(); void abortHostLookup(); - void abortHostLookupInDifferentThread(); protected slots: void resultsReady(const QHostInfo &); @@ -621,25 +620,5 @@ public: int id; }; -void tst_QHostInfo::abortHostLookupInDifferentThread() -{ - //reset counter - lookupsDoneCounter = 0; - bool valid = false; - int id = -1; - QHostInfo result = qt_qhostinfo_lookup("a-single" TEST_DOMAIN, this, SLOT(resultsReady(QHostInfo)), &valid, &id); - QVERIFY(!valid); - QThread thread; - LookupAborter aborter; - aborter.id = id; - aborter.moveToThread(&thread); - connect(&thread, SIGNAL(started()), &aborter, SLOT(abort())); - //it is assumed that the DNS request/response in the backend is slower than it takes to schedule the thread and call abort - thread.start(); - QVERIFY(thread.wait(5000)); - QTestEventLoop::instance().enterLoop(5); - QCOMPARE(lookupsDoneCounter, 0); -} - QTEST_MAIN(tst_QHostInfo) #include "tst_qhostinfo.moc" -- cgit v1.2.3 From 6c20a01cb9032a6abc0b82549a4242e2441894f7 Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Wed, 15 Apr 2015 13:26:55 +0200 Subject: QSysInfo: Expand Linux distribution detection Expand Linux distribution detection to /etc/redhat-release and /etc/debian_version to follow what /usr/bin/lsb_release script does. If /usr/bin/lsb_release fails to extract the distribution information from /etc/lsb-release, it then checks /etc/redhat-release and, as a last fallback, /etc/debian_version. Some Red Hat distributions have a /etc/lsb-release file that does not provide the values we are looking for (DISTRIB_ID, DISTRIB_RELEASE and DISTRIB_DESCRIPTION). If both productType or productVersion are empty after reading /etc/lsb-release, readEtcLsbRelease() will return false, allowing further parsing of /etc/redhat-release. This scenario mimics what the /usr/bin/lsb_release script does if /etc/lsb-release does not contains enough information. The productType and productVersion returned by QSysInfo after reading /etc/redhat-release match the distributor id and release information returned by the /usr/bin/lsb_release script. For Debian Linux distributions where /etc/os-release, /etc/lsb-release and /etc/redhat-release are not available nor usable, the /usr/bin/lsb_release script also checks for the /etc/debian_version file. In this case, we also enable parsing of /etc/debian_version to retrieve a fallback productVersion, the productType being set to Debian. Change-Id: Ia20d513d78be8a8ee8c0410d0aaa052fde81a41d Reviewed-by: Oswald Buddenhagen --- src/corelib/global/qglobal.cpp | 86 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index eb8dd73727..d6f5162648 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2120,9 +2120,9 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion() # define USE_ETC_OS_RELEASE struct QUnixOSVersion { - // from /etc/os-release older /etc/lsb-release - QString productType; // $ID $DISTRIB_ID - QString productVersion; // $VERSION_ID $DISTRIB_RELEASE + // from /etc/os-release older /etc/lsb-release // redhat /etc/redhat-release // debian /etc/debian_version + QString productType; // $ID $DISTRIB_ID // single line file containing: // Debian + QString productVersion; // $VERSION_ID $DISTRIB_RELEASE // // single line file QString prettyName; // $PRETTY_NAME $DISTRIB_DESCRIPTION }; @@ -2134,24 +2134,32 @@ static QString unquote(const char *begin, const char *end) } return QString::fromLatin1(begin, end - begin); } - -static bool readEtcFile(QUnixOSVersion &v, const char *filename, - const QByteArray &idKey, const QByteArray &versionKey, const QByteArray &prettyNameKey) +static QByteArray getEtcFileContent(const char *filename) { // we're avoiding QFile here int fd = qt_safe_open(filename, O_RDONLY); if (fd == -1) - return false; + return QByteArray(); QT_STATBUF sbuf; if (QT_FSTAT(fd, &sbuf) == -1) { qt_safe_close(fd); - return false; + return QByteArray(); } QByteArray buffer(sbuf.st_size, Qt::Uninitialized); buffer.resize(qt_safe_read(fd, buffer.data(), sbuf.st_size)); qt_safe_close(fd); + return buffer; +} + +static bool readEtcFile(QUnixOSVersion &v, const char *filename, + const QByteArray &idKey, const QByteArray &versionKey, const QByteArray &prettyNameKey) +{ + + QByteArray buffer = getEtcFileContent(filename); + if (buffer.isEmpty()) + return false; const char *ptr = buffer.constData(); const char *end = buffer.constEnd(); @@ -2215,14 +2223,72 @@ static bool readEtcLsbRelease(QUnixOSVersion &v) } } - return ok; + // some distributions have a /etc/lsb-release file that does not provide the values + // we are looking for, i.e. DISTRIB_ID, DISTRIB_RELEASE and DISTRIB_DESCRIPTION. + // Assuming that neither DISTRIB_ID nor DISTRIB_RELEASE were found, or contained valid values, + // returning false for readEtcLsbRelease will allow further /etc/-release parsing. + return ok && !(v.productType.isEmpty() && v.productVersion.isEmpty()); } +#if defined(Q_OS_LINUX) +static QByteArray getEtcFileFirstLine(const char *fileName) +{ + QByteArray buffer = getEtcFileContent(fileName); + if (buffer.isEmpty()) + return QByteArray(); + + const char *ptr = buffer.constData(); + int eol = buffer.indexOf("\n"); + return QByteArray(ptr, eol).trimmed(); +} + +static bool readEtcRedHatRelease(QUnixOSVersion &v) +{ + // /etc/redhat-release analysed should be a one line file + // the format of its content is + // i.e. "Red Hat Enterprise Linux Workstation release 6.5 (Santiago)" + QByteArray line = getEtcFileFirstLine("/etc/redhat-release"); + if (line.isEmpty()) + return false; + + v.prettyName = QString::fromLatin1(line); + + const char keyword[] = "release "; + int releaseIndex = line.indexOf(keyword); + v.productType = QString::fromLatin1(line.mid(0, releaseIndex)).remove(QLatin1Char(' ')); + int spaceIndex = line.indexOf(' ', releaseIndex + strlen(keyword)); + v.productVersion = QString::fromLatin1(line.mid(releaseIndex + strlen(keyword), spaceIndex > -1 ? spaceIndex - releaseIndex - strlen(keyword) : -1)); + return true; +} + +static bool readEtcDebianVersion(QUnixOSVersion &v) +{ + // /etc/debian_version analysed should be a one line file + // the format of its content is + // i.e. "jessie/sid" + QByteArray line = getEtcFileFirstLine("/etc/debian_version"); + if (line.isEmpty()) + return false; + + v.productType = QStringLiteral("Debian"); + v.productVersion = QString::fromLatin1(line); + return true; +} +#endif + static bool findUnixOsVersion(QUnixOSVersion &v) { if (readEtcOsRelease(v)) return true; - return readEtcLsbRelease(v); + if (readEtcLsbRelease(v)) + return true; +#if defined(Q_OS_LINUX) + if (readEtcRedHatRelease(v)) + return true; + if (readEtcDebianVersion(v)) + return true; +#endif + return false; } # endif // USE_ETC_OS_RELEASE #endif // Q_OS_UNIX -- cgit v1.2.3 From 406934a6323d37d879fa1ce4894a62635c2ec834 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 12 May 2015 14:50:42 +0200 Subject: Purge default locations from commonly used device makespecs Including /usr/include and lib can cause cryptic failures if there is already a Qt installed to /usr. Having standard locations listed should not be necessary at all. Change-Id: I08a15a064cc1aec126733f7e1962a2fa2ec38fcb Reviewed-by: Oswald Buddenhagen Reviewed-by: Andy Nichols --- mkspecs/devices/linux-beagleboard-g++/qmake.conf | 4 ++-- mkspecs/devices/linux-imx53qsb-g++/qmake.conf | 5 ----- mkspecs/devices/linux-imx6-g++/qmake.conf | 5 ----- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/mkspecs/devices/linux-beagleboard-g++/qmake.conf b/mkspecs/devices/linux-beagleboard-g++/qmake.conf index 3b9ca66306..1d32d374c6 100644 --- a/mkspecs/devices/linux-beagleboard-g++/qmake.conf +++ b/mkspecs/devices/linux-beagleboard-g++/qmake.conf @@ -36,8 +36,8 @@ QMAKE_CXXFLAGS_RELEASE += -O3 QMAKE_LIBS += -lrt -lpthread -ldl # Extra stuff (OpenGL, DirectFB, ...) -QMAKE_INCDIR_EGL = $$[QT_SYSROOT]/usr/include -QMAKE_LIBDIR_EGL = $$[QT_SYSROOT]/usr/lib +QMAKE_INCDIR_EGL = +QMAKE_LIBDIR_EGL = QMAKE_INCDIR_OPENGL_ES2 = $${QMAKE_INCDIR_EGL} QMAKE_LIBDIR_OPENGL_ES2 = $${QMAKE_LIBDIR_EGL} QMAKE_INCDIR_OPENVG = $${QMAKE_INCDIR_EGL} diff --git a/mkspecs/devices/linux-imx53qsb-g++/qmake.conf b/mkspecs/devices/linux-imx53qsb-g++/qmake.conf index 937bbf2416..39462d83d9 100644 --- a/mkspecs/devices/linux-imx53qsb-g++/qmake.conf +++ b/mkspecs/devices/linux-imx53qsb-g++/qmake.conf @@ -16,15 +16,10 @@ include(../common/linux_device_pre.conf) -QMAKE_INCDIR += $$[QT_SYSROOT]/usr/include -QMAKE_LIBDIR += $$[QT_SYSROOT]/usr/lib - QMAKE_LIBS_EGL += -lEGL QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lEGL QMAKE_LIBS_OPENVG += -lOpenVG -lEGL -QMAKE_LFLAGS += -Wl,-rpath-link,$$[QT_SYSROOT]/usr/lib - IMX5_CFLAGS = -march=armv7-a -mfpu=neon -DLINUX=1 -DEGL_API_FB=1 -Wno-psabi QMAKE_CFLAGS += $$IMX5_CFLAGS QMAKE_CXXFLAGS += $$IMX5_CFLAGS diff --git a/mkspecs/devices/linux-imx6-g++/qmake.conf b/mkspecs/devices/linux-imx6-g++/qmake.conf index 1646c5fe77..71e37845c3 100644 --- a/mkspecs/devices/linux-imx6-g++/qmake.conf +++ b/mkspecs/devices/linux-imx6-g++/qmake.conf @@ -4,15 +4,10 @@ include(../common/linux_device_pre.conf) -QMAKE_INCDIR += $$[QT_SYSROOT]/usr/include -QMAKE_LIBDIR += $$[QT_SYSROOT]/usr/lib - QMAKE_LIBS_EGL += -lEGL QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lEGL -lGAL QMAKE_LIBS_OPENVG += -lOpenVG -lEGL -lGAL -QMAKE_LFLAGS += -Wl,-rpath-link,$$[QT_SYSROOT]/usr/lib - IMX6_CFLAGS = -march=armv7-a -mfpu=neon -DLINUX=1 -DEGL_API_FB=1 QMAKE_CFLAGS += $$IMX6_CFLAGS QMAKE_CXXFLAGS += $$IMX6_CFLAGS -- cgit v1.2.3 From 7ffcf328c75ddfc93e45d35eef549adb474cbda1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 11 May 2015 21:56:57 +0200 Subject: Remove QNSView from superview in ~QCocoaWindow() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A QNSView without a corresponding live QCocoaWindow object is not in a valid state. Previously we would call removeFromSuperview for child QWindows to avoid having Cocoa send messages to the now invalid QNSView. Do this for QWindows embedded in native Cocoa hierarchies as well. Change-Id: I49c6daef8ed061b3f40138fe9b4ce6be190f2fd0 Reviewed-by: Tor Arne Vestbø Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoawindow.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 3db3fc3547..cbe4227b63 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -415,7 +415,7 @@ QCocoaWindow::~QCocoaWindow() if (m_isNSWindowChild) { if (m_parentCocoaWindow) m_parentCocoaWindow->removeChildWindow(this); - } else if (parent()) { + } else if ([m_contentView superview]) { [m_contentView removeFromSuperview]; } -- cgit v1.2.3 From a4d66348d64368bfae10662a1f11a4e40eca8ae2 Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Tue, 12 May 2015 14:59:02 +0200 Subject: Doc: Added the Qt Multimedia backends wiki link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The wiki will be linked to from the Qt Multimedia index page. Change-Id: I2b60c203f759494cdf12021659847817007639f1 Task-number: QTBUG-30381 Reviewed-by: Leena Miettinen Reviewed-by: Yoann Lopes Reviewed-by: Topi Reiniö --- doc/global/externalsites/qt-webpages.qdoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/global/externalsites/qt-webpages.qdoc b/doc/global/externalsites/qt-webpages.qdoc index 057f0259e9..386573e526 100644 --- a/doc/global/externalsites/qt-webpages.qdoc +++ b/doc/global/externalsites/qt-webpages.qdoc @@ -110,3 +110,7 @@ \externalpage http://wiki.qt.io/BlackBerry \title Qt for BlackBerry */ +/*! + \externalpage http://wiki.qt.io/Qt_Multimedia_Backends + \title Qt Multimedia Backends +*/ -- cgit v1.2.3 From d6efc6b543d1a8fe2e1232750a98e396db07be0f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 11 May 2015 12:52:34 +0200 Subject: moc: Fix type for gadget's CreateInstance metacall An error similar to the one below would be emitted by the compiler on the moc generated file: error: assigning to 'QObject *' from incompatible type 'Gadget *' if (_a[0]) *reinterpret_cast(_a[0]) = _r; } break; Change-Id: I75ae7bd6c46d20db2d47a80eaa08aae302d7d6c8 Reviewed-by: Simon Hausmann Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/tools/moc/generator.cpp | 3 ++- tests/auto/tools/moc/tst_moc.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 8b6a0519c5..3b00e21208 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -1125,7 +1125,8 @@ void Generator::generateStaticMetacall() fprintf(out, "%s", QByteArray("QPrivateSignal()").constData()); } fprintf(out, ");\n"); - fprintf(out, " if (_a[0]) *reinterpret_cast(_a[0]) = _r; } break;\n"); + fprintf(out, " if (_a[0]) *reinterpret_cast<%s**>(_a[0]) = _r; } break;\n", + cdef->hasQGadget ? "void" : "QObject"); } fprintf(out, " default: break;\n"); fprintf(out, " }\n"); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 405d273f4b..7fa5de3377 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -87,6 +87,16 @@ struct QTBUG_31218_Derived : QTBUG_31218<-1<0> {}; class QTBUG_45790 : Bug() { }; #endif +class CreatableGadget +{ + Q_GADGET + Q_PROPERTY(int a MEMBER a) +public: + Q_INVOKABLE CreatableGadget() : a(0xdeadbeef) { } + + int a; +}; + struct MyStruct {}; struct MyStruct2 {}; -- cgit v1.2.3 From 629f5a46d531886cebe654a4ddb9269b62874e6a Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 11 May 2015 13:11:59 +0200 Subject: moc: Generate qt_static_metacall for creatable-only gadgets Prior to this, moc would not generate the function unless the gadget class had a property or a non-constructor invokable. Change-Id: Ic020ea5f8f59702f5e9e194a46e26850e53e5cfe Reviewed-by: Simon Hausmann Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/tools/moc/generator.cpp | 3 ++- tests/auto/tools/moc/tst_moc.cpp | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 3b00e21208..5be58d3c4b 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -448,7 +448,8 @@ void Generator::generateCode() // Generate internal qt_static_metacall() function // const bool hasStaticMetaCall = !isQt && - (cdef->hasQObject || !cdef->methodList.isEmpty() || !cdef->propertyList.isEmpty()); + (cdef->hasQObject || !cdef->methodList.isEmpty() + || !cdef->propertyList.isEmpty() || !cdef->constructorList.isEmpty()); if (hasStaticMetaCall) generateStaticMetacall(); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 7fa5de3377..8bef678af9 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -90,13 +90,15 @@ struct QTBUG_31218_Derived : QTBUG_31218<-1<0> {}; class CreatableGadget { Q_GADGET - Q_PROPERTY(int a MEMBER a) public: - Q_INVOKABLE CreatableGadget() : a(0xdeadbeef) { } - - int a; + Q_INVOKABLE CreatableGadget() + { + CreatableGadget::qt_static_metacall((QObject*)this, QMetaObject::ReadProperty, -1, Q_NULLPTR); + } }; +CreatableGadget creatableGadget; // Force the compiler to use the constructor + struct MyStruct {}; struct MyStruct2 {}; -- cgit v1.2.3 From 4201d85cdece4715080861357c04da6e0cf8cf46 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 11 May 2015 10:16:32 +0200 Subject: QPA plugins: Use _iid macros instead of strings in Q_PLUGIN_METADATA. This makes it easier to change the version numbers by changing the macros in QtGui. Task-number: QTBUG-46009 Change-Id: I94c9591ec6f7c9173a698df9e1fe8fd6a904caf4 Reviewed-by: Paul Olav Tvete --- src/plugins/generic/evdevkeyboard/main.cpp | 2 +- src/plugins/generic/evdevmouse/main.cpp | 2 +- src/plugins/generic/evdevtablet/main.cpp | 2 +- src/plugins/generic/evdevtouch/main.cpp | 2 +- src/plugins/generic/libinput/main.cpp | 2 +- src/plugins/generic/tslib/main.cpp | 2 +- src/plugins/generic/tuiotouch/main.cpp | 2 +- .../platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp | 2 +- src/plugins/platforminputcontexts/ibus/main.cpp | 2 +- src/plugins/platforms/android/androidplatformplugin.cpp | 2 +- src/plugins/platforms/cocoa/main.mm | 2 +- src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp | 2 +- src/plugins/platforms/directfb/main.cpp | 2 +- src/plugins/platforms/eglfs/qeglfsmain.cpp | 2 +- src/plugins/platforms/haiku/main.h | 2 +- src/plugins/platforms/ios/plugin.mm | 2 +- src/plugins/platforms/kms/main.cpp | 2 +- src/plugins/platforms/linuxfb/main.cpp | 2 +- src/plugins/platforms/minimal/main.cpp | 2 +- src/plugins/platforms/minimalegl/main.cpp | 2 +- src/plugins/platforms/offscreen/main.cpp | 2 +- src/plugins/platforms/openwfd/main.cpp | 2 +- src/plugins/platforms/qnx/main.h | 2 +- src/plugins/platforms/windows/main.cpp | 2 +- src/plugins/platforms/winrt/main.cpp | 2 +- src/plugins/platforms/xcb/qxcbmain.cpp | 2 +- src/plugins/platformthemes/gtk2/main.cpp | 2 +- src/plugins/printsupport/cocoa/main.cpp | 2 +- src/plugins/printsupport/cups/main.cpp | 2 +- src/plugins/printsupport/windows/main.cpp | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/plugins/generic/evdevkeyboard/main.cpp b/src/plugins/generic/evdevkeyboard/main.cpp index ceb8f4f792..444c9f1559 100644 --- a/src/plugins/generic/evdevkeyboard/main.cpp +++ b/src/plugins/generic/evdevkeyboard/main.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QEvdevKeyboardPlugin : public QGenericPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "evdevkeyboard.json") + Q_PLUGIN_METADATA(IID QGenericPluginFactoryInterface_iid FILE "evdevkeyboard.json") public: QEvdevKeyboardPlugin(); diff --git a/src/plugins/generic/evdevmouse/main.cpp b/src/plugins/generic/evdevmouse/main.cpp index 7e9932ceb9..f39f92cfd2 100644 --- a/src/plugins/generic/evdevmouse/main.cpp +++ b/src/plugins/generic/evdevmouse/main.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QEvdevMousePlugin : public QGenericPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "evdevmouse.json") + Q_PLUGIN_METADATA(IID QGenericPluginFactoryInterface_iid FILE "evdevmouse.json") public: QEvdevMousePlugin(); diff --git a/src/plugins/generic/evdevtablet/main.cpp b/src/plugins/generic/evdevtablet/main.cpp index 7d62e1a2bc..62524e8f33 100644 --- a/src/plugins/generic/evdevtablet/main.cpp +++ b/src/plugins/generic/evdevtablet/main.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QEvdevTabletPlugin : public QGenericPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "evdevtablet.json") + Q_PLUGIN_METADATA(IID QGenericPluginFactoryInterface_iid FILE "evdevtablet.json") public: QEvdevTabletPlugin(); diff --git a/src/plugins/generic/evdevtouch/main.cpp b/src/plugins/generic/evdevtouch/main.cpp index ef6774b0a0..bb78dd6e84 100644 --- a/src/plugins/generic/evdevtouch/main.cpp +++ b/src/plugins/generic/evdevtouch/main.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QEvdevTouchScreenPlugin : public QGenericPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "evdevtouch.json") + Q_PLUGIN_METADATA(IID QGenericPluginFactoryInterface_iid FILE "evdevtouch.json") public: QEvdevTouchScreenPlugin(); diff --git a/src/plugins/generic/libinput/main.cpp b/src/plugins/generic/libinput/main.cpp index 2adc0c747b..9459ca3621 100644 --- a/src/plugins/generic/libinput/main.cpp +++ b/src/plugins/generic/libinput/main.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QLibInputPlugin : public QGenericPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "libinput.json") + Q_PLUGIN_METADATA(IID QGenericPluginFactoryInterface_iid FILE "libinput.json") public: QObject *create(const QString &key, const QString &specification); diff --git a/src/plugins/generic/tslib/main.cpp b/src/plugins/generic/tslib/main.cpp index 36f1ac7c3c..9459e85544 100644 --- a/src/plugins/generic/tslib/main.cpp +++ b/src/plugins/generic/tslib/main.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QTsLibPlugin : public QGenericPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "tslib.json") + Q_PLUGIN_METADATA(IID QGenericPluginFactoryInterface_iid FILE "tslib.json") public: QObject* create(const QString &key, const QString &specification); diff --git a/src/plugins/generic/tuiotouch/main.cpp b/src/plugins/generic/tuiotouch/main.cpp index e1d08f0e26..35e74e32bd 100644 --- a/src/plugins/generic/tuiotouch/main.cpp +++ b/src/plugins/generic/tuiotouch/main.cpp @@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE class QTuioTouchPlugin : public QGenericPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "tuiotouch.json") + Q_PLUGIN_METADATA(IID QGenericPluginFactoryInterface_iid FILE "tuiotouch.json") public: QTuioTouchPlugin(); diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp index 5ab0dd8f04..96f6424ba2 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp @@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE class QComposePlatformInputContextPlugin : public QPlatformInputContextPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface" FILE "compose.json") + Q_PLUGIN_METADATA(IID QPlatformInputContextFactoryInterface_iid FILE "compose.json") public: QComposeInputContext *create(const QString &, const QStringList &) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforminputcontexts/ibus/main.cpp b/src/plugins/platforminputcontexts/ibus/main.cpp index b621bec1ee..1b1a3be2c4 100644 --- a/src/plugins/platforminputcontexts/ibus/main.cpp +++ b/src/plugins/platforminputcontexts/ibus/main.cpp @@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE class QIbusPlatformInputContextPlugin : public QPlatformInputContextPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface" FILE "ibus.json") + Q_PLUGIN_METADATA(IID QPlatformInputContextFactoryInterface_iid FILE "ibus.json") public: QIBusPlatformInputContext *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/android/androidplatformplugin.cpp b/src/plugins/platforms/android/androidplatformplugin.cpp index ea7a3c397a..245691e79f 100644 --- a/src/plugins/platforms/android/androidplatformplugin.cpp +++ b/src/plugins/platforms/android/androidplatformplugin.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QAndroidPlatformIntegrationPlugin: public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "android.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "android.json") public: QPlatformIntegration *create(const QString &key, const QStringList ¶mList); }; diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm index eed2ad7dc5..b7e8fa1fca 100644 --- a/src/plugins/platforms/cocoa/main.mm +++ b/src/plugins/platforms/cocoa/main.mm @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE class QCocoaIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "cocoa.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "cocoa.json") public: QPlatformIntegration *create(const QString&, const QStringList&); }; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp index ab4be67bbe..e4cc163b9e 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp @@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE class QWindowsDirect2DIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "direct2d.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "direct2d.json") public: QPlatformIntegration *create(const QString&, const QStringList&); }; diff --git a/src/plugins/platforms/directfb/main.cpp b/src/plugins/platforms/directfb/main.cpp index 3faa7c9a8b..4308a164ae 100644 --- a/src/plugins/platforms/directfb/main.cpp +++ b/src/plugins/platforms/directfb/main.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE class QDirectFbIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "directfb.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "directfb.json") public: QPlatformIntegration *create(const QString&, const QStringList&); }; diff --git a/src/plugins/platforms/eglfs/qeglfsmain.cpp b/src/plugins/platforms/eglfs/qeglfsmain.cpp index 4aae7118ac..89b2f20569 100644 --- a/src/plugins/platforms/eglfs/qeglfsmain.cpp +++ b/src/plugins/platforms/eglfs/qeglfsmain.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QEglFSIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "eglfs.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "eglfs.json") public: QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; }; diff --git a/src/plugins/platforms/haiku/main.h b/src/plugins/platforms/haiku/main.h index fbf0bee527..9889109c7e 100644 --- a/src/plugins/platforms/haiku/main.h +++ b/src/plugins/platforms/haiku/main.h @@ -38,7 +38,7 @@ QT_BEGIN_NAMESPACE class QHaikuIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "haiku.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "haiku.json") public: QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/ios/plugin.mm b/src/plugins/platforms/ios/plugin.mm index 41fe712f60..e68e1dfd6f 100644 --- a/src/plugins/platforms/ios/plugin.mm +++ b/src/plugins/platforms/ios/plugin.mm @@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE class QIOSIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "ios.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "ios.json") public: QPlatformIntegration *create(const QString&, const QStringList&); }; diff --git a/src/plugins/platforms/kms/main.cpp b/src/plugins/platforms/kms/main.cpp index 8683a9c8d1..565ac7a7d4 100644 --- a/src/plugins/platforms/kms/main.cpp +++ b/src/plugins/platforms/kms/main.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QKmsIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "kms.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "kms.json") public: QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; }; diff --git a/src/plugins/platforms/linuxfb/main.cpp b/src/plugins/platforms/linuxfb/main.cpp index 046ee913d8..ba70984073 100644 --- a/src/plugins/platforms/linuxfb/main.cpp +++ b/src/plugins/platforms/linuxfb/main.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QLinuxFbIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "linuxfb.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "linuxfb.json") public: QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; }; diff --git a/src/plugins/platforms/minimal/main.cpp b/src/plugins/platforms/minimal/main.cpp index 4c746a85f2..98babf6876 100644 --- a/src/plugins/platforms/minimal/main.cpp +++ b/src/plugins/platforms/minimal/main.cpp @@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE class QMinimalIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "minimal.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "minimal.json") public: QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; }; diff --git a/src/plugins/platforms/minimalegl/main.cpp b/src/plugins/platforms/minimalegl/main.cpp index 7ee14ae5ff..52ab3ad689 100644 --- a/src/plugins/platforms/minimalegl/main.cpp +++ b/src/plugins/platforms/minimalegl/main.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QMinimalEglIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "minimalegl.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "minimalegl.json") public: QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; }; diff --git a/src/plugins/platforms/offscreen/main.cpp b/src/plugins/platforms/offscreen/main.cpp index 64a0586036..363f2afcc3 100644 --- a/src/plugins/platforms/offscreen/main.cpp +++ b/src/plugins/platforms/offscreen/main.cpp @@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE class QOffscreenIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "offscreen.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "offscreen.json") public: QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE; }; diff --git a/src/plugins/platforms/openwfd/main.cpp b/src/plugins/platforms/openwfd/main.cpp index d28ab945fa..b0403bc533 100644 --- a/src/plugins/platforms/openwfd/main.cpp +++ b/src/plugins/platforms/openwfd/main.cpp @@ -38,7 +38,7 @@ QT_BEGIN_NAMESPACE class QOpenWFDIntegrationPlugin : public QPlatformIntegrationPlugin { - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid) public: QPlatformIntegration *create(const QString&, const QStringList&); }; diff --git a/src/plugins/platforms/qnx/main.h b/src/plugins/platforms/qnx/main.h index 5e69ee3889..955bef471c 100644 --- a/src/plugins/platforms/qnx/main.h +++ b/src/plugins/platforms/qnx/main.h @@ -38,7 +38,7 @@ QT_BEGIN_NAMESPACE class QQnxIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "qnx.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "qnx.json") public: QPlatformIntegration *create(const QString&, const QStringList&); }; diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp index 5bdcbef01e..29bb9562e3 100644 --- a/src/plugins/platforms/windows/main.cpp +++ b/src/plugins/platforms/windows/main.cpp @@ -97,7 +97,7 @@ QT_BEGIN_NAMESPACE class QWindowsIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "windows.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "windows.json") public: QPlatformIntegration *create(const QString&, const QStringList&, int &, char **); }; diff --git a/src/plugins/platforms/winrt/main.cpp b/src/plugins/platforms/winrt/main.cpp index 1398c52e96..128e0b78b6 100644 --- a/src/plugins/platforms/winrt/main.cpp +++ b/src/plugins/platforms/winrt/main.cpp @@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE class QWinRTIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "winrt.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "winrt.json") public: QStringList keys() const; diff --git a/src/plugins/platforms/xcb/qxcbmain.cpp b/src/plugins/platforms/xcb/qxcbmain.cpp index 0c3e8b5cd3..4a07b66491 100644 --- a/src/plugins/platforms/xcb/qxcbmain.cpp +++ b/src/plugins/platforms/xcb/qxcbmain.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QXcbIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "xcb.json") + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "xcb.json") public: QPlatformIntegration *create(const QString&, const QStringList&, int &, char **) Q_DECL_OVERRIDE; }; diff --git a/src/plugins/platformthemes/gtk2/main.cpp b/src/plugins/platformthemes/gtk2/main.cpp index 2431443dfa..34ac3ffc07 100644 --- a/src/plugins/platformthemes/gtk2/main.cpp +++ b/src/plugins/platformthemes/gtk2/main.cpp @@ -39,7 +39,7 @@ QT_BEGIN_NAMESPACE class QGtk2ThemePlugin : public QPlatformThemePlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformThemeFactoryInterface.5.1" FILE "gtk2.json") + Q_PLUGIN_METADATA(IID QPlatformThemeFactoryInterface_iid FILE "gtk2.json") public: QPlatformTheme *create(const QString &key, const QStringList ¶ms) Q_DECL_OVERRIDE; diff --git a/src/plugins/printsupport/cocoa/main.cpp b/src/plugins/printsupport/cocoa/main.cpp index d0925bbc34..2037724719 100644 --- a/src/plugins/printsupport/cocoa/main.cpp +++ b/src/plugins/printsupport/cocoa/main.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE class QCocoaPrinterSupportPlugin : public QPlatformPrinterSupportPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.QPlatformPrinterSupportFactoryInterface" FILE "cocoa.json") + Q_PLUGIN_METADATA(IID QPlatformPrinterSupportFactoryInterface_iid FILE "cocoa.json") public: QPlatformPrinterSupport *create(const QString &); diff --git a/src/plugins/printsupport/cups/main.cpp b/src/plugins/printsupport/cups/main.cpp index 9651a074cc..82485114ab 100644 --- a/src/plugins/printsupport/cups/main.cpp +++ b/src/plugins/printsupport/cups/main.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE class QCupsPrinterSupportPlugin : public QPlatformPrinterSupportPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.QPlatformPrinterSupportFactoryInterface" FILE "cups.json") + Q_PLUGIN_METADATA(IID QPlatformPrinterSupportFactoryInterface_iid FILE "cups.json") public: QStringList keys() const; diff --git a/src/plugins/printsupport/windows/main.cpp b/src/plugins/printsupport/windows/main.cpp index f1ee620b8b..28e99f1916 100644 --- a/src/plugins/printsupport/windows/main.cpp +++ b/src/plugins/printsupport/windows/main.cpp @@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE class QWindowsPrinterSupportPlugin : public QPlatformPrinterSupportPlugin { Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.QPlatformPrinterSupportFactoryInterface" FILE "windows.json") + Q_PLUGIN_METADATA(IID QPlatformPrinterSupportFactoryInterface_iid FILE "windows.json") public: QPlatformPrinterSupport *create(const QString &); -- cgit v1.2.3 From 45ccabdd497616c8500052a7413d2220a451248f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 11 May 2015 09:27:02 +0200 Subject: Increase version number of QPlatformIntegrationFactoryInterface. Increase version 5.2->5.3 in macro QPlatformIntegrationFactoryInterface_iid and use that in the plugins. Task-number: QTBUG-46009 Change-Id: I491ab0ac169ede5c103b40e1bcbcbf511922a911 Reviewed-by: Paul Olav Tvete --- src/gui/kernel/qplatformintegrationplugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qplatformintegrationplugin.h b/src/gui/kernel/qplatformintegrationplugin.h index b5e0b1874c..89808cde5e 100644 --- a/src/gui/kernel/qplatformintegrationplugin.h +++ b/src/gui/kernel/qplatformintegrationplugin.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QPlatformIntegration; -#define QPlatformIntegrationFactoryInterface_iid "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" +#define QPlatformIntegrationFactoryInterface_iid "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3" class Q_GUI_EXPORT QPlatformIntegrationPlugin : public QObject { -- cgit v1.2.3 From 2142f09c3d6502056dd5a667d238532e699f276d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 11 May 2015 09:36:17 +0200 Subject: Introduce a version number to QPlatformPrinterSupportFactoryInterface. Append a version number to QPlatformPrinterSupportFactoryInterface_iid as is done for QPlatformIntegrationFactoryInterface. Start with 5.1 since a6bcdf151647ab7a97c9fe1d2c8c8dd2b718244e changes the API in 5.5. Use macro in plugins. Task-number: QTBUG-46009 Change-Id: Ib9d2a02d20b9c4c6ad6c1045a907d69d80e3def4 Reviewed-by: Paul Olav Tvete --- src/printsupport/kernel/qplatformprintplugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printsupport/kernel/qplatformprintplugin.h b/src/printsupport/kernel/qplatformprintplugin.h index 279de9b952..ad39bf5a0c 100644 --- a/src/printsupport/kernel/qplatformprintplugin.h +++ b/src/printsupport/kernel/qplatformprintplugin.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QPlatformPrinterSupport; -#define QPlatformPrinterSupportFactoryInterface_iid "org.qt-project.QPlatformPrinterSupportFactoryInterface" +#define QPlatformPrinterSupportFactoryInterface_iid "org.qt-project.QPlatformPrinterSupportFactoryInterface.5.1" class Q_PRINTSUPPORT_EXPORT QPlatformPrinterSupportPlugin : public QObject { -- cgit v1.2.3 From c2e0c126d8be8782201b2e4b5e47d9abe7a64df0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 11 May 2015 10:00:30 +0200 Subject: Introduce a version number to QPlatformInputContextFactoryInterface. Append a version number to QPlatformInputContextFactoryInterface_iid as is done for QPlatformIntegrationFactoryInterface. Start with 5.1 since c91c05b056c769c3df0d7634aed7d9bf2c0e550d changes the API in 5.4. Use macro in plugins. Task-number: QTBUG-46009 Change-Id: I1d1a89bde50d263354f33a6917efb1c084211842 Reviewed-by: Paul Olav Tvete --- src/gui/kernel/qplatforminputcontextplugin_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qplatforminputcontextplugin_p.h b/src/gui/kernel/qplatforminputcontextplugin_p.h index 732eba3e06..d05672558d 100644 --- a/src/gui/kernel/qplatforminputcontextplugin_p.h +++ b/src/gui/kernel/qplatforminputcontextplugin_p.h @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE class QPlatformInputContext; -#define QPlatformInputContextFactoryInterface_iid "org.qt-project.Qt.QPlatformInputContextFactoryInterface" +#define QPlatformInputContextFactoryInterface_iid "org.qt-project.Qt.QPlatformInputContextFactoryInterface.5.1" class Q_GUI_EXPORT QPlatformInputContextPlugin : public QObject { -- cgit v1.2.3 From 31dfdb49b48c93059402c2beb701bd96e4c0e3f3 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 11 May 2015 14:21:06 +0200 Subject: iOS: remove 'truncation from double to float' compiler warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0b4b1f062180cfe09ceb275484c39afeaaa90cac Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/quiview.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 6f2664e708..87dc3b9dcb 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -77,7 +77,7 @@ if (QIOSIntegration::instance()->debugWindowManagement()) { static CGFloat hue = 0.0; CGFloat lastHue = hue; - for (CGFloat diff = 0; diff < 0.1 || diff > 0.9; diff = fabsf(hue - lastHue)) + for (CGFloat diff = 0; diff < 0.1 || diff > 0.9; diff = fabs(hue - lastHue)) hue = drand48(); #define colorWithBrightness(br) \ -- cgit v1.2.3 From 6ef5ca2e2f34e821375cc730c293f1a87179ccd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Fri, 8 May 2015 18:13:44 +0100 Subject: QSize, QSizeF: Add Q_REQUIRED_RESULT ...to signatures matching the pattern: T T::() const; Change-Id: I75d724a3eef5cb94559e31d86914c6e0655b7f13 Reviewed-by: Marc Mutz --- src/corelib/tools/qsize.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qsize.h b/src/corelib/tools/qsize.h index a5e30b10b6..e71eeb607e 100644 --- a/src/corelib/tools/qsize.h +++ b/src/corelib/tools/qsize.h @@ -58,11 +58,11 @@ public: inline void scale(int w, int h, Qt::AspectRatioMode mode) Q_DECL_NOTHROW; inline void scale(const QSize &s, Qt::AspectRatioMode mode) Q_DECL_NOTHROW; - QSize scaled(int w, int h, Qt::AspectRatioMode mode) const Q_DECL_NOTHROW; - QSize scaled(const QSize &s, Qt::AspectRatioMode mode) const Q_DECL_NOTHROW; + QSize scaled(int w, int h, Qt::AspectRatioMode mode) const Q_DECL_NOTHROW Q_REQUIRED_RESULT; + QSize scaled(const QSize &s, Qt::AspectRatioMode mode) const Q_DECL_NOTHROW Q_REQUIRED_RESULT; - Q_DECL_CONSTEXPR inline QSize expandedTo(const QSize &) const Q_DECL_NOTHROW; - Q_DECL_CONSTEXPR inline QSize boundedTo(const QSize &) const Q_DECL_NOTHROW; + Q_DECL_CONSTEXPR inline QSize expandedTo(const QSize &) const Q_DECL_NOTHROW Q_REQUIRED_RESULT; + Q_DECL_CONSTEXPR inline QSize boundedTo(const QSize &) const Q_DECL_NOTHROW Q_REQUIRED_RESULT; Q_DECL_RELAXED_CONSTEXPR inline int &rwidth() Q_DECL_NOTHROW; Q_DECL_RELAXED_CONSTEXPR inline int &rheight() Q_DECL_NOTHROW; @@ -214,15 +214,15 @@ public: Q_DECL_RELAXED_CONSTEXPR inline void setWidth(qreal w) Q_DECL_NOTHROW; Q_DECL_RELAXED_CONSTEXPR inline void setHeight(qreal h) Q_DECL_NOTHROW; void transpose() Q_DECL_NOTHROW; - Q_DECL_CONSTEXPR inline QSizeF transposed() const Q_DECL_NOTHROW; + Q_DECL_CONSTEXPR inline QSizeF transposed() const Q_DECL_NOTHROW Q_REQUIRED_RESULT; inline void scale(qreal w, qreal h, Qt::AspectRatioMode mode) Q_DECL_NOTHROW; inline void scale(const QSizeF &s, Qt::AspectRatioMode mode) Q_DECL_NOTHROW; - QSizeF scaled(qreal w, qreal h, Qt::AspectRatioMode mode) const Q_DECL_NOTHROW; - QSizeF scaled(const QSizeF &s, Qt::AspectRatioMode mode) const Q_DECL_NOTHROW; + QSizeF scaled(qreal w, qreal h, Qt::AspectRatioMode mode) const Q_DECL_NOTHROW Q_REQUIRED_RESULT; + QSizeF scaled(const QSizeF &s, Qt::AspectRatioMode mode) const Q_DECL_NOTHROW Q_REQUIRED_RESULT; - Q_DECL_CONSTEXPR inline QSizeF expandedTo(const QSizeF &) const Q_DECL_NOTHROW; - Q_DECL_CONSTEXPR inline QSizeF boundedTo(const QSizeF &) const Q_DECL_NOTHROW; + Q_DECL_CONSTEXPR inline QSizeF expandedTo(const QSizeF &) const Q_DECL_NOTHROW Q_REQUIRED_RESULT; + Q_DECL_CONSTEXPR inline QSizeF boundedTo(const QSizeF &) const Q_DECL_NOTHROW Q_REQUIRED_RESULT; Q_DECL_RELAXED_CONSTEXPR inline qreal &rwidth() Q_DECL_NOTHROW; Q_DECL_RELAXED_CONSTEXPR inline qreal &rheight() Q_DECL_NOTHROW; -- cgit v1.2.3 From 86601fc5758b223bc74687b19e3ec020b1d61d3a Mon Sep 17 00:00:00 2001 From: Kati Kankaanpaa Date: Wed, 13 May 2015 10:28:42 -0700 Subject: Fix division by zero crash when restoring screen settings The restoredScreenNumber was used before it's existence was checked, which caused 'division by zero' if the screen has been removed after storing the screen number. The check if restoredScreenNumber exists was moved to happen before restoredScreenNumber is used for the first time. Change-Id: Iada0e8c5cbb6d8ca88df171dbee045be249f50cd Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidget.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index c7b141e700..910468b53a 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7315,6 +7315,8 @@ bool QWidget::restoreGeometry(const QByteArray &geometry) stream >> restoredScreenWidth; const QDesktopWidget * const desktop = QApplication::desktop(); + if (restoredScreenNumber >= desktop->numScreens()) + restoredScreenNumber = desktop->primaryScreen(); const qreal screenWidthF = qreal(desktop->screenGeometry(restoredScreenNumber).width()); // Sanity check bailing out when large variations of screen sizes occur due to // high DPI scaling or different levels of DPI awareness. @@ -7342,9 +7344,6 @@ bool QWidget::restoreGeometry(const QByteArray &geometry) .expandedTo(d_func()->adjustedSize())); } - if (restoredScreenNumber >= desktop->numScreens()) - restoredScreenNumber = desktop->primaryScreen(); - const QRect availableGeometry = desktop->availableGeometry(restoredScreenNumber); // Modify the restored geometry if we are about to restore to coordinates -- cgit v1.2.3 From e905526090feb798e5746412027d2d757d2ff7b5 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 13 May 2015 13:13:51 +0200 Subject: Better match thin font styles A style name 'Extra Thin' or 'Thin Italic' should be parsed as Thin font weight. Change-Id: I8acebed7330c23231b3742d887081d8b3d0aeb19 Reviewed-by: Konstantin Ritt --- src/gui/text/qfontdatabase.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index e77856c8d1..dae4d560a8 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -121,6 +121,8 @@ static int getFontWeight(const QString &weightString) return QFont::DemiBold; return QFont::Bold; } + if (s.contains(QLatin1String("thin"))) + return QFont::Thin; if (s.contains(QLatin1String("light"))) return QFont::Light; if (s.contains(QLatin1String("black"))) -- cgit v1.2.3 From a4cba90e194a65930c0e66469cd2ef2cc5c1f5ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 13 May 2015 21:30:04 +0200 Subject: Set correct target.path for legacy GL examples Fix Library not loaded/image not found error on application startup. With @rpath enabled (commit 6e18f57a) qmake now requires a correct target.path in order to emit correct -rpath @loader_path linker directives. Change-Id: Ia32b038ad2d64819477be5cd9d1ed36768e2251b Reviewed-by: Jake Petroules --- examples/opengl/legacy/framebufferobject2/framebufferobject2.pro | 2 +- examples/opengl/legacy/grabber/grabber.pro | 2 +- examples/opengl/legacy/hellogl/hellogl.pro | 2 +- examples/opengl/legacy/overpainting/overpainting.pro | 2 +- examples/opengl/legacy/pbuffers/pbuffers.pro | 2 +- examples/opengl/legacy/pbuffers2/pbuffers2.pro | 2 +- examples/opengl/legacy/samplebuffers/samplebuffers.pro | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro b/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro index e0067cf27f..6171450925 100644 --- a/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro +++ b/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro @@ -5,7 +5,7 @@ RESOURCES += framebufferobject2.qrc QT += opengl widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/opengl/framebufferobject2 +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/framebufferobject2 INSTALLS += target contains(QT_CONFIG, opengles.) { diff --git a/examples/opengl/legacy/grabber/grabber.pro b/examples/opengl/legacy/grabber/grabber.pro index b8567580f0..88485ff183 100644 --- a/examples/opengl/legacy/grabber/grabber.pro +++ b/examples/opengl/legacy/grabber/grabber.pro @@ -6,7 +6,7 @@ SOURCES = glwidget.cpp \ QT += opengl widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/opengl/grabber +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/grabber INSTALLS += target contains(QT_CONFIG, opengles.) { diff --git a/examples/opengl/legacy/hellogl/hellogl.pro b/examples/opengl/legacy/hellogl/hellogl.pro index 500bd85b3c..01e8ca1f74 100644 --- a/examples/opengl/legacy/hellogl/hellogl.pro +++ b/examples/opengl/legacy/hellogl/hellogl.pro @@ -11,7 +11,7 @@ SOURCES = glwidget.cpp \ QT += opengl widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/opengl/hellogl +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/hellogl INSTALLS += target contains(QT_CONFIG, opengles.) { diff --git a/examples/opengl/legacy/overpainting/overpainting.pro b/examples/opengl/legacy/overpainting/overpainting.pro index c1bda7853d..9187314b75 100644 --- a/examples/opengl/legacy/overpainting/overpainting.pro +++ b/examples/opengl/legacy/overpainting/overpainting.pro @@ -13,7 +13,7 @@ SOURCES = bubble.cpp \ qtlogo.cpp # install -target.path = $$[QT_INSTALL_EXAMPLES]/opengl/overpainting +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/overpainting INSTALLS += target contains(QT_CONFIG, opengles.) { diff --git a/examples/opengl/legacy/pbuffers/pbuffers.pro b/examples/opengl/legacy/pbuffers/pbuffers.pro index a349e39f68..fe88de05d1 100644 --- a/examples/opengl/legacy/pbuffers/pbuffers.pro +++ b/examples/opengl/legacy/pbuffers/pbuffers.pro @@ -7,7 +7,7 @@ RESOURCES += pbuffers.qrc QT += opengl widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/opengl/pbuffers +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/pbuffers INSTALLS += target contains(QT_CONFIG, opengles.) { diff --git a/examples/opengl/legacy/pbuffers2/pbuffers2.pro b/examples/opengl/legacy/pbuffers2/pbuffers2.pro index f9dd269eea..f331498d3a 100644 --- a/examples/opengl/legacy/pbuffers2/pbuffers2.pro +++ b/examples/opengl/legacy/pbuffers2/pbuffers2.pro @@ -5,7 +5,7 @@ SOURCES += glwidget.cpp main.cpp RESOURCES += pbuffers2.qrc # install -target.path = $$[QT_INSTALL_EXAMPLES]/opengl/pbuffers2 +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/pbuffers2 INSTALLS += target contains(QT_CONFIG, opengles.) { diff --git a/examples/opengl/legacy/samplebuffers/samplebuffers.pro b/examples/opengl/legacy/samplebuffers/samplebuffers.pro index b57599aae4..9b471243f3 100644 --- a/examples/opengl/legacy/samplebuffers/samplebuffers.pro +++ b/examples/opengl/legacy/samplebuffers/samplebuffers.pro @@ -4,7 +4,7 @@ SOURCES += glwidget.cpp main.cpp QT += opengl widgets # install -target.path = $$[QT_INSTALL_EXAMPLES]/opengl/samplebuffers +target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/samplebuffers INSTALLS += target contains(QT_CONFIG, opengles.) { -- cgit v1.2.3 From 7d1ec1ae9e263df1a655e13f8feea7b5a5c7d9ed Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Mon, 11 May 2015 10:45:38 +0200 Subject: Reorder member variables to avoid padding. Saves 8 byte in each case on 64bit systems, no change on 32bit systems. Change-Id: I2a2e8786fc7914ee9ae369ba05bedfc9e5e0ca5c Reviewed-by: Marc Mutz --- src/corelib/global/qlogging.cpp | 4 ++-- src/corelib/mimetypes/qmimetype.cpp | 6 +++--- src/corelib/mimetypes/qmimetype_p.h | 2 +- src/corelib/statemachine/qeventtransition_p.h | 2 +- src/corelib/statemachine/qstate_p.h | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index d9d21c535c..447a875655 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -972,8 +972,8 @@ struct QMessagePattern { QElapsedTimer timer; #endif #ifdef QLOGGING_HAVE_BACKTRACE - int backtraceDepth; QString backtraceSeparator; + int backtraceDepth; #endif bool fromEnvironment; @@ -986,8 +986,8 @@ QMessagePattern::QMessagePattern() : literals(0) , tokens(0) #ifdef QLOGGING_HAVE_BACKTRACE - , backtraceDepth(5) , backtraceSeparator(QLatin1Char('|')) + , backtraceDepth(5) #endif , fromEnvironment(false) { diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp index 70df9868b6..a5f9cb70d5 100644 --- a/src/corelib/mimetypes/qmimetype.cpp +++ b/src/corelib/mimetypes/qmimetype.cpp @@ -53,12 +53,12 @@ QMimeTypePrivate::QMimeTypePrivate() {} QMimeTypePrivate::QMimeTypePrivate(const QMimeType &other) - : name(other.d->name), + : loaded(other.d->loaded), + name(other.d->name), localeComments(other.d->localeComments), genericIconName(other.d->genericIconName), iconName(other.d->iconName), - globPatterns(other.d->globPatterns), - loaded(other.d->loaded) + globPatterns(other.d->globPatterns) {} void QMimeTypePrivate::clear() diff --git a/src/corelib/mimetypes/qmimetype_p.h b/src/corelib/mimetypes/qmimetype_p.h index bf533bbcb0..2161dd8901 100644 --- a/src/corelib/mimetypes/qmimetype_p.h +++ b/src/corelib/mimetypes/qmimetype_p.h @@ -66,12 +66,12 @@ public: void addGlobPattern(const QString &pattern); + bool loaded; // QSharedData leaves a 4 byte gap, so don't put 8 byte members first QString name; LocaleHash localeComments; QString genericIconName; QString iconName; QStringList globPatterns; - bool loaded; }; QT_END_NAMESPACE diff --git a/src/corelib/statemachine/qeventtransition_p.h b/src/corelib/statemachine/qeventtransition_p.h index 64ab945187..59b0fcb30f 100644 --- a/src/corelib/statemachine/qeventtransition_p.h +++ b/src/corelib/statemachine/qeventtransition_p.h @@ -61,8 +61,8 @@ public: void unregister(); void maybeRegister(); - bool registered; QObject *object; + bool registered; QEvent::Type eventType; }; diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h index 28bb176b56..2ce0c13522 100644 --- a/src/corelib/statemachine/qstate_p.h +++ b/src/corelib/statemachine/qstate_p.h @@ -103,8 +103,8 @@ public: QAbstractState *initialState; QState::ChildMode childMode; mutable bool childStatesListNeedsRefresh; - mutable QList childStatesList; mutable bool transitionsListNeedsRefresh; + mutable QList childStatesList; mutable QList transitionsList; #ifndef QT_NO_PROPERTIES -- cgit v1.2.3 From 083c9269ed73e8771e1dbe10812696b45b7389f3 Mon Sep 17 00:00:00 2001 From: Evangelos Foutras Date: Mon, 11 May 2015 12:20:57 +0300 Subject: Try to ensure that -fPIC is used in CMake builds In commit 36d6eb721e7d5997ade75e289d4088dc48678d0d the -fPIE switch was replaced with -fPIC in an effort to avoid generating copy relocations which are incompatible with Qt5 when built with -reduce-relocations. Task-number: QTBUG-45755 Change-Id: I59a55ea15052f498104848c5fd867e563ddc2290 Reviewed-by: Thiago Macieira --- src/corelib/Qt5CoreConfigExtras.cmake.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 48d5f21447..d4abc5f271 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -70,8 +70,9 @@ set(_qt5_corelib_extra_includes) # Qt5_POSITION_INDEPENDENT_CODE variable is used in the # qt5_use_module # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) -set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") +set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") +set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}) !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) -- cgit v1.2.3 From 7d3f353a5bd573dc0e72f7f55c70212a6b3837fa Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Thu, 14 May 2015 12:49:31 +0300 Subject: xcb: Fix FP1616 to double conversion We should divide the fractional part of the FP1616 value by 0x10000 instead of 0xFFFF, otherwise 1.FFFF will be converted to 2.0. And right-shifting the integer part by 16 is equal to dividing it by 0x10000. So just divide the whole FP1616 value by 0x10000. Change-Id: Ia89a274b81be9cf502e1f311f696a610a7f37d7f Task-number: QTBUG-45378 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 2895a2762a..c43816fa05 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -450,7 +450,7 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) #if defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT) static qreal fixed1616ToReal(FP1616 val) { - return (qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF; + return qreal(val) / 0x10000; } #endif // defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT) -- cgit v1.2.3 From 1842322b2b18467e8641e89a9f2356c9f1ba044a Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Fri, 15 May 2015 09:17:22 +0200 Subject: Tests: Remove EXPECT_FAIL in tst_QWidget::widgetAt() The test is marked as XPASS in CI. This change follow 201bf9e6736a3. Change-Id: I0938b1417f792aa88fc1b40c08e7cd810e7d22f7 Task-number: QTBUG-22326 Reviewed-by: Friedemann Kleint --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 085677315d..a0d94d2dc9 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -3354,8 +3354,6 @@ void tst_QWidget::widgetAt() #if defined(Q_OS_WINCE) QEXPECT_FAIL("", "Windows CE does only support rectangular regions", Continue); //See also task 147191 #endif - if (!QGuiApplication::platformName().compare(QLatin1String("cocoa"), Qt::CaseInsensitive)) - QEXPECT_FAIL("", "Window mask not implemented on Mac QTBUG-22326", Continue); QTRY_VERIFY(QApplication::widgetAt(testPos) == w1.data()); QTRY_VERIFY(QApplication::widgetAt(testPos + QPoint(1, 1)) == w2.data()); } -- cgit v1.2.3 From 1485c2f3fac4fb3819f6d6f493665308bba726c2 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 13 May 2015 09:55:03 +0200 Subject: tst_QDialog::snapToDefaultButton - tune the test for OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QCursor::setPos with Cocoa integration is calling CGEventPost. Some time is required before the cursor position is really set, so we can not immediately call QCOMPARE. Change-Id: I83a4c13f06ec151a4b9ab18c83de1eb5247ea9cc Task-number: QTBUG-45553 Reviewed-by: Morten Johan Sørvig Reviewed-by: Caroline Chao --- tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index fecc14f541..e62ce3ceb5 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -564,6 +564,11 @@ void tst_QDialog::snapToDefaultButton() topLeftPos = QPoint(topLeftPos.x() + 100, topLeftPos.y() + 100); QPoint startingPos(topLeftPos.x() + 250, topLeftPos.y() + 250); QCursor::setPos(startingPos); +#ifdef Q_OS_OSX + // On OS X we use CGEventPost to move the cursor, it needs at least + // some time before the event handled and the position really set. + QTest::qWait(100); +#endif QCOMPARE(QCursor::pos(), startingPos); QDialog dialog; QPushButton *button = new QPushButton(&dialog); -- cgit v1.2.3 From 03281150b9c49f7f0a08b004e5638831bdb91e52 Mon Sep 17 00:00:00 2001 From: Timo Jyrinki Date: Tue, 24 Feb 2015 14:12:38 +0000 Subject: Add environment variable support for testability library use. Add the option to load the testability library based on whether an environment variable QT_LOAD_TESTABILITY is set, in addition to the current "-testability" flag. This improves the use of testability library together with the autopilot functional testing tool. Task-number: QTBUG-32974 Change-Id: I6abf2c004cbff2ce0aff44e24a99bcc8188a52ae Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/kernel/qguiapplication.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index af93a93cfe..4146ddd8ba 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1329,6 +1329,9 @@ void QGuiApplicationPrivate::init() #endif #ifndef QT_NO_LIBRARY + if (qEnvironmentVariableIntValue("QT_LOAD_TESTABILITY") > 0) + loadTestability = true; + if (loadTestability) { QLibrary testLib(QStringLiteral("qttestability")); if (testLib.load()) { -- cgit v1.2.3 From 45f60d2da2dc2fa1cf84bce5c09a3e63dd48440a Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 14 May 2015 12:05:24 +0200 Subject: QFileSystemModel: remove useless check The NULL check is on the line before, no point of repeating it again. Change-Id: Id6fa9ffc4dcc00819882f2d3157e9dbdb0e1db78 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/dialogs/qfilesystemmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 04238f242a..88d327168c 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -544,7 +544,7 @@ QModelIndex QFileSystemModel::parent(const QModelIndex &index) const QFileSystemModelPrivate::QFileSystemNode *indexNode = d->node(index); Q_ASSERT(indexNode != 0); - QFileSystemModelPrivate::QFileSystemNode *parentNode = (indexNode ? indexNode->parent : 0); + QFileSystemModelPrivate::QFileSystemNode *parentNode = indexNode->parent; if (parentNode == 0 || parentNode == &d->root) return QModelIndex(); -- cgit v1.2.3 From d1528919de343317b82ed52eb62ee3eb3fd8488b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 28 Apr 2015 14:30:57 +0200 Subject: xcode generator: don't change output_dir when opening a pbx file directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ProjectBuilderMakefileGenerator::openOutput should only change back Option::output_dir when creating a pbx file inside an Xcode project. Since the pbx file will be placed inside a different directory than output_dir when creating an Xcode project, MakefileGenerator::openOutput() will redirect output_dir to be inside the Xcode project as well. Since we don't want this redirection, we change output_dir back to what it was once the call returns. But we should only do this when creating the whole Xcode project, since only then we create a pbx file that is different from output_dir in the first place. A bug with this is seen when making qt_makeqmake.mak (which is a helper makefile inside the Xcode project). That file will only regenerate the pbx file (and not the whole Xcode project), which means that we don't enter the fileName.isEmpty() section, which means that output_dir should stay as it is. Task-number: QTBUG-45826 Change-Id: I03d5c3dec395ff4768f9272fd1981c6fd35efb1e Reviewed-by: Tor Arne Vestbø --- qmake/generators/mac/pbuilder_pbx.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index fcd6bf8308..d9eb149177 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1812,11 +1812,14 @@ ProjectBuilderMakefileGenerator::openOutput(QFile &file, const QString &build) c } output += QString("project.pbxproj"); file.setFileName(output); + bool ret = UnixMakefileGenerator::openOutput(file, build); + ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1); + Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2); + return ret; } - bool ret = UnixMakefileGenerator::openOutput(file, build); - ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1); - Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2); - return ret; + + ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir; + return UnixMakefileGenerator::openOutput(file, build); } /* This function is such a hack it is almost pointless, but it -- cgit v1.2.3 From 189280026f091716dfda91ff652cc20b299683c2 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 13 May 2015 14:33:10 +0200 Subject: xcode generator: use absolute path when creating PBXFileReferences for libraries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the Xcode generator uses "sourceTree = " for all PBXFileReferences. But the paths we use for referencing libraries are relative. This patch will change this, so that we always use absolute paths to be consequent. This will fix a crash in Xcode that happens when opening projects generated by Qt. Change-Id: I3a372b93598a777c96ba353205cf19710a5923f5 Task-number: QTBUG-45966 Reviewed-by: Tor Arne Vestbø Reviewed-by: Oswald Buddenhagen --- qmake/generators/mac/pbuilder_pbx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 8f24c20712..b54f634cf9 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -950,7 +950,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(!path.isEmpty() && !libdirs.contains(path)) libdirs += path; } - library = fileFixify(library); + library = fileFixify(library, FileFixifyAbsolute); QString filetype = xcodeFiletypeForFilename(library); QString key = keyFor(library); if (!project->values("QMAKE_PBX_LIBRARIES").contains(key)) { -- cgit v1.2.3 From 9d85490ea2171f1fbad1e6a264db835fc0e9a702 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 15 May 2015 09:59:08 +0200 Subject: Fix exclusion for legacy Open GL examples. Add dynamic GL and remove warning about ANGLE since that package no longer exists. Task-number: QTBUG-46103 Change-Id: Icf93d1105434395a3c9ad61bb8c921fcedfc7137 Reviewed-by: Laszlo Agocs --- examples/opengl/legacy/framebufferobject2/framebufferobject2.pro | 6 +----- examples/opengl/legacy/grabber/grabber.pro | 6 +----- examples/opengl/legacy/hellogl/hellogl.pro | 6 +----- examples/opengl/legacy/overpainting/overpainting.pro | 6 +----- examples/opengl/legacy/pbuffers/pbuffers.pro | 6 +----- examples/opengl/legacy/pbuffers2/pbuffers2.pro | 6 +----- examples/opengl/legacy/samplebuffers/samplebuffers.pro | 6 +----- examples/widgets/graphicsview/boxes/boxes.pro | 6 +----- 8 files changed, 8 insertions(+), 40 deletions(-) diff --git a/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro b/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro index 6171450925..78fc6b1a63 100644 --- a/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro +++ b/examples/opengl/legacy/framebufferobject2/framebufferobject2.pro @@ -8,8 +8,4 @@ QT += opengl widgets target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/framebufferobject2 INSTALLS += target -contains(QT_CONFIG, opengles.) { - contains(QT_CONFIG, angle): \ - warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") - error("This example requires Qt to be configured with -opengl desktop") -} +contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/grabber/grabber.pro b/examples/opengl/legacy/grabber/grabber.pro index 88485ff183..1db0e23156 100644 --- a/examples/opengl/legacy/grabber/grabber.pro +++ b/examples/opengl/legacy/grabber/grabber.pro @@ -9,8 +9,4 @@ QT += opengl widgets target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/grabber INSTALLS += target -contains(QT_CONFIG, opengles.) { - contains(QT_CONFIG, angle): \ - warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") - error("This example requires Qt to be configured with -opengl desktop") -} +contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/hellogl/hellogl.pro b/examples/opengl/legacy/hellogl/hellogl.pro index 01e8ca1f74..bb75b07200 100644 --- a/examples/opengl/legacy/hellogl/hellogl.pro +++ b/examples/opengl/legacy/hellogl/hellogl.pro @@ -14,8 +14,4 @@ QT += opengl widgets target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/hellogl INSTALLS += target -contains(QT_CONFIG, opengles.) { - contains(QT_CONFIG, angle): \ - warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") - error("This example requires Qt to be configured with -opengl desktop") -} +contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/overpainting/overpainting.pro b/examples/opengl/legacy/overpainting/overpainting.pro index 9187314b75..cbed7eed2b 100644 --- a/examples/opengl/legacy/overpainting/overpainting.pro +++ b/examples/opengl/legacy/overpainting/overpainting.pro @@ -16,8 +16,4 @@ SOURCES = bubble.cpp \ target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/overpainting INSTALLS += target -contains(QT_CONFIG, opengles.) { - contains(QT_CONFIG, angle): \ - warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") - error("This example requires Qt to be configured with -opengl desktop") -} +contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/pbuffers/pbuffers.pro b/examples/opengl/legacy/pbuffers/pbuffers.pro index fe88de05d1..d779a2a2dc 100644 --- a/examples/opengl/legacy/pbuffers/pbuffers.pro +++ b/examples/opengl/legacy/pbuffers/pbuffers.pro @@ -10,8 +10,4 @@ QT += opengl widgets target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/pbuffers INSTALLS += target -contains(QT_CONFIG, opengles.) { - contains(QT_CONFIG, angle): \ - warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") - error("This example requires Qt to be configured with -opengl desktop") -} +contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/pbuffers2/pbuffers2.pro b/examples/opengl/legacy/pbuffers2/pbuffers2.pro index f331498d3a..2ba40a6f74 100644 --- a/examples/opengl/legacy/pbuffers2/pbuffers2.pro +++ b/examples/opengl/legacy/pbuffers2/pbuffers2.pro @@ -8,8 +8,4 @@ RESOURCES += pbuffers2.qrc target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/pbuffers2 INSTALLS += target -contains(QT_CONFIG, opengles.) { - contains(QT_CONFIG, angle): \ - warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") - error("This example requires Qt to be configured with -opengl desktop") -} +contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/samplebuffers/samplebuffers.pro b/examples/opengl/legacy/samplebuffers/samplebuffers.pro index 9b471243f3..3719f5039d 100644 --- a/examples/opengl/legacy/samplebuffers/samplebuffers.pro +++ b/examples/opengl/legacy/samplebuffers/samplebuffers.pro @@ -7,8 +7,4 @@ QT += opengl widgets target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/samplebuffers INSTALLS += target -contains(QT_CONFIG, opengles.) { - contains(QT_CONFIG, angle): \ - warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") - error("This example requires Qt to be configured with -opengl desktop") -} +contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/widgets/graphicsview/boxes/boxes.pro b/examples/widgets/graphicsview/boxes/boxes.pro index e608b1c845..15d26f02f0 100644 --- a/examples/widgets/graphicsview/boxes/boxes.pro +++ b/examples/widgets/graphicsview/boxes/boxes.pro @@ -1,10 +1,6 @@ QT += opengl widgets -contains(QT_CONFIG, opengles.) { - contains(QT_CONFIG, angle): \ - warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c") - error("This example requires Qt to be configured with -opengl desktop") -} +contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") HEADERS += 3rdparty/fbm.h \ glbuffers.h \ -- cgit v1.2.3 From 6779ec383d9609cd02a4aaf0dc82d6a9f958a07c Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 14 May 2015 12:06:16 +0200 Subject: QMenuBar: honor the left widget size hint expandedTo() returns the expanded size, so we must assign the return value (otherwise it's a no op). We were accidentally discarding it. Task-number: QTBUG-36010 Change-Id: Ic70c12648382a6b2ef7d70809bf25caa4cbe2f3a Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qmenubar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 4659d9cf6c..1ad99bed9c 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1632,7 +1632,7 @@ QSize QMenuBar::sizeHint() const if(d->leftWidget) { QSize sz = d->leftWidget->sizeHint(); sz.rheight() += margin; - ret.expandedTo(sz); + ret = ret.expandedTo(sz); } if(d->rightWidget) { QSize sz = d->rightWidget->sizeHint(); -- cgit v1.2.3 From a2c4e68141b4b80d317f5295aa687b5cb4f1dd9c Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 14 May 2015 12:07:20 +0200 Subject: QStyle debug helpers: refactor dead code ... or compilers complain about the second, unreachable return. Change-Id: Ic89361859fcf5cf33a57de0c803526702fa831b8 Reviewed-by: Friedemann Kleint --- 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 862a4302f3..1849331b79 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -2368,8 +2368,8 @@ QDebug operator<<(QDebug debug, QStyle::State state) return operator<< (debug, state); # else Q_UNUSED(state); -# endif return debug; +# endif } # endif // !QT_NO_DEBUG_STREAM #endif // QT_VERSION < QT_VERSION_CHECK(6,0,0) -- cgit v1.2.3 From 298a60d958c6dbebc3c3d863f375884c071209c0 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 12 May 2015 11:58:08 +0200 Subject: WinRT: fix namespaced build Change-Id: I0505523a5524995e374dc8f005f101d0cea8b01e Reviewed-by: Oliver Wolff --- src/corelib/kernel/qfunctions_winrt.h | 8 ++++++-- src/corelib/thread/qthread_p.h | 14 ++++++++++---- src/plugins/platforms/winrt/qwinrtcursor.cpp | 5 ++++- src/plugins/platforms/winrt/qwinrtcursor.h | 4 +++- src/plugins/platforms/winrt/qwinrtfileengine.h | 4 ++-- src/plugins/platforms/winrt/qwinrtfontdatabase.h | 6 ++++-- src/plugins/platforms/winrt/qwinrtservices.h | 4 +++- 7 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/corelib/kernel/qfunctions_winrt.h b/src/corelib/kernel/qfunctions_winrt.h index 3fff52a22c..7efd042456 100644 --- a/src/corelib/kernel/qfunctions_winrt.h +++ b/src/corelib/kernel/qfunctions_winrt.h @@ -131,9 +131,13 @@ generate_inline_return_func2(_putenv_s, errno_t, const char *, const char *) generate_inline_return_func0(tzset, void) generate_inline_return_func0(_tzset, void) -QT_BEGIN_NAMESPACE +namespace Microsoft { + namespace WRL { + template class ComPtr; + } +} -namespace Microsoft { namespace WRL { template class ComPtr; } } +QT_BEGIN_NAMESPACE namespace QWinRTFunctions { diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index b8544b1f0a..2008f76621 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -57,6 +57,16 @@ #include +#ifdef Q_OS_WINRT +namespace ABI { + namespace Windows { + namespace Foundation { + struct IAsyncAction; + } + } +} +#endif // Q_OS_WINRT + QT_BEGIN_NAMESPACE class QAbstractEventDispatcher; @@ -125,10 +135,6 @@ private: #ifndef QT_NO_THREAD -#ifdef Q_OS_WINRT -namespace ABI { namespace Windows { namespace Foundation { struct IAsyncAction; } } } -#endif - class QThreadPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QThread) diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp index 1adb2bb89f..e86590c260 100644 --- a/src/plugins/platforms/winrt/qwinrtcursor.cpp +++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp @@ -46,7 +46,7 @@ using namespace Microsoft::WRL::Wrappers; using namespace ABI::Windows::UI::Core; using namespace ABI::Windows::Foundation; -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class QWinRTCursorPrivate { @@ -155,3 +155,6 @@ QPoint QWinRTCursor::pos() const coreWindow->get_PointerPosition(&point); return QPoint(point.X, point.Y); } + +QT_END_NAMESPACE + diff --git a/src/plugins/platforms/winrt/qwinrtcursor.h b/src/plugins/platforms/winrt/qwinrtcursor.h index 4245faab6f..de951b1844 100644 --- a/src/plugins/platforms/winrt/qwinrtcursor.h +++ b/src/plugins/platforms/winrt/qwinrtcursor.h @@ -36,7 +36,7 @@ #include -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class QWinRTCursorPrivate; class QWinRTCursor : public QPlatformCursor @@ -54,4 +54,6 @@ private: Q_DECLARE_PRIVATE(QWinRTCursor) }; +QT_END_NAMESPACE + #endif // QWINRTCURSOR_H diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.h b/src/plugins/platforms/winrt/qwinrtfileengine.h index 983338f2e2..c31bf741fa 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.h +++ b/src/plugins/platforms/winrt/qwinrtfileengine.h @@ -36,8 +36,6 @@ #include -QT_BEGIN_NAMESPACE - namespace ABI { namespace Windows { namespace Storage { @@ -46,6 +44,8 @@ namespace ABI { } } +QT_BEGIN_NAMESPACE + class QWinRTFileEngineHandlerPrivate; class QWinRTFileEngineHandler : public QAbstractFileEngineHandler { diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h index cde81baa44..eb643d4930 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h @@ -36,12 +36,14 @@ #include -QT_BEGIN_NAMESPACE - #ifdef QT_WINRT_USE_DWRITE struct IDWriteFontFile; struct IDWriteFontFamily; +#endif +QT_BEGIN_NAMESPACE + +#ifdef QT_WINRT_USE_DWRITE struct FontDescription { quint32 index; diff --git a/src/plugins/platforms/winrt/qwinrtservices.h b/src/plugins/platforms/winrt/qwinrtservices.h index 0262a2ab83..3551803b79 100644 --- a/src/plugins/platforms/winrt/qwinrtservices.h +++ b/src/plugins/platforms/winrt/qwinrtservices.h @@ -37,7 +37,7 @@ #include #include -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class QWinRTServicesPrivate; class QWinRTServices : public QPlatformServices @@ -54,4 +54,6 @@ private: Q_DECLARE_PRIVATE(QWinRTServices) }; +QT_END_NAMESPACE + #endif // QWINRTSERVICES_H -- cgit v1.2.3 From ea92ee8e1551ead4186fa4e65c33a87a3b558a52 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 16 May 2015 18:22:46 +0200 Subject: QList: partially revert ab8366b5923ec0feb730df98040885669f7bbe38 That commit removed the user-defined copy constructors, under the assumption that this would be ok for these non-exported classes. But the change is still BiC, because it turns the iterators into trivial types, which changes the way they are passed into functions by value. So, delay the change until Qt 6. Change-Id: I8065ff1ff78f5722505328447f2496777d1e8957 Reviewed-by: Konstantin Ritt Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qlist.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 1e002633df..e446a6625b 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -221,6 +221,11 @@ public: inline iterator() : i(0) {} inline iterator(Node *n) : i(n) {} +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) + // can't remove it in Qt 5, since doing so would make the type trivial, + // which changes the way it's passed to functions by value. + inline iterator(const iterator &o): i(o.i){} +#endif inline T &operator*() const { return i->t(); } inline T *operator->() const { return &i->t(); } inline T &operator[](difference_type j) const { return i[j].t(); } @@ -268,6 +273,11 @@ public: inline const_iterator() : i(0) {} inline const_iterator(Node *n) : i(n) {} +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) + // can't remove it in Qt 5, since doing so would make the type trivial, + // which changes the way it's passed to functions by value. + inline const_iterator(const const_iterator &o): i(o.i) {} +#endif #ifdef QT_STRICT_ITERATORS inline explicit const_iterator(const iterator &o): i(o.i) {} #else -- cgit v1.2.3 From 35a125971cd09318f59918dba9255c8a0ad9a97c Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Sat, 16 May 2015 12:21:22 +0200 Subject: Fix QtPrivate::IsQEnumHelper Change-Id: I1633ef128212a6b99b66129f13e0b4d5ea46644d Reviewed-by: Thiago Macieira --- src/corelib/kernel/qmetatype.h | 1 + tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 1e2a860d8c..b854dc16fd 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1381,6 +1381,7 @@ QT_WARNING_DISABLE_CLANG("-Wlocal-type-template-args") // qt_getEnumMetaObject(T) which returns 'char' enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) }; }; + template<> struct IsQEnumHelper { enum { Value = false }; }; QT_WARNING_POP template diff --git a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp index 17b00ebf63..5a10cf51e6 100644 --- a/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp +++ b/tests/auto/corelib/kernel/qmetaenum/tst_qmetaenum.cpp @@ -91,5 +91,13 @@ void tst_QMetaEnum::valuesToKeys() QCOMPARE(me.valueToKeys(windowFlags), expected); } +Q_STATIC_ASSERT(QtPrivate::IsQEnumHelper::Value); +Q_STATIC_ASSERT(QtPrivate::IsQEnumHelper::Value); +Q_STATIC_ASSERT(QtPrivate::IsQEnumHelper::Value); +Q_STATIC_ASSERT(!QtPrivate::IsQEnumHelper::Value); +Q_STATIC_ASSERT(!QtPrivate::IsQEnumHelper::Value); +Q_STATIC_ASSERT(!QtPrivate::IsQEnumHelper::Value); +Q_STATIC_ASSERT(!QtPrivate::IsQEnumHelper::Value); + QTEST_MAIN(tst_QMetaEnum) #include "tst_qmetaenum.moc" -- cgit v1.2.3 From 59840faacfb682a9503c026a6e0357c6ebf97b00 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 23 Apr 2015 14:22:53 +0200 Subject: Respecting correct text interaction flags when setting text cursor. Currently the text cursor is hidden when a cursor was set using setTextCursor on a widget with a widget text control and the interaction flag TextSelectableByKeyboard. The documentation indicates that this is incorrect behavior. Change-Id: I624a470617f15d09f5772213016e552a5149424c Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/widgets/widgets/qwidgettextcontrol.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index faa63cb400..53b2406fc1 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -883,7 +883,8 @@ void QWidgetTextControl::setTextCursor(const QTextCursor &cursor) const bool posChanged = cursor.position() != d->cursor.position(); const QTextCursor oldSelection = d->cursor; d->cursor = cursor; - d->cursorOn = d->hasFocus && (d->interactionFlags & Qt::TextEditable); + d->cursorOn = d->hasFocus + && (d->interactionFlags & (Qt::TextSelectableByKeyboard | Qt::TextEditable)); d->_q_updateCurrentCharFormatAndSelection(); ensureCursorVisible(); d->repaintOldAndNewSelection(oldSelection); @@ -2138,7 +2139,7 @@ void QWidgetTextControlPrivate::focusEvent(QFocusEvent *e) #ifdef QT_KEYPAD_NAVIGATION if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason))) { #endif - cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard); + cursorOn = (interactionFlags & (Qt::TextSelectableByKeyboard | Qt::TextEditable)); if (interactionFlags & Qt::TextEditable) { setBlinkingCursorEnabled(true); } -- cgit v1.2.3 From a4848142b4b53dc541cc3851055761bdb7f50986 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Wed, 22 Apr 2015 13:34:38 +0200 Subject: Doc: added doc for non-documented functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-36985 Change-Id: I85f58c2877d83b98bf3427cbb0f567575803524f Reviewed-by: Venugopal Shivashankar Reviewed-by: Topi Reiniö --- src/dbus/qdbusunixfiledescriptor.cpp | 6 ++++++ src/dbus/qdbusvirtualobject.cpp | 6 ++++++ src/gui/accessible/qaccessible.cpp | 6 ++++++ src/sql/kernel/qsqlresult.cpp | 3 +++ src/sql/models/qsqltablemodel.cpp | 8 ++++++++ 5 files changed, 29 insertions(+) diff --git a/src/dbus/qdbusunixfiledescriptor.cpp b/src/dbus/qdbusunixfiledescriptor.cpp index 96caa80549..77f48c03a4 100644 --- a/src/dbus/qdbusunixfiledescriptor.cpp +++ b/src/dbus/qdbusunixfiledescriptor.cpp @@ -173,6 +173,12 @@ QDBusUnixFileDescriptor &QDBusUnixFileDescriptor::operator=(const QDBusUnixFileD return *this; } +/*! + \fn QDBusUnixFileDescriptor &operator=(QDBusUnixFileDescriptor &&other) + + Move-assigns \a other to this QDBusUnixFileDescriptor. +*/ + /*! Destroys this QDBusUnixFileDescriptor object and disposes of the Unix file descriptor that it contained. */ diff --git a/src/dbus/qdbusvirtualobject.cpp b/src/dbus/qdbusvirtualobject.cpp index aeeb2a1f2b..b65e71eef7 100644 --- a/src/dbus/qdbusvirtualobject.cpp +++ b/src/dbus/qdbusvirtualobject.cpp @@ -37,11 +37,17 @@ QT_BEGIN_NAMESPACE +/*! + Constructs a QDBusVirtualObject with \a parent. +*/ QDBusVirtualObject::QDBusVirtualObject(QObject *parent) : QObject(parent) { } +/*! + Destroys the object, deleting all of its child objects. +*/ QDBusVirtualObject::~QDBusVirtualObject() { } diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index cc9d789c6a..5b6bae7cab 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -1409,6 +1409,12 @@ QAccessible::Id QAccessibleEvent::uniqueId() const Constructs a new QAccessibleStateChangeEvent for \a object. The difference to the object's previous state is in \a state. */ +/*! + \fn QAccessibleStateChangeEvent::QAccessibleStateChangeEvent(QAccessibleInterface *iface, QAccessible::State state) + Constructs a new QAccessibleStateChangeEvent. + \a iface is the interface associated with the event + \a state is the state of the accessible object. +*/ /*! \fn QAccessible::State QAccessibleStateChangeEvent::changedStates() const \brief Returns the states that have been changed. diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 6262c25e0d..c35fca7217 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -837,6 +837,9 @@ QString QSqlResult::executedQuery() const return d->executedQuery; } +/*! + Resets the number of bind parameters. +*/ void QSqlResult::resetBindCount() { Q_D(QSqlResult); diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index b687ae568d..b0d3e6df9d 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -1302,6 +1302,14 @@ Qt::ItemFlags QSqlTableModel::flags(const QModelIndex &index) const return QSqlQueryModel::flags(index) | Qt::ItemIsEditable; } +/*! + This is an overloaded function. + + It returns an empty record, having only the field names. This function can be used to + retrieve the field names of a record. + + \sa QSqlRecord::isEmpty() +*/ QSqlRecord QSqlTableModel::record() const { return QSqlQueryModel::record(); -- cgit v1.2.3 From c056e529c808f52e4d9e77b6112e805bdc7d660e Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Thu, 7 May 2015 10:33:39 +0200 Subject: Doc: added doc to undocumented functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-36985 Change-Id: Ia98654f88cf5da77245b3fcd903b860d12862fc2 Reviewed-by: Martin Smith Reviewed-by: Topi Reiniö --- src/corelib/codecs/qtextcodec.cpp | 23 ++++++- src/corelib/global/qnamespace.qdoc | 17 +++++ src/corelib/tools/qcollator.cpp | 22 ++++-- src/corelib/tools/qpair.qdoc | 54 +++++++++------ src/corelib/tools/qregularexpression.cpp | 20 ++++++ src/corelib/tools/qscopedpointer.cpp | 7 ++ src/corelib/tools/qset.qdoc | 13 ++++ src/corelib/tools/qstring.cpp | 112 ++++++++++++++++++++++++++++++- 8 files changed, 237 insertions(+), 31 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 050f8f207f..8fef333a77 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -1147,13 +1147,30 @@ QTextCodec *QTextCodec::codecForUtfText(const QByteArray &ba) return codecForUtfText(ba, QTextCodec::codecForMib(/*Latin 1*/ 4)); } +/*! + \fn QTextCodec * QTextCodec::codecForTr () + \obsolete + + Returns the codec used by QObject::tr() on its argument. If this + function returns 0 (the default), tr() assumes Latin-1. + + \sa setCodecForTr() +*/ + +/*! + \fn QTextCodec::setCodecForTr ( QTextCodec * c ) + \obsolete + + Sets the codec used by QObject::tr() on its argument to c. If c + is 0 (the default), tr() assumes Latin-1. +*/ /*! \internal \since 4.3 - Determines whether the decoder encountered a failure while decoding the input. If - an error was encountered, the produced result is undefined, and gets converted as according - to the conversion flags. + Determines whether the decoder encountered a failure while decoding the + input. If an error was encountered, the produced result is undefined, and + gets converted as according to the conversion flags. */ bool QTextDecoder::hasFailure() const { diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index f9d968d47b..38ee8edb49 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2907,6 +2907,23 @@ \sa QWidget::grabGesture(), QGraphicsObject::grabGesture() */ +/*! + \enum Qt::NativeGestureType + \since 5.2 + + This enum returns the gesture type. + + \value BeginNativeGesture Sent before gesture event stream. + \value EndNativeGesture Sent after gesture event stream. + \value PanNativeGesture Sent after a panning gesture. + Similar to a click-and-drag mouse movement. + \value ZoomNativeGesture Specifies the magnification delta in percent. + \value SmartZoomNativeGesture Boolean magnification state. + \value RotateNativeGesture Rotation delta in degrees. + \value SwipeNativeGesture Sent after a swipe movements. + +*/ + /*! \enum Qt::NavigationMode \since 4.6 diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp index 9148ecf6fc..615b7a4e3e 100644 --- a/src/corelib/tools/qcollator.cpp +++ b/src/corelib/tools/qcollator.cpp @@ -87,7 +87,7 @@ QCollator::QCollator(const QCollator &other) } /*! - Destroys the collator. + Destructor for QCollator. */ QCollator::~QCollator() { @@ -109,8 +109,8 @@ QCollator &QCollator::operator=(const QCollator &other) return *this; } -/* - \fn void QCollator::QCollator(QCollator &&other) +/*! + \fn QCollator::QCollator(QCollator &&other) Move constructor. Moves from \a other into this collator. @@ -119,8 +119,8 @@ QCollator &QCollator::operator=(const QCollator &other) one of the assignment operators is undefined. */ -/* - \fn QCollator &QCollator::operator=(QCollator &&other) +/*! + \fn QCollator & QCollator::operator=(QCollator && other) Move-assigns from \a other to this collator. @@ -366,6 +366,12 @@ QCollatorSortKey& QCollatorSortKey::operator=(const QCollatorSortKey &other) return *this; } +/*! + \fn QCollatorSortKey &QCollatorSortKey::operator=(QCollatorSortKey && other) + + Move-assigns \a other to this collator key. +*/ + /*! \fn bool operator<(const QCollatorSortKey &lhs, const QCollatorSortKey &rhs) \relates QCollatorSortKey @@ -376,6 +382,12 @@ QCollatorSortKey& QCollatorSortKey::operator=(const QCollatorSortKey &other) \sa QCollatorSortKey::compare() */ +/*! + \fn void QCollatorSortKey::swap(QCollatorSortKey & other) + + Swaps this collator key with \a other. +*/ + /*! \fn int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const diff --git a/src/corelib/tools/qpair.qdoc b/src/corelib/tools/qpair.qdoc index 48555ed6d1..4452d2f0b8 100644 --- a/src/corelib/tools/qpair.qdoc +++ b/src/corelib/tools/qpair.qdoc @@ -96,6 +96,30 @@ \sa qMakePair() */ +\fn void QPair::swap(QPair &other) + + \since 5.5 + Swaps this pair with \a other. + + Equivalent to + \code + qSwap(this->first, other.first); + qSwap(this->second, other.second); + \endcode + + Swap overloads are found in namespace \c std as well as via + argument-dependent lookup (ADL) in \c{T}'s namespace. +*/ + +/*! +\fn void swap(QPair &lhs, QPair &rhs) + \overload + \relates QPair + \since 5.5 + + Swaps \a lhs with \a rhs. +*/ + /*! \fn QPair::QPair(const QPair &p) \since 5.2 @@ -108,37 +132,27 @@ */ /*! - \fn QPair &QPair::operator=(const QPair &p) + \fn QPair::QPair(QPair &&p) \since 5.2 - Copies the pair \a p onto this pair. - - \sa qMakePair() + Move-constructs a QPair instance, making it point to the same object that + \a p was pointing to. */ /*! - \fn void QPair::swap(QPair &other) - \since 5.5 - - Swaps this pair with \a other. + \fn QPair & QPair::operator=(const QPair &p) + \since 5.2 - Equivalent to - \code - qSwap(this->first, other.first); - qSwap(this->second, other.second); - \endcode + Copies pair \a p into this pair. - Swap overloads are found in namespace \c std as well as via - argument-dependent lookup (ADL) in \c{T}'s namespace. + \sa qMakePair() */ /*! - \fn void swap(QPair &lhs, QPair &rhs) - \overload - \relates QPair - \since 5.5 + \fn QPair & QPair::operator=(QPair &&p) + \since 5.2 - Swaps \a lhs with \a rhs. + Move-assigns pair \a p into this pair instance. */ /*! \fn bool operator==(const QPair &p1, const QPair &p2) diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp index 9950b90720..2e3c2ca79f 100644 --- a/src/corelib/tools/qregularexpression.cpp +++ b/src/corelib/tools/qregularexpression.cpp @@ -1828,6 +1828,13 @@ bool QRegularExpression::operator==(const QRegularExpression &re) const (d->pattern == re.d->pattern && d->patternOptions == re.d->patternOptions); } +/*! + \fn QRegularExpression & QRegularExpression::operator=(QRegularExpression && re) + + Move-assigns the regular expression \a re to this object, and returns a reference + to the copy. Both the pattern and the pattern options are copied. +*/ + /*! \fn bool QRegularExpression::operator!=(const QRegularExpression &re) const @@ -1939,6 +1946,13 @@ QRegularExpressionMatch &QRegularExpressionMatch::operator=(const QRegularExpres return *this; } +/*! + \fn QRegularExpressionMatch &QRegularExpressionMatch::operator=(QRegularExpressionMatch &&match) + + Move-assigns the match result \a match to this object, and returns a reference + to the copy. +*/ + /*! \fn void QRegularExpressionMatch::swap(QRegularExpressionMatch &other) @@ -2303,6 +2317,12 @@ QRegularExpressionMatchIterator &QRegularExpressionMatchIterator::operator=(cons return *this; } +/*! + \fn QRegularExpressionMatchIterator &QRegularExpressionMatchIterator::operator=(QRegularExpressionMatchIterator &&iterator) + + Move-assigns the \a iterator to this object. +*/ + /*! \fn void QRegularExpressionMatchIterator::swap(QRegularExpressionMatchIterator &other) diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp index 35551f4061..c113c38aa2 100644 --- a/src/corelib/tools/qscopedpointer.cpp +++ b/src/corelib/tools/qscopedpointer.cpp @@ -254,6 +254,13 @@ QT_BEGIN_NAMESPACE Constructs a QScopedArrayPointer instance. */ +/*! + \fn QScopedArrayPointer::QScopedArrayPointer(D * p, QtPrivate::QScopedArrayEnsureSameType::Type = 0) + \internal + + Constructs a QScopedArrayPointer and stores the array of objects. +*/ + /*! \fn T *QScopedArrayPointer::operator[](int i) diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc index 94cfa729f5..c38fe858fb 100644 --- a/src/corelib/tools/qset.qdoc +++ b/src/corelib/tools/qset.qdoc @@ -126,6 +126,13 @@ \sa operator=() */ +/*! + \fn QSet::QSet(QSet && other) + + Move-constructs a QSet instance, making it point to the same object that \a other was pointing to. +*/ + + /*! \fn QSet &QSet::operator=(const QSet &other) @@ -133,6 +140,12 @@ this set. */ +/*! + \fn QSet &QSet::operator=(QSet &&other) + + Move-assigns the \a other set to this set. +*/ + /*! \fn void QSet::swap(QSet &other) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 51b1617cdc..c933e261cc 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -2661,6 +2661,8 @@ bool QString::operator<(QLatin1String other) const /*! \fn bool QString::operator<=(const QString &s1, const QString &s2) + \relates Qstring + Returns \c true if string \a s1 is lexically less than or equal to string \a s2; otherwise returns \c false. @@ -2706,9 +2708,10 @@ bool QString::operator<(QLatin1String other) const */ /*! \fn bool QString::operator>(const QString &s1, const QString &s2) + \relates QString - Returns \c true if string \a s1 is lexically greater than string \a - s2; otherwise returns \c false. + Returns \c true if string \a s1 is lexically greater than string \a s2; + otherwise returns \c false. The comparison is based exclusively on the numeric Unicode values of the characters and is very fast, but is not what a human would @@ -8795,6 +8798,110 @@ bool operator<(const QStringRef &s1,const QStringRef &s2) this string reference, returning the result. */ +/*! + \fn bool QStringRef::operator==(const char * s) const + + \overload operator==() + + The \a s byte array is converted to a QStringRef using the + fromUtf8() function. This function stops conversion at the + first NUL character found, or the end of the byte array. + + You can disable this operator by defining \c + QT_NO_CAST_FROM_ASCII when you compile your applications. This + can be useful if you want to ensure that all user-visible strings + go through QObject::tr(), for example. + + Returns \c true if this string is lexically equal to the parameter + string \a s. Otherwise returns \c false. + +*/ + +/*! + \fn bool QStringRef::operator!=(const char * s) const + + \overload operator!=() + + The \a s const char pointer is converted to a QStringRef using + the fromUtf8() function. + + You can disable this operator by defining \c + QT_NO_CAST_FROM_ASCII when you compile your applications. This + can be useful if you want to ensure that all user-visible strings + go through QObject::tr(), for example. + + Returns \c true if this string is not lexically equal to the parameter + string \a s. Otherwise returns \c false. +*/ + +/*! + \fn bool QStringRef::operator<(const char * s) const + + \overload operator<() + + The \a s const char pointer is converted to a QStringRef using + the fromUtf8() function. + + You can disable this operator by defining \c + QT_NO_CAST_FROM_ASCII when you compile your applications. This + can be useful if you want to ensure that all user-visible strings + go through QObject::tr(), for example. + + Returns \c true if this string is lexically smaller than the parameter + string \a s. Otherwise returns \c false. +*/ + +/*! + \fn bool QStringRef::operator<=(const char * s) const + + \overload operator<=() + + The \a s const char pointer is converted to a QStringRef using + the fromUtf8() function. + + You can disable this operator by defining \c + QT_NO_CAST_FROM_ASCII when you compile your applications. This + can be useful if you want to ensure that all user-visible strings + go through QObject::tr(), for example. + + Returns \c true if this string is lexically smaller than or equal to the parameter + string \a s. Otherwise returns \c false. +*/ + +/*! + \fn bool QStringRef::operator>(const char * s) const + + + \overload operator>() + + The \a s const char pointer is converted to a QStringRef using + the fromUtf8() function. + + You can disable this operator by defining \c + QT_NO_CAST_FROM_ASCII when you compile your applications. This + can be useful if you want to ensure that all user-visible strings + go through QObject::tr(), for example. + + Returns \c true if this string is lexically greater than the parameter + string \a s. Otherwise returns \c false. +*/ + +/*! + \fn bool QStringRef::operator>= (const char * s) const + + \overload operator>=() + + The \a s const char pointer is converted to a QStringRef using + the fromUtf8() function. + + You can disable this operator by defining \c + QT_NO_CAST_FROM_ASCII when you compile your applications. This + can be useful if you want to ensure that all user-visible strings + go through QObject::tr(), for example. + + Returns \c true if this string is lexically greater than or equal to the + parameter string \a s. Otherwise returns \c false. +*/ /*! \typedef QString::Data \internal @@ -10205,7 +10312,6 @@ QString QString::toHtmlEscaped() const \endlist */ - /*! \internal */ -- cgit v1.2.3 From 31e055cee97b5d41ff0bed3246b5e85a8d954164 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 20 Apr 2015 12:52:55 +0200 Subject: Fix typo and formatting in QWidget font documentation. Change-Id: I6dea7f1aa2827dbc4c4068184690c80a36ef2be6 Reviewed-by: Venugopal Shivashankar --- src/widgets/kernel/qwidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 910468b53a..e701eb07ba 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -4859,7 +4859,7 @@ void QWidget::unsetLayoutDirection() \fn QFontMetrics QWidget::fontMetrics() const Returns the font metrics for the widget's current font. - Equivalent to QFontMetrics(widget->font()). + Equivalent to \c QFontMetrics(widget->font()). \sa font(), fontInfo(), setFont() */ @@ -4868,7 +4868,7 @@ void QWidget::unsetLayoutDirection() \fn QFontInfo QWidget::fontInfo() const Returns the font info for the widget's current font. - Equivalent to QFontInto(widget->font()). + Equivalent to \c QFontInfo(widget->font()). \sa font(), fontMetrics(), setFont() */ -- cgit v1.2.3 From f65c04b37e63526540f9717a63fd305f4c3ac579 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 12 May 2015 15:06:53 +0200 Subject: WinRT/Winphone: Fix warnings in qtbase Change-Id: I41725bcfeee0124b259e96f1e3a261e30f14350a Reviewed-by: Kai Koehne Reviewed-by: Maurice Kalinowski --- src/corelib/codecs/qwindowscodec.cpp | 2 +- src/corelib/io/qlockfile_win.cpp | 6 +++++- src/corelib/kernel/qeventdispatcher_winrt.cpp | 3 ++- src/network/kernel/qhostinfo_winrt.cpp | 1 - src/widgets/dialogs/qfileinfogatherer.cpp | 2 ++ src/widgets/dialogs/qfilesystemmodel.cpp | 4 +++- src/widgets/styles/qwindowsstyle.cpp | 9 +++++---- 7 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/corelib/codecs/qwindowscodec.cpp b/src/corelib/codecs/qwindowscodec.cpp index cf427c64b6..0f8c5e1a4e 100644 --- a/src/corelib/codecs/qwindowscodec.cpp +++ b/src/corelib/codecs/qwindowscodec.cpp @@ -172,7 +172,7 @@ QString QWindowsLocalCodec::convertToUnicodeCharByChar(const char *chars, int le } #else QString s; - int size = mbstowcs(NULL, mb, length); + size_t size = mbstowcs(NULL, mb, length); if (size < 0) { Q_ASSERT("Error in CE TextCodec"); return QString(); diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index 27a63e126a..4e0d8134ec 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -142,7 +142,11 @@ bool QLockFilePrivate::isApparentlyStale() const return true; } } -#endif // !Q_OS_WINRT +#else // !Q_OS_WINRT + Q_UNUSED(pid); + Q_UNUSED(hostname); + Q_UNUSED(appname); +#endif // Q_OS_WINRT const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); return staleLockTime > 0 && age > staleLockTime; } diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index cc8e961be1..b5cfccd649 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -484,7 +484,8 @@ bool QEventDispatcherWinRT::event(QEvent *e) QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate() { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); - HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Threading_ThreadPoolTimer).Get(), &timerFactory); + HRESULT hr; + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Threading_ThreadPoolTimer).Get(), &timerFactory); Q_ASSERT_SUCCEEDED(hr); HANDLE interruptHandle = CreateEventEx(NULL, NULL, NULL, SYNCHRONIZE|EVENT_MODIFY_STATE); timerIdToHandle.insert(INTERRUPT_HANDLE, interruptHandle); diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp index 0e606c2070..1a97fe0e40 100644 --- a/src/network/kernel/qhostinfo_winrt.cpp +++ b/src/network/kernel/qhostinfo_winrt.cpp @@ -35,7 +35,6 @@ #include -#include #include #include #include diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp index df07de7975..7329019a87 100644 --- a/src/widgets/dialogs/qfileinfogatherer.cpp +++ b/src/widgets/dialogs/qfileinfogatherer.cpp @@ -185,6 +185,8 @@ void QFileInfoGatherer::removePath(const QString &path) #ifndef QT_NO_FILESYSTEMWATCHER QMutexLocker locker(&mutex); watcher->removePath(path); +#else + Q_UNUSED(path); #endif } diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 88d327168c..4859231d95 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -653,10 +653,12 @@ int QFileSystemModel::columnCount(const QModelIndex &parent) const */ QVariant QFileSystemModel::myComputer(int role) const { +#ifndef QT_NO_FILESYSTEMWATCHER Q_D(const QFileSystemModel); +#endif switch (role) { case Qt::DisplayRole: - return d->myComputer(); + return QFileSystemModelPrivate::myComputer(); #ifndef QT_NO_FILESYSTEMWATCHER case Qt::DecorationRole: return d->fileInfoGatherer.iconProvider()->icon(QFileIconProvider::Computer); diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index bed2b5c57a..14af5ede39 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -299,8 +299,8 @@ void QWindowsStyle::polish(QPalette &pal) int QWindowsStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *, const QWidget *widget) { - switch (pm) { #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) + switch (pm) { case QStyle::PM_DockWidgetFrameWidth: # ifndef Q_OS_WINCE return GetSystemMetrics(SM_CXFRAME); @@ -337,13 +337,14 @@ int QWindowsStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const # else return GetSystemMetrics(SM_CYDLGFRAME); # endif -#else - Q_UNUSED(widget) -#endif // Q_OS_WIN default: break; } +#else // Q_OS_WIN && !Q_OS_WINRT + Q_UNUSED(pm); + Q_UNUSED(widget); +#endif return QWindowsStylePrivate::InvalidMetric; } -- cgit v1.2.3 From 661f604fbc8d16151f1d523b0c140d610329f67b Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 13 Apr 2015 15:55:13 +0200 Subject: Let MSVC treat warnings as errors Treat warnings printed by MSVC 2012, 2013 as errors in the modules that declare themselves warning_clean (for developer builds). Change-Id: I55fb3bde460e13cfdbd6f59634e3b5335b2dd715 Reviewed-by: Thiago Macieira Reviewed-by: Friedemann Kleint --- mkspecs/features/qt_common.prf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index 6a66b76305..5861941848 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -79,6 +79,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 } unset(ver) } -- cgit v1.2.3 From e124ad54b8c1944435e7a26efb109dc0ca3a07e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 17 Apr 2015 15:08:21 +0200 Subject: Allow RESOURCES to contain standalone files and collections of files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Standalone files are added by using RESOURCES += file.txt, while collections of files are defined as collection.files = f1.txt f2.txt and then added using RESOURCES += collection. For collections a prefix can also be set using collection.prefix = /foo. The standalone files are not prefixed. Change-Id: I8236808238414da05e744f799a1bb15a72f4a46f Reviewed-by: Tor Arne Vestbø --- mkspecs/features/resources.prf | 60 ++++++++++++++++++++++ tests/auto/tools/qmake/qmake.pro | 6 +++ tests/auto/tools/qmake/testdata/resources/main.cpp | 42 +++++++++++++++ .../tools/qmake/testdata/resources/resources.pro | 10 ++++ .../tools/qmake/testdata/resources/subdir/file.txt | 0 tests/auto/tools/qmake/testdata/resources/test.qrc | 5 ++ tests/auto/tools/qmake/tst_qmake.cpp | 42 +++++++++++++++ 7 files changed, 165 insertions(+) create mode 100644 tests/auto/tools/qmake/testdata/resources/main.cpp create mode 100644 tests/auto/tools/qmake/testdata/resources/resources.pro create mode 100644 tests/auto/tools/qmake/testdata/resources/subdir/file.txt create mode 100644 tests/auto/tools/qmake/testdata/resources/test.qrc diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf index 8564731a22..7a38ff8f38 100644 --- a/mkspecs/features/resources.prf +++ b/mkspecs/features/resources.prf @@ -6,6 +6,66 @@ isEmpty(QMAKE_MOD_RCC):QMAKE_MOD_RCC = qrc !contains(QMAKE_RESOURCE_FLAGS, -root):!isEmpty(QMAKE_RESOURCE_ROOT):QMAKE_RESOURCE_FLAGS += -root $$QMAKE_RESOURCE_ROOT !contains(QMAKE_RESOURCE_FLAGS, -name): QMAKE_RESOURCE_FLAGS += -name ${QMAKE_FILE_BASE} +# http://www.w3.org/TR/xml/#syntax +defineReplace(xml_escape) { + 1 ~= s,&,&, + 1 ~= s,\',', + 1 ~= s,\",", + 1 ~= s,<,<, + 1 ~= s,>,>, + return($$1) +} + +RESOURCES += qmake_immediate +for(resource, RESOURCES) { + # Regular case of user qrc file + contains(resource, ".*\.qrc$"): \ + next() + + # Fallback for stand-alone files/directories + !defined($${resource}.files, var) { + !equals(resource, qmake_immediate) { + !exists($$absolute_path($$resource, $$_PRO_FILE_PWD_)): \ + warning("Failure to find: $$resource") + qmake_immediate.files += $$resource + } + RESOURCES -= $$resource + next() + } + + resource_file = $$RCC_DIR/qmake_$${resource}.qrc + + !debug_and_release|build_pass { + # Collection of files, generate qrc file + prefix = $$eval($${resource}.prefix) + isEmpty(prefix): \ + prefix = "/" + + resource_file_content = \ + "" \ + "" + + abs_base = $$absolute_path($$eval($${resource}.base), $$_PRO_FILE_PWD_) + + for(file, $${resource}.files) { + abs_path = $$absolute_path($$file, $$_PRO_FILE_PWD_) + alias = $$relative_path($$abs_path, $$abs_base) + resource_file_content += \ + "$$xml_escape($$abs_path)" + } + + resource_file_content += \ + "" \ + "" + + !write_file($$OUT_PWD/$$resource_file, resource_file_content): \ + error("Aborting.") + } + + RESOURCES -= $$resource + RESOURCES += $$resource_file +} + rcc.input = RESOURCES rcc.name = RCC ${QMAKE_FILE_IN} rcc.depend_command = $$QMAKE_RCC_DEP -list $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN} diff --git a/tests/auto/tools/qmake/qmake.pro b/tests/auto/tools/qmake/qmake.pro index 5ed3073e20..d0817247db 100644 --- a/tests/auto/tools/qmake/qmake.pro +++ b/tests/auto/tools/qmake/qmake.pro @@ -8,5 +8,11 @@ SOURCES += tst_qmake.cpp testcompiler.cpp QT = core testlib cross_compile: DEFINES += QMAKE_CROSS_COMPILED +debug_and_release { + CONFIG(debug, debug|release): \ + DEFINES += DEBUG_BUILD + else: \ + DEFINES += RELEASE_BUILD +} TESTDATA += testdata/* diff --git a/tests/auto/tools/qmake/testdata/resources/main.cpp b/tests/auto/tools/qmake/testdata/resources/main.cpp new file mode 100644 index 0000000000..78f9814396 --- /dev/null +++ b/tests/auto/tools/qmake/testdata/resources/main.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + + +#include + +int main( int argc, char **argv ) +{ + QGuiApplication a( argc, argv ); + return a.exec(); +} diff --git a/tests/auto/tools/qmake/testdata/resources/resources.pro b/tests/auto/tools/qmake/testdata/resources/resources.pro new file mode 100644 index 0000000000..f024fe5617 --- /dev/null +++ b/tests/auto/tools/qmake/testdata/resources/resources.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +SOURCES = main.cpp + +pro_file.files = resources.pro +pro_file.prefix = /prefix + +subdir.files = subdir/file.txt +subdir.base = subdir + +RESOURCES = test.qrc main.cpp pro_file subdir diff --git a/tests/auto/tools/qmake/testdata/resources/subdir/file.txt b/tests/auto/tools/qmake/testdata/resources/subdir/file.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/tools/qmake/testdata/resources/test.qrc b/tests/auto/tools/qmake/testdata/resources/test.qrc new file mode 100644 index 0000000000..decde3dd24 --- /dev/null +++ b/tests/auto/tools/qmake/testdata/resources/test.qrc @@ -0,0 +1,5 @@ + + + test.qrc + + diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp index 8d7f7bbc68..48c6c0ac84 100644 --- a/tests/auto/tools/qmake/tst_qmake.cpp +++ b/tests/auto/tools/qmake/tst_qmake.cpp @@ -39,6 +39,14 @@ #include #include +#if defined(DEBUG_BUILD) +# define DIR_INFIX "debug/" +#elif defined(RELEASE_BUILD) +# define DIR_INFIX "release/" +#else +# define DIR_INFIX "" +#endif + class tst_qmake : public QObject { Q_OBJECT @@ -85,6 +93,7 @@ private slots: void project(); void proFileCache(); void json(); + void resources(); private: TestCompiler test_compiler; @@ -583,5 +592,38 @@ void tst_qmake::json() QVERIFY(output.contains("json.false is false")); } +void tst_qmake::resources() +{ + QString workDir = base_path + "/testdata/resources"; + QVERIFY(test_compiler.qmake(workDir, "resources")); + + { + QFile qrcFile(workDir + "/.rcc/" DIR_INFIX "qmake_pro_file.qrc"); + QVERIFY(qrcFile.exists()); + QVERIFY(qrcFile.open(QFile::ReadOnly)); + QByteArray qrcXml = qrcFile.readAll(); + QVERIFY(qrcXml.contains("alias=\"resources.pro\"")); + QVERIFY(qrcXml.contains("prefix=\"/prefix\"")); + } + + { + QFile qrcFile(workDir + "/.rcc/" DIR_INFIX "qmake_subdir.qrc"); + QVERIFY(qrcFile.exists()); + QVERIFY(qrcFile.open(QFile::ReadOnly)); + QByteArray qrcXml = qrcFile.readAll(); + QVERIFY(qrcXml.contains("alias=\"file.txt\"")); + } + + { + QFile qrcFile(workDir + "/.rcc/" DIR_INFIX "qmake_qmake_immediate.qrc"); + QVERIFY(qrcFile.exists()); + QVERIFY(qrcFile.open(QFile::ReadOnly)); + QByteArray qrcXml = qrcFile.readAll(); + QVERIFY(qrcXml.contains("alias=\"main.cpp\"")); + } + + QVERIFY(test_compiler.make(workDir)); +} + QTEST_MAIN(tst_qmake) #include "tst_qmake.moc" -- cgit v1.2.3 From 412eb090c9b7d17a3f5b0fbc0f3aebdce70a443b Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 12 May 2015 12:52:06 +0200 Subject: Fix GLES3 functions on iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-45933 Change-Id: I784e34c1cfee5ea69955c221f0448c1d04e0b6d7 Reviewed-by: jian liang Reviewed-by: Tor Arne Vestbø --- src/gui/opengl/qopenglextensions_p.h | 3 ++ src/gui/opengl/qopenglfunctions.cpp | 70 +++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h index ff5d79566c..7def687f49 100644 --- a/src/gui/opengl/qopenglextensions_p.h +++ b/src/gui/opengl/qopenglextensions_p.h @@ -76,6 +76,9 @@ public: void (QOPENGLF_APIENTRYP TexStorage2D)(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height); private: + bool init(); + QFunctionPointer resolve(const char *name); + QLibrary m_gl; }; diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 49926a4d93..b9d674fd3b 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -39,6 +39,10 @@ #include #include +#ifdef Q_OS_IOS +#include +#endif + #ifndef GL_FRAMEBUFFER_SRGB_CAPABLE_EXT #define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA #endif @@ -3202,35 +3206,53 @@ static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribPointer(GLuint indx, GL Q_GLOBAL_STATIC(QOpenGLES3Helper, qgles3Helper) -QOpenGLES3Helper::QOpenGLES3Helper() +bool QOpenGLES3Helper::init() { -#ifdef Q_OS_WIN -#ifdef QT_DEBUG +#ifndef Q_OS_IOS +# ifdef Q_OS_WIN +# ifndef QT_DEBUG m_gl.setFileName(QStringLiteral("libGLESv2")); -#else +# else m_gl.setFileName(QStringLiteral("libGLESv2d")); -#endif -#else +# endif +# else m_gl.setFileName(QStringLiteral("GLESv2")); +# endif // Q_OS_WIN + return m_gl.load(); +#else + return true; +#endif // Q_OS_IOS +} + +QFunctionPointer QOpenGLES3Helper::resolve(const char *name) +{ +#ifdef Q_OS_IOS + return QFunctionPointer(dlsym(RTLD_DEFAULT, name)); +#else + return m_gl.resolve(name); #endif - if (m_gl.load()) { - MapBufferRange = (GLvoid* (QOPENGLF_APIENTRYP)(GLenum, qopengl_GLintptr, qopengl_GLsizeiptr, GLbitfield)) m_gl.resolve("glMapBufferRange"); - UnmapBuffer = (GLboolean (QOPENGLF_APIENTRYP)(GLenum)) m_gl.resolve("glUnmapBuffer"); - BlitFramebuffer = (void (QOPENGLF_APIENTRYP)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) m_gl.resolve("glBlitFramebuffer"); - RenderbufferStorageMultisample = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) m_gl.resolve("glRenderbufferStorageMultisample"); - - GenVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, GLuint *)) m_gl.resolve("glGenVertexArrays"); - DeleteVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, const GLuint *)) m_gl.resolve("glDeleteVertexArrays"); - BindVertexArray = (void (QOPENGLF_APIENTRYP)(GLuint)) m_gl.resolve("glBindVertexArray"); - IsVertexArray = (GLboolean (QOPENGLF_APIENTRYP)(GLuint)) m_gl.resolve("glIsVertexArray"); - - TexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) m_gl.resolve("glTexImage3D"); - TexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) m_gl.resolve("glTexSubImage3D"); - CompressedTexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) m_gl.resolve("glCompressedTexImage3D"); - CompressedTexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) m_gl.resolve("glCompressedTexSubImage3D"); - - TexStorage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei)) m_gl.resolve("glTexStorage3D"); - TexStorage2D = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) m_gl.resolve("glTexStorage2D"); +} + +QOpenGLES3Helper::QOpenGLES3Helper() +{ + if (init()) { + MapBufferRange = (GLvoid* (QOPENGLF_APIENTRYP)(GLenum, qopengl_GLintptr, qopengl_GLsizeiptr, GLbitfield)) resolve("glMapBufferRange"); + UnmapBuffer = (GLboolean (QOPENGLF_APIENTRYP)(GLenum)) resolve("glUnmapBuffer"); + BlitFramebuffer = (void (QOPENGLF_APIENTRYP)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) resolve("glBlitFramebuffer"); + RenderbufferStorageMultisample = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glRenderbufferStorageMultisample"); + + GenVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, GLuint *)) resolve("glGenVertexArrays"); + DeleteVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, const GLuint *)) resolve("glDeleteVertexArrays"); + BindVertexArray = (void (QOPENGLF_APIENTRYP)(GLuint)) resolve("glBindVertexArray"); + IsVertexArray = (GLboolean (QOPENGLF_APIENTRYP)(GLuint)) resolve("glIsVertexArray"); + + TexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) resolve("glTexImage3D"); + TexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) resolve("glTexSubImage3D"); + CompressedTexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) resolve("glCompressedTexImage3D"); + CompressedTexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) resolve("glCompressedTexSubImage3D"); + + TexStorage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei)) resolve("glTexStorage3D"); + TexStorage2D = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) resolve("glTexStorage2D"); if (!MapBufferRange || !GenVertexArrays || !TexImage3D || !TexStorage3D) qFatal("OpenGL ES 3.0 entry points not found"); -- cgit v1.2.3 From 3f0f707d4b898a96e63e16c13a29f12be01d9b4c Mon Sep 17 00:00:00 2001 From: Mikhail Lappo Date: Thu, 7 May 2015 12:18:14 +0300 Subject: Prevent bad-ptrs deref in QNetworkConfigurationManagerPrivate Prevent application to crash with segfault in Qt bearer thread. Corrected hardly reproduceable bug, when QNetworkConfigurationManagerPrivate in pollEngines slot dereferenced null and bad pointers and caused crash Task-number: QTBUG-44407 Change-Id: I2f0b11b2d10125a21a62588d76ad824f375e4a1d Reviewed-by: Richard J. Moore --- src/network/bearer/qnetworkconfigmanager_p.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 6bbea1683c..b963aebbd5 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -75,6 +75,7 @@ QNetworkConfigurationManagerPrivate::~QNetworkConfigurationManagerPrivate() QMutexLocker locker(&mutex); qDeleteAll(sessionEngines); + sessionEngines.clear(); if (bearerThread) bearerThread->quit(); } -- cgit v1.2.3 From 009b11c30086f2ab40d3e86691f34cad31999a8f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 30 Apr 2015 10:23:58 +0200 Subject: QStateMachine: fix RestorableId exception specification We're interested in whether qHash(QByteArray) throws, not declval, of course. Change-Id: If3ba6e90aba69d0d4d12ac289e817f0d9705a601 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/statemachine/qstatemachine_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 5db6489fa9..426f2732df 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -210,7 +210,8 @@ public: QObject *obj; QByteArray prop; // two overloads because friends can't have default arguments - friend uint qHash(const RestorableId &key, uint seed) Q_DECL_NOEXCEPT_EXPR(noexcept(std::declval())) + friend uint qHash(const RestorableId &key, uint seed) + Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(std::declval()))) { return qHash(qMakePair(key.obj, key.prop), seed); } friend uint qHash(const RestorableId &key) Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(key, 0U))) { return qHash(key, 0U); } -- cgit v1.2.3 From 67d255f18343d74bbc9a0eec460995ca615473be Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 12 May 2015 13:06:46 +0200 Subject: QStateMachine: empty the whole internal queue before external queue If the internal queue contained multiple events, but the first one did not select any transitions, the external event queue would be checked before the remaining events in the internal queue. Change-Id: I1a7f49afdefaaf2b4330bf13b079b61344385ea0 Task-number: QTBUG-46059 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine.cpp | 26 ++++++--------- .../qstatemachine/tst_qstatemachine.cpp | 39 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index bea6822ecc..e5d019dc8b 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -1925,7 +1925,7 @@ void QStateMachinePrivate::_q_process() delete e; e = 0; } - if (enabledTransitions.isEmpty() && ((e = dequeueInternalEvent()) != 0)) { + while (enabledTransitions.isEmpty() && ((e = dequeueInternalEvent()) != 0)) { #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": dequeued internal event" << e << "of type" << e->type(); #endif @@ -1935,8 +1935,7 @@ void QStateMachinePrivate::_q_process() e = 0; } } - if (enabledTransitions.isEmpty()) { - if ((e = dequeueExternalEvent()) != 0) { + while (enabledTransitions.isEmpty() && ((e = dequeueExternalEvent()) != 0)) { #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": dequeued external event" << e << "of type" << e->type(); #endif @@ -1945,24 +1944,19 @@ void QStateMachinePrivate::_q_process() delete e; e = 0; } - } else { - if (isInternalEventQueueEmpty()) { - processing = false; - stopProcessingReason = EventQueueEmpty; - } - } } - if (!enabledTransitions.isEmpty()) { - didChange = true; - q->beginMicrostep(e); - microstep(e, enabledTransitions, &calculationCache); - q->endMicrostep(e); - } - else { + if (enabledTransitions.isEmpty()) { + processing = false; + stopProcessingReason = EventQueueEmpty; noMicrostep(); #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": no transitions enabled"; #endif + } else { + didChange = true; + q->beginMicrostep(e); + microstep(e, enabledTransitions, &calculationCache); + q->endMicrostep(e); } delete e; } diff --git a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp index 3718b07b33..1292c3b98f 100644 --- a/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp @@ -249,6 +249,7 @@ private slots: void qtbug_44783(); void internalTransition(); void conflictingTransition(); + void qtbug_46059(); }; class TestState : public QState @@ -6446,5 +6447,43 @@ void tst_QStateMachine::conflictingTransition() QVERIFY(machine.isRunning()); } +void tst_QStateMachine::qtbug_46059() +{ + QStateMachine machine; + QState a(&machine); + QState b(&a); + QState c(&a); + QState success(&a); + QState failure(&machine); + + machine.setInitialState(&a); + a.setInitialState(&b); + b.addTransition(new EventTransition(QEvent::Type(QEvent::User + 1), &c)); + c.addTransition(new EventTransition(QEvent::Type(QEvent::User + 2), &success)); + b.addTransition(new EventTransition(QEvent::Type(QEvent::User + 2), &failure)); + + machine.start(); + QCoreApplication::processEvents(); + + QTRY_COMPARE(machine.configuration().contains(&a), true); + QTRY_COMPARE(machine.configuration().contains(&b), true); + QTRY_COMPARE(machine.configuration().contains(&c), false); + QTRY_COMPARE(machine.configuration().contains(&failure), false); + QTRY_COMPARE(machine.configuration().contains(&success), false); + + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 0)), QStateMachine::HighPriority); + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 1)), QStateMachine::HighPriority); + machine.postEvent(new QEvent(QEvent::Type(QEvent::User + 2)), QStateMachine::NormalPriority); + QCoreApplication::processEvents(); + + QTRY_COMPARE(machine.configuration().contains(&a), true); + QTRY_COMPARE(machine.configuration().contains(&b), false); + QTRY_COMPARE(machine.configuration().contains(&c), false); + QTRY_COMPARE(machine.configuration().contains(&failure), false); + QTRY_COMPARE(machine.configuration().contains(&success), true); + + QVERIFY(machine.isRunning()); +} + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" -- cgit v1.2.3 From 528b7b1435d5e542ad45caea194487afd6ed087c Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 19 May 2015 10:26:45 +0200 Subject: Fix warning on WinRT arm Change-Id: Ibc6a34553bb42319a6937e06ef54cf92847da53c Reviewed-by: Oliver Wolff --- src/corelib/codecs/qwindowscodec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/codecs/qwindowscodec.cpp b/src/corelib/codecs/qwindowscodec.cpp index 0f8c5e1a4e..dded93ccb5 100644 --- a/src/corelib/codecs/qwindowscodec.cpp +++ b/src/corelib/codecs/qwindowscodec.cpp @@ -181,7 +181,7 @@ QString QWindowsLocalCodec::convertToUnicodeCharByChar(const char *chars, int le ws[size +1] = 0; ws[size] = 0; size = mbstowcs(ws, mb, length); - for (int i=0; i< size; i++) + for (size_t i = 0; i < size; i++) s.append(QChar(ws[i])); delete [] ws; #endif -- cgit v1.2.3 From f81dda39dd9eb82403127c0f810de3405b53227e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 11 May 2015 15:36:18 +0200 Subject: Manual touch test: Draw touch points. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Draw touch points as dots and mouse points as circles to be able to verify High DPI scaling. Change-Id: I2293adbcc726391f0d9e156935d609b957432029 Reviewed-by: Morten Johan Sørvig Reviewed-by: Shawn Rutledge --- tests/manual/touch/main.cpp | 184 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 159 insertions(+), 25 deletions(-) diff --git a/tests/manual/touch/main.cpp b/tests/manual/touch/main.cpp index f4c9f6bf8b..727e7a32b7 100644 --- a/tests/manual/touch/main.cpp +++ b/tests/manual/touch/main.cpp @@ -38,15 +38,20 @@ #include #include #include +#include #include #include #include #include +#include +#include #include #include #include #include +bool optIgnoreTouch = false; + QDebug operator<<(QDebug debug, const QTouchDevice *d) { QDebugStateSaver saver(debug); @@ -92,27 +97,135 @@ bool EventFilter::eventFilter(QObject *o, QEvent *e) return false; } +enum PointType { + TouchPoint, + MousePress, + MouseRelease +}; + +struct Point +{ + Point(const QPointF &p = QPoint(), PointType t = TouchPoint, + Qt::MouseEventSource s = Qt::MouseEventNotSynthesized) : pos(p), type(t), source(s) {} + + QColor color() const; + + QPointF pos; + PointType type; + Qt::MouseEventSource source; +}; + +QColor Point::color() const +{ + Qt::GlobalColor globalColor = Qt::black; + if (type != TouchPoint) { + switch (source) { + case Qt::MouseEventSynthesizedBySystem: + globalColor = Qt::red; + break; + case Qt::MouseEventSynthesizedByQt: + globalColor = Qt::blue; + break; + case Qt::MouseEventNotSynthesized: + break; + } + } + const QColor result(globalColor); + return type == MousePress ? result.lighter() : result; +} + class TouchTestWidget : public QWidget { + Q_OBJECT + Q_PROPERTY(bool drawPoints READ drawPoints WRITE setDrawPoints) public: - explicit TouchTestWidget(QWidget *parent = 0) : QWidget(parent) + explicit TouchTestWidget(QWidget *parent = 0) : QWidget(parent), m_drawPoints(true) { setAttribute(Qt::WA_AcceptTouchEvents); } - bool event(QEvent *event) Q_DECL_OVERRIDE - { - switch (event->type()) { - case QEvent::TouchBegin: - case QEvent::TouchUpdate: - case QEvent::TouchEnd: + bool drawPoints() const { return m_drawPoints; } + +public slots: + void clearPoints(); + void setDrawPoints(bool drawPoints); + +protected: + bool event(QEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; + +private: + QVector m_points; + bool m_drawPoints; +}; + +void TouchTestWidget::clearPoints() +{ + if (!m_points.isEmpty()) { + m_points.clear(); + update(); + } +} + +void TouchTestWidget::setDrawPoints(bool drawPoints) +{ + if (m_drawPoints != drawPoints) { + clearPoints(); + m_drawPoints = drawPoints; + } +} + +bool TouchTestWidget::event(QEvent *event) +{ + const QEvent::Type type = event->type(); + switch (type) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + if (m_drawPoints) { + const QMouseEvent *me = static_cast(event); + m_points.append(Point(me->localPos(), + type == QEvent::MouseButtonPress ? MousePress : MouseRelease, + me->source())); + update(); + } + break; + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + if (m_drawPoints) { + foreach (const QTouchEvent::TouchPoint &p, static_cast(event)->touchPoints()) + m_points.append(Point(p.pos(), TouchPoint)); + update(); + } + case QEvent::TouchEnd: + if (optIgnoreTouch) + event->ignore(); + else event->accept(); - return true; - default: - break; + return true; + default: + break; + } + return QWidget::event(event); +} + +void TouchTestWidget::paintEvent(QPaintEvent *) +{ + // Draw touch points as dots, mouse press as light filled circles, mouse release as circles. + QPainter painter(this); + const QRectF geom = QRectF(QPointF(0, 0), QSizeF(size())); + painter.fillRect(geom, Qt::white); + painter.drawRect(QRectF(geom.topLeft(), geom.bottomRight() - QPointF(1, 1))); + foreach (const Point &point, m_points) { + if (geom.contains(point.pos)) { + QPainterPath painterPath; + const qreal radius = point.type == TouchPoint ? 1 : 4; + painterPath.addEllipse(point.pos, radius, radius); + if (point.type == MouseRelease) + painter.strokePath(painterPath, QPen(point.color())); + else + painter.fillPath(painterPath, point.color()); } - return QWidget::event(event); } -}; +} class MainWindow : public QMainWindow { @@ -126,7 +239,7 @@ public slots: void dumpTouchDevices(); private: - QWidget *m_touchWidget; + TouchTestWidget *m_touchWidget; QPlainTextEdit *m_logTextEdit; }; @@ -137,23 +250,37 @@ MainWindow::MainWindow() setWindowTitle(QStringLiteral("Touch Event Tester ") + QT_VERSION_STR); setObjectName("MainWin"); + QToolBar *toolBar = new QToolBar(this); + addToolBar(Qt::TopToolBarArea, toolBar); QMenu *fileMenu = menuBar()->addMenu("File"); - QAction *da = fileMenu->addAction(QStringLiteral("Dump devices")); - da->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D)); - connect(da, SIGNAL(triggered()), this, SLOT(dumpTouchDevices())); - QAction *qa = fileMenu->addAction(QStringLiteral("Quit")); - qa->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); - connect(qa, SIGNAL(triggered()), this, SLOT(close())); + QAction *dumpDeviceAction = fileMenu->addAction(QStringLiteral("Dump devices")); + dumpDeviceAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D)); + connect(dumpDeviceAction, SIGNAL(triggered()), this, SLOT(dumpTouchDevices())); + toolBar->addAction(dumpDeviceAction); + QAction *clearLogAction = fileMenu->addAction(QStringLiteral("Clear Log")); + clearLogAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L)); + connect(clearLogAction, SIGNAL(triggered()), m_logTextEdit, SLOT(clear())); + toolBar->addAction(clearLogAction); + QAction *toggleDrawPointAction = fileMenu->addAction(QStringLiteral("Draw Points")); + toggleDrawPointAction->setCheckable(true); + toggleDrawPointAction->setChecked(m_touchWidget->drawPoints()); + connect(toggleDrawPointAction, SIGNAL(toggled(bool)), m_touchWidget, SLOT(setDrawPoints(bool))); + toolBar->addAction(toggleDrawPointAction); + QAction *clearPointAction = fileMenu->addAction(QStringLiteral("Clear Points")); + clearPointAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P)); + connect(clearPointAction, SIGNAL(triggered()), m_touchWidget, SLOT(clearPoints())); + toolBar->addAction(clearPointAction); + QAction *quitAction = fileMenu->addAction(QStringLiteral("Quit")); + quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); + connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); + toolBar->addAction(quitAction); - QSplitter *mainSplitter = new QSplitter(Qt::Vertical); + QSplitter *mainSplitter = new QSplitter(Qt::Vertical, this); m_touchWidget->setObjectName(QStringLiteral("TouchWidget")); - const QSize screenSize = QGuiApplication::primaryScreen()->availableGeometry().size(); - m_touchWidget->setMinimumSize(screenSize / 2); mainSplitter->addWidget(m_touchWidget); m_logTextEdit->setObjectName(QStringLiteral("LogTextEdit")); - m_logTextEdit->setMinimumHeight(screenSize.height() / 4); mainSplitter->addWidget(m_logTextEdit); setCentralWidget(mainSplitter); @@ -183,12 +310,19 @@ int main(int argc, char *argv[]) const QCommandLineOption globalFilterOption(QStringLiteral("global"), QStringLiteral("Global event filter")); parser.addOption(globalFilterOption); + + const QCommandLineOption ignoreTouchOption(QStringLiteral("ignore"), + QStringLiteral("Ignore touch events (for testing mouse emulation).")); + parser.addOption(ignoreTouchOption); parser.process(QApplication::arguments()); + optIgnoreTouch = parser.isSet(ignoreTouchOption); MainWindow w; + const QSize screenSize = QGuiApplication::primaryScreen()->availableGeometry().size(); + w.resize(screenSize / 2); + const QSize sizeDiff = screenSize - w.size(); + w.move(sizeDiff.width() / 2, sizeDiff.height() / 2); w.show(); - const QSize pos = QGuiApplication::primaryScreen()->availableGeometry().size() - w.size(); - w.move(pos.width() / 2, pos.height() / 2); EventTypeVector eventTypes; eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease -- cgit v1.2.3 From e994f39a84b58975ed46ebb60401b5f153362471 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 19 May 2015 12:53:09 +0200 Subject: WinRT: Fix warnings for Windows Phone Change-Id: I712facd3054eb0ee54b7d4fcd754845ddcea0ef0 Reviewed-by: Oliver Wolff --- src/corelib/kernel/qsharedmemory_win.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp index 4d37368b2e..5cc54b1def 100644 --- a/src/corelib/kernel/qsharedmemory_win.cpp +++ b/src/corelib/kernel/qsharedmemory_win.cpp @@ -163,6 +163,7 @@ bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode) #if defined(Q_OS_WINPHONE) Q_UNIMPLEMENTED(); Q_UNUSED(mode) + Q_UNUSED(permissions) memory = 0; #elif defined(Q_OS_WINRT) memory = (void *)MapViewOfFileFromApp(handle(), permissions, 0, 0); -- cgit v1.2.3 From f1fdac97abe2d9fedcf83469505f5704b3e2a26c Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 15 May 2015 14:35:43 +0200 Subject: qdoc: Improve logic for automatic example tag generation QDoc generates tags for examples based on the example title and the name of the module. This change makes the following improvements: - Edit regular expression to match strings like 'OpenGL' and 'Qt3D' as a single tag. - Strip off enclosing parentheses. - Filter out common words ('and', 'the') - When cleaning/modifying generated tags, keep them in a QSet to eliminate duplicates. Change-Id: I288104df12bf23a224068d40bce1f980148a412a Reviewed-by: Martin Smith --- src/tools/qdoc/htmlgenerator.cpp | 50 ++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 710ce08abb..8d84019ab5 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -4543,33 +4543,49 @@ void HtmlGenerator::generateManifestFile(const QString &manifest, const QString writer.writeCDATA(QString("No description available")); writer.writeEndElement(); // description - // Add words from module name as tags (QtQuickControls -> qt,quick,controls) - QRegExp re("([A-Z]+[a-z0-9]*)"); + // Add words from module name as tags + // QtQuickControls -> qt,quick,controls + // QtOpenGL -> qt,opengl + QRegExp re("([A-Z]+[a-z0-9]*(3D|GL)?)"); int pos = 0; while ((pos = re.indexIn(project, pos)) != -1) { tags << re.cap(1).toLower(); pos += re.matchedLength(); } tags += QSet::fromList(en->title().toLower().split(QLatin1Char(' '))); + + // Clean up tags, exclude invalid and common words + QSet::iterator tag_it = tags.begin(); + QSet modified; + while (tag_it != tags.end()) { + QString s = *tag_it; + if (s.at(0) == '(') + s.remove(0, 1).chop(1); + if (s.endsWith(QLatin1Char(':'))) + s.chop(1); + + if (s.length() < 2 + || s.at(0).isDigit() + || s.at(0) == '-' + || s == QStringLiteral("qt") + || s == QStringLiteral("the") + || s == QStringLiteral("and") + || s.startsWith(QStringLiteral("example")) + || s.startsWith(QStringLiteral("chapter"))) + tag_it = tags.erase(tag_it); + else if (s != *tag_it) { + modified << s; + tag_it = tags.erase(tag_it); + } + else + ++tag_it; + } + tags += modified; + if (!tags.isEmpty()) { writer.writeStartElement("tags"); bool wrote_one = false; - // Exclude invalid and common words foreach (QString tag, tags) { - if (tag.length() < 2) - continue; - if (tag.at(0).isDigit()) - continue; - if (tag.at(0) == '-') - continue; - if (tag == QLatin1String("qt")) - continue; - if (tag.startsWith("example")) - continue; - if (tag.startsWith("chapter")) - continue; - if (tag.endsWith(QLatin1Char(':'))) - tag.chop(1); if (wrote_one) writer.writeCharacters(","); writer.writeCharacters(tag); -- cgit v1.2.3 From b6634023faf7de3a85aba489fa2763f8a79fd9f5 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 19 May 2015 12:54:09 +0200 Subject: WinRT: Disable exceptions when turned off On desktop windows we define _HAS_EXCEPTIONS=0 to also forward this option. Hence harmonize this with WinRT builds as well. As a side-effect qtdeclarative now compiles without warnings on WinRT. Change-Id: I8e343f172160991ffb2ede01303802f321de82b5 Reviewed-by: Kai Koehne Reviewed-by: Oliver Wolff --- mkspecs/common/winrt_winphone/qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf index d71915408d..97ef661230 100644 --- a/mkspecs/common/winrt_winphone/qmake.conf +++ b/mkspecs/common/winrt_winphone/qmake.conf @@ -50,7 +50,7 @@ QMAKE_CXXFLAGS_STL_OFF = QMAKE_CXXFLAGS_RTTI_ON = -GR QMAKE_CXXFLAGS_RTTI_OFF = QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc -QMAKE_CXXFLAGS_EXCEPTIONS_OFF = +QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0 QMAKE_INCDIR = -- cgit v1.2.3 From e2102752ba8ccafef1cc480e82463ea76685a4e2 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 19 May 2015 16:07:42 +0200 Subject: Workaround for Samsung keyboard bug Return null string instead of empty string when the selection is empty. It looks like Samsung just tests for selection == null when doing backspace. Task-number: QTBUG-45785 Change-Id: Id26ce707130777fcd0ab1a4cff08367bb2810f2f Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/qandroidinputcontext.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 88bc4a653a..5c8406ca03 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -176,6 +176,8 @@ static jstring getSelectedText(JNIEnv *env, jobject /*thiz*/, jint flags) #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug() << "@@@ GETSEL" << text; #endif + if (text.isEmpty()) + return 0; return env->NewString(reinterpret_cast(text.constData()), jsize(text.length())); } -- cgit v1.2.3 From d204dd1d5e0f8399234ac1f804a1283457f393f2 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 11 May 2015 13:11:16 +0200 Subject: doc: add QStandardPaths documentation for iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-36171 Change-Id: I15c5ac4f5c4944218e5f30c11530160f65699be9 Reviewed-by: Topi Reiniö Reviewed-by: Samuel Gaist Reviewed-by: Tor Arne Vestbø --- src/corelib/io/qstandardpaths.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index c5c596fd2e..74252d1f0a 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -275,45 +275,67 @@ QT_BEGIN_NAMESPACE \endtable \table - \header \li Path type \li Android + \header \li Path type \li Android \li iOS \row \li DesktopLocation \li "/files" + \li "/" (not writable) \row \li DocumentsLocation \li "/Documents", "//Documents" + \li "/Documents" \row \li FontsLocation \li "/system/fonts" (not writable) + \li "/Documents/.fonts" \row \li ApplicationsLocation \li not supported (directory not readable) + \li not supported \row \li MusicLocation \li "/Music", "//Music" + \li "/Documents/Music" \row \li MoviesLocation \li "/Movies", "//Movies" + \li "/Documents/Movies" \row \li PicturesLocation \li "/Pictures", "//Pictures" + \li "/Documents/Pictures", "assets-library://" \row \li TempLocation \li "/cache" + \li "/tmp" \row \li HomeLocation \li "/files" + \li "/" (not writable) \row \li DataLocation \li "/files", "//files" + \li "/Library/Application Support" \row \li CacheLocation \li "/cache", "//cache" + \li "/Library/Caches" \row \li GenericDataLocation \li "" + \li "/Documents" \row \li RuntimeLocation \li "/cache" + \li not supported \row \li ConfigLocation \li "/files/settings" + \li "/Documents" \row \li GenericConfigLocation \li "/files/settings" (there is no shared settings) + \li "/Documents" \row \li DownloadLocation \li "/Downloads", "//Downloads" + \li "/Documents/Download" \row \li GenericCacheLocation \li "/cache" (there is no shared cache) + \li "/Library/Caches" \row \li AppDataLocation \li "/files", "//files" + \li "/Library/Application Support" \row \li AppConfigLocation \li "/files/settings" + \li "/Documents" + \row \li AppLocalDataLocation + \li "/files", "//files" + \li "/Library/Application Support" \endtable In the table above, \c is usually the organization name, the @@ -328,6 +350,12 @@ QT_BEGIN_NAMESPACE \note On Android, applications with open files on the external storage ( locations), will be killed if the external storage is unmounted. + \note On iOS, if you do pass \c {QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).last()} + as argument to \l{QFileDialog::setDirectory()}, + a native image picker dialog will be used for accessing the user's photo album. + The filename returned can be loaded using QFile and related APIs. + This feature was added in Qt 5.5. + \sa writableLocation(), standardLocations(), displayName(), locate(), locateAll() */ -- cgit v1.2.3 From 20e36879d72f840005a0361368985b72ce4dc6a4 Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Fri, 15 May 2015 14:42:45 +0200 Subject: Doc: Excluded qdoc files that caused unnecessary Qt Creator warnings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The customcompleter and textcodes are widget examples, but they end up in the Qt Core exampledirs boundary because of a reference to the plugandpaint example in the docs. This resulted in a couple of wrong entries being written into the examples-manifest.xml, which is used by Qt Creator. This change explicitly exludes the qdoc pages for the two examples so that qdoc doesn't add the corresponding entries into examples-manifest.xml. Task-number: QTBUG-41996 Change-Id: I0e95b6d4d93e0ce18f5b34e5034b279598b4924f Reviewed-by: Topi Reiniö Reviewed-by: Martin Smith --- src/corelib/doc/qtcore.qdocconf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index f3aff83a8b..a166df1143 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -42,5 +42,8 @@ imagedirs += images excludedirs += snippets +excludefiles += ../../../examples/widgets/tools/customcompleter/doc/src/customcompleter.qdoc \ + ../../../examples/widgets/tools/codecs/doc/src/codecs.qdoc + navigation.landingpage = "Qt Core" navigation.cppclassespage = "Qt Core C++ Classes" -- cgit v1.2.3 From 938f9fc0f8ff1575413ca3d6d66860b5fa315768 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 19 May 2015 16:07:42 +0200 Subject: Workaround for Samsung keyboard bug Return null string instead of empty string when the selection is empty. It looks like Samsung just tests for selection == null when doing backspace. Task-number: QTBUG-45785 Change-Id: Iaa006a8ffe52b2704c7348646dde9ca4e1f78c5c Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/qandroidinputcontext.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 7e81735de9..7264f9a74c 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -176,6 +176,8 @@ static jstring getSelectedText(JNIEnv *env, jobject /*thiz*/, jint flags) #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug() << "@@@ GETSEL" << text; #endif + if (text.isEmpty()) + return 0; return env->NewString(reinterpret_cast(text.constData()), jsize(text.length())); } -- cgit v1.2.3 From 9a1283f8d3a671c3d4d08b9a50c3ad1460b1b1f8 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 20 May 2015 10:56:11 +0200 Subject: Doc: Qt Network: List the classes on SSL Classes page Change-Id: I32693ac3012142c04671f8278e06165396ca3242 Task-number: QTBUG-46145 Reviewed-by: Venugopal Shivashankar Reviewed-by: Martin Smith --- src/network/doc/src/ssl.qdoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/doc/src/ssl.qdoc b/src/network/doc/src/ssl.qdoc index 5a994a114c..45dffc95a3 100644 --- a/src/network/doc/src/ssl.qdoc +++ b/src/network/doc/src/ssl.qdoc @@ -36,6 +36,8 @@ the Secure Sockets Layer (SSL) protocol, using the OpenSSL Toolkit (\l{http://www.openssl.org/}) to perform encryption and protocol handling. + \annotatedlist ssl + See the \l {openssl-v1later}{OpenSSL Compatibility} page for information about the versions of OpenSSL that are known to work with Qt. -- cgit v1.2.3 From e227b8ecf686bb2ace31be62e683bd76591ad7b1 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Fri, 1 May 2015 14:02:16 +0300 Subject: Deinline QRingBuffer class Reduce the size of .text section in QtCore by 4.5KB and in QtNetwork by 26.5KB. Change-Id: If7998776166b9681c1e4b24c51d40444aa996d7a Reviewed-by: Oswald Buddenhagen --- qmake/Makefile.unix | 6 +- qmake/Makefile.win32 | 1 + src/corelib/tools/qringbuffer.cpp | 327 +++++++++++++++++++++ src/corelib/tools/qringbuffer_p.h | 266 ++--------------- src/corelib/tools/tools.pri | 1 + src/tools/bootstrap/bootstrap.pro | 1 + .../corelib/tools/qringbuffer/tst_qringbuffer.cpp | 23 ++ tools/configure/Makefile.mingw | 1 + tools/configure/Makefile.win32 | 2 + tools/configure/configure.pro | 2 + 10 files changed, 386 insertions(+), 244 deletions(-) create mode 100644 src/corelib/tools/qringbuffer.cpp diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 86f884fe20..520ae667e9 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -13,7 +13,7 @@ OBJS=project.o option.o property.o main.o ioutils.o proitems.o \ #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qstring_compat.o qstringbuilder.o qtextstream.o qiodevice.o \ - qdebug.o qmalloc.o qglobal.o \ + qringbuffer.o qdebug.o qmalloc.o qglobal.o \ qarraydata.o qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfiledevice.o qfile.o \ qfilesystementry.o qfilesystemengine.o qfsfileengine.o qfsfileengine_iterator.o qregexp.o qvector.o \ qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o qfileinfo.o qdatetime.o qstringlist.o \ @@ -44,6 +44,7 @@ DEPEND_SRC = \ $(SOURCE_PATH)/src/corelib/tools/qstring_compat.cpp \ $(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp \ $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp \ + $(SOURCE_PATH)/src/corelib/tools/qringbuffer.cpp \ $(SOURCE_PATH)/src/corelib/io/qdebug.cpp \ $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp \ $(SOURCE_PATH)/src/corelib/global/qglobal.cpp $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp \ @@ -242,6 +243,9 @@ qsettings_win.o: $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp qiodevice.o: $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp +qringbuffer.o: $(SOURCE_PATH)/src/corelib/tools/qringbuffer.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qringbuffer.cpp + qdebug.o: $(SOURCE_PATH)/src/corelib/io/qdebug.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdebug.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 9dda6ca1e7..272a0c09b1 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -88,6 +88,7 @@ QTOBJS= \ qglobal.obj \ qhash.obj \ qiodevice.obj \ + qringbuffer.obj \ qdebug.obj \ qlist.obj \ qlinkedlist.obj \ diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp new file mode 100644 index 0000000000..d8becbe07d --- /dev/null +++ b/src/corelib/tools/qringbuffer.cpp @@ -0,0 +1,327 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Alex Trotsenko +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "private/qringbuffer_p.h" +#include + +QT_BEGIN_NAMESPACE + +/*! + \internal + + Access the bytes at a specified position the out-variable length will + contain the amount of bytes readable from there, e.g. the amount still + the same QByteArray +*/ +const char *QRingBuffer::readPointerAtPosition(qint64 pos, qint64 &length) const +{ + if (pos >= 0) { + pos += head; + for (int i = 0; i < buffers.size(); ++i) { + length = (i == tailBuffer ? tail : buffers[i].size()); + if (length > pos) { + length -= pos; + return buffers[i].constData() + pos; + } + pos -= length; + } + } + + length = 0; + return 0; +} + +void QRingBuffer::free(qint64 bytes) +{ + while (bytes > 0) { + const qint64 blockSize = buffers.first().size() - head; + + if (tailBuffer == 0 || blockSize > bytes) { + // keep a single block around if it does not exceed + // the basic block size, to avoid repeated allocations + // between uses of the buffer + if (bufferSize <= bytes) { + if (buffers.first().size() <= basicBlockSize) { + bufferSize = 0; + head = tail = 0; + } else { + clear(); // try to minify/squeeze us + } + } else { + Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); + head += int(bytes); + bufferSize -= bytes; + } + return; + } + + bufferSize -= blockSize; + bytes -= blockSize; + buffers.removeFirst(); + --tailBuffer; + head = 0; + } +} + +char *QRingBuffer::reserve(qint64 bytes) +{ + if (bytes <= 0 || quint64(bytes) >= QByteArray::MaxSize) + return 0; + + const qint64 newSize = bytes + tail; + // if need buffer reallocation + if (newSize > buffers.last().size()) { + if (newSize > buffers.last().capacity() && (tail >= basicBlockSize + || quint64(newSize) >= QByteArray::MaxSize)) { + // shrink this buffer to its current size + buffers.last().resize(tail); + + // create a new QByteArray + buffers.append(QByteArray()); + ++tailBuffer; + tail = 0; + } + buffers.last().resize(qMax(basicBlockSize, tail + int(bytes))); + } + + char *writePtr = buffers.last().data() + tail; + bufferSize += bytes; + Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); + tail += int(bytes); + return writePtr; +} + +/*! + \internal + + Allocate data at buffer head +*/ +char *QRingBuffer::reserveFront(qint64 bytes) +{ + if (bytes <= 0 || quint64(bytes) >= QByteArray::MaxSize) + return 0; + + if (head < bytes) { + buffers.first().remove(0, head); + if (tailBuffer == 0) + tail -= head; + + buffers.prepend(QByteArray()); + head = qMax(basicBlockSize, int(bytes)); + buffers.first().resize(head); + ++tailBuffer; + } + + head -= int(bytes); + bufferSize += bytes; + return buffers.first().data() + head; +} + +void QRingBuffer::chop(qint64 bytes) +{ + while (bytes > 0) { + if (tailBuffer == 0 || tail > bytes) { + // keep a single block around if it does not exceed + // the basic block size, to avoid repeated allocations + // between uses of the buffer + if (bufferSize <= bytes) { + if (buffers.first().size() <= basicBlockSize) { + bufferSize = 0; + head = tail = 0; + } else { + clear(); // try to minify/squeeze us + } + } else { + Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); + tail -= int(bytes); + bufferSize -= bytes; + } + return; + } + + bufferSize -= tail; + bytes -= tail; + buffers.removeLast(); + --tailBuffer; + tail = buffers.last().size(); + } +} + +void QRingBuffer::clear() +{ + buffers.erase(buffers.begin() + 1, buffers.end()); + buffers.first().clear(); + + head = tail = 0; + tailBuffer = 0; + bufferSize = 0; +} + +qint64 QRingBuffer::indexOf(char c) const +{ + qint64 index = 0; + qint64 j = head; + for (int i = 0; i < buffers.size(); ++i) { + const char *ptr = buffers[i].constData() + j; + j = index + (i == tailBuffer ? tail : buffers[i].size()) - j; + + while (index < j) { + if (*ptr++ == c) + return index; + ++index; + } + j = 0; + } + return -1; +} + +qint64 QRingBuffer::indexOf(char c, qint64 maxLength) const +{ + qint64 index = 0; + qint64 j = head; + for (int i = 0; index < maxLength && i < buffers.size(); ++i) { + const char *ptr = buffers[i].constData() + j; + j = qMin(index + (i == tailBuffer ? tail : buffers[i].size()) - j, maxLength); + + while (index < j) { + if (*ptr++ == c) + return index; + ++index; + } + j = 0; + } + return -1; +} + +qint64 QRingBuffer::read(char *data, qint64 maxLength) +{ + const qint64 bytesToRead = qMin(size(), maxLength); + qint64 readSoFar = 0; + while (readSoFar < bytesToRead) { + const qint64 bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, + nextDataBlockSize()); + if (data) + memcpy(data + readSoFar, readPointer(), bytesToReadFromThisBlock); + readSoFar += bytesToReadFromThisBlock; + free(bytesToReadFromThisBlock); + } + return readSoFar; +} + +/*! + \internal + + Read an unspecified amount (will read the first buffer) +*/ +QByteArray QRingBuffer::read() +{ + if (bufferSize == 0) + return QByteArray(); + + QByteArray qba(buffers.takeFirst()); + + qba.reserve(0); // avoid that resizing needlessly reallocates + if (tailBuffer == 0) { + qba.resize(tail); + tail = 0; + buffers.append(QByteArray()); + } else { + --tailBuffer; + } + qba.remove(0, head); // does nothing if head is 0 + head = 0; + bufferSize -= qba.size(); + return qba; +} + +/*! + \internal + + Peek the bytes from a specified position +*/ +qint64 QRingBuffer::peek(char *data, qint64 maxLength, qint64 pos) const +{ + qint64 readSoFar = 0; + + if (pos >= 0) { + pos += head; + for (int i = 0; readSoFar < maxLength && i < buffers.size(); ++i) { + qint64 blockLength = (i == tailBuffer ? tail : buffers[i].size()); + + if (pos < blockLength) { + blockLength = qMin(blockLength - pos, maxLength - readSoFar); + memcpy(data + readSoFar, buffers[i].constData() + pos, blockLength); + readSoFar += blockLength; + pos = 0; + } else { + pos -= blockLength; + } + } + } + + return readSoFar; +} + +/*! + \internal + + Append a new buffer to the end +*/ +void QRingBuffer::append(const QByteArray &qba) +{ + if (tail == 0) { + buffers.last() = qba; + } else { + buffers.last().resize(tail); + buffers.append(qba); + ++tailBuffer; + } + tail = qba.size(); + bufferSize += tail; +} + +qint64 QRingBuffer::readLine(char *data, qint64 maxLength) +{ + if (!data || --maxLength <= 0) + return -1; + + qint64 i = indexOf('\n', maxLength); + i = read(data, i >= 0 ? (i + 1) : maxLength); + + // Terminate it. + data[i] = '\0'; + return i; +} + +QT_END_NAMESPACE diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index 9ca14d2987..3a8cca46d8 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -66,117 +66,17 @@ public: return bufferSize == 0 ? Q_NULLPTR : (buffers.first().constData() + head); } - // access the bytes at a specified position - // the out-variable length will contain the amount of bytes readable - // from there, e.g. the amount still the same QByteArray - inline const char *readPointerAtPosition(qint64 pos, qint64 &length) const { - if (pos >= 0) { - pos += head; - for (int i = 0; i < buffers.size(); ++i) { - length = (i == tailBuffer ? tail : buffers[i].size()); - if (length > pos) { - length -= pos; - return buffers[i].constData() + pos; - } - pos -= length; - } - } - - length = 0; - return 0; - } - - inline void free(qint64 bytes) { - while (bytes > 0) { - const qint64 blockSize = buffers.first().size() - head; - - if (tailBuffer == 0 || blockSize > bytes) { - // keep a single block around if it does not exceed - // the basic block size, to avoid repeated allocations - // between uses of the buffer - if (bufferSize <= bytes) { - if (buffers.first().size() <= basicBlockSize) { - bufferSize = 0; - head = tail = 0; - } else { - clear(); // try to minify/squeeze us - } - } else { - Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); - head += int(bytes); - bufferSize -= bytes; - } - return; - } - - bufferSize -= blockSize; - bytes -= blockSize; - buffers.removeFirst(); - --tailBuffer; - head = 0; - } - } - - inline char *reserve(qint64 bytes) { - if (bytes <= 0 || quint64(bytes) >= QByteArray::MaxSize) - return 0; - - const qint64 newSize = bytes + tail; - // if need buffer reallocation - if (newSize > buffers.last().size()) { - if (newSize > buffers.last().capacity() && (tail >= basicBlockSize - || quint64(newSize) >= QByteArray::MaxSize)) { - // shrink this buffer to its current size - buffers.last().resize(tail); - - // create a new QByteArray - buffers.append(QByteArray()); - ++tailBuffer; - tail = 0; - } - buffers.last().resize(qMax(basicBlockSize, tail + int(bytes))); - } - - char *writePtr = buffers.last().data() + tail; - bufferSize += bytes; - Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); - tail += int(bytes); - return writePtr; - } + Q_CORE_EXPORT const char *readPointerAtPosition(qint64 pos, qint64 &length) const; + Q_CORE_EXPORT void free(qint64 bytes); + Q_CORE_EXPORT char *reserve(qint64 bytes); + Q_CORE_EXPORT char *reserveFront(qint64 bytes); inline void truncate(qint64 pos) { if (pos < size()) chop(size() - pos); } - inline void chop(qint64 bytes) { - while (bytes > 0) { - if (tailBuffer == 0 || tail > bytes) { - // keep a single block around if it does not exceed - // the basic block size, to avoid repeated allocations - // between uses of the buffer - if (bufferSize <= bytes) { - if (buffers.first().size() <= basicBlockSize) { - bufferSize = 0; - head = tail = 0; - } else { - clear(); // try to minify/squeeze us - } - } else { - Q_ASSERT(quint64(bytes) < QByteArray::MaxSize); - tail -= int(bytes); - bufferSize -= bytes; - } - return; - } - - bufferSize -= tail; - bytes -= tail; - buffers.removeLast(); - --tailBuffer; - tail = buffers.last().size(); - } - } + Q_CORE_EXPORT void chop(qint64 bytes); inline bool isEmpty() const { return bufferSize == 0; @@ -195,156 +95,36 @@ public: *ptr = c; } - inline void ungetChar(char c) { - --head; - if (head < 0) { - if (bufferSize != 0) { - buffers.prepend(QByteArray()); - ++tailBuffer; - } else { - tail = basicBlockSize; - } - buffers.first().resize(basicBlockSize); - head = basicBlockSize - 1; - } - buffers.first()[head] = c; - ++bufferSize; - } - - inline qint64 size() const { - return bufferSize; - } - - inline void clear() { - buffers.erase(buffers.begin() + 1, buffers.end()); - buffers.first().clear(); - - head = tail = 0; - tailBuffer = 0; - bufferSize = 0; - } - - inline qint64 indexOf(char c) const { - qint64 index = 0; - qint64 j = head; - for (int i = 0; i < buffers.size(); ++i) { - const char *ptr = buffers[i].constData() + j; - j = index + (i == tailBuffer ? tail : buffers[i].size()) - j; - - while (index < j) { - if (*ptr++ == c) - return index; - ++index; - } - j = 0; - } - return -1; - } - - inline qint64 indexOf(char c, qint64 maxLength) const { - qint64 index = 0; - qint64 j = head; - for (int i = 0; index < maxLength && i < buffers.size(); ++i) { - const char *ptr = buffers[i].constData() + j; - j = qMin(index + (i == tailBuffer ? tail : buffers[i].size()) - j, maxLength); - - while (index < j) { - if (*ptr++ == c) - return index; - ++index; - } - j = 0; - } - return -1; - } - - inline qint64 read(char *data, qint64 maxLength) { - const qint64 bytesToRead = qMin(size(), maxLength); - qint64 readSoFar = 0; - while (readSoFar < bytesToRead) { - const qint64 bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar, - nextDataBlockSize()); - if (data) - memcpy(data + readSoFar, readPointer(), bytesToReadFromThisBlock); - readSoFar += bytesToReadFromThisBlock; - free(bytesToReadFromThisBlock); - } - return readSoFar; - } - - // read an unspecified amount (will read the first buffer) - inline QByteArray read() { - if (bufferSize == 0) - return QByteArray(); - - QByteArray qba(buffers.takeFirst()); - - qba.reserve(0); // avoid that resizing needlessly reallocates - if (tailBuffer == 0) { - qba.resize(tail); - tail = 0; - buffers.append(QByteArray()); + void ungetChar(char c) + { + if (head > 0) { + --head; + buffers.first()[head] = c; + ++bufferSize; } else { - --tailBuffer; + char *ptr = reserveFront(1); + *ptr = c; } - qba.remove(0, head); // does nothing if head is 0 - head = 0; - bufferSize -= qba.size(); - return qba; } - // peek the bytes from a specified position - inline qint64 peek(char *data, qint64 maxLength, qint64 pos = 0) const - { - qint64 readSoFar = 0; - - if (pos >= 0) { - pos += head; - for (int i = 0; readSoFar < maxLength && i < buffers.size(); ++i) { - qint64 blockLength = (i == tailBuffer ? tail : buffers[i].size()); - - if (pos < blockLength) { - blockLength = qMin(blockLength - pos, maxLength - readSoFar); - memcpy(data + readSoFar, buffers[i].constData() + pos, blockLength); - readSoFar += blockLength; - pos = 0; - } else { - pos -= blockLength; - } - } - } - return readSoFar; + inline qint64 size() const { + return bufferSize; } - // append a new buffer to the end - inline void append(const QByteArray &qba) { - if (tail == 0) { - buffers.last() = qba; - } else { - buffers.last().resize(tail); - buffers.append(qba); - ++tailBuffer; - } - tail = qba.size(); - bufferSize += tail; - } + Q_CORE_EXPORT void clear(); + Q_CORE_EXPORT qint64 indexOf(char c) const; + Q_CORE_EXPORT qint64 indexOf(char c, qint64 maxLength) const; + Q_CORE_EXPORT qint64 read(char *data, qint64 maxLength); + Q_CORE_EXPORT QByteArray read(); + Q_CORE_EXPORT qint64 peek(char *data, qint64 maxLength, qint64 pos = 0) const; + Q_CORE_EXPORT void append(const QByteArray &qba); inline qint64 skip(qint64 length) { return read(0, length); } - inline qint64 readLine(char *data, qint64 maxLength) { - if (!data || --maxLength <= 0) - return -1; - - qint64 i = indexOf('\n', maxLength); - i = read(data, i >= 0 ? (i + 1) : maxLength); - - // Terminate it. - data[i] = '\0'; - return i; - } + Q_CORE_EXPORT qint64 readLine(char *data, qint64 maxLength); inline bool canReadLine() const { return indexOf('\n') >= 0; diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 5e4a22e283..1dba6784b6 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -106,6 +106,7 @@ SOURCES += \ tools/qrect.cpp \ tools/qregexp.cpp \ tools/qrefcount.cpp \ + tools/qringbuffer.cpp \ tools/qshareddata.cpp \ tools/qsharedpointer.cpp \ tools/qsimd.cpp \ diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index a92e5b8f3d..be6bcadacb 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -97,6 +97,7 @@ SOURCES += \ ../../corelib/tools/qlocale_tools.cpp \ ../../corelib/tools/qmap.cpp \ ../../corelib/tools/qregexp.cpp \ + ../../corelib/tools/qringbuffer.cpp \ ../../corelib/tools/qpoint.cpp \ ../../corelib/tools/qrect.cpp \ ../../corelib/tools/qsize.cpp \ diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp index 044fdbdee5..f9bca77ed3 100644 --- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp +++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp @@ -48,6 +48,7 @@ private slots: void sizeWhenReserved(); void free(); void reserveAndRead(); + void reserveFrontAndRead(); void chop(); void ungetChar(); void indexOf(); @@ -219,6 +220,28 @@ void tst_QRingBuffer::reserveAndRead() QVERIFY(ringBuffer.size() == 0); } +void tst_QRingBuffer::reserveFrontAndRead() +{ + QRingBuffer ringBuffer; + // fill buffer with an arithmetic progression + for (int i = 1; i < 256; ++i) { + QByteArray ba(i, char(i)); + char *ringPos = ringBuffer.reserveFront(i); + QVERIFY(ringPos); + memcpy(ringPos, ba.constData(), i); + } + + // readback and check stored data + for (int i = 255; i > 0; --i) { + QByteArray ba; + ba.resize(i); + qint64 thisRead = ringBuffer.read(ba.data(), i); + QCOMPARE(thisRead, qint64(i)); + QVERIFY(ba.count(char(i)) == i); + } + QVERIFY(ringBuffer.size() == 0); +} + void tst_QRingBuffer::chop() { QRingBuffer ringBuffer; diff --git a/tools/configure/Makefile.mingw b/tools/configure/Makefile.mingw index 40c2112132..a626bd6052 100644 --- a/tools/configure/Makefile.mingw +++ b/tools/configure/Makefile.mingw @@ -48,6 +48,7 @@ OBJECTS = \ qfsfileengine_win.o \ qfsfileengine_iterator.o \ qiodevice.o \ + qringbuffer.o \ qdebug.o \ qtextstream.o \ qlogging.o \ diff --git a/tools/configure/Makefile.win32 b/tools/configure/Makefile.win32 index b74b0bc82d..148872525a 100644 --- a/tools/configure/Makefile.win32 +++ b/tools/configure/Makefile.win32 @@ -47,6 +47,7 @@ OBJECTS = \ qfsfileengine_win.obj \ qfsfileengine_iterator.obj \ qiodevice.obj \ + qringbuffer.obj \ qdebug.obj \ qtextstream.obj \ qlogging.obj \ @@ -122,6 +123,7 @@ qfsfileengine.obj: $(CORESRC)\io\qfsfileengine.cpp $(PCH) qfsfileengine_win.obj: $(CORESRC)\io\qfsfileengine_win.cpp $(PCH) qfsfileengine_iterator.obj: $(CORESRC)\io\qfsfileengine_iterator.cpp $(PCH) qiodevice.obj: $(CORESRC)\io\qiodevice.cpp $(PCH) +qringbuffer.obj: $(CORESRC)\tools\qringbuffer.cpp $(PCH) qdebug.obj: $(CORESRC)\io\qdebug.cpp $(PCH) qtextstream.obj: $(CORESRC)\io\qtextstream.cpp $(PCH) qtemporaryfile.obj: $(CORESRC)\io\qtemporaryfile.cpp $(PCH) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index d3237d472b..13ab3746ed 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -68,6 +68,7 @@ HEADERS = configureapp.h environment.h tools.h\ $$QT_SOURCE_TREE/src/corelib/tools/qdatetime.h \ $$QT_SOURCE_TREE/src/corelib/tools/qmap.h \ $$QT_SOURCE_TREE/src/corelib/tools/qregexp.h \ + $$QT_SOURCE_TREE/src/corelib/tools/qringbuffer_p.h \ $$QT_SOURCE_TREE/src/corelib/tools/qstring.h \ $$QT_SOURCE_TREE/src/corelib/tools/qstringlist.h \ $$QT_SOURCE_TREE/src/corelib/tools/qstringmatcher.h \ @@ -119,6 +120,7 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qdatetime.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qmap.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qregexp.cpp \ + $$QT_SOURCE_TREE/src/corelib/tools/qringbuffer.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qstring.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qstring_compat.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qstringlist.cpp \ -- cgit v1.2.3 From 9269dcc8ed9839c403f4f88edd79d0b8f0945d4a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 24 Apr 2015 08:50:16 -0700 Subject: Fix compilation of QContiguousCache::operator= freeData() takes a Data*, not a QContiguousCacheData*. Task-number: QTBUG-45783 Change-Id: I96d7ac38dac24b418138ffff13d7fdf09b1d6b07 Reviewed-by: Marc Mutz Reviewed-by: Giuseppe D'Angelo --- src/corelib/tools/qcontiguouscache.h | 2 +- .../corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index fc4fb1e7cb..41d198f9bc 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -291,7 +291,7 @@ QContiguousCache &QContiguousCache::operator=(const QContiguousCache &o { other.d->ref.ref(); if (!d->ref.deref()) - freeData(d); + freeData(p); d = other.d; if (!d->sharable) detach_helper(); diff --git a/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp b/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp index 01855a730e..76687bd478 100644 --- a/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp +++ b/tests/auto/corelib/tools/qcontiguouscache/tst_qcontiguouscache.cpp @@ -43,6 +43,8 @@ class tst_QContiguousCache : public QObject { Q_OBJECT private slots: + void assignment(); + void empty(); void swap(); @@ -64,6 +66,16 @@ private slots: QTEST_MAIN(tst_QContiguousCache) +void tst_QContiguousCache::assignment() +{ + // compile-only test: QTBUG-45783 + QContiguousCache cc1, cc2; + // copy: + cc1 = cc2; + // move: + cc1 = qMove(cc2); +} + void tst_QContiguousCache::empty() { QContiguousCache c(10); -- cgit v1.2.3 From 79de60f38b36ec06b343c91f2301030259352425 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 13 May 2015 20:23:04 +0200 Subject: silence MSVC warnings about using TS() without parameters Change-Id: I23264dcabc02b89441fa47c890fc662e9a41f7ce Reviewed-by: Joerg Bornemann --- tests/auto/tools/qmakelib/tst_qmakelib.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/tools/qmakelib/tst_qmakelib.cpp b/tests/auto/tools/qmakelib/tst_qmakelib.cpp index 1c6d43338d..0667b67300 100644 --- a/tests/auto/tools/qmakelib/tst_qmakelib.cpp +++ b/tests/auto/tools/qmakelib/tst_qmakelib.cpp @@ -228,6 +228,9 @@ private: #define S(s) ProString(QString::fromWCharArray(s)) #define HS(s) ProKey(QString::fromWCharArray(s)) +QT_WARNING_PUSH +QT_WARNING_DISABLE_MSVC(4003) // "not enough actual parameters for macro TS()" + void tst_qmakelib::proParser_data() { QTest::addColumn("in"); @@ -2068,6 +2071,8 @@ void tst_qmakelib::proParser_data() << false; } +QT_WARNING_POP + void tst_qmakelib::proParser() { QFETCH(QString, in); -- cgit v1.2.3 From a3fac538645e0c672ac7c8d5e86f8cfbb1ec8426 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 13 May 2015 19:34:19 +0200 Subject: add parser tests for use of 'else' after bad conditionals Change-Id: I9885f629a2f6511574eebd81896a1d9f258e55cb Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- tests/auto/tools/qmakelib/tst_qmakelib.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/auto/tools/qmakelib/tst_qmakelib.cpp b/tests/auto/tools/qmakelib/tst_qmakelib.cpp index 0667b67300..441a36e34d 100644 --- a/tests/auto/tools/qmakelib/tst_qmakelib.cpp +++ b/tests/auto/tools/qmakelib/tst_qmakelib.cpp @@ -1373,6 +1373,29 @@ void tst_qmakelib::proParser_data() << "in:1: Unexpected 'else'." << false; + QTest::newRow("double-test-else") + << "foo bar\nelse" + << TS( + /* 0 */ << H(TokBranch) + /* 1 */ /* then branch */ << I(0) + /* 3 */ /* else branch */ << I(1) // This seems weird + /* 5 */ << H(TokTerminator)) + << "in:1: Extra characters after test expression." + << false; + + QTest::newRow("test-function-else") + << "foo bar()\nelse" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestCall) // This seems pointless + /* 3 */ << H(TokFuncTerminator) + /* 4 */ << H(TokBranch) + /* 5 */ /* then branch */ << I(0) + /* 7 */ /* else branch */ << I(1) // This seems weird + /* 9 */ << H(TokTerminator)) + << "in:1: Extra characters after test expression." + << false; + // Braces QTest::newRow("{}") -- cgit v1.2.3 From f37381e29246b5fc984aaff6cd07731c33b4e0df Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 6 Mar 2015 21:14:17 +0100 Subject: add autotest for ProString also adds documentation, which is kind of a sanity test. ehm. Change-Id: I6b520e8b505a2bfbb1e376fa72be0f140227a3a4 Reviewed-by: Joerg Bornemann --- qmake/library/proitems.cpp | 12 +++++ tests/auto/tools/qmakelib/tst_qmakelib.cpp | 81 ++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp index e780259417..f3526846e9 100644 --- a/qmake/library/proitems.cpp +++ b/qmake/library/proitems.cpp @@ -159,6 +159,18 @@ QString &ProString::toQString(QString &tmp) const return tmp.setRawData(m_string.constData() + m_offset, m_length); } +/*! + * \brief ProString::prepareExtend + * \param extraLen number of new characters to be added + * \param thisTarget offset to which current contents should be moved + * \param extraTarget offset at which new characters will be added + * \return pointer to storage location for new characters + * + * Prepares the string for adding new characters. + * If the string is detached and has enough space, it will be changed in place. + * Otherwise, it will be replaced with a new string object, thus detaching. + * In either case, the hash will be reset. + */ QChar *ProString::prepareExtend(int extraLen, int thisTarget, int extraTarget) { if (m_string.isDetached() && m_length + extraLen <= m_string.capacity()) { diff --git a/tests/auto/tools/qmakelib/tst_qmakelib.cpp b/tests/auto/tools/qmakelib/tst_qmakelib.cpp index 441a36e34d..ab14de0e24 100644 --- a/tests/auto/tools/qmakelib/tst_qmakelib.cpp +++ b/tests/auto/tools/qmakelib/tst_qmakelib.cpp @@ -57,12 +57,93 @@ private slots: void quoteArgWin(); void pathUtils(); + void proString(); void proStringList(); void proParser_data(); void proParser(); }; +void tst_qmakelib::proString() +{ + QString qs1(QStringLiteral("this is a string")); + + ProString s1(qs1); + QCOMPARE(s1.toQString(), QStringLiteral("this is a string")); + + ProString s2(qs1, 5, 8); + QCOMPARE(s2.toQString(), QStringLiteral("is a str")); + + QCOMPARE(s2.hash(), 0x80000000); + qHash(s2); + QCOMPARE(s2.hash(), 90404018U); + + QCOMPARE(s2.mid(0, 10).toQString(), QStringLiteral("is a str")); + QCOMPARE(s2.mid(1, 5).toQString(), QStringLiteral("s a s")); + QCOMPARE(s2.mid(10, 3).toQString(), QStringLiteral("")); + + QString qs2(QStringLiteral(" spacy string ")); + QCOMPARE(ProString(qs2, 3, 13).trimmed().toQString(), QStringLiteral("spacy string")); + QCOMPARE(ProString(qs2, 1, 17).trimmed().toQString(), QStringLiteral("spacy string")); + + QVERIFY(s2.toQStringRef().string()->isSharedWith(qs1)); + s2.prepend(ProString("there ")); + QCOMPARE(s2.toQString(), QStringLiteral("there is a str")); + QVERIFY(!s2.toQStringRef().string()->isSharedWith(qs1)); + + ProString s3("this is a longish string with bells and whistles"); + s3 = s3.mid(18, 17); + // Prepend to detached string with lots of spare space in it. + s3.prepend(ProString("another ")); + QCOMPARE(s3.toQString(), QStringLiteral("another string with bells")); + + // Note: The string still has plenty of spare space. + s3.append(QLatin1Char('.')); + QCOMPARE(s3.toQString(), QStringLiteral("another string with bells.")); + s3.append(QLatin1String(" eh?")); + QCOMPARE(s3.toQString(), QStringLiteral("another string with bells. eh?")); + + s3.append(ProString(" yeah!")); + QCOMPARE(s3.toQString(), QStringLiteral("another string with bells. eh? yeah!")); + + bool pending = false; // Not in string, but joining => add space + s3.append(ProString("..."), &pending); + QCOMPARE(s3.toQString(), QStringLiteral("another string with bells. eh? yeah! ...")); + QVERIFY(pending); + + ProStringList sl1; + sl1 << ProString("") << ProString("foo") << ProString("barbaz"); + ProString s4a("hallo"); + s4a.append(sl1); + QCOMPARE(s4a.toQString(), QStringLiteral("hallo foo barbaz")); + ProString s4b("hallo"); + pending = false; + s4b.append(sl1, &pending); + QCOMPARE(s4b.toQString(), QStringLiteral("hallo foo barbaz")); + ProString s4c; + pending = false; + s4c.append(sl1, &pending); + QCOMPARE(s4c.toQString(), QStringLiteral(" foo barbaz")); + // bizarreness + ProString s4d("hallo"); + pending = false; + s4d.append(sl1, &pending, true); + QCOMPARE(s4d.toQString(), QStringLiteral("hallo foo barbaz")); + ProString s4e; + pending = false; + s4e.append(sl1, &pending, true); + QCOMPARE(s4e.toQString(), QStringLiteral("foo barbaz")); + + ProStringList sl2; + sl2 << ProString("foo"); + ProString s5; + s5.append(sl2); + QCOMPARE(s5.toQString(), QStringLiteral("foo")); + QVERIFY(s5.toQStringRef().string()->isSharedWith(*sl2.first().toQStringRef().string())); + + QCOMPARE(ProString("one") + ProString(" more"), QStringLiteral("one more")); +} + void tst_qmakelib::proStringList() { ProStringList sl1; -- cgit v1.2.3 From c9270d66395c90068388857c8fd201c62fb5e96f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 28 Apr 2015 21:25:50 +0200 Subject: fix quote nesting in split_value_list() a single quote must not disrupt a double quoted string and vice-versa. Change-Id: Ibb277bc1c930a7dbe9199ca572507ababbcfae4c Reviewed-by: Joerg Bornemann --- qmake/library/qmakeevaluator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 5c9dc45f3a..acf09c11aa 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -314,7 +314,8 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil switch (unicode) { case '"': case '\'': - quote = unicode; + if (!quote) + quote = unicode; hadWord = true; break; case ' ': -- cgit v1.2.3 From bd19870b81cee218e67feee4d5c4a46143334365 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 11 May 2015 14:01:49 +0200 Subject: make infinite loop protection work even without an iterator variable ... (which is the usual case). Change-Id: I464b6b284f963df45c7340ed079d540b528136f0 Reviewed-by: Joerg Bornemann --- qmake/library/qmakeevaluator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index acf09c11aa..cb7e0d4bf2 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -797,8 +797,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( forever { if (infinite) { if (!variable.isEmpty()) - m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index++))); - if (index > 1000) { + m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index))); + if (++index > 1000) { evalError(fL1S("Ran into infinite loop (> 1000 iterations).")); break; } -- cgit v1.2.3 From 109e3fa0ae77dd911ff2bf9feb3ef5db4779299a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 11 May 2015 16:36:09 +0200 Subject: make defined() error message tell about "var" type Change-Id: I21d994ebaee2db0d9b114812a8f89bb680ca311e Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index e384d26f4c..f8027c6ec4 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1121,7 +1121,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( switch (func_t) { case T_DEFINED: { if (args.count() < 1 || args.count() > 2) { - evalError(fL1S("defined(function, [\"test\"|\"replace\"])" + evalError(fL1S("defined(function, [\"test\"|\"replace\"|\"var\"])" " requires one or two arguments.")); return ReturnFalse; } -- cgit v1.2.3 From 4334ddc76bdcf1e6d379faae562bc5916c50c4ba Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 13 May 2015 20:53:19 +0200 Subject: remove trailing dots from some error messages the i/o functions are not very consistent about having the dot already in the message. the windows api does, and qt passes this on. Change-Id: I2d1a213965e15478985d6eff205689ea44aa2a03 Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index f8027c6ec4..9efcd7eec3 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -362,7 +362,7 @@ QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::Open { QString errStr; if (!m_vfs->writeFile(fn, mode, contents, &errStr)) { - evalError(fL1S("Cannot write %1file %2: %3.") + evalError(fL1S("Cannot write %1file %2: %3") .arg(ctx, QDir::toNativeSeparators(fn), errStr)); return ReturnFalse; } @@ -1582,7 +1582,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (rHand == INVALID_HANDLE_VALUE) { - evalError(fL1S("Cannot open() reference file %1: %2.").arg(rfn, windowsErrorCode())); + evalError(fL1S("Cannot open() reference file %1: %2").arg(rfn, windowsErrorCode())); return ReturnFalse; } FILETIME ft; @@ -1592,7 +1592,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (wHand == INVALID_HANDLE_VALUE) { - evalError(fL1S("Cannot open() %1: %2.").arg(tfn, windowsErrorCode())); + evalError(fL1S("Cannot open() %1: %2").arg(tfn, windowsErrorCode())); return ReturnFalse; } SetFileTime(wHand, 0, 0, &ft); -- cgit v1.2.3 From fe9baf7e5b10dc7dfe074791d5e286a29cc33560 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 13 May 2015 20:53:49 +0200 Subject: trim whitespace from windows error messages the messages contain a trailing CRLF, which is not helpful. Change-Id: I4a27115a191dc416a62e28a41f2a9c5893bdc64b Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 9efcd7eec3..cf4149f339 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -214,7 +214,7 @@ static QString windowsErrorCode() NULL); QString ret = QString::fromWCharArray(string); LocalFree((HLOCAL)string); - return ret; + return ret.trimmed(); } #endif -- cgit v1.2.3 From 637a0889b2766e40fe089d0028395d1113d5e6fb Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 13 May 2015 21:09:43 +0200 Subject: remove bogus parens from error messages Change-Id: I2683a4fb19a7251dc537e3265db3ba28079eb4b8 Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index cf4149f339..02d5d5dd31 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1582,7 +1582,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (rHand == INVALID_HANDLE_VALUE) { - evalError(fL1S("Cannot open() reference file %1: %2").arg(rfn, windowsErrorCode())); + evalError(fL1S("Cannot open reference file %1: %2").arg(rfn, windowsErrorCode())); return ReturnFalse; } FILETIME ft; @@ -1592,7 +1592,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (wHand == INVALID_HANDLE_VALUE) { - evalError(fL1S("Cannot open() %1: %2").arg(tfn, windowsErrorCode())); + evalError(fL1S("Cannot open %1: %2").arg(tfn, windowsErrorCode())); return ReturnFalse; } SetFileTime(wHand, 0, 0, &ft); -- cgit v1.2.3 From df436839756ca7488b9eabcd11be04844a4ca8a3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 4 Mar 2015 21:38:31 +0100 Subject: move get{,Hash}Str from QMakeEvaluator to ProFile this makes it possible to use these functions without an evaluator. Change-Id: I23e4ec141b427f4c3c8b647305532be179058c07 Reviewed-by: Joerg Bornemann --- qmake/library/proitems.cpp | 19 +++++++++++++++++++ qmake/library/proitems.h | 3 +++ qmake/library/qmakeevaluator.cpp | 36 ++++++++++-------------------------- qmake/library/qmakeevaluator.h | 2 -- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp index f3526846e9..a610da6b69 100644 --- a/qmake/library/proitems.cpp +++ b/qmake/library/proitems.cpp @@ -485,4 +485,23 @@ ProFile::~ProFile() { } +ProString ProFile::getStr(const ushort *&tPtr) +{ + uint len = *tPtr++; + ProString ret(items(), tPtr - tokPtr(), len); + ret.setSource(this); + tPtr += len; + return ret; +} + +ProKey ProFile::getHashStr(const ushort *&tPtr) +{ + uint hash = *tPtr++; + hash |= (uint)*tPtr++ << 16; + uint len = *tPtr++; + ProKey ret(items(), tPtr - tokPtr(), len, hash); + tPtr += len; + return ret; +} + QT_END_NAMESPACE diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index d31367361d..9430d28521 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -352,6 +352,9 @@ public: bool isHostBuild() const { return m_hostBuild; } void setHostBuild(bool host_build) { m_hostBuild = host_build; } + ProString getStr(const ushort *&tPtr); + ProKey getHashStr(const ushort *&tPtr); + private: ProItemRefCount m_refCount; QString m_proitems; diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index cb7e0d4bf2..5ed14caf76 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -258,24 +258,6 @@ uint QMakeEvaluator::getBlockLen(const ushort *&tokPtr) return len; } -ProString QMakeEvaluator::getStr(const ushort *&tokPtr) -{ - uint len = *tokPtr++; - ProString ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len); - ret.setSource(m_current.pro); - tokPtr += len; - return ret; -} - -ProKey QMakeEvaluator::getHashStr(const ushort *&tokPtr) -{ - uint hash = getBlockLen(tokPtr); - uint len = *tokPtr++; - ProKey ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len, hash); - tokPtr += len; - return ret; -} - void QMakeEvaluator::skipStr(const ushort *&tokPtr) { uint len = *tokPtr++; @@ -430,6 +412,7 @@ void QMakeEvaluator::evaluateExpression( const ushort *&tokPtr, ProStringList *ret, bool joined) { debugMsg(2, joined ? "evaluating joined expression" : "evaluating expression"); + ProFile *pro = m_current.pro; if (joined) *ret << ProString(); bool pending = false; @@ -445,35 +428,35 @@ void QMakeEvaluator::evaluateExpression( m_current.line = *tokPtr++; break; case TokLiteral: { - const ProString &val = getStr(tokPtr); + const ProString &val = pro->getStr(tokPtr); debugMsg(2, "literal %s", dbgStr(val)); addStr(val, ret, pending, joined); break; } case TokHashLiteral: { - const ProKey &val = getHashStr(tokPtr); + const ProKey &val = pro->getHashStr(tokPtr); debugMsg(2, "hashed literal %s", dbgStr(val.toString())); addStr(val, ret, pending, joined); break; } case TokVariable: { - const ProKey &var = getHashStr(tokPtr); + const ProKey &var = pro->getHashStr(tokPtr); const ProStringList &val = values(map(var)); debugMsg(2, "variable %s => %s", dbgKey(var), dbgStrList(val)); addStrList(val, tok, ret, pending, joined); break; } case TokProperty: { - const ProKey &var = getHashStr(tokPtr); + const ProKey &var = pro->getHashStr(tokPtr); const ProString &val = propertyValue(var); debugMsg(2, "property %s => %s", dbgKey(var), dbgStr(val)); addStr(val, ret, pending, joined); break; } case TokEnvVar: { - const ProString &var = getStr(tokPtr); + const ProString &var = pro->getStr(tokPtr); const ProString &val = ProString(m_option->getEnv(var.toQString(m_tmp1))); debugMsg(2, "env var %s => %s", dbgStr(var), dbgStr(val)); addStr(val, ret, pending, joined); break; } case TokFuncName: { - const ProKey &func = getHashStr(tokPtr); + const ProKey &func = pro->getHashStr(tokPtr); debugMsg(2, "function %s", dbgKey(func)); addStrList(evaluateExpandFunction(func, tokPtr), tok, ret, pending, joined); break; } @@ -538,6 +521,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( { traceMsg("entering block"); ProStringList curr; + ProFile *pro = m_current.pro; bool okey = true, or_op = false, invert = false; uint blockLen; while (ushort tok = *tokPtr++) { @@ -597,7 +581,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( blockLen = getBlockLen(tokPtr); ret = visitProBlock(tokPtr); } else if (okey != or_op) { - const ProKey &variable = getHashStr(tokPtr); + const ProKey &variable = pro->getHashStr(tokPtr); uint exprLen = getBlockLen(tokPtr); const ushort *exprPtr = tokPtr; tokPtr += exprLen; @@ -617,7 +601,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( case TokTestDef: case TokReplaceDef: if (m_cumulative || okey != or_op) { - const ProKey &name = getHashStr(tokPtr); + const ProKey &name = pro->getHashStr(tokPtr); blockLen = getBlockLen(tokPtr); visitProFunctionDef(tok, name, tokPtr); traceMsg("defined %s function %s", diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 4f2acf25ee..a60adde84e 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -150,8 +150,6 @@ public: { return b ? ReturnTrue : ReturnFalse; } static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr); - ProString getStr(const ushort *&tokPtr); - ProKey getHashStr(const ushort *&tokPtr); void evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined); static ALWAYS_INLINE void skipStr(const ushort *&tokPtr); static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr); -- cgit v1.2.3 From 48c38aae10e5fe9c85e0e045916f6abfed936463 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 15 May 2015 21:05:44 +0200 Subject: move parser test to a separate file for better structure. Change-Id: I16bd1ca245640e92ffe167241a5a565e7a550e1d Reviewed-by: Joerg Bornemann --- tests/auto/tools/qmakelib/parsertest.cpp | 1966 +++++++++++++++++++++++++++ tests/auto/tools/qmakelib/qmakelib.pro | 4 + tests/auto/tools/qmakelib/tst_qmakelib.cpp | 2002 +--------------------------- tests/auto/tools/qmakelib/tst_qmakelib.h | 77 ++ 4 files changed, 2061 insertions(+), 1988 deletions(-) create mode 100644 tests/auto/tools/qmakelib/parsertest.cpp create mode 100644 tests/auto/tools/qmakelib/tst_qmakelib.h diff --git a/tests/auto/tools/qmakelib/parsertest.cpp b/tests/auto/tools/qmakelib/parsertest.cpp new file mode 100644 index 0000000000..2fe8e90b51 --- /dev/null +++ b/tests/auto/tools/qmakelib/parsertest.cpp @@ -0,0 +1,1966 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "tst_qmakelib.h" + +#include +#include +#include + +class TokenStream +{ +public: + TokenStream() {} + QString toString() const { return ts; } + + TokenStream &operator<<(ushort n) { ts += QChar(n); return *this; } + TokenStream &operator<<(uint n) { ts += QChar(n & 0xffff); ts += QChar(n >> 16); return *this; } + TokenStream &operator<<(const QStringRef &s) { ts += s; return *this; } + TokenStream &operator<<(const ProString &s) { return *this << ushort(s.length()) << s.toQStringRef(); } + TokenStream &operator<<(const ProKey &s) { return *this << s.hash() << s.toString(); } + +private: + QString ts; +}; + +#define TS(s) (TokenStream() s).toString() +#define H(n) ushort(n) +#define I(n) uint(n) +#define S(s) ProString(QString::fromWCharArray(s)) +#define HS(s) ProKey(QString::fromWCharArray(s)) + +QT_WARNING_PUSH +QT_WARNING_DISABLE_MSVC(4003) // "not enough actual parameters for macro TS()" + +void tst_qmakelib::proParser_data() +{ + QTest::addColumn("in"); + QTest::addColumn("out"); + QTest::addColumn("msgs"); + QTest::addColumn("ok"); + + QTest::newRow("empty") + << "" + << TS() + << "" + << true; + + QTest::newRow("empty (whitespace)") + << " \t \t" + << TS() + << "" + << true; + + // Variable operators + + QTest::newRow("assign none") + << "VAR =" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokAssign) << H(0) + /* 11 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("append none") + << "VAR +=" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokAppend) << H(0) + /* 11 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("unique append none") + << "VAR *=" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokAppendUnique) << H(0) + /* 11 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("remove none") + << "VAR -=" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokRemove) << H(0) + /* 11 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("replace empty") + << "VAR ~=" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokReplace) << H(0) + /* 11 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("assignment without variable") + << "=" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokAssign) << H(0) + /* 4 */ << H(TokValueTerminator)) + << "in:1: Assignment needs exactly one word on the left hand side." + << false; + + QTest::newRow("assignment with multiple variables") + << "VAR VAR =" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokAssign) << H(0) + /* 4 */ << H(TokValueTerminator)) + << "in:1: Assignment needs exactly one word on the left hand side." + << false; + + // Values + +#define ASSIGN_VAR(h) \ + H(TokLine) << H(1) \ + << H(TokHashLiteral) << HS(L"VAR") \ + << H(TokAssign) << H(h) + + QTest::newRow("one literal") + << "VAR = val" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"val") + /* 16 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("one literal (squeezed)") + << "VAR=val" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"val") + /* 16 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("many literals") + << "VAR = foo barbaz bak hello" + << TS( + /* 0 */ << ASSIGN_VAR(4) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz") + /* 24 */ << H(TokLiteral | TokNewStr) << S(L"bak") + /* 29 */ << H(TokLiteral | TokNewStr) << S(L"hello") + /* 36 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("many literals (tab-separated") + << "VAR\t=\tfoo\tbarbaz\tbak\thello" + << TS( + /* 0 */ << ASSIGN_VAR(4) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz") + /* 24 */ << H(TokLiteral | TokNewStr) << S(L"bak") + /* 29 */ << H(TokLiteral | TokNewStr) << S(L"hello") + /* 36 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("one quoted literal") + << "VAR = \"val ue\"" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"val ue") + /* 19 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("quoted literal with missing quote") + << "VAR = val \"ue" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokAssign) << H(0) + /* 11 */ << H(TokValueTerminator)) + << "in:1: Missing closing \" quote" + << false; + + QTest::newRow("many quoted literals") + << "VAR = \"foo\" barbaz 'bak hello' \"\"" + << TS( + /* 0 */ << ASSIGN_VAR(3) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz") + /* 24 */ << H(TokLiteral | TokNewStr) << S(L"bak hello") + /* 35 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("many quoted literals (with tabs)") + << "VAR\t=\t\"foo\"\tbarbaz\t'bak\thello'" + << TS( + /* 0 */ << ASSIGN_VAR(3) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz") + /* 24 */ << H(TokLiteral | TokNewStr) << S(L"bak\thello") + /* 35 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("quoted and unquoted spaces") + << " VAR = \"val ue \" " + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"val ue ") + /* 22 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("funny literals") + << "VAR = foo:bar|!baz(blam!, ${foo})" + << TS( + /* 0 */ << ASSIGN_VAR(2) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo:bar|!baz(blam!,") + /* 32 */ << H(TokLiteral | TokNewStr) << S(L"${foo})") + /* 41 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("literals with escapes") + << "VAR = \\{hi\\} \\[ho\\] \\)uh\\( \"\\\\oh\\$\"\\' \\$\\${FOO}" + << TS( + /* 0 */ << ASSIGN_VAR(5) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"{hi}") + /* 17 */ << H(TokLiteral | TokNewStr) << S(L"[ho]") + /* 23 */ << H(TokLiteral | TokNewStr) << S(L")uh(") + /* 29 */ << H(TokLiteral | TokNewStr) << S(L"\\oh$'") + /* 36 */ << H(TokLiteral | TokNewStr) << S(L"$${FOO}") + /* 45 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("magic variables") + << "VAR = $$LITERAL_HASH $$LITERAL_DOLLAR $$LITERAL_WHITESPACE $$_FILE_ $$_LINE_" + << TS( + /* 0 */ << ASSIGN_VAR(5) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"#") + /* 14 */ << H(TokLiteral | TokNewStr) << S(L"$") + /* 17 */ << H(TokLiteral | TokNewStr) << S(L"\t") + /* 20 */ << H(TokLiteral | TokNewStr) << S(L"in") + /* 24 */ << H(TokLiteral | TokNewStr) << S(L"1") + /* 27 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("continuations and comments") + << "VAR = foo \\\n bar\n \n" + "GAR = foo \\ # comment\n bar \\\n # comment\n baz \\\n" + "\"quoted \\ #comment\n escape\" \\\n right\\\n after \\\n gorilla!\n \n\n" + "MOO = \\\n kuh # comment\nLOO =\n\n" + "FOO = bar \\\n# comment\n baz \\\n \n# comment\n" + "GAZ=" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokAssign) << H(2) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 16 */ << H(TokLiteral | TokNewStr) << S(L"bar") + /* 21 */ << H(TokValueTerminator) + /* 22 */ << H(TokLine) << H(4) + /* 24 */ << H(TokHashLiteral) << HS(L"GAR") + /* 31 */ << H(TokAssign) << H(7) + /* 33 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 38 */ << H(TokLiteral | TokNewStr) << S(L"bar") + /* 43 */ << H(TokLiteral | TokNewStr) << S(L"baz") + /* 48 */ << H(TokLiteral | TokNewStr) << S(L"quoted escape") + /* 64 */ << H(TokLiteral | TokNewStr) << S(L"right") + /* 71 */ << H(TokLiteral | TokNewStr) << S(L"after") + /* 78 */ << H(TokLiteral | TokNewStr) << S(L"gorilla!") + /* 88 */ << H(TokValueTerminator) + /* 89 */ << H(TokLine) << H(15) + /* 91 */ << H(TokHashLiteral) << HS(L"MOO") + /* 98 */ << H(TokAssign) << H(0) + /* 100 */ << H(TokLiteral | TokNewStr) << S(L"kuh") + /* 105 */ << H(TokValueTerminator) + /* 106 */ << H(TokLine) << H(17) + /* 108 */ << H(TokHashLiteral) << HS(L"LOO") + /* 115 */ << H(TokAssign) << H(0) + /* 117 */ << H(TokValueTerminator) + /* 118 */ << H(TokLine) << H(19) + /* 120 */ << H(TokHashLiteral) << HS(L"FOO") + /* 127 */ << H(TokAssign) << H(2) + /* 129 */ << H(TokLiteral | TokNewStr) << S(L"bar") + /* 134 */ << H(TokLiteral | TokNewStr) << S(L"baz") + /* 139 */ << H(TokValueTerminator) + /* 140 */ << H(TokLine) << H(24) + /* 142 */ << H(TokHashLiteral) << HS(L"GAZ") + /* 149 */ << H(TokAssign) << H(0) + /* 151 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("accidental continuation") + << "VAR0 = \\\n this \\\n is \\\n ok\n" + "VAR1 = \\\n this \\\n is=still \\\n ok\n" + "VAR2 = \\\n this \\\n is \\\n" + "VAR3 = \\\n not ok\n" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR0") + /* 10 */ << H(TokAssign) << H(3) + /* 12 */ << H(TokLiteral | TokNewStr) << S(L"this") + /* 18 */ << H(TokLiteral | TokNewStr) << S(L"is") + /* 22 */ << H(TokLiteral | TokNewStr) << S(L"ok") + /* 26 */ << H(TokValueTerminator) + /* 27 */ << H(TokLine) << H(5) + /* 29 */ << H(TokHashLiteral) << HS(L"VAR1") + /* 37 */ << H(TokAssign) << H(3) + /* 39 */ << H(TokLiteral | TokNewStr) << S(L"this") + /* 45 */ << H(TokLiteral | TokNewStr) << S(L"is=still") + /* 55 */ << H(TokLiteral | TokNewStr) << S(L"ok") + /* 59 */ << H(TokValueTerminator) + /* 60 */ << H(TokLine) << H(9) + /* 62 */ << H(TokHashLiteral) << HS(L"VAR2") + /* 70 */ << H(TokAssign) << H(6) + /* 72 */ << H(TokLiteral | TokNewStr) << S(L"this") + /* 78 */ << H(TokLiteral | TokNewStr) << S(L"is") + /* 82 */ << H(TokLiteral | TokNewStr) << S(L"VAR3") + /* 88 */ << H(TokLiteral | TokNewStr) << S(L"=") + /* 91 */ << H(TokLiteral | TokNewStr) << S(L"not") + /* 96 */ << H(TokLiteral | TokNewStr) << S(L"ok") + /* 100 */ << H(TokValueTerminator)) + << "WARNING: in:12: Possible accidental line continuation" + << true; + + QTest::newRow("plain variable expansion") + << "VAR = $$bar" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokVariable | TokNewStr) << HS(L"bar") + /* 18 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("braced variable expansion") + << "VAR = $${foo/bar}" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokVariable | TokNewStr) << HS(L"foo/bar") + /* 22 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("bogus variable expansion") + << "VAR = $$ " + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokVariable | TokNewStr) << HS(L"") + /* 15 */ << H(TokValueTerminator)) + << "WARNING: in:1: Missing name in expansion" + << true; + + QTest::newRow("bogus braced variable expansion") + << "VAR = $${}" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokVariable | TokNewStr) << HS(L"") + /* 15 */ << H(TokValueTerminator)) + << "WARNING: in:1: Missing name in expansion" + << true; + + QTest::newRow("unterminated braced variable expansion") + << "VAR = $${FOO" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokAssign) << H(0) + /* 11 */ << H(TokVariable | TokNewStr) << HS(L"FOO") + /* 18 */ << H(TokValueTerminator)) + << "in:1: Missing } terminator [found end-of-line]" + << false; + + QTest::newRow("invalid identifier in braced variable expansion") + << "VAR = $${FOO/BAR+BAZ}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokAssign) << H(0) + /* 11 */ << H(TokVariable | TokNewStr) << HS(L"FOO/BAR") + /* 22 */ << H(TokLiteral) << S(L"+BAZ") + /* 28 */ << H(TokValueTerminator)) + << "in:1: Missing } terminator [found +]" + << false; + + QTest::newRow("property expansion") + << "VAR = $$[bar]" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokProperty | TokNewStr) << HS(L"bar") + /* 18 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("environment expansion") + << "VAR = $$(bar)" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokEnvVar | TokNewStr) << S(L"bar") + /* 16 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("plain function call") + << "VAR = $$bar()" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"bar") + /* 18 */ << H(TokFuncTerminator) + /* 19 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("braced function call") + << "VAR = $${bar()}" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"bar") + /* 18 */ << H(TokFuncTerminator) + /* 19 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("function call with one argument") + << "VAR = $$bar(blubb)" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"bar") + /* 18 */ << H(TokLiteral | TokNewStr) << S(L"blubb") + /* 25 */ << H(TokFuncTerminator) + /* 26 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("function call with multiple arguments") + << "VAR = $$bar( blubb blubb, hey ,$$you)" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"bar") + /* 18 */ << H(TokLiteral | TokNewStr) << S(L"blubb") + /* 25 */ << H(TokLiteral | TokNewStr) << S(L"blubb") + /* 32 */ << H(TokArgSeparator) + /* 33 */ << H(TokLiteral | TokNewStr) << S(L"hey") + /* 38 */ << H(TokArgSeparator) + /* 39 */ << H(TokVariable | TokNewStr) << HS(L"you") + /* 46 */ << H(TokFuncTerminator) + /* 47 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("nested function call") + << "VAR = $$foo(yo, $$bar(blubb))" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"foo") + /* 18 */ << H(TokLiteral | TokNewStr) << S(L"yo") + /* 22 */ << H(TokArgSeparator) + /* 23 */ << H(TokFuncName | TokNewStr) << HS(L"bar") + /* 30 */ << H(TokLiteral | TokNewStr) << S(L"blubb") + /* 37 */ << H(TokFuncTerminator) + /* 38 */ << H(TokFuncTerminator) + /* 39 */ << H(TokValueTerminator)) + << "" + << true; + + // This is a rather questionable "feature" + QTest::newRow("function call with parenthesized argument") + << "VAR = $$bar(blubb (yo, man) blabb, nope)" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"bar") + /* 18 */ << H(TokLiteral | TokNewStr) << S(L"blubb") + /* 25 */ << H(TokLiteral | TokNewStr) << S(L"(yo,") + /* 31 */ << H(TokLiteral | TokNewStr) << S(L"man)") + /* 37 */ << H(TokLiteral | TokNewStr) << S(L"blabb") + /* 44 */ << H(TokArgSeparator) + /* 45 */ << H(TokLiteral | TokNewStr) << S(L"nope") + /* 51 */ << H(TokFuncTerminator) + /* 52 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("separate literal and expansion") + << "VAR = foo $$bar" + << TS( + /* 0 */ << ASSIGN_VAR(2) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 16 */ << H(TokVariable | TokNewStr) << HS(L"bar") + /* 23 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("separate expansion and literal") + << "VAR = $$bar foo" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokVariable | TokNewStr) << HS(L"bar") + /* 18 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 23 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("joined literal and expansion") + << "VAR = foo$$bar" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 16 */ << H(TokVariable) << HS(L"bar") + /* 23 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("joined expansion and literal") + << "VAR = $${bar}foo" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokVariable | TokNewStr) << HS(L"bar") + /* 18 */ << H(TokLiteral) << S(L"foo") + /* 23 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("plain variable expansion with funny name and literal") + << "VAR = $$az_AZ_09.dot/nix" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokVariable | TokNewStr) << HS(L"az_AZ_09.dot") + /* 27 */ << H(TokLiteral) << S(L"/nix") + /* 33 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("braced variable expansion with funny name") + << "VAR = $${az_AZ_09.dot/nix}" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokVariable | TokNewStr) << HS(L"az_AZ_09.dot/nix") + /* 31 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("quoted joined literal and expansion") + << "VAR = 'foo$$bar'" + << TS( + /* 0 */ << ASSIGN_VAR(0) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 16 */ << H(TokVariable | TokQuoted) << HS(L"bar") + /* 23 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("assignment with expansion in variable name") + << "VAR$$EXTRA =" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokVariable) << HS(L"EXTRA") + /* 18 */ << H(TokAssign) << H(0) + /* 20 */ << H(TokValueTerminator)) + << "" + << true; + + // Conditionals ("Tests") + + QTest::newRow("one test") + << "foo" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("wildcard-test") + << "foo-*" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo-*") + /* 11 */ << H(TokCondition)) + << "" + << true; + + // This is a rather questionable "feature" + QTest::newRow("one quoted test") + << "\"foo\"" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("two tests") + << "foo\nbar" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokLine) << H(2) + /* 12 */ << H(TokHashLiteral) << HS(L"bar") + /* 19 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("bogus two tests") + << "foo bar\nbaz" + << TS() + << "in:1: Extra characters after test expression." + << false; + + QTest::newRow("test-AND-test") + << "foo:bar" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokAnd) + /* 11 */ << H(TokHashLiteral) << HS(L"bar") + /* 18 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("test-OR-test") + << " foo | bar " + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokOr) + /* 11 */ << H(TokHashLiteral) << HS(L"bar") + /* 18 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("NOT-test") + << "!foo" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokNot) + /* 3 */ << H(TokHashLiteral) << HS(L"foo") + /* 10 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("NOT-NOT-test") + << "!!foo" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition)) + << "" + << true; + + // This is a rather questionable "feature" + QTest::newRow("quoted-NOT-test") + << "\"!foo\"" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokNot) + /* 3 */ << H(TokHashLiteral) << HS(L"foo") + /* 10 */ << H(TokCondition)) + << "" + << true; + + // This is a rather questionable "feature" + QTest::newRow("NOT-quoted-test") + << "!\"foo\"" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokNot) + /* 3 */ << H(TokHashLiteral) << HS(L"foo") + /* 10 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("test-AND-NOT-test") + << "foo:!bar" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokAnd) + /* 11 */ << H(TokNot) + /* 12 */ << H(TokHashLiteral) << HS(L"bar") + /* 19 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("test-assignment") + << "foo\nVAR=" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokLine) << H(2) + /* 12 */ << H(TokHashLiteral) << HS(L"VAR") + /* 19 */ << H(TokAssign) << H(0) + /* 21 */ << H(TokValueTerminator)) + << "" + << true; + + QTest::newRow("test-AND-assignment") + << "foo: VAR =" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokBranch) + /* 11 */ /* then branch */ << I(11) + /* 13 */ << H(TokHashLiteral) << HS(L"VAR") + /* 20 */ << H(TokAssign) << H(0) + /* 22 */ << H(TokValueTerminator) + /* 23 */ << H(TokTerminator) + /* 24 */ /* else branch */ << I(0)) + << "" + << true; + + QTest::newRow("test-else-test") + << "foo\nelse: bar" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokBranch) + /* 11 */ /* then branch */ << I(0) + /* 13 */ /* else branch */ << I(11) + /* 15 */ << H(TokLine) << H(2) + /* 17 */ << H(TokHashLiteral) << HS(L"bar") + /* 24 */ << H(TokCondition) + /* 25 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("function-else-test") + << "foo()\nelse: bar" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokTestCall) + /* 10 */ << H(TokFuncTerminator) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(0) + /* 14 */ /* else branch */ << I(11) + /* 16 */ << H(TokLine) << H(2) + /* 18 */ << H(TokHashLiteral) << HS(L"bar") + /* 25 */ << H(TokCondition) + /* 26 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("test-AND-test-else-test") + << "foo:bar\nelse: baz" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokAnd) + /* 11 */ << H(TokHashLiteral) << HS(L"bar") + /* 18 */ << H(TokCondition) + /* 19 */ << H(TokBranch) + /* 20 */ /* then branch */ << I(0) + /* 22 */ /* else branch */ << I(11) + /* 24 */ << H(TokLine) << H(2) + /* 26 */ << H(TokHashLiteral) << HS(L"baz") + /* 33 */ << H(TokCondition) + /* 34 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("test-AND-test-else-test-else-test-function") + << "foo:bar\nelse: baz\nelse: bak\nbuzz()" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokAnd) + /* 11 */ << H(TokHashLiteral) << HS(L"bar") + /* 18 */ << H(TokCondition) + /* 19 */ << H(TokBranch) + /* 20 */ /* then branch */ << I(0) + /* 22 */ /* else branch */ << I(27) + /* 24 */ << H(TokLine) << H(2) + /* 26 */ << H(TokHashLiteral) << HS(L"baz") + /* 33 */ << H(TokCondition) + /* 34 */ << H(TokBranch) + /* 35 */ /* then branch */ << I(0) + /* 37 */ /* else branch */ << I(11) + /* 39 */ << H(TokLine) << H(3) + /* 41 */ << H(TokHashLiteral) << HS(L"bak") + /* 48 */ << H(TokCondition) + /* 49 */ << H(TokTerminator) + /* 50 */ << H(TokTerminator) + /* 51 */ << H(TokLine) << H(4) + /* 53 */ << H(TokHashLiteral) << HS(L"buzz") + /* 61 */ << H(TokTestCall) + /* 62 */ << H(TokFuncTerminator)) + << "" + << true; + + QTest::newRow("test-assignment-else-assignment") + << "foo: VAR =\nelse: VAR=" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokBranch) + /* 11 */ /* then branch */ << I(11) + /* 13 */ << H(TokHashLiteral) << HS(L"VAR") + /* 20 */ << H(TokAssign) << H(0) + /* 22 */ << H(TokValueTerminator) + /* 23 */ << H(TokTerminator) + /* 24 */ /* else branch */ << I(13) + /* 26 */ << H(TokLine) << H(2) + /* 28 */ << H(TokHashLiteral) << HS(L"VAR") + /* 35 */ << H(TokAssign) << H(0) + /* 37 */ << H(TokValueTerminator) + /* 38 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("test-else-test-assignment") + << "foo\nelse: bar: VAR =" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokBranch) + /* 11 */ /* then branch */ << I(0) + /* 13 */ /* else branch */ << I(27) + /* 15 */ << H(TokLine) << H(2) + /* 17 */ << H(TokHashLiteral) << HS(L"bar") + /* 24 */ << H(TokCondition) + /* 25 */ << H(TokBranch) + /* 26 */ /* then branch */ << I(11) + /* 28 */ << H(TokHashLiteral) << HS(L"VAR") + /* 35 */ << H(TokAssign) << H(0) + /* 37 */ << H(TokValueTerminator) + /* 38 */ << H(TokTerminator) + /* 39 */ /* else branch */ << I(0) + /* 41 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("one function") + << "foo()" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokTestCall) + /* 10 */ << H(TokFuncTerminator)) + << "" + << true; + + QTest::newRow("one function (with spaces)") + << " foo( ) " + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokTestCall) + /* 10 */ << H(TokFuncTerminator)) + << "" + << true; + + QTest::newRow("unterminated function call") + << "foo(\nfoo" + << TS() + << "in:1: Missing closing parenthesis in function call" + << false; + + QTest::newRow("function with arguments") + << "foo(blah, hi ho)" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokTestCall) + /* 10 */ << H(TokLiteral | TokNewStr) << S(L"blah") + /* 16 */ << H(TokArgSeparator) + /* 17 */ << H(TokLiteral | TokNewStr) << S(L"hi") + /* 21 */ << H(TokLiteral | TokNewStr) << S(L"ho") + /* 25 */ << H(TokFuncTerminator)) + << "" + << true; + + QTest::newRow("function with empty arguments") + << "foo(,)" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokTestCall) + /* 10 */ << H(TokArgSeparator) + /* 11 */ << H(TokFuncTerminator)) + << "" + << true; + + QTest::newRow("function with funny arguments") + << "foo(blah\\, \"hi , \\ho\" ,uh\\ ,\\oh ,, )" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokTestCall) + /* 10 */ << H(TokLiteral | TokNewStr) << S(L"blah\\") + /* 17 */ << H(TokArgSeparator) + /* 18 */ << H(TokLiteral | TokNewStr) << S(L"hi , \\ho") + /* 29 */ << H(TokArgSeparator) + /* 30 */ << H(TokLiteral | TokNewStr) << S(L"uh\\") + /* 35 */ << H(TokArgSeparator) + /* 36 */ << H(TokLiteral | TokNewStr) << S(L"\\oh") + /* 41 */ << H(TokArgSeparator) + /* 42 */ << H(TokArgSeparator) + /* 43 */ << H(TokFuncTerminator)) + << "WARNING: in:1: Unescaped backslashes are deprecated\n" + "WARNING: in:1: Unescaped backslashes are deprecated\n" + "WARNING: in:1: Unescaped backslashes are deprecated\n" + "WARNING: in:1: Unescaped backslashes are deprecated" + << true; + + QTest::newRow("function with nested call") + << "foo($$blah(hi ho))" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokTestCall) + /* 10 */ << H(TokFuncName | TokNewStr) << HS(L"blah") + /* 18 */ << H(TokLiteral | TokNewStr) << S(L"hi") + /* 22 */ << H(TokLiteral | TokNewStr) << S(L"ho") + /* 26 */ << H(TokFuncTerminator) + /* 27 */ << H(TokFuncTerminator)) + << "" + << true; + + QTest::newRow("stand-alone parentheses") + << "()" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestCall) + /* 3 */ << H(TokFuncTerminator)) + << "in:1: Opening parenthesis without prior test name." + << false; + + QTest::newRow("bogus test and function") + << "foo bar()" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestCall) + /* 3 */ << H(TokFuncTerminator)) + << "in:1: Extra characters after test expression." + << false; + + // This is a rather questionable "feature" + QTest::newRow("two functions") + << "foo() bar()" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokTestCall) + /* 10 */ << H(TokFuncTerminator) + /* 11 */ << H(TokHashLiteral) << HS(L"bar") + /* 18 */ << H(TokTestCall) + /* 19 */ << H(TokFuncTerminator)) + << "" + << true; + + QTest::newRow("function-AND-test") + << "foo():bar" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokTestCall) + /* 10 */ << H(TokFuncTerminator) + /* 11 */ << H(TokAnd) + /* 12 */ << H(TokHashLiteral) << HS(L"bar") + /* 19 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("test-AND-function") + << "foo:bar()" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokAnd) + /* 11 */ << H(TokHashLiteral) << HS(L"bar") + /* 18 */ << H(TokTestCall) + /* 19 */ << H(TokFuncTerminator)) + << "" + << true; + + QTest::newRow("NOT-function-AND-test") + << "!foo():bar" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokNot) + /* 3 */ << H(TokHashLiteral) << HS(L"foo") + /* 10 */ << H(TokTestCall) + /* 11 */ << H(TokFuncTerminator) + /* 12 */ << H(TokAnd) + /* 13 */ << H(TokHashLiteral) << HS(L"bar") + /* 20 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("test-AND-NOT-function") + << "foo:!bar()" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"foo") + /* 9 */ << H(TokCondition) + /* 10 */ << H(TokAnd) + /* 11 */ << H(TokNot) + /* 12 */ << H(TokHashLiteral) << HS(L"bar") + /* 19 */ << H(TokTestCall) + /* 20 */ << H(TokFuncTerminator)) + << "" + << true; + + // Control statements + + QTest::newRow("for(VAR, LIST) loop") + << "for(VAR, LIST)" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokForLoop) << HS(L"VAR") + /* 9 */ /* iterator */ << I(7) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"LIST") + /* 17 */ << H(TokValueTerminator) + /* 18 */ /* body */ << I(1) + /* 20 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("for(ever) loop") + << "for(ever)" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokForLoop) << HS(L"") + /* 6 */ /* iterator */ << I(9) + /* 8 */ << H(TokHashLiteral) << HS(L"ever") + /* 16 */ << H(TokValueTerminator) + /* 17 */ /* body */ << I(1) + /* 19 */ << H(TokTerminator)) + << "" + << true; + + // This is a rather questionable "feature" + QTest::newRow("for($$blub) loop") + << "for($$blub)" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokForLoop) << HS(L"") + /* 6 */ /* iterator */ << I(9) + /* 8 */ << H(TokVariable | TokNewStr) << HS(L"blub") + /* 16 */ << H(TokValueTerminator) + /* 17 */ /* body */ << I(1) + /* 19 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("test-for-test-else-test") + << "true:for(VAR, LIST): true\nelse: true" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(31) + /* 14 */ << H(TokForLoop) << HS(L"VAR") + /* 21 */ /* iterator */ << I(7) + /* 23 */ << H(TokLiteral | TokNewStr) << S(L"LIST") + /* 29 */ << H(TokValueTerminator) + /* 30 */ /* body */ << I(12) + /* 32 */ << H(TokLine) << H(1) + /* 34 */ << H(TokHashLiteral) << HS(L"true") + /* 42 */ << H(TokCondition) + /* 43 */ << H(TokTerminator) + /* 44 */ << H(TokTerminator) + /* 45 */ /* else branch */ << I(12) + /* 47 */ << H(TokLine) << H(2) + /* 49 */ << H(TokHashLiteral) << HS(L"true") + /* 57 */ << H(TokCondition) + /* 58 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("next()") + << "for(ever): next()" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokForLoop) << HS(L"") + /* 6 */ /* iterator */ << I(9) + /* 8 */ << H(TokHashLiteral) << HS(L"ever") + /* 16 */ << H(TokValueTerminator) + /* 17 */ /* body */ << I(4) + /* 19 */ << H(TokLine) << H(1) + /* 21 */ << H(TokNext) + /* 22 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("break()") + << "for(ever): break()" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokForLoop) << HS(L"") + /* 6 */ /* iterator */ << I(9) + /* 8 */ << H(TokHashLiteral) << HS(L"ever") + /* 16 */ << H(TokValueTerminator) + /* 17 */ /* body */ << I(4) + /* 19 */ << H(TokLine) << H(1) + /* 21 */ << H(TokBreak) + /* 22 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("top-level return()") + << "return()" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokReturn)) + << "" + << true; + + QTest::newRow("else") + << "else" + << TS() + << "in:1: Unexpected 'else'." + << false; + + QTest::newRow("test-{else}") + << "test { else }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(1) + /* 14 */ << H(TokTerminator) + /* 15 */ /* else branch */ << I(0)) + << "in:1: Unexpected 'else'." + << false; + + QTest::newRow("defineTest-{else}") + << "defineTest(fn) { else }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestDef) << HS(L"fn") + /* 8 */ /* body */ << I(1) + /* 10 */ << H(TokTerminator)) + << "in:1: Unexpected 'else'." + << false; + + QTest::newRow("for-else") + << "for(ever) { else }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokForLoop) << HS(L"") + /* 6 */ /* iterator */ << I(9) + /* 8 */ << H(TokHashLiteral) << HS(L"ever") + /* 16 */ << H(TokValueTerminator) + /* 17 */ /* body */ << I(1) + /* 19 */ << H(TokTerminator)) + << "in:1: Unexpected 'else'." + << false; + + QTest::newRow("double-test-else") + << "foo bar\nelse" + << TS( + /* 0 */ << H(TokBranch) + /* 1 */ /* then branch */ << I(0) + /* 3 */ /* else branch */ << I(1) // This seems weird + /* 5 */ << H(TokTerminator)) + << "in:1: Extra characters after test expression." + << false; + + QTest::newRow("test-function-else") + << "foo bar()\nelse" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestCall) // This seems pointless + /* 3 */ << H(TokFuncTerminator) + /* 4 */ << H(TokBranch) + /* 5 */ /* then branch */ << I(0) + /* 7 */ /* else branch */ << I(1) // This seems weird + /* 9 */ << H(TokTerminator)) + << "in:1: Extra characters after test expression." + << false; + + // Braces + + QTest::newRow("{}") + << "{ }" + << TS() + << "" + << true; + + QTest::newRow("{}-newlines") + << "\n\n{ }\n\n" + << TS() + << "" + << true; + + QTest::newRow("{") + << "{" + << TS() + << "in:2: Missing closing brace(s)." + << false; + + QTest::newRow("test {") + << "test {" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(1) + /* 14 */ << H(TokTerminator) + /* 15 */ /* else branch */ << I(0)) + << "in:2: Missing closing brace(s)." + << false; + + QTest::newRow("}") + << "}" + << TS() + << "in:1: Excess closing brace." + << false; + + QTest::newRow("{test}") + << "{ true }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("{test-newlines}") + << "{\ntrue\n}" + << TS( + /* 0 */ << H(TokLine) << H(2) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("{assignment-test}-test") + << "{ VAR = { foo } bar } true" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokAssign) << H(4) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"{") + /* 14 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 19 */ << H(TokLiteral | TokNewStr) << S(L"}") + /* 22 */ << H(TokLiteral | TokNewStr) << S(L"bar") + /* 27 */ << H(TokValueTerminator) + /* 28 */ << H(TokHashLiteral) << HS(L"true") + /* 36 */ << H(TokCondition)) + << "" + << true; + + QTest::newRow("assignment with excess opening brace") + << "VAR = { { foo }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"VAR") + /* 9 */ << H(TokAssign) << H(4) + /* 11 */ << H(TokLiteral | TokNewStr) << S(L"{") + /* 14 */ << H(TokLiteral | TokNewStr) << S(L"{") + /* 17 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 22 */ << H(TokLiteral | TokNewStr) << S(L"}") + /* 25 */ << H(TokValueTerminator)) + << "WARNING: in:1: Possible braces mismatch" + << true; + + QTest::newRow("test-{}") + << "true {}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(1) + /* 14 */ << H(TokTerminator) + /* 15 */ /* else branch */ << I(0)) + << "" + << true; + + QTest::newRow("test-{newlines}") + << "true {\n}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(1) + /* 14 */ << H(TokTerminator) + /* 15 */ /* else branch */ << I(0)) + << "" + << true; + + QTest::newRow("test-{test}") + << "true { true }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(10) + /* 14 */ << H(TokHashLiteral) << HS(L"true") + /* 22 */ << H(TokCondition) + /* 23 */ << H(TokTerminator) + /* 24 */ /* else branch */ << I(0)) + << "" + << true; + + QTest::newRow("test:-{test}") + << "true: { true }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(10) + /* 14 */ << H(TokHashLiteral) << HS(L"true") + /* 22 */ << H(TokCondition) + /* 23 */ << H(TokTerminator) + /* 24 */ /* else branch */ << I(0)) + << "WARNING: in:1: Excess colon in front of opening brace." + << true; + + QTest::newRow("test-{test-newlines}") + << "true {\ntrue\n}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(12) + /* 14 */ << H(TokLine) << H(2) + /* 16 */ << H(TokHashLiteral) << HS(L"true") + /* 24 */ << H(TokCondition) + /* 25 */ << H(TokTerminator) + /* 26 */ /* else branch */ << I(0)) + << "" + << true; + + QTest::newRow("test:-{test-newlines}") + << "true: {\ntrue\n}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(12) + /* 14 */ << H(TokLine) << H(2) + /* 16 */ << H(TokHashLiteral) << HS(L"true") + /* 24 */ << H(TokCondition) + /* 25 */ << H(TokTerminator) + /* 26 */ /* else branch */ << I(0)) + << "WARNING: in:1: Excess colon in front of opening brace." + << true; + + QTest::newRow("test-{assignment}") + << "true { VAR = {foo} }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(18) + /* 14 */ << H(TokHashLiteral) << HS(L"VAR") + /* 21 */ << H(TokAssign) << H(0) + /* 23 */ << H(TokLiteral | TokNewStr) << S(L"{foo}") + /* 30 */ << H(TokValueTerminator) + /* 31 */ << H(TokTerminator) + /* 32 */ /* else branch */ << I(0)) + << "" + << true; + + QTest::newRow("test-{test-assignment}") + << "true { true: VAR = {foo} }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(33) + /* 14 */ << H(TokHashLiteral) << HS(L"true") + /* 22 */ << H(TokCondition) + /* 23 */ << H(TokBranch) + /* 24 */ /* then branch */ << I(18) + /* 26 */ << H(TokHashLiteral) << HS(L"VAR") + /* 33 */ << H(TokAssign) << H(0) + /* 35 */ << H(TokLiteral | TokNewStr) << S(L"{foo}") + /* 42 */ << H(TokValueTerminator) + /* 43 */ << H(TokTerminator) + /* 44 */ /* else branch */ << I(0) + /* 46 */ << H(TokTerminator) + /* 47 */ /* else branch */ << I(0)) + << "" + << true; + + QTest::newRow("test-{assignment-newlines}") + << "true {\nVAR = {foo}\n}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(20) + /* 14 */ << H(TokLine) << H(2) + /* 16 */ << H(TokHashLiteral) << HS(L"VAR") + /* 23 */ << H(TokAssign) << H(0) + /* 25 */ << H(TokLiteral | TokNewStr) << S(L"{foo}") + /* 32 */ << H(TokValueTerminator) + /* 33 */ << H(TokTerminator) + /* 34 */ /* else branch */ << I(0)) + << "" + << true; + + QTest::newRow("test-{}-else-test-{}") + << "true {} else: true {}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(1) + /* 14 */ << H(TokTerminator) + /* 15 */ /* else branch */ << I(18) + /* 17 */ << H(TokLine) << H(1) + /* 19 */ << H(TokHashLiteral) << HS(L"true") + /* 27 */ << H(TokCondition) + /* 28 */ << H(TokBranch) + /* 29 */ /* then branch */ << I(1) + /* 31 */ << H(TokTerminator) + /* 32 */ /* else branch */ << I(0) + /* 34 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("test-{}-else-test-{}-newlines") + << "true {\n}\nelse: true {\n}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(1) + /* 14 */ << H(TokTerminator) + /* 15 */ /* else branch */ << I(18) + /* 17 */ << H(TokLine) << H(3) + /* 19 */ << H(TokHashLiteral) << HS(L"true") + /* 27 */ << H(TokCondition) + /* 28 */ << H(TokBranch) + /* 29 */ /* then branch */ << I(1) + /* 31 */ << H(TokTerminator) + /* 32 */ /* else branch */ << I(0) + /* 34 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("test-{test}-else-test-{}-newlines") + << "true {\ntrue\n}\nelse: true {\n}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(12) + /* 14 */ << H(TokLine) << H(2) + /* 16 */ << H(TokHashLiteral) << HS(L"true") + /* 24 */ << H(TokCondition) + /* 25 */ << H(TokTerminator) + /* 26 */ /* else branch */ << I(18) + /* 28 */ << H(TokLine) << H(4) + /* 30 */ << H(TokHashLiteral) << HS(L"true") + /* 38 */ << H(TokCondition) + /* 39 */ << H(TokBranch) + /* 40 */ /* then branch */ << I(1) + /* 42 */ << H(TokTerminator) + /* 43 */ /* else branch */ << I(0) + /* 45 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("for-{next}") + << "for(ever) { next() }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokForLoop) << HS(L"") + /* 6 */ /* iterator */ << I(9) + /* 8 */ << H(TokHashLiteral) << HS(L"ever") + /* 16 */ << H(TokValueTerminator) + /* 17 */ /* body */ << I(4) + /* 19 */ << H(TokLine) << H(1) + /* 21 */ << H(TokNext) + /* 22 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("for:-{next}") + << "for(ever): { next() }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokForLoop) << HS(L"") + /* 6 */ /* iterator */ << I(9) + /* 8 */ << H(TokHashLiteral) << HS(L"ever") + /* 16 */ << H(TokValueTerminator) + /* 17 */ /* body */ << I(4) + /* 19 */ << H(TokLine) << H(1) + /* 21 */ << H(TokNext) + /* 22 */ << H(TokTerminator)) + << "WARNING: in:1: Excess colon in front of opening brace." + << true; + + QTest::newRow("test-for-{test-else-test-newlines}") + << "true:for(VAR, LIST) {\ntrue\nelse: true\n}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(48) + /* 14 */ << H(TokForLoop) << HS(L"VAR") + /* 21 */ /* iterator */ << I(7) + /* 23 */ << H(TokLiteral | TokNewStr) << S(L"LIST") + /* 29 */ << H(TokValueTerminator) + /* 30 */ /* body */ << I(29) + /* 32 */ << H(TokLine) << H(2) + /* 34 */ << H(TokHashLiteral) << HS(L"true") + /* 42 */ << H(TokCondition) + /* 43 */ << H(TokBranch) + /* 44 */ /* then branch */ << I(0) + /* 46 */ /* else branch */ << I(12) + /* 48 */ << H(TokLine) << H(3) + /* 50 */ << H(TokHashLiteral) << HS(L"true") + /* 58 */ << H(TokCondition) + /* 59 */ << H(TokTerminator) + /* 60 */ << H(TokTerminator) + /* 61 */ << H(TokTerminator) + /* 62 */ /* else branch */ << I(0)) + << "" + << true; + + QTest::newRow("test-for-{test-else-test}") + << "true:for(VAR, LIST) { true\nelse: true }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"true") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(48) + /* 14 */ << H(TokForLoop) << HS(L"VAR") + /* 21 */ /* iterator */ << I(7) + /* 23 */ << H(TokLiteral | TokNewStr) << S(L"LIST") + /* 29 */ << H(TokValueTerminator) + /* 30 */ /* body */ << I(29) + /* 32 */ << H(TokLine) << H(1) + /* 34 */ << H(TokHashLiteral) << HS(L"true") + /* 42 */ << H(TokCondition) + /* 43 */ << H(TokBranch) + /* 44 */ /* then branch */ << I(0) + /* 46 */ /* else branch */ << I(12) + /* 48 */ << H(TokLine) << H(2) + /* 50 */ << H(TokHashLiteral) << HS(L"true") + /* 58 */ << H(TokCondition) + /* 59 */ << H(TokTerminator) + /* 60 */ << H(TokTerminator) + /* 61 */ << H(TokTerminator) + /* 62 */ /* else branch */ << I(0)) + << "" + << true; + + // Custom functions + + QTest::newRow("defineTest-{newlines}") + << "defineTest(test) {\n}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestDef) << HS(L"test") + /* 10 */ /* body */ << I(1) + /* 12 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("defineTest:-test") + << "defineTest(test): test" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestDef) << HS(L"test") + /* 10 */ /* body */ << I(12) + /* 12 */ << H(TokLine) << H(1) + /* 14 */ << H(TokHashLiteral) << HS(L"test") + /* 22 */ << H(TokCondition) + /* 23 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("defineTest-{test}") + << "defineTest(test) { test }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestDef) << HS(L"test") + /* 10 */ /* body */ << I(12) + /* 12 */ << H(TokLine) << H(1) + /* 14 */ << H(TokHashLiteral) << HS(L"test") + /* 22 */ << H(TokCondition) + /* 23 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("defineTest-{return}") + << "defineTest(test) { return() }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokTestDef) << HS(L"test") + /* 10 */ /* body */ << I(4) + /* 12 */ << H(TokLine) << H(1) + /* 14 */ << H(TokReturn) + /* 15 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("defineReplace-{return-stuff}") + << "defineReplace(stuff) { return(foo bar) }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokReplaceDef) << HS(L"stuff") + /* 11 */ /* body */ << I(14) + /* 13 */ << H(TokLine) << H(1) + /* 15 */ << H(TokLiteral | TokNewStr) << S(L"foo") + /* 20 */ << H(TokLiteral | TokNewStr) << S(L"bar") + /* 25 */ << H(TokReturn) + /* 26 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("test-AND-defineTest-{}") + << "test: defineTest(test) {}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokAnd) + /* 12 */ << H(TokTestDef) << HS(L"test") + /* 20 */ /* body */ << I(1) + /* 22 */ << H(TokTerminator)) + << "" + << true; + + QTest::newRow("test-OR-defineTest-{}") + << "test| defineTest(test) {}" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokOr) + /* 12 */ << H(TokTestDef) << HS(L"test") + /* 20 */ /* body */ << I(1) + /* 22 */ << H(TokTerminator)) + << "" + << true; + + // Operator abuse + + QTest::newRow("!") + << "" + << TS() + << "" + << true; + + QTest::newRow("|") + << "" + << TS() + << "" + << true; + + QTest::newRow(":") + << "" + << TS() + << "" + << true; + + QTest::newRow("NOT-assignment") + << "!VAR =" + << TS() + << "in:1: Unexpected NOT operator in front of assignment." + << false; + + QTest::newRow("NOT-{}") + << "!{}" + << TS() + << "in:1: Unexpected NOT operator in front of opening brace." + << false; + + QTest::newRow("NOT-else") + << "test\n!else {}" + << TS() + << "in:2: Unexpected NOT operator in front of else." + << false; + + QTest::newRow("NOT-for-{}") + << "!for(ever) {}" + << TS() + << "in:1: Unexpected NOT operator in front of for()." + << false; + + QTest::newRow("NOT-defineTest-{}") + << "!defineTest(test) {}" + << TS() + << "in:1: Unexpected NOT operator in front of function definition." + << false; + + QTest::newRow("AND-test") + << ":test" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition)) + << "in:1: AND operator without prior condition." + << false; + + QTest::newRow("test-AND-else") + << "test:else" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition)) + << "in:1: Unexpected AND operator in front of else." + << false; + + QTest::newRow("test-AND-AND-test") + << "test::test" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokAnd) + /* 12 */ << H(TokHashLiteral) << HS(L"test") + /* 20 */ << H(TokCondition)) + << "WARNING: in:1: Stray AND operator in front of AND operator." + << true; + + QTest::newRow("test-AND-OR-test") + << "test:|test" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokOr) + /* 12 */ << H(TokHashLiteral) << HS(L"test") + /* 20 */ << H(TokCondition)) + << "WARNING: in:1: Stray AND operator in front of OR operator." + << true; + + QTest::newRow("test-{AND-test}") + << "test { :test }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(10) + /* 14 */ << H(TokHashLiteral) << HS(L"test") + /* 22 */ << H(TokCondition) + /* 23 */ << H(TokTerminator) + /* 24 */ /* else branch */ << I(0)) + << "in:1: AND operator without prior condition." + << false; + + QTest::newRow("test-OR-assignment") + << "foo| VAR =" + << TS() + << "in:1: Unexpected OR operator in front of assignment." + << false; + + QTest::newRow("test-OR-{}") + << "foo|{}" + << TS() + << "in:1: Unexpected OR operator in front of opening brace." + << false; + + QTest::newRow("test-OR-for") + << "foo|for(ever) {}" + << TS() + << "in:1: Unexpected OR operator in front of for()." + << false; + + QTest::newRow("OR-test") + << "|test" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition)) + << "in:1: OR operator without prior condition." + << false; + + QTest::newRow("test-OR-else") + << "test|else" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition)) + << "in:1: Unexpected OR operator in front of else." + << false; + + QTest::newRow("test-OR-OR-test") + << "test||test" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokOr) + /* 12 */ << H(TokHashLiteral) << HS(L"test") + /* 20 */ << H(TokCondition)) + << "WARNING: in:1: Stray OR operator in front of OR operator." + << true; + + QTest::newRow("test-OR-AND-test") + << "test|:test" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokAnd) + /* 12 */ << H(TokHashLiteral) << HS(L"test") + /* 20 */ << H(TokCondition)) + << "WARNING: in:1: Stray OR operator in front of AND operator." + << true; + + QTest::newRow("test-{OR-test}") + << "test { |test }" + << TS( + /* 0 */ << H(TokLine) << H(1) + /* 2 */ << H(TokHashLiteral) << HS(L"test") + /* 10 */ << H(TokCondition) + /* 11 */ << H(TokBranch) + /* 12 */ /* then branch */ << I(10) + /* 14 */ << H(TokHashLiteral) << HS(L"test") + /* 22 */ << H(TokCondition) + /* 23 */ << H(TokTerminator) + /* 24 */ /* else branch */ << I(0)) + << "in:1: OR operator without prior condition." + << false; + + // option() (these produce no tokens) + + QTest::newRow("option(host_build)") + << "option(host_build)" + << TS() + << "" + << true; + + QTest::newRow("option()") + << "option()" + << TS() + << "in:1: option() requires one literal argument." + << false; + + QTest::newRow("option(host_build magic)") + << "option(host_build magic)" + << TS() + << "in:1: option() requires one literal argument." + << false; + + QTest::newRow("option(host_build, magic)") + << "option(host_build, magic)" + << TS() + << "in:1: option() requires one literal argument." + << false; + + QTest::newRow("option($$OPTION)") + << "option($$OPTION)" + << TS() + << "in:1: option() requires one literal argument." + << false; + + QTest::newRow("{option(host_build)}") + << "{option(host_build)}" + << TS() + << "in:1: option() must appear outside any control structures." + << false; +} + +QT_WARNING_POP + +void tst_qmakelib::proParser() +{ + QFETCH(QString, in); + QFETCH(QString, out); + QFETCH(QString, msgs); + QFETCH(bool, ok); + + bool verified = true; + QMakeHandler handler; + handler.setExpectedMessages(msgs.split('\n', QString::SkipEmptyParts)); + QMakeVfs vfs; + QMakeParser parser(0, &vfs, &handler); + ProFile *pro = parser.parsedProBlock(in, "in", 1, QMakeParser::FullGrammar); + if (handler.printedMessages()) { + qWarning("Got unexpected message(s)"); + verified = false; + } + QStringList missingMsgs = handler.expectedMessages(); + if (!missingMsgs.isEmpty()) { + foreach (const QString &msg, missingMsgs) + qWarning("Missing message: %s", qPrintable(msg)); + verified = false; + } + if (pro->isOk() != ok) { + static const char * const lbl[] = { "failure", "success" }; + qWarning("Expected %s, got %s", lbl[int(ok)], lbl[1 - int(ok)]); + verified = false; + } + if (pro->items() != out && (ok || !out.isEmpty())) { + qWarning("Bytecode mismatch.\nActual:%s\nExpected:%s", + qPrintable(QMakeParser::formatProBlock(pro->items())), + qPrintable(QMakeParser::formatProBlock(out))); + verified = false; + } + pro->deref(); + QVERIFY(verified); +} diff --git a/tests/auto/tools/qmakelib/qmakelib.pro b/tests/auto/tools/qmakelib/qmakelib.pro index e7807838aa..41aae95068 100644 --- a/tests/auto/tools/qmakelib/qmakelib.pro +++ b/tests/auto/tools/qmakelib/qmakelib.pro @@ -6,8 +6,12 @@ QT = core testlib INCLUDEPATH += ../../../../qmake/library VPATH += ../../../../qmake/library +HEADERS += \ + tst_qmakelib.h + SOURCES += \ tst_qmakelib.cpp \ + parsertest.cpp \ ioutils.cpp \ proitems.cpp \ qmakevfs.cpp \ diff --git a/tests/auto/tools/qmakelib/tst_qmakelib.cpp b/tests/auto/tools/qmakelib/tst_qmakelib.cpp index ab14de0e24..5caa730a19 100644 --- a/tests/auto/tools/qmakelib/tst_qmakelib.cpp +++ b/tests/auto/tools/qmakelib/tst_qmakelib.cpp @@ -31,39 +31,12 @@ ** ****************************************************************************/ -#include +#include "tst_qmakelib.h" #include -#include -#include -#include - -#include using namespace QMakeInternal; -class tst_qmakelib : public QObject -{ - Q_OBJECT - -public: - tst_qmakelib() {} - virtual ~tst_qmakelib() {} - -private slots: - void quoteArgUnix_data(); - void quoteArgUnix(); - void quoteArgWin_data(); - void quoteArgWin(); - void pathUtils(); - - void proString(); - void proStringList(); - - void proParser_data(); - void proParser(); -}; - void tst_qmakelib::proString() { QString qs1(QStringLiteral("this is a string")); @@ -252,1968 +225,21 @@ void tst_qmakelib::pathUtils() QCOMPARE(IoUtils::resolvePath(fnbase, fn1), QStringLiteral("/a/unix/file/path")); } -class QMakeHandler : public QMakeParserHandler { -public: - QMakeHandler() : QMakeParserHandler(), printed(false) {} - virtual void message(int type, const QString &msg, const QString &fileName, int lineNo) - { print(fileName, lineNo, type, msg); } - - void setExpectedMessages(const QStringList &msgs) { expected = msgs; } - QStringList expectedMessages() const { return expected; } - - bool printedMessages() const { return printed; } - -private: - void print(const QString &fileName, int lineNo, int type, const QString &msg) - { - QString pfx = ((type & QMakeParserHandler::CategoryMask) == QMakeParserHandler::WarningMessage) - ? QString::fromLatin1("WARNING: ") : QString(); - QString out; - if (lineNo) - out = QStringLiteral("%1%2:%3: %4").arg(pfx, fileName, QString::number(lineNo), msg); - else - out = QStringLiteral("%1%2").arg(pfx, msg); - if (!expected.isEmpty() && expected.first() == out) { - expected.removeAt(0); - return; - } - qWarning("%s", qPrintable(out)); - printed = true; - } - - QStringList expected; - bool printed; -}; - -static QMakeHandler qmakeHandler; - -class TokenStream -{ -public: - TokenStream() {} - QString toString() const { return ts; } - - TokenStream &operator<<(ushort n) { ts += QChar(n); return *this; } - TokenStream &operator<<(uint n) { ts += QChar(n & 0xffff); ts += QChar(n >> 16); return *this; } - TokenStream &operator<<(const QStringRef &s) { ts += s; return *this; } - TokenStream &operator<<(const ProString &s) { return *this << ushort(s.length()) << s.toQStringRef(); } - TokenStream &operator<<(const ProKey &s) { return *this << s.hash() << s.toString(); } - -private: - QString ts; -}; - -#define TS(s) (TokenStream() s).toString() -#define H(n) ushort(n) -#define I(n) uint(n) -#define S(s) ProString(QString::fromWCharArray(s)) -#define HS(s) ProKey(QString::fromWCharArray(s)) - -QT_WARNING_PUSH -QT_WARNING_DISABLE_MSVC(4003) // "not enough actual parameters for macro TS()" - -void tst_qmakelib::proParser_data() -{ - QTest::addColumn("in"); - QTest::addColumn("out"); - QTest::addColumn("msgs"); - QTest::addColumn("ok"); - - QTest::newRow("empty") - << "" - << TS() - << "" - << true; - - QTest::newRow("empty (whitespace)") - << " \t \t" - << TS() - << "" - << true; - - // Variable operators - - QTest::newRow("assign none") - << "VAR =" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokAssign) << H(0) - /* 11 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("append none") - << "VAR +=" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokAppend) << H(0) - /* 11 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("unique append none") - << "VAR *=" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokAppendUnique) << H(0) - /* 11 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("remove none") - << "VAR -=" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokRemove) << H(0) - /* 11 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("replace empty") - << "VAR ~=" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokReplace) << H(0) - /* 11 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("assignment without variable") - << "=" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokAssign) << H(0) - /* 4 */ << H(TokValueTerminator)) - << "in:1: Assignment needs exactly one word on the left hand side." - << false; - - QTest::newRow("assignment with multiple variables") - << "VAR VAR =" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokAssign) << H(0) - /* 4 */ << H(TokValueTerminator)) - << "in:1: Assignment needs exactly one word on the left hand side." - << false; - - // Values - -#define ASSIGN_VAR(h) \ - H(TokLine) << H(1) \ - << H(TokHashLiteral) << HS(L"VAR") \ - << H(TokAssign) << H(h) - - QTest::newRow("one literal") - << "VAR = val" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"val") - /* 16 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("one literal (squeezed)") - << "VAR=val" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"val") - /* 16 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("many literals") - << "VAR = foo barbaz bak hello" - << TS( - /* 0 */ << ASSIGN_VAR(4) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz") - /* 24 */ << H(TokLiteral | TokNewStr) << S(L"bak") - /* 29 */ << H(TokLiteral | TokNewStr) << S(L"hello") - /* 36 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("many literals (tab-separated") - << "VAR\t=\tfoo\tbarbaz\tbak\thello" - << TS( - /* 0 */ << ASSIGN_VAR(4) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz") - /* 24 */ << H(TokLiteral | TokNewStr) << S(L"bak") - /* 29 */ << H(TokLiteral | TokNewStr) << S(L"hello") - /* 36 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("one quoted literal") - << "VAR = \"val ue\"" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"val ue") - /* 19 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("quoted literal with missing quote") - << "VAR = val \"ue" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokAssign) << H(0) - /* 11 */ << H(TokValueTerminator)) - << "in:1: Missing closing \" quote" - << false; - - QTest::newRow("many quoted literals") - << "VAR = \"foo\" barbaz 'bak hello' \"\"" - << TS( - /* 0 */ << ASSIGN_VAR(3) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz") - /* 24 */ << H(TokLiteral | TokNewStr) << S(L"bak hello") - /* 35 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("many quoted literals (with tabs)") - << "VAR\t=\t\"foo\"\tbarbaz\t'bak\thello'" - << TS( - /* 0 */ << ASSIGN_VAR(3) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 16 */ << H(TokLiteral | TokNewStr) << S(L"barbaz") - /* 24 */ << H(TokLiteral | TokNewStr) << S(L"bak\thello") - /* 35 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("quoted and unquoted spaces") - << " VAR = \"val ue \" " - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"val ue ") - /* 22 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("funny literals") - << "VAR = foo:bar|!baz(blam!, ${foo})" - << TS( - /* 0 */ << ASSIGN_VAR(2) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo:bar|!baz(blam!,") - /* 32 */ << H(TokLiteral | TokNewStr) << S(L"${foo})") - /* 41 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("literals with escapes") - << "VAR = \\{hi\\} \\[ho\\] \\)uh\\( \"\\\\oh\\$\"\\' \\$\\${FOO}" - << TS( - /* 0 */ << ASSIGN_VAR(5) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"{hi}") - /* 17 */ << H(TokLiteral | TokNewStr) << S(L"[ho]") - /* 23 */ << H(TokLiteral | TokNewStr) << S(L")uh(") - /* 29 */ << H(TokLiteral | TokNewStr) << S(L"\\oh$'") - /* 36 */ << H(TokLiteral | TokNewStr) << S(L"$${FOO}") - /* 45 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("magic variables") - << "VAR = $$LITERAL_HASH $$LITERAL_DOLLAR $$LITERAL_WHITESPACE $$_FILE_ $$_LINE_" - << TS( - /* 0 */ << ASSIGN_VAR(5) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"#") - /* 14 */ << H(TokLiteral | TokNewStr) << S(L"$") - /* 17 */ << H(TokLiteral | TokNewStr) << S(L"\t") - /* 20 */ << H(TokLiteral | TokNewStr) << S(L"in") - /* 24 */ << H(TokLiteral | TokNewStr) << S(L"1") - /* 27 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("continuations and comments") - << "VAR = foo \\\n bar\n \n" - "GAR = foo \\ # comment\n bar \\\n # comment\n baz \\\n" - "\"quoted \\ #comment\n escape\" \\\n right\\\n after \\\n gorilla!\n \n\n" - "MOO = \\\n kuh # comment\nLOO =\n\n" - "FOO = bar \\\n# comment\n baz \\\n \n# comment\n" - "GAZ=" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokAssign) << H(2) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 16 */ << H(TokLiteral | TokNewStr) << S(L"bar") - /* 21 */ << H(TokValueTerminator) - /* 22 */ << H(TokLine) << H(4) - /* 24 */ << H(TokHashLiteral) << HS(L"GAR") - /* 31 */ << H(TokAssign) << H(7) - /* 33 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 38 */ << H(TokLiteral | TokNewStr) << S(L"bar") - /* 43 */ << H(TokLiteral | TokNewStr) << S(L"baz") - /* 48 */ << H(TokLiteral | TokNewStr) << S(L"quoted escape") - /* 64 */ << H(TokLiteral | TokNewStr) << S(L"right") - /* 71 */ << H(TokLiteral | TokNewStr) << S(L"after") - /* 78 */ << H(TokLiteral | TokNewStr) << S(L"gorilla!") - /* 88 */ << H(TokValueTerminator) - /* 89 */ << H(TokLine) << H(15) - /* 91 */ << H(TokHashLiteral) << HS(L"MOO") - /* 98 */ << H(TokAssign) << H(0) - /* 100 */ << H(TokLiteral | TokNewStr) << S(L"kuh") - /* 105 */ << H(TokValueTerminator) - /* 106 */ << H(TokLine) << H(17) - /* 108 */ << H(TokHashLiteral) << HS(L"LOO") - /* 115 */ << H(TokAssign) << H(0) - /* 117 */ << H(TokValueTerminator) - /* 118 */ << H(TokLine) << H(19) - /* 120 */ << H(TokHashLiteral) << HS(L"FOO") - /* 127 */ << H(TokAssign) << H(2) - /* 129 */ << H(TokLiteral | TokNewStr) << S(L"bar") - /* 134 */ << H(TokLiteral | TokNewStr) << S(L"baz") - /* 139 */ << H(TokValueTerminator) - /* 140 */ << H(TokLine) << H(24) - /* 142 */ << H(TokHashLiteral) << HS(L"GAZ") - /* 149 */ << H(TokAssign) << H(0) - /* 151 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("accidental continuation") - << "VAR0 = \\\n this \\\n is \\\n ok\n" - "VAR1 = \\\n this \\\n is=still \\\n ok\n" - "VAR2 = \\\n this \\\n is \\\n" - "VAR3 = \\\n not ok\n" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR0") - /* 10 */ << H(TokAssign) << H(3) - /* 12 */ << H(TokLiteral | TokNewStr) << S(L"this") - /* 18 */ << H(TokLiteral | TokNewStr) << S(L"is") - /* 22 */ << H(TokLiteral | TokNewStr) << S(L"ok") - /* 26 */ << H(TokValueTerminator) - /* 27 */ << H(TokLine) << H(5) - /* 29 */ << H(TokHashLiteral) << HS(L"VAR1") - /* 37 */ << H(TokAssign) << H(3) - /* 39 */ << H(TokLiteral | TokNewStr) << S(L"this") - /* 45 */ << H(TokLiteral | TokNewStr) << S(L"is=still") - /* 55 */ << H(TokLiteral | TokNewStr) << S(L"ok") - /* 59 */ << H(TokValueTerminator) - /* 60 */ << H(TokLine) << H(9) - /* 62 */ << H(TokHashLiteral) << HS(L"VAR2") - /* 70 */ << H(TokAssign) << H(6) - /* 72 */ << H(TokLiteral | TokNewStr) << S(L"this") - /* 78 */ << H(TokLiteral | TokNewStr) << S(L"is") - /* 82 */ << H(TokLiteral | TokNewStr) << S(L"VAR3") - /* 88 */ << H(TokLiteral | TokNewStr) << S(L"=") - /* 91 */ << H(TokLiteral | TokNewStr) << S(L"not") - /* 96 */ << H(TokLiteral | TokNewStr) << S(L"ok") - /* 100 */ << H(TokValueTerminator)) - << "WARNING: in:12: Possible accidental line continuation" - << true; - - QTest::newRow("plain variable expansion") - << "VAR = $$bar" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokVariable | TokNewStr) << HS(L"bar") - /* 18 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("braced variable expansion") - << "VAR = $${foo/bar}" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokVariable | TokNewStr) << HS(L"foo/bar") - /* 22 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("bogus variable expansion") - << "VAR = $$ " - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokVariable | TokNewStr) << HS(L"") - /* 15 */ << H(TokValueTerminator)) - << "WARNING: in:1: Missing name in expansion" - << true; - - QTest::newRow("bogus braced variable expansion") - << "VAR = $${}" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokVariable | TokNewStr) << HS(L"") - /* 15 */ << H(TokValueTerminator)) - << "WARNING: in:1: Missing name in expansion" - << true; - - QTest::newRow("unterminated braced variable expansion") - << "VAR = $${FOO" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokAssign) << H(0) - /* 11 */ << H(TokVariable | TokNewStr) << HS(L"FOO") - /* 18 */ << H(TokValueTerminator)) - << "in:1: Missing } terminator [found end-of-line]" - << false; - - QTest::newRow("invalid identifier in braced variable expansion") - << "VAR = $${FOO/BAR+BAZ}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokAssign) << H(0) - /* 11 */ << H(TokVariable | TokNewStr) << HS(L"FOO/BAR") - /* 22 */ << H(TokLiteral) << S(L"+BAZ") - /* 28 */ << H(TokValueTerminator)) - << "in:1: Missing } terminator [found +]" - << false; - - QTest::newRow("property expansion") - << "VAR = $$[bar]" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokProperty | TokNewStr) << HS(L"bar") - /* 18 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("environment expansion") - << "VAR = $$(bar)" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokEnvVar | TokNewStr) << S(L"bar") - /* 16 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("plain function call") - << "VAR = $$bar()" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"bar") - /* 18 */ << H(TokFuncTerminator) - /* 19 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("braced function call") - << "VAR = $${bar()}" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"bar") - /* 18 */ << H(TokFuncTerminator) - /* 19 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("function call with one argument") - << "VAR = $$bar(blubb)" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"bar") - /* 18 */ << H(TokLiteral | TokNewStr) << S(L"blubb") - /* 25 */ << H(TokFuncTerminator) - /* 26 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("function call with multiple arguments") - << "VAR = $$bar( blubb blubb, hey ,$$you)" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"bar") - /* 18 */ << H(TokLiteral | TokNewStr) << S(L"blubb") - /* 25 */ << H(TokLiteral | TokNewStr) << S(L"blubb") - /* 32 */ << H(TokArgSeparator) - /* 33 */ << H(TokLiteral | TokNewStr) << S(L"hey") - /* 38 */ << H(TokArgSeparator) - /* 39 */ << H(TokVariable | TokNewStr) << HS(L"you") - /* 46 */ << H(TokFuncTerminator) - /* 47 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("nested function call") - << "VAR = $$foo(yo, $$bar(blubb))" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"foo") - /* 18 */ << H(TokLiteral | TokNewStr) << S(L"yo") - /* 22 */ << H(TokArgSeparator) - /* 23 */ << H(TokFuncName | TokNewStr) << HS(L"bar") - /* 30 */ << H(TokLiteral | TokNewStr) << S(L"blubb") - /* 37 */ << H(TokFuncTerminator) - /* 38 */ << H(TokFuncTerminator) - /* 39 */ << H(TokValueTerminator)) - << "" - << true; - - // This is a rather questionable "feature" - QTest::newRow("function call with parenthesized argument") - << "VAR = $$bar(blubb (yo, man) blabb, nope)" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokFuncName | TokNewStr) << HS(L"bar") - /* 18 */ << H(TokLiteral | TokNewStr) << S(L"blubb") - /* 25 */ << H(TokLiteral | TokNewStr) << S(L"(yo,") - /* 31 */ << H(TokLiteral | TokNewStr) << S(L"man)") - /* 37 */ << H(TokLiteral | TokNewStr) << S(L"blabb") - /* 44 */ << H(TokArgSeparator) - /* 45 */ << H(TokLiteral | TokNewStr) << S(L"nope") - /* 51 */ << H(TokFuncTerminator) - /* 52 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("separate literal and expansion") - << "VAR = foo $$bar" - << TS( - /* 0 */ << ASSIGN_VAR(2) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 16 */ << H(TokVariable | TokNewStr) << HS(L"bar") - /* 23 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("separate expansion and literal") - << "VAR = $$bar foo" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokVariable | TokNewStr) << HS(L"bar") - /* 18 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 23 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("joined literal and expansion") - << "VAR = foo$$bar" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 16 */ << H(TokVariable) << HS(L"bar") - /* 23 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("joined expansion and literal") - << "VAR = $${bar}foo" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokVariable | TokNewStr) << HS(L"bar") - /* 18 */ << H(TokLiteral) << S(L"foo") - /* 23 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("plain variable expansion with funny name and literal") - << "VAR = $$az_AZ_09.dot/nix" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokVariable | TokNewStr) << HS(L"az_AZ_09.dot") - /* 27 */ << H(TokLiteral) << S(L"/nix") - /* 33 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("braced variable expansion with funny name") - << "VAR = $${az_AZ_09.dot/nix}" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokVariable | TokNewStr) << HS(L"az_AZ_09.dot/nix") - /* 31 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("quoted joined literal and expansion") - << "VAR = 'foo$$bar'" - << TS( - /* 0 */ << ASSIGN_VAR(0) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 16 */ << H(TokVariable | TokQuoted) << HS(L"bar") - /* 23 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("assignment with expansion in variable name") - << "VAR$$EXTRA =" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokVariable) << HS(L"EXTRA") - /* 18 */ << H(TokAssign) << H(0) - /* 20 */ << H(TokValueTerminator)) - << "" - << true; - - // Conditionals ("Tests") - - QTest::newRow("one test") - << "foo" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("wildcard-test") - << "foo-*" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo-*") - /* 11 */ << H(TokCondition)) - << "" - << true; - - // This is a rather questionable "feature" - QTest::newRow("one quoted test") - << "\"foo\"" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("two tests") - << "foo\nbar" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokLine) << H(2) - /* 12 */ << H(TokHashLiteral) << HS(L"bar") - /* 19 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("bogus two tests") - << "foo bar\nbaz" - << TS() - << "in:1: Extra characters after test expression." - << false; - - QTest::newRow("test-AND-test") - << "foo:bar" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokAnd) - /* 11 */ << H(TokHashLiteral) << HS(L"bar") - /* 18 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("test-OR-test") - << " foo | bar " - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokOr) - /* 11 */ << H(TokHashLiteral) << HS(L"bar") - /* 18 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("NOT-test") - << "!foo" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokNot) - /* 3 */ << H(TokHashLiteral) << HS(L"foo") - /* 10 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("NOT-NOT-test") - << "!!foo" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition)) - << "" - << true; - - // This is a rather questionable "feature" - QTest::newRow("quoted-NOT-test") - << "\"!foo\"" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokNot) - /* 3 */ << H(TokHashLiteral) << HS(L"foo") - /* 10 */ << H(TokCondition)) - << "" - << true; - - // This is a rather questionable "feature" - QTest::newRow("NOT-quoted-test") - << "!\"foo\"" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokNot) - /* 3 */ << H(TokHashLiteral) << HS(L"foo") - /* 10 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("test-AND-NOT-test") - << "foo:!bar" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokAnd) - /* 11 */ << H(TokNot) - /* 12 */ << H(TokHashLiteral) << HS(L"bar") - /* 19 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("test-assignment") - << "foo\nVAR=" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokLine) << H(2) - /* 12 */ << H(TokHashLiteral) << HS(L"VAR") - /* 19 */ << H(TokAssign) << H(0) - /* 21 */ << H(TokValueTerminator)) - << "" - << true; - - QTest::newRow("test-AND-assignment") - << "foo: VAR =" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokBranch) - /* 11 */ /* then branch */ << I(11) - /* 13 */ << H(TokHashLiteral) << HS(L"VAR") - /* 20 */ << H(TokAssign) << H(0) - /* 22 */ << H(TokValueTerminator) - /* 23 */ << H(TokTerminator) - /* 24 */ /* else branch */ << I(0)) - << "" - << true; - - QTest::newRow("test-else-test") - << "foo\nelse: bar" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokBranch) - /* 11 */ /* then branch */ << I(0) - /* 13 */ /* else branch */ << I(11) - /* 15 */ << H(TokLine) << H(2) - /* 17 */ << H(TokHashLiteral) << HS(L"bar") - /* 24 */ << H(TokCondition) - /* 25 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("function-else-test") - << "foo()\nelse: bar" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokTestCall) - /* 10 */ << H(TokFuncTerminator) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(0) - /* 14 */ /* else branch */ << I(11) - /* 16 */ << H(TokLine) << H(2) - /* 18 */ << H(TokHashLiteral) << HS(L"bar") - /* 25 */ << H(TokCondition) - /* 26 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("test-AND-test-else-test") - << "foo:bar\nelse: baz" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokAnd) - /* 11 */ << H(TokHashLiteral) << HS(L"bar") - /* 18 */ << H(TokCondition) - /* 19 */ << H(TokBranch) - /* 20 */ /* then branch */ << I(0) - /* 22 */ /* else branch */ << I(11) - /* 24 */ << H(TokLine) << H(2) - /* 26 */ << H(TokHashLiteral) << HS(L"baz") - /* 33 */ << H(TokCondition) - /* 34 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("test-AND-test-else-test-else-test-function") - << "foo:bar\nelse: baz\nelse: bak\nbuzz()" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokAnd) - /* 11 */ << H(TokHashLiteral) << HS(L"bar") - /* 18 */ << H(TokCondition) - /* 19 */ << H(TokBranch) - /* 20 */ /* then branch */ << I(0) - /* 22 */ /* else branch */ << I(27) - /* 24 */ << H(TokLine) << H(2) - /* 26 */ << H(TokHashLiteral) << HS(L"baz") - /* 33 */ << H(TokCondition) - /* 34 */ << H(TokBranch) - /* 35 */ /* then branch */ << I(0) - /* 37 */ /* else branch */ << I(11) - /* 39 */ << H(TokLine) << H(3) - /* 41 */ << H(TokHashLiteral) << HS(L"bak") - /* 48 */ << H(TokCondition) - /* 49 */ << H(TokTerminator) - /* 50 */ << H(TokTerminator) - /* 51 */ << H(TokLine) << H(4) - /* 53 */ << H(TokHashLiteral) << HS(L"buzz") - /* 61 */ << H(TokTestCall) - /* 62 */ << H(TokFuncTerminator)) - << "" - << true; - - QTest::newRow("test-assignment-else-assignment") - << "foo: VAR =\nelse: VAR=" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokBranch) - /* 11 */ /* then branch */ << I(11) - /* 13 */ << H(TokHashLiteral) << HS(L"VAR") - /* 20 */ << H(TokAssign) << H(0) - /* 22 */ << H(TokValueTerminator) - /* 23 */ << H(TokTerminator) - /* 24 */ /* else branch */ << I(13) - /* 26 */ << H(TokLine) << H(2) - /* 28 */ << H(TokHashLiteral) << HS(L"VAR") - /* 35 */ << H(TokAssign) << H(0) - /* 37 */ << H(TokValueTerminator) - /* 38 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("test-else-test-assignment") - << "foo\nelse: bar: VAR =" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokBranch) - /* 11 */ /* then branch */ << I(0) - /* 13 */ /* else branch */ << I(27) - /* 15 */ << H(TokLine) << H(2) - /* 17 */ << H(TokHashLiteral) << HS(L"bar") - /* 24 */ << H(TokCondition) - /* 25 */ << H(TokBranch) - /* 26 */ /* then branch */ << I(11) - /* 28 */ << H(TokHashLiteral) << HS(L"VAR") - /* 35 */ << H(TokAssign) << H(0) - /* 37 */ << H(TokValueTerminator) - /* 38 */ << H(TokTerminator) - /* 39 */ /* else branch */ << I(0) - /* 41 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("one function") - << "foo()" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokTestCall) - /* 10 */ << H(TokFuncTerminator)) - << "" - << true; - - QTest::newRow("one function (with spaces)") - << " foo( ) " - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokTestCall) - /* 10 */ << H(TokFuncTerminator)) - << "" - << true; - - QTest::newRow("unterminated function call") - << "foo(\nfoo" - << TS() - << "in:1: Missing closing parenthesis in function call" - << false; - - QTest::newRow("function with arguments") - << "foo(blah, hi ho)" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokTestCall) - /* 10 */ << H(TokLiteral | TokNewStr) << S(L"blah") - /* 16 */ << H(TokArgSeparator) - /* 17 */ << H(TokLiteral | TokNewStr) << S(L"hi") - /* 21 */ << H(TokLiteral | TokNewStr) << S(L"ho") - /* 25 */ << H(TokFuncTerminator)) - << "" - << true; - - QTest::newRow("function with empty arguments") - << "foo(,)" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokTestCall) - /* 10 */ << H(TokArgSeparator) - /* 11 */ << H(TokFuncTerminator)) - << "" - << true; - - QTest::newRow("function with funny arguments") - << "foo(blah\\, \"hi , \\ho\" ,uh\\ ,\\oh ,, )" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokTestCall) - /* 10 */ << H(TokLiteral | TokNewStr) << S(L"blah\\") - /* 17 */ << H(TokArgSeparator) - /* 18 */ << H(TokLiteral | TokNewStr) << S(L"hi , \\ho") - /* 29 */ << H(TokArgSeparator) - /* 30 */ << H(TokLiteral | TokNewStr) << S(L"uh\\") - /* 35 */ << H(TokArgSeparator) - /* 36 */ << H(TokLiteral | TokNewStr) << S(L"\\oh") - /* 41 */ << H(TokArgSeparator) - /* 42 */ << H(TokArgSeparator) - /* 43 */ << H(TokFuncTerminator)) - << "WARNING: in:1: Unescaped backslashes are deprecated\n" - "WARNING: in:1: Unescaped backslashes are deprecated\n" - "WARNING: in:1: Unescaped backslashes are deprecated\n" - "WARNING: in:1: Unescaped backslashes are deprecated" - << true; - - QTest::newRow("function with nested call") - << "foo($$blah(hi ho))" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokTestCall) - /* 10 */ << H(TokFuncName | TokNewStr) << HS(L"blah") - /* 18 */ << H(TokLiteral | TokNewStr) << S(L"hi") - /* 22 */ << H(TokLiteral | TokNewStr) << S(L"ho") - /* 26 */ << H(TokFuncTerminator) - /* 27 */ << H(TokFuncTerminator)) - << "" - << true; - - QTest::newRow("stand-alone parentheses") - << "()" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokTestCall) - /* 3 */ << H(TokFuncTerminator)) - << "in:1: Opening parenthesis without prior test name." - << false; - - QTest::newRow("bogus test and function") - << "foo bar()" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokTestCall) - /* 3 */ << H(TokFuncTerminator)) - << "in:1: Extra characters after test expression." - << false; - - // This is a rather questionable "feature" - QTest::newRow("two functions") - << "foo() bar()" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokTestCall) - /* 10 */ << H(TokFuncTerminator) - /* 11 */ << H(TokHashLiteral) << HS(L"bar") - /* 18 */ << H(TokTestCall) - /* 19 */ << H(TokFuncTerminator)) - << "" - << true; - - QTest::newRow("function-AND-test") - << "foo():bar" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokTestCall) - /* 10 */ << H(TokFuncTerminator) - /* 11 */ << H(TokAnd) - /* 12 */ << H(TokHashLiteral) << HS(L"bar") - /* 19 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("test-AND-function") - << "foo:bar()" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokAnd) - /* 11 */ << H(TokHashLiteral) << HS(L"bar") - /* 18 */ << H(TokTestCall) - /* 19 */ << H(TokFuncTerminator)) - << "" - << true; - - QTest::newRow("NOT-function-AND-test") - << "!foo():bar" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokNot) - /* 3 */ << H(TokHashLiteral) << HS(L"foo") - /* 10 */ << H(TokTestCall) - /* 11 */ << H(TokFuncTerminator) - /* 12 */ << H(TokAnd) - /* 13 */ << H(TokHashLiteral) << HS(L"bar") - /* 20 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("test-AND-NOT-function") - << "foo:!bar()" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"foo") - /* 9 */ << H(TokCondition) - /* 10 */ << H(TokAnd) - /* 11 */ << H(TokNot) - /* 12 */ << H(TokHashLiteral) << HS(L"bar") - /* 19 */ << H(TokTestCall) - /* 20 */ << H(TokFuncTerminator)) - << "" - << true; - - // Control statements - - QTest::newRow("for(VAR, LIST) loop") - << "for(VAR, LIST)" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokForLoop) << HS(L"VAR") - /* 9 */ /* iterator */ << I(7) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"LIST") - /* 17 */ << H(TokValueTerminator) - /* 18 */ /* body */ << I(1) - /* 20 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("for(ever) loop") - << "for(ever)" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokForLoop) << HS(L"") - /* 6 */ /* iterator */ << I(9) - /* 8 */ << H(TokHashLiteral) << HS(L"ever") - /* 16 */ << H(TokValueTerminator) - /* 17 */ /* body */ << I(1) - /* 19 */ << H(TokTerminator)) - << "" - << true; - - // This is a rather questionable "feature" - QTest::newRow("for($$blub) loop") - << "for($$blub)" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokForLoop) << HS(L"") - /* 6 */ /* iterator */ << I(9) - /* 8 */ << H(TokVariable | TokNewStr) << HS(L"blub") - /* 16 */ << H(TokValueTerminator) - /* 17 */ /* body */ << I(1) - /* 19 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("test-for-test-else-test") - << "true:for(VAR, LIST): true\nelse: true" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(31) - /* 14 */ << H(TokForLoop) << HS(L"VAR") - /* 21 */ /* iterator */ << I(7) - /* 23 */ << H(TokLiteral | TokNewStr) << S(L"LIST") - /* 29 */ << H(TokValueTerminator) - /* 30 */ /* body */ << I(12) - /* 32 */ << H(TokLine) << H(1) - /* 34 */ << H(TokHashLiteral) << HS(L"true") - /* 42 */ << H(TokCondition) - /* 43 */ << H(TokTerminator) - /* 44 */ << H(TokTerminator) - /* 45 */ /* else branch */ << I(12) - /* 47 */ << H(TokLine) << H(2) - /* 49 */ << H(TokHashLiteral) << HS(L"true") - /* 57 */ << H(TokCondition) - /* 58 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("next()") - << "for(ever): next()" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokForLoop) << HS(L"") - /* 6 */ /* iterator */ << I(9) - /* 8 */ << H(TokHashLiteral) << HS(L"ever") - /* 16 */ << H(TokValueTerminator) - /* 17 */ /* body */ << I(4) - /* 19 */ << H(TokLine) << H(1) - /* 21 */ << H(TokNext) - /* 22 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("break()") - << "for(ever): break()" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokForLoop) << HS(L"") - /* 6 */ /* iterator */ << I(9) - /* 8 */ << H(TokHashLiteral) << HS(L"ever") - /* 16 */ << H(TokValueTerminator) - /* 17 */ /* body */ << I(4) - /* 19 */ << H(TokLine) << H(1) - /* 21 */ << H(TokBreak) - /* 22 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("top-level return()") - << "return()" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokReturn)) - << "" - << true; - - QTest::newRow("else") - << "else" - << TS() - << "in:1: Unexpected 'else'." - << false; - - QTest::newRow("test-{else}") - << "test { else }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(1) - /* 14 */ << H(TokTerminator) - /* 15 */ /* else branch */ << I(0)) - << "in:1: Unexpected 'else'." - << false; - - QTest::newRow("defineTest-{else}") - << "defineTest(fn) { else }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokTestDef) << HS(L"fn") - /* 8 */ /* body */ << I(1) - /* 10 */ << H(TokTerminator)) - << "in:1: Unexpected 'else'." - << false; - - QTest::newRow("for-else") - << "for(ever) { else }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokForLoop) << HS(L"") - /* 6 */ /* iterator */ << I(9) - /* 8 */ << H(TokHashLiteral) << HS(L"ever") - /* 16 */ << H(TokValueTerminator) - /* 17 */ /* body */ << I(1) - /* 19 */ << H(TokTerminator)) - << "in:1: Unexpected 'else'." - << false; - - QTest::newRow("double-test-else") - << "foo bar\nelse" - << TS( - /* 0 */ << H(TokBranch) - /* 1 */ /* then branch */ << I(0) - /* 3 */ /* else branch */ << I(1) // This seems weird - /* 5 */ << H(TokTerminator)) - << "in:1: Extra characters after test expression." - << false; - - QTest::newRow("test-function-else") - << "foo bar()\nelse" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokTestCall) // This seems pointless - /* 3 */ << H(TokFuncTerminator) - /* 4 */ << H(TokBranch) - /* 5 */ /* then branch */ << I(0) - /* 7 */ /* else branch */ << I(1) // This seems weird - /* 9 */ << H(TokTerminator)) - << "in:1: Extra characters after test expression." - << false; - - // Braces - - QTest::newRow("{}") - << "{ }" - << TS() - << "" - << true; - - QTest::newRow("{}-newlines") - << "\n\n{ }\n\n" - << TS() - << "" - << true; - - QTest::newRow("{") - << "{" - << TS() - << "in:2: Missing closing brace(s)." - << false; - - QTest::newRow("test {") - << "test {" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(1) - /* 14 */ << H(TokTerminator) - /* 15 */ /* else branch */ << I(0)) - << "in:2: Missing closing brace(s)." - << false; - - QTest::newRow("}") - << "}" - << TS() - << "in:1: Excess closing brace." - << false; - - QTest::newRow("{test}") - << "{ true }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("{test-newlines}") - << "{\ntrue\n}" - << TS( - /* 0 */ << H(TokLine) << H(2) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("{assignment-test}-test") - << "{ VAR = { foo } bar } true" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokAssign) << H(4) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"{") - /* 14 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 19 */ << H(TokLiteral | TokNewStr) << S(L"}") - /* 22 */ << H(TokLiteral | TokNewStr) << S(L"bar") - /* 27 */ << H(TokValueTerminator) - /* 28 */ << H(TokHashLiteral) << HS(L"true") - /* 36 */ << H(TokCondition)) - << "" - << true; - - QTest::newRow("assignment with excess opening brace") - << "VAR = { { foo }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"VAR") - /* 9 */ << H(TokAssign) << H(4) - /* 11 */ << H(TokLiteral | TokNewStr) << S(L"{") - /* 14 */ << H(TokLiteral | TokNewStr) << S(L"{") - /* 17 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 22 */ << H(TokLiteral | TokNewStr) << S(L"}") - /* 25 */ << H(TokValueTerminator)) - << "WARNING: in:1: Possible braces mismatch" - << true; - - QTest::newRow("test-{}") - << "true {}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(1) - /* 14 */ << H(TokTerminator) - /* 15 */ /* else branch */ << I(0)) - << "" - << true; - - QTest::newRow("test-{newlines}") - << "true {\n}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(1) - /* 14 */ << H(TokTerminator) - /* 15 */ /* else branch */ << I(0)) - << "" - << true; - - QTest::newRow("test-{test}") - << "true { true }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(10) - /* 14 */ << H(TokHashLiteral) << HS(L"true") - /* 22 */ << H(TokCondition) - /* 23 */ << H(TokTerminator) - /* 24 */ /* else branch */ << I(0)) - << "" - << true; - - QTest::newRow("test:-{test}") - << "true: { true }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(10) - /* 14 */ << H(TokHashLiteral) << HS(L"true") - /* 22 */ << H(TokCondition) - /* 23 */ << H(TokTerminator) - /* 24 */ /* else branch */ << I(0)) - << "WARNING: in:1: Excess colon in front of opening brace." - << true; - - QTest::newRow("test-{test-newlines}") - << "true {\ntrue\n}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(12) - /* 14 */ << H(TokLine) << H(2) - /* 16 */ << H(TokHashLiteral) << HS(L"true") - /* 24 */ << H(TokCondition) - /* 25 */ << H(TokTerminator) - /* 26 */ /* else branch */ << I(0)) - << "" - << true; - - QTest::newRow("test:-{test-newlines}") - << "true: {\ntrue\n}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(12) - /* 14 */ << H(TokLine) << H(2) - /* 16 */ << H(TokHashLiteral) << HS(L"true") - /* 24 */ << H(TokCondition) - /* 25 */ << H(TokTerminator) - /* 26 */ /* else branch */ << I(0)) - << "WARNING: in:1: Excess colon in front of opening brace." - << true; - - QTest::newRow("test-{assignment}") - << "true { VAR = {foo} }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(18) - /* 14 */ << H(TokHashLiteral) << HS(L"VAR") - /* 21 */ << H(TokAssign) << H(0) - /* 23 */ << H(TokLiteral | TokNewStr) << S(L"{foo}") - /* 30 */ << H(TokValueTerminator) - /* 31 */ << H(TokTerminator) - /* 32 */ /* else branch */ << I(0)) - << "" - << true; - - QTest::newRow("test-{test-assignment}") - << "true { true: VAR = {foo} }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(33) - /* 14 */ << H(TokHashLiteral) << HS(L"true") - /* 22 */ << H(TokCondition) - /* 23 */ << H(TokBranch) - /* 24 */ /* then branch */ << I(18) - /* 26 */ << H(TokHashLiteral) << HS(L"VAR") - /* 33 */ << H(TokAssign) << H(0) - /* 35 */ << H(TokLiteral | TokNewStr) << S(L"{foo}") - /* 42 */ << H(TokValueTerminator) - /* 43 */ << H(TokTerminator) - /* 44 */ /* else branch */ << I(0) - /* 46 */ << H(TokTerminator) - /* 47 */ /* else branch */ << I(0)) - << "" - << true; - - QTest::newRow("test-{assignment-newlines}") - << "true {\nVAR = {foo}\n}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(20) - /* 14 */ << H(TokLine) << H(2) - /* 16 */ << H(TokHashLiteral) << HS(L"VAR") - /* 23 */ << H(TokAssign) << H(0) - /* 25 */ << H(TokLiteral | TokNewStr) << S(L"{foo}") - /* 32 */ << H(TokValueTerminator) - /* 33 */ << H(TokTerminator) - /* 34 */ /* else branch */ << I(0)) - << "" - << true; - - QTest::newRow("test-{}-else-test-{}") - << "true {} else: true {}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(1) - /* 14 */ << H(TokTerminator) - /* 15 */ /* else branch */ << I(18) - /* 17 */ << H(TokLine) << H(1) - /* 19 */ << H(TokHashLiteral) << HS(L"true") - /* 27 */ << H(TokCondition) - /* 28 */ << H(TokBranch) - /* 29 */ /* then branch */ << I(1) - /* 31 */ << H(TokTerminator) - /* 32 */ /* else branch */ << I(0) - /* 34 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("test-{}-else-test-{}-newlines") - << "true {\n}\nelse: true {\n}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(1) - /* 14 */ << H(TokTerminator) - /* 15 */ /* else branch */ << I(18) - /* 17 */ << H(TokLine) << H(3) - /* 19 */ << H(TokHashLiteral) << HS(L"true") - /* 27 */ << H(TokCondition) - /* 28 */ << H(TokBranch) - /* 29 */ /* then branch */ << I(1) - /* 31 */ << H(TokTerminator) - /* 32 */ /* else branch */ << I(0) - /* 34 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("test-{test}-else-test-{}-newlines") - << "true {\ntrue\n}\nelse: true {\n}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(12) - /* 14 */ << H(TokLine) << H(2) - /* 16 */ << H(TokHashLiteral) << HS(L"true") - /* 24 */ << H(TokCondition) - /* 25 */ << H(TokTerminator) - /* 26 */ /* else branch */ << I(18) - /* 28 */ << H(TokLine) << H(4) - /* 30 */ << H(TokHashLiteral) << HS(L"true") - /* 38 */ << H(TokCondition) - /* 39 */ << H(TokBranch) - /* 40 */ /* then branch */ << I(1) - /* 42 */ << H(TokTerminator) - /* 43 */ /* else branch */ << I(0) - /* 45 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("for-{next}") - << "for(ever) { next() }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokForLoop) << HS(L"") - /* 6 */ /* iterator */ << I(9) - /* 8 */ << H(TokHashLiteral) << HS(L"ever") - /* 16 */ << H(TokValueTerminator) - /* 17 */ /* body */ << I(4) - /* 19 */ << H(TokLine) << H(1) - /* 21 */ << H(TokNext) - /* 22 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("for:-{next}") - << "for(ever): { next() }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokForLoop) << HS(L"") - /* 6 */ /* iterator */ << I(9) - /* 8 */ << H(TokHashLiteral) << HS(L"ever") - /* 16 */ << H(TokValueTerminator) - /* 17 */ /* body */ << I(4) - /* 19 */ << H(TokLine) << H(1) - /* 21 */ << H(TokNext) - /* 22 */ << H(TokTerminator)) - << "WARNING: in:1: Excess colon in front of opening brace." - << true; - - QTest::newRow("test-for-{test-else-test-newlines}") - << "true:for(VAR, LIST) {\ntrue\nelse: true\n}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(48) - /* 14 */ << H(TokForLoop) << HS(L"VAR") - /* 21 */ /* iterator */ << I(7) - /* 23 */ << H(TokLiteral | TokNewStr) << S(L"LIST") - /* 29 */ << H(TokValueTerminator) - /* 30 */ /* body */ << I(29) - /* 32 */ << H(TokLine) << H(2) - /* 34 */ << H(TokHashLiteral) << HS(L"true") - /* 42 */ << H(TokCondition) - /* 43 */ << H(TokBranch) - /* 44 */ /* then branch */ << I(0) - /* 46 */ /* else branch */ << I(12) - /* 48 */ << H(TokLine) << H(3) - /* 50 */ << H(TokHashLiteral) << HS(L"true") - /* 58 */ << H(TokCondition) - /* 59 */ << H(TokTerminator) - /* 60 */ << H(TokTerminator) - /* 61 */ << H(TokTerminator) - /* 62 */ /* else branch */ << I(0)) - << "" - << true; - - QTest::newRow("test-for-{test-else-test}") - << "true:for(VAR, LIST) { true\nelse: true }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"true") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(48) - /* 14 */ << H(TokForLoop) << HS(L"VAR") - /* 21 */ /* iterator */ << I(7) - /* 23 */ << H(TokLiteral | TokNewStr) << S(L"LIST") - /* 29 */ << H(TokValueTerminator) - /* 30 */ /* body */ << I(29) - /* 32 */ << H(TokLine) << H(1) - /* 34 */ << H(TokHashLiteral) << HS(L"true") - /* 42 */ << H(TokCondition) - /* 43 */ << H(TokBranch) - /* 44 */ /* then branch */ << I(0) - /* 46 */ /* else branch */ << I(12) - /* 48 */ << H(TokLine) << H(2) - /* 50 */ << H(TokHashLiteral) << HS(L"true") - /* 58 */ << H(TokCondition) - /* 59 */ << H(TokTerminator) - /* 60 */ << H(TokTerminator) - /* 61 */ << H(TokTerminator) - /* 62 */ /* else branch */ << I(0)) - << "" - << true; - - // Custom functions - - QTest::newRow("defineTest-{newlines}") - << "defineTest(test) {\n}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokTestDef) << HS(L"test") - /* 10 */ /* body */ << I(1) - /* 12 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("defineTest:-test") - << "defineTest(test): test" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokTestDef) << HS(L"test") - /* 10 */ /* body */ << I(12) - /* 12 */ << H(TokLine) << H(1) - /* 14 */ << H(TokHashLiteral) << HS(L"test") - /* 22 */ << H(TokCondition) - /* 23 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("defineTest-{test}") - << "defineTest(test) { test }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokTestDef) << HS(L"test") - /* 10 */ /* body */ << I(12) - /* 12 */ << H(TokLine) << H(1) - /* 14 */ << H(TokHashLiteral) << HS(L"test") - /* 22 */ << H(TokCondition) - /* 23 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("defineTest-{return}") - << "defineTest(test) { return() }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokTestDef) << HS(L"test") - /* 10 */ /* body */ << I(4) - /* 12 */ << H(TokLine) << H(1) - /* 14 */ << H(TokReturn) - /* 15 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("defineReplace-{return-stuff}") - << "defineReplace(stuff) { return(foo bar) }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokReplaceDef) << HS(L"stuff") - /* 11 */ /* body */ << I(14) - /* 13 */ << H(TokLine) << H(1) - /* 15 */ << H(TokLiteral | TokNewStr) << S(L"foo") - /* 20 */ << H(TokLiteral | TokNewStr) << S(L"bar") - /* 25 */ << H(TokReturn) - /* 26 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("test-AND-defineTest-{}") - << "test: defineTest(test) {}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokAnd) - /* 12 */ << H(TokTestDef) << HS(L"test") - /* 20 */ /* body */ << I(1) - /* 22 */ << H(TokTerminator)) - << "" - << true; - - QTest::newRow("test-OR-defineTest-{}") - << "test| defineTest(test) {}" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokOr) - /* 12 */ << H(TokTestDef) << HS(L"test") - /* 20 */ /* body */ << I(1) - /* 22 */ << H(TokTerminator)) - << "" - << true; - - // Operator abuse - - QTest::newRow("!") - << "" - << TS() - << "" - << true; - - QTest::newRow("|") - << "" - << TS() - << "" - << true; - - QTest::newRow(":") - << "" - << TS() - << "" - << true; - - QTest::newRow("NOT-assignment") - << "!VAR =" - << TS() - << "in:1: Unexpected NOT operator in front of assignment." - << false; - - QTest::newRow("NOT-{}") - << "!{}" - << TS() - << "in:1: Unexpected NOT operator in front of opening brace." - << false; - - QTest::newRow("NOT-else") - << "test\n!else {}" - << TS() - << "in:2: Unexpected NOT operator in front of else." - << false; - - QTest::newRow("NOT-for-{}") - << "!for(ever) {}" - << TS() - << "in:1: Unexpected NOT operator in front of for()." - << false; - - QTest::newRow("NOT-defineTest-{}") - << "!defineTest(test) {}" - << TS() - << "in:1: Unexpected NOT operator in front of function definition." - << false; - - QTest::newRow("AND-test") - << ":test" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition)) - << "in:1: AND operator without prior condition." - << false; - - QTest::newRow("test-AND-else") - << "test:else" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition)) - << "in:1: Unexpected AND operator in front of else." - << false; - - QTest::newRow("test-AND-AND-test") - << "test::test" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokAnd) - /* 12 */ << H(TokHashLiteral) << HS(L"test") - /* 20 */ << H(TokCondition)) - << "WARNING: in:1: Stray AND operator in front of AND operator." - << true; - - QTest::newRow("test-AND-OR-test") - << "test:|test" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokOr) - /* 12 */ << H(TokHashLiteral) << HS(L"test") - /* 20 */ << H(TokCondition)) - << "WARNING: in:1: Stray AND operator in front of OR operator." - << true; - - QTest::newRow("test-{AND-test}") - << "test { :test }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(10) - /* 14 */ << H(TokHashLiteral) << HS(L"test") - /* 22 */ << H(TokCondition) - /* 23 */ << H(TokTerminator) - /* 24 */ /* else branch */ << I(0)) - << "in:1: AND operator without prior condition." - << false; - - QTest::newRow("test-OR-assignment") - << "foo| VAR =" - << TS() - << "in:1: Unexpected OR operator in front of assignment." - << false; - - QTest::newRow("test-OR-{}") - << "foo|{}" - << TS() - << "in:1: Unexpected OR operator in front of opening brace." - << false; - - QTest::newRow("test-OR-for") - << "foo|for(ever) {}" - << TS() - << "in:1: Unexpected OR operator in front of for()." - << false; - - QTest::newRow("OR-test") - << "|test" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition)) - << "in:1: OR operator without prior condition." - << false; - - QTest::newRow("test-OR-else") - << "test|else" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition)) - << "in:1: Unexpected OR operator in front of else." - << false; - - QTest::newRow("test-OR-OR-test") - << "test||test" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokOr) - /* 12 */ << H(TokHashLiteral) << HS(L"test") - /* 20 */ << H(TokCondition)) - << "WARNING: in:1: Stray OR operator in front of OR operator." - << true; - - QTest::newRow("test-OR-AND-test") - << "test|:test" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokAnd) - /* 12 */ << H(TokHashLiteral) << HS(L"test") - /* 20 */ << H(TokCondition)) - << "WARNING: in:1: Stray OR operator in front of AND operator." - << true; - - QTest::newRow("test-{OR-test}") - << "test { |test }" - << TS( - /* 0 */ << H(TokLine) << H(1) - /* 2 */ << H(TokHashLiteral) << HS(L"test") - /* 10 */ << H(TokCondition) - /* 11 */ << H(TokBranch) - /* 12 */ /* then branch */ << I(10) - /* 14 */ << H(TokHashLiteral) << HS(L"test") - /* 22 */ << H(TokCondition) - /* 23 */ << H(TokTerminator) - /* 24 */ /* else branch */ << I(0)) - << "in:1: OR operator without prior condition." - << false; - - // option() (these produce no tokens) - - QTest::newRow("option(host_build)") - << "option(host_build)" - << TS() - << "" - << true; - - QTest::newRow("option()") - << "option()" - << TS() - << "in:1: option() requires one literal argument." - << false; - - QTest::newRow("option(host_build magic)") - << "option(host_build magic)" - << TS() - << "in:1: option() requires one literal argument." - << false; - - QTest::newRow("option(host_build, magic)") - << "option(host_build, magic)" - << TS() - << "in:1: option() requires one literal argument." - << false; - - QTest::newRow("option($$OPTION)") - << "option($$OPTION)" - << TS() - << "in:1: option() requires one literal argument." - << false; - - QTest::newRow("{option(host_build)}") - << "{option(host_build)}" - << TS() - << "in:1: option() must appear outside any control structures." - << false; -} - -QT_WARNING_POP - -void tst_qmakelib::proParser() +void QMakeHandler::print(const QString &fileName, int lineNo, int type, const QString &msg) { - QFETCH(QString, in); - QFETCH(QString, out); - QFETCH(QString, msgs); - QFETCH(bool, ok); - - bool verified = true; - QMakeHandler handler; - handler.setExpectedMessages(msgs.split('\n', QString::SkipEmptyParts)); - QMakeVfs vfs; - QMakeParser parser(0, &vfs, &handler); - ProFile *pro = parser.parsedProBlock(in, "in", 1, QMakeParser::FullGrammar); - if (handler.printedMessages()) { - qWarning("Got unexpected message(s)"); - verified = false; - } - QStringList missingMsgs = handler.expectedMessages(); - if (!missingMsgs.isEmpty()) { - foreach (const QString &msg, missingMsgs) - qWarning("Missing message: %s", qPrintable(msg)); - verified = false; - } - if (pro->isOk() != ok) { - static const char * const lbl[] = { "failure", "success" }; - qWarning("Expected %s, got %s", lbl[int(ok)], lbl[1 - int(ok)]); - verified = false; - } - if (pro->items() != out && (ok || !out.isEmpty())) { - qWarning("Bytecode mismatch.\nActual:%s\nExpected:%s", - qPrintable(QMakeParser::formatProBlock(pro->items())), - qPrintable(QMakeParser::formatProBlock(out))); - verified = false; + QString pfx = ((type & QMakeParserHandler::CategoryMask) == QMakeParserHandler::WarningMessage) + ? QString::fromLatin1("WARNING: ") : QString(); + QString out; + if (lineNo) + out = QStringLiteral("%1%2:%3: %4").arg(pfx, fileName, QString::number(lineNo), msg); + else + out = QStringLiteral("%1%2").arg(pfx, msg); + if (!expected.isEmpty() && expected.first() == out) { + expected.removeAt(0); + return; } - pro->deref(); - QVERIFY(verified); + qWarning("%s", qPrintable(out)); + printed = true; } QTEST_MAIN(tst_qmakelib) -#include "tst_qmakelib.moc" diff --git a/tests/auto/tools/qmakelib/tst_qmakelib.h b/tests/auto/tools/qmakelib/tst_qmakelib.h new file mode 100644 index 0000000000..1ae408bfc1 --- /dev/null +++ b/tests/auto/tools/qmakelib/tst_qmakelib.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include + +class tst_qmakelib : public QObject +{ + Q_OBJECT + +public: + tst_qmakelib() {} + virtual ~tst_qmakelib() {} + +private slots: + void quoteArgUnix_data(); + void quoteArgUnix(); + void quoteArgWin_data(); + void quoteArgWin(); + void pathUtils(); + + void proString(); + void proStringList(); + + void proParser_data(); + void proParser(); +}; + +class QMakeHandler : public QMakeParserHandler { +public: + QMakeHandler() : QMakeParserHandler(), printed(false) {} + virtual void message(int type, const QString &msg, const QString &fileName, int lineNo) + { print(fileName, lineNo, type, msg); } + + void setExpectedMessages(const QStringList &msgs) { expected = msgs; } + QStringList expectedMessages() const { return expected; } + + bool printedMessages() const { return printed; } + +private: + void print(const QString &fileName, int lineNo, int type, const QString &msg); + + QStringList expected; + bool printed; +}; -- cgit v1.2.3 From ef50e244cd293394eeec7f7d410f1a6f6320c3e5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 15 May 2015 21:22:14 +0200 Subject: split parser test initialization the idea was to speed up optimized msvc compilation, but it didn't help. still, it's better structured that way. Change-Id: I4b2108d02a47ef8ef704b0b542b0f281bff20165 Reviewed-by: Joerg Bornemann --- tests/auto/tools/qmakelib/parsertest.cpp | 85 ++++++++++++++++++++------------ tests/auto/tools/qmakelib/tst_qmakelib.h | 9 ++++ 2 files changed, 62 insertions(+), 32 deletions(-) diff --git a/tests/auto/tools/qmakelib/parsertest.cpp b/tests/auto/tools/qmakelib/parsertest.cpp index 2fe8e90b51..35c0d8261a 100644 --- a/tests/auto/tools/qmakelib/parsertest.cpp +++ b/tests/auto/tools/qmakelib/parsertest.cpp @@ -62,27 +62,8 @@ private: QT_WARNING_PUSH QT_WARNING_DISABLE_MSVC(4003) // "not enough actual parameters for macro TS()" -void tst_qmakelib::proParser_data() +void tst_qmakelib::addParseOperators() { - QTest::addColumn("in"); - QTest::addColumn("out"); - QTest::addColumn("msgs"); - QTest::addColumn("ok"); - - QTest::newRow("empty") - << "" - << TS() - << "" - << true; - - QTest::newRow("empty (whitespace)") - << " \t \t" - << TS() - << "" - << true; - - // Variable operators - QTest::newRow("assign none") << "VAR =" << TS( @@ -150,9 +131,10 @@ void tst_qmakelib::proParser_data() /* 4 */ << H(TokValueTerminator)) << "in:1: Assignment needs exactly one word on the left hand side." << false; +} - // Values - +void tst_qmakelib::addParseValues() +{ #define ASSIGN_VAR(h) \ H(TokLine) << H(1) \ << H(TokHashLiteral) << HS(L"VAR") \ @@ -601,9 +583,10 @@ void tst_qmakelib::proParser_data() /* 20 */ << H(TokValueTerminator)) << "" << true; +} - // Conditionals ("Tests") - +void tst_qmakelib::addParseConditions() +{ QTest::newRow("one test") << "foo" << TS( @@ -1055,9 +1038,10 @@ void tst_qmakelib::proParser_data() /* 20 */ << H(TokFuncTerminator)) << "" << true; +} - // Control statements - +void tst_qmakelib::addParseControlStatements() +{ QTest::newRow("for(VAR, LIST) loop") << "for(VAR, LIST)" << TS( @@ -1226,9 +1210,10 @@ void tst_qmakelib::proParser_data() /* 9 */ << H(TokTerminator)) << "in:1: Extra characters after test expression." << false; +} - // Braces - +void tst_qmakelib::addParseBraces() +{ QTest::newRow("{}") << "{ }" << TS() @@ -1613,9 +1598,10 @@ void tst_qmakelib::proParser_data() /* 62 */ /* else branch */ << I(0)) << "" << true; +} - // Custom functions - +void tst_qmakelib::addParseCustomFunctions() +{ QTest::newRow("defineTest-{newlines}") << "defineTest(test) {\n}" << TS( @@ -1703,9 +1689,10 @@ void tst_qmakelib::proParser_data() /* 22 */ << H(TokTerminator)) << "" << true; +} - // Operator abuse - +void tst_qmakelib::addParseAbuse() +{ QTest::newRow("!") << "" << TS() @@ -1885,6 +1872,40 @@ void tst_qmakelib::proParser_data() /* 24 */ /* else branch */ << I(0)) << "in:1: OR operator without prior condition." << false; +} + +void tst_qmakelib::proParser_data() +{ + QTest::addColumn("in"); + QTest::addColumn("out"); + QTest::addColumn("msgs"); + QTest::addColumn("ok"); + + QTest::newRow("empty") + << "" + << TS() + << "" + << true; + + QTest::newRow("empty (whitespace)") + << " \t \t" + << TS() + << "" + << true; + + addParseOperators(); // Variable operators + + addParseValues(); + + addParseConditions(); // "Tests" + + addParseControlStatements(); + + addParseBraces(); + + addParseCustomFunctions(); + + addParseAbuse(); // Mostly operator abuse // option() (these produce no tokens) diff --git a/tests/auto/tools/qmakelib/tst_qmakelib.h b/tests/auto/tools/qmakelib/tst_qmakelib.h index 1ae408bfc1..e84b1319d0 100644 --- a/tests/auto/tools/qmakelib/tst_qmakelib.h +++ b/tests/auto/tools/qmakelib/tst_qmakelib.h @@ -56,6 +56,15 @@ private slots: void proParser_data(); void proParser(); + +private: + void addParseOperators(); + void addParseValues(); + void addParseConditions(); + void addParseControlStatements(); + void addParseBraces(); + void addParseCustomFunctions(); + void addParseAbuse(); }; class QMakeHandler : public QMakeParserHandler { -- cgit v1.2.3 From 5ddc16b5df1c95140124430553f91dcc4789f831 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 15 May 2015 20:58:50 +0200 Subject: add qmake evaluator test Change-Id: I31b95daede5edef245dd1ba447f2937a0db34232 Reviewed-by: Joerg Bornemann --- qmake/library/qmakeglobals.h | 1 + tests/auto/tools/qmakelib/evaltest.cpp | 2513 ++++++++++++++++++++ tests/auto/tools/qmakelib/parsertest.cpp | 2 +- tests/auto/tools/qmakelib/qmakelib.pro | 8 +- tests/auto/tools/qmakelib/testdata/cat/file1.txt | 2 + tests/auto/tools/qmakelib/testdata/cat/file2.txt | 5 + .../tools/qmakelib/testdata/files/dir/file1.txt | 0 .../tools/qmakelib/testdata/files/dir/file2.txt | 0 tests/auto/tools/qmakelib/testdata/files/file1.txt | 0 tests/auto/tools/qmakelib/testdata/files/file2.txt | 0 tests/auto/tools/qmakelib/testdata/files/other.txt | 0 .../tools/qmakelib/testdata/fromfile/badfile.prx | 1 + .../tools/qmakelib/testdata/fromfile/infile.prx | 1 + tests/auto/tools/qmakelib/testdata/include/inc.pri | 8 + .../qmakelib/testdata/mkspecs/fake-g++/qmake.conf | 1 + .../testdata/mkspecs/features/default_post.prf | 1 + .../testdata/mkspecs/features/default_pre.prf | 1 + .../testdata/mkspecs/features/spec_post.prf | 1 + .../testdata/mkspecs/features/spec_pre.prf | 1 + .../testdata/mkspecs/features/testfeat.prf | 1 + tests/auto/tools/qmakelib/tst_qmakelib.cpp | 40 +- tests/auto/tools/qmakelib/tst_qmakelib.h | 31 +- 22 files changed, 2604 insertions(+), 14 deletions(-) create mode 100644 tests/auto/tools/qmakelib/evaltest.cpp create mode 100644 tests/auto/tools/qmakelib/testdata/cat/file1.txt create mode 100644 tests/auto/tools/qmakelib/testdata/cat/file2.txt create mode 100644 tests/auto/tools/qmakelib/testdata/files/dir/file1.txt create mode 100644 tests/auto/tools/qmakelib/testdata/files/dir/file2.txt create mode 100644 tests/auto/tools/qmakelib/testdata/files/file1.txt create mode 100644 tests/auto/tools/qmakelib/testdata/files/file2.txt create mode 100644 tests/auto/tools/qmakelib/testdata/files/other.txt create mode 100644 tests/auto/tools/qmakelib/testdata/fromfile/badfile.prx create mode 100644 tests/auto/tools/qmakelib/testdata/fromfile/infile.prx create mode 100644 tests/auto/tools/qmakelib/testdata/include/inc.pri create mode 100644 tests/auto/tools/qmakelib/testdata/mkspecs/fake-g++/qmake.conf create mode 100644 tests/auto/tools/qmakelib/testdata/mkspecs/features/default_post.prf create mode 100644 tests/auto/tools/qmakelib/testdata/mkspecs/features/default_pre.prf create mode 100644 tests/auto/tools/qmakelib/testdata/mkspecs/features/spec_post.prf create mode 100644 tests/auto/tools/qmakelib/testdata/mkspecs/features/spec_pre.prf create mode 100644 tests/auto/tools/qmakelib/testdata/mkspecs/features/testfeat.prf diff --git a/qmake/library/qmakeglobals.h b/qmake/library/qmakeglobals.h index 7c77450523..de46ebbe74 100644 --- a/qmake/library/qmakeglobals.h +++ b/qmake/library/qmakeglobals.h @@ -135,6 +135,7 @@ public: bool initProperties(); # else void setProperties(const QHash &props); + void setProperties(const QHash &props) { properties = props; } # endif ProString propertyValue(const ProKey &name) const { return properties.value(name); } #endif diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp new file mode 100644 index 0000000000..fab2cdce17 --- /dev/null +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -0,0 +1,2513 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "tst_qmakelib.h" + +#include +#include +#include +#include +#include + +void tst_qmakelib::addAssignments() +{ + QTest::newRow("assignment") + << "VAR = foo bar baz" + << "VAR = foo bar baz" + << "" + << true; + + QTest::newRow("appending") + << "VAR = foo bar baz\nVAR += foo gaz gaz" + << "VAR = foo bar baz foo gaz gaz" + << "" + << true; + + QTest::newRow("unique appending") + << "VAR = foo bar baz\nVAR *= foo gaz gaz" + << "VAR = foo bar baz gaz" + << "" + << true; + + QTest::newRow("removing") + << "VAR = foo bar foo baz\nVAR -= foo gaz gaz" + << "VAR = bar baz" + << "" + << true; + + // Somewhat unexpectedly, the g modifier is implicit within each element. + QTest::newRow("replacing") + << "VAR = foo bar foo baz\nVAR ~= s,o,0," + << "VAR = f00 bar foo baz" + << "" + << true; + + // Consistently with the "there are no empty elements", what becomes empty gets zapped. + QTest::newRow("replacing with nothing") + << "VAR = foo bar foo baz\nVAR ~= s,foo,," + << "VAR = bar foo baz" + << "" + << true; + + QTest::newRow("replacing case-insensitively") + << "VAR = foO bar foo baz\nVAR ~= s,o,0,i" + << "VAR = f00 bar foo baz" + << "" + << true; + + // In all elements, not all within each/one/??? element. + QTest::newRow("replacing globally") + << "VAR = foo bar foo baz\nVAR ~= s,o,0,g" + << "VAR = f00 bar f00 baz" + << "" + << true; + + // Replacing with the same string counts as no match. + // This is rather questionable ... + QTest::newRow("replacing with same") + << "VAR = foo bar foo baz\nVAR ~= s,ba[rz],bar," + << "VAR = foo bar foo bar" + << "" + << true; + + QTest::newRow("replacing with auto-quote") + << "VAR = foo [bar] foo baz\nVAR ~= s,[bar],bar,q" + << "VAR = foo bar foo baz" + << "" + << true; + + QTest::newRow("replacing with expansions") + << "VAR = foo bar foo baz\nPAT = foo\nREPL = 'yee haw'\nVAR ~= s,$$PAT,$$REPL," + << "VAR = 'yee haw' bar foo baz" + << "" + << true; + + QTest::newRow("~= with bad function") + << "VAR ~= m/foo/" + << "" + << "##:1: The ~= operator can handle only the s/// function." + << true; // rather questionable + + QTest::newRow("~= s with bad number of arguments") + << "VAR ~= s/bla\nVAR ~= s/bla/foo//" + << "" + << "##:1: The s/// function expects 3 or 4 arguments.\n" + "##:2: The s/// function expects 3 or 4 arguments." + << true; // rather questionable +} + +void tst_qmakelib::addExpansions() +{ + QTest::newRow("expand variable") + << "V1 = foo\nVAR = $$V1" + << "VAR = foo" + << "" + << true; + + QTest::newRow("expand property") + << "VAR = $$[P1]" + << "VAR = 'prop val'" + << "" + << true; + + QTest::newRow("expand environment variable") + << "VAR = $$(E1)" + << "VAR = 'env var'" + << "" + << true; + + // These test addStr/addStr. + + QTest::newRow("expand: str $$(env)") + << "VAR = foo $$(E1)" + << "VAR = foo 'env var'" + << "" + << true; + + QTest::newRow("expand: str$$(env)") + << "VAR = foo$$(E1)" + << "VAR = 'fooenv var'" + << "" + << true; + + QTest::newRow("expand: 'str $$(env)'") + << "VAR = 'foo $$(E1)'" + << "VAR = 'foo env var'" + << "" + << true; + + // These test addStr/addStrList + + QTest::newRow("expand: str $$var") + << "V1 = foo barbaz\nVAR = str $$V1" + << "VAR = str foo barbaz" + << "" + << true; + + QTest::newRow("expand: $$var str") + << "V1 = foo barbaz\nVAR = $$V1 str" + << "VAR = foo barbaz str" + << "" + << true; + + QTest::newRow("expand: str$$var") + << "V1 = foo barbaz\nVAR = str$$V1" + << "VAR = strfoo barbaz" + << "" + << true; + + QTest::newRow("expand: $${var}str") + << "V1 = foo barbaz\nVAR = $${V1}str" + << "VAR = foo barbazstr" + << "" + << true; + + QTest::newRow("expand: 'str $$var'") + << "V1 = foo barbaz\nVAR = 'str $$V1'" + << "VAR = 'str foo barbaz'" + << "" + << true; + + QTest::newRow("expand: '$$var str'") + << "V1 = foo barbaz\nVAR = '$$V1 str'" + << "VAR = 'foo barbaz str'" + << "" + << true; + + // Same again in joined context + + QTest::newRow("expand joined: str $$(env)") + << "VAR = $$quote(foo $$(E1))" + << "VAR = 'foo env var'" + << "" + << true; + + QTest::newRow("expand joined: str$$(env)") + << "VAR = $$quote(foo$$(E1))" + << "VAR = 'fooenv var'" + << "" + << true; + + QTest::newRow("expand joined: 'str $$(env)'") + << "VAR = $$quote('foo $$(E1)')" + << "VAR = 'foo env var'" + << "" + << true; + + QTest::newRow("expand joined: str $$var") + << "V1 = foo barbaz\nVAR = $$quote(str $$V1)" + << "VAR = 'str foo barbaz'" + << "" + << true; + + QTest::newRow("expand joined: $$var str") + << "V1 = foo barbaz\nVAR = $$quote($$V1 str)" + << "VAR = 'foo barbaz str'" + << "" + << true; + + QTest::newRow("expand joined: str$$var") + << "V1 = foo barbaz\nVAR = $$quote(str$$V1)" + << "VAR = 'strfoo barbaz'" + << "" + << true; + + QTest::newRow("expand joined: $${var}str") + << "V1 = foo barbaz\nVAR = $$quote($${V1}str)" + << "VAR = 'foo barbazstr'" + << "" + << true; + + QTest::newRow("expand joined: 'str $$var'") + << "V1 = foo barbaz\nVAR = $$quote('str $$V1')" + << "VAR = 'str foo barbaz'" + << "" + << true; + + QTest::newRow("expand joined: '$$var str'") + << "V1 = foo barbaz\nVAR = $$quote('$$V1 str')" + << "VAR = 'foo barbaz str'" + << "" + << true; + + // Variable expansions on LHS + + QTest::newRow("indirect assign: $$var") + << "V = VAR\n$$V = foo" + << "VAR = foo" + << "" + << true; + + QTest::newRow("indirect assign: fix$$var") + << "V = AR\nV$$V = foo" + << "VAR = foo" + << "" + << true; + + QTest::newRow("indirect assign: $${var}fix") + << "V = VA\n$${V}R = foo" + << "VAR = foo" + << "" + << true; + + QTest::newRow("indirect assign: eval") + << "V = VAR\n$$eval(V) = foo" + << "VAR = foo" + << "" + << true; + + QTest::newRow("indirect assign: multiple") + << "V = FOO BAR\n$$V = foo" + << "" + << "##:2: Left hand side of assignment must expand to exactly one word." + << true; +} + +void tst_qmakelib::addControlStructs() +{ + QTest::newRow("true") + << "true: VAR = 1" + << "VAR = 1" + << "" + << true; + + QTest::newRow("false") + << "false: VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + QTest::newRow("true-config") + << "CONFIG += test\ntest: VAR = 1" + << "VAR = 1" + << "" + << true; + + QTest::newRow("false-config") + << "test: VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + QTest::newRow("true-wildcard") + << "CONFIG += testing\ntest*: VAR = 1" + << "VAR = 1" + << "" + << true; + + QTest::newRow("false-wildcard") + << "test*: VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + QTest::newRow("true-else") + << "true: VAR1 = 1\nelse: VAR2 = 1" + << "VAR1 = 1\nVAR2 = UNDEF" + << "" + << true; + + QTest::newRow("false-else") + << "false: VAR1 = 1\nelse: VAR2 = 1" + << "VAR1 = UNDEF\nVAR2 = 1" + << "" + << true; + + QTest::newRow("true-else-true-else") + << "true: VAR1 = 1\nelse: true: VAR2 = 1\nelse: VAR3 = 1" + << "VAR1 = 1\nVAR2 = UNDEF\nVAR3 = UNDEF" + << "" + << true; + + QTest::newRow("true-else-false-else") + << "true: VAR1 = 1\nelse: false: VAR2 = 1\nelse: VAR3 = 1" + << "VAR1 = 1\nVAR2 = UNDEF\nVAR3 = UNDEF" + << "" + << true; + + QTest::newRow("false-else-true-else") + << "false: VAR1 = 1\nelse: true: VAR2 = 1\nelse: VAR3 = 1" + << "VAR1 = UNDEF\nVAR2 = 1\nVAR3 = UNDEF" + << "" + << true; + + QTest::newRow("false-else-false-else") + << "false: VAR1 = 1\nelse: false: VAR2 = 1\nelse: VAR3 = 1" + << "VAR1 = UNDEF\nVAR2 = UNDEF\nVAR3 = 1" + << "" + << true; + + QTest::newRow("true-{false-else}-else") + << "true {\nfalse: VAR1 = 1\nelse: VAR2 = 1\n}\nelse: VAR3 = 1" + << "VAR1 = UNDEF\nVAR2 = 1\nVAR3 = UNDEF" + << "" + << true; + + QTest::newRow("NOT-true") + << "!true: VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + QTest::newRow("NOT-false") + << "!false: VAR = 1" + << "VAR = 1" + << "" + << true; + + QTest::newRow("true-AND-true") + << "true:true: VAR = 1" + << "VAR = 1" + << "" + << true; + + QTest::newRow("true-AND-false") + << "true:false: VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + QTest::newRow("false-AND-true") + << "false:true: VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + QTest::newRow("false-OR-false") + << "false|false: VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + QTest::newRow("true-OR-false") + << "true|false: VAR = 1" + << "VAR = 1" + << "" + << true; + + QTest::newRow("false-OR-true") + << "false|true: VAR = 1" + << "VAR = 1" + << "" + << true; + + QTest::newRow("NOT-false-AND-true") + << "!false:true: VAR = 1" + << "VAR = 1" + << "" + << true; + + QTest::newRow("true-AND-message") + << "true:message(hi): VAR = 1" + << "VAR = 1" + << "Project MESSAGE: hi" + << true; + + QTest::newRow("false-AND-message") + << "false:message(hi): VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + QTest::newRow("true-OR-message") + << "true|message(hi): VAR = 1" + << "VAR = 1" + << "" + << true; + + QTest::newRow("false-OR-message") + << "false|message(hi): VAR = 1" + << "VAR = 1" + << "Project MESSAGE: hi" + << true; + + QTest::newRow("true-OR-message-AND-false") + << "true|message(hi):false: VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + QTest::newRow("false-OR-message-AND-false") + << "false|message(hi):false: VAR = 1" + << "VAR = UNDEF" + << "Project MESSAGE: hi" + << true; + + QTest::newRow("true (indirect)") + << "TEST = true\n$$TEST: VAR = 1" + << "VAR = 1" + << "" + << true; + + QTest::newRow("false (indirect)") + << "TEST = false\n$$TEST: VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + // Yes, this is not supposed to work + QTest::newRow("true|false (indirect)") + << "TEST = true|false\n$$TEST: VAR = 1" + << "VAR = UNDEF" + << "" + << true; + + QTest::newRow("for (var, var)") + << "IN = one two three\nfor (IT, IN) { OUT += $$IT }" + << "OUT = one two three" + << "" + << true; + + QTest::newRow("for (var, range)") + << "for (IT, 1..3) { OUT += $$IT }" + << "OUT = 1 2 3" + << "" + << true; + + QTest::newRow("for (var, reverse-range)") + << "for (IT, 3..1) { OUT += $$IT }" + << "OUT = 3 2 1" + << "" + << true; + + // This syntax is rather ridiculous. + QTest::newRow("for (ever)") + << "for (ever) {}" + << "" + << "##:1: Ran into infinite loop (> 1000 iterations)." + << true; + + // This is even worse. + QTest::newRow("for (VAR, forever)") + << "for (VAR, forever) { OUT = $$VAR }" + << "OUT = 999" + << "##:1: Ran into infinite loop (> 1000 iterations)." + << true; + + QTest::newRow("for (garbage)") + << "for (garbage) { OUT = FAIL }" + << "OUT = UNDEF" + << "##:1: Invalid loop expression." + << true; + + QTest::newRow("next()") + << "IN = one two three\nfor (IT, IN) {\nequals(IT, two):next()\nOUT += $$IT\n}" + << "OUT = one three" + << "" + << true; + + QTest::newRow("nested next()") + << "IN = one two three\nfor (IT, IN) {\nfor (NIT, IN):next()\nOUT += $$IT\n}" + << "OUT = one two three" + << "" + << true; + + QTest::newRow("break()") + << "IN = one two three\nfor (IT, IN) {\nequals(IT, three):break()\nOUT += $$IT\n}" + << "OUT = one two" + << "" + << true; + + QTest::newRow("nested break()") + << "IN = one two three\nfor (IT, IN) {\nfor (NIT, IN):break()\nOUT += $$IT\n}" + << "OUT = one two three" + << "" + << true; + + QTest::newRow("defineReplace()") + << "defineReplace(func) { return($$1 + $$2) }\n" + "VAR = $$func(test me, \"foo bar\")" + << "VAR = test me + 'foo bar'" + << "" + << true; + + QTest::newRow("defineTest()") + << "defineTest(func) { return($$1) }\n" + "func(true): VAR += true\n" + "func(false): VAR += false" + << "VAR = true" + << "" + << true; + + QTest::newRow("true-AND-defineTest()") + << "true: defineTest(func)\n" + "defined(func): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("false-AND-defineTest()") + << "false: defineTest(func)\n" + "defined(func): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("true-OR-defineTest()") + << "true| defineTest(func)\n" + "defined(func): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("false-OR-defineTest()") + << "false| defineTest(func)\n" + "defined(func): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("variable scoping") + << "defineTest(func) {\n" + "VAR1 = modified\n!equals(VAR1, modified): return(false)\n" + "VAR2 += modified\n!equals(VAR2, original modified): return(false)\n" + "VAR3 = new var\n!equals(VAR3, new var): return(false)\n" + "return(true)\n" + "}\n" + "VAR1 = pristine\nVAR2 = original\nfunc(): OK = 1" + << "OK = 1\nVAR1 = pristine\nVAR2 = original\nVAR3 = UNDEF" + << "" + << true; + + QTest::newRow("ARGC and ARGS") + << "defineTest(func) {\n" + "export(ARGC)\n" + "export(ARGS)\n" + "}\n" + "func(test me, \"foo bar\")" + << "ARGC = 2\nARGS = test me 'foo bar'" + << "" + << true; + + QTest::newRow("recursion") + << "defineReplace(func) {\n" + "RET = *$$member(1, 0)*\n" + "REST = $$member(1, 1, -1)\n" + "!isEmpty(REST): RET += $$func($$REST)\n" + "return($$RET)\n" + "}\n" + "VAR = $$func(you are ...)" + << "VAR = *you* *are* *...*" + << "" + << true; + + QTest::newRow("top-level return()") + << "VAR = good\nreturn()\nVAR = bad" + << "VAR = good" + << "" + << true; + + QTest::newRow("return() from function") + << "defineTest(func) {\nVAR = good\nexport(VAR)\nreturn()\nVAR = bad\nexport(VAR)\n}\n" + "func()" + << "VAR = good" + << "" + << true; + + QTest::newRow("return() from nested function") + << "defineTest(inner) {\nVAR = initial\nexport(VAR)\nreturn()\nVAR = bad\nexport(VAR)\n}\n" + "defineTest(outer) {\ninner()\nVAR = final\nexport(VAR)\n}\n" + "outer()" + << "VAR = final" + << "" + << true; +} + +void tst_qmakelib::addReplaceFunctions(const QString &qindir) +{ + QTest::newRow("$$member(): empty") + << "IN = \nVAR = $$member(IN)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$member(): too short") + << "IN = one two three\nVAR = $$member(IN, 1, 5)" + << "VAR =" // this is actually kinda stupid + << "" + << true; + + QTest::newRow("$$member(): ok") + << "IN = one two three four five six seven\nVAR = $$member(IN, 1, 4)" + << "VAR = two three four five" + << "" + << true; + + QTest::newRow("$$member(): ok (default start)") + << "IN = one two three\nVAR = $$member(IN)" + << "VAR = one" + << "" + << true; + + QTest::newRow("$$member(): ok (default end)") + << "IN = one two three\nVAR = $$member(IN, 2)" + << "VAR = three" + << "" + << true; + + QTest::newRow("$$member(): negative") + << "IN = one two three four five six seven\nVAR = $$member(IN, -4, -3)" + << "VAR = four five" + << "" + << true; + + QTest::newRow("$$member(): inverse") + << "IN = one two three four five six seven\nVAR = $$member(IN, 4, 1)" + << "VAR = five four three two" + << "" + << true; + + QTest::newRow("$$member(): dots") + << "IN = one two three four five six seven\nVAR = $$member(IN, 1..4)" + << "VAR = two three four five" + << "" + << true; + + QTest::newRow("$$member(): bad number of arguments") + << "VAR = $$member(1, 2, 3, 4)" + << "VAR =" + << "##:1: member(var, start, end) requires one to three arguments." + << true; + + QTest::newRow("$$member(): bad args (1)") + << "IN = one two three\nVAR = $$member(IN, foo, 4)" + << "VAR =" + << "##:2: member() argument 2 (start) 'foo' invalid." + << true; + + QTest::newRow("$$member(): bad args (2)") + << "IN = one two three\nVAR = $$member(IN, foo..4)" + << "VAR =" + << "##:2: member() argument 2 (start) 'foo..4' invalid." + << true; + + QTest::newRow("$$member(): bad args (3)") + << "IN = one two three\nVAR = $$member(IN, 4, foo)" + << "VAR =" + << "##:2: member() argument 3 (end) 'foo' invalid." + << true; + + QTest::newRow("$$member(): bad args (4)") + << "IN = one two three\nVAR = $$member(IN, 4..foo)" + << "VAR =" + << "##:2: member() argument 2 (start) '4..foo' invalid." + << true; + + QTest::newRow("$$first(): empty") + << "IN = \nVAR = $$first(IN)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$first(): one") + << "IN = one\nVAR = $$first(IN)" + << "VAR = one" + << "" + << true; + + QTest::newRow("$$first(): multiple") + << "IN = one two three\nVAR = $$first(IN)" + << "VAR = one" + << "" + << true; + + QTest::newRow("$$first(): bad number of arguments") + << "VAR = $$first(1, 2)" + << "VAR =" + << "##:1: first(var) requires one argument." + << true; + + QTest::newRow("$$last(): empty") + << "IN = \nVAR = $$last(IN)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$last(): one") + << "IN = one\nVAR = $$last(IN)" + << "VAR = one" + << "" + << true; + + QTest::newRow("$$last(): multiple") + << "IN = one two three\nVAR = $$last(IN)" + << "VAR = three" + << "" + << true; + + QTest::newRow("$$last(): bad number of arguments") + << "VAR = $$last(1, 2)" + << "VAR =" + << "##:1: last(var) requires one argument." + << true; + + QTest::newRow("$$size()") + << "IN = one two three\nVAR = $$size(IN)" + << "VAR = 3" + << "" + << true; + + QTest::newRow("$$size(): bad number of arguments") + << "VAR = $$size(1, 2)" + << "VAR =" + << "##:1: size(var) requires one argument." + << true; + + QTest::newRow("$$fromfile(): right var") + << "VAR = $$fromfile(" + qindir + "/fromfile/infile.prx, DEFINES)" + << "VAR = QT_DLL" + << "" + << true; + + QTest::newRow("$$fromfile(): wrong var") + << "VAR = $$fromfile(" + qindir + "/fromfile/infile.prx, INCLUDES)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$fromfile(): bad file") + << "VAR = $$fromfile(" + qindir + "/fromfile/badfile.prx, DEFINES)" + << "VAR =" + << "Project ERROR: fail!" + << true; + + QTest::newRow("$$fromfile(): bad number of arguments") + << "VAR = $$fromfile(1) \\\n$$fromfile(1, 2, 3)" + << "VAR =" + << "##:1: fromfile(file, variable) requires two arguments.\n" + "##:2: fromfile(file, variable) requires two arguments." + << true; + + QTest::newRow("$$eval()") + << "IN = one two three\nVAR = $$eval(IN)" + << "VAR = one two three" + << "" + << true; + + QTest::newRow("$$eval(): bad number of arguments") + << "VAR = $$eval(1, 2)" + << "VAR =" + << "##:1: eval(variable) requires one argument." + << true; + + QTest::newRow("$$list()") + << "VARNAME = $$list(one, two three, 'four five')\nVAR = $$eval($$VARNAME)" + << "VAR = one two three four five" // total nonsense ... + << "" + << true; + + QTest::newRow("$$sprintf()") + << "VAR = $$sprintf(hello %1 %2, you, there)" + << "VAR = 'hello you there'" + << "" + << true; + + QTest::newRow("$$format_number(): simple number format") + << "VAR = $$format_number(13)" + << "VAR = 13" + << "" + << true; + + QTest::newRow("$$format_number(): negative number format") + << "VAR = $$format_number(-13)" + << "VAR = -13" + << "" + << true; + + QTest::newRow("$$format_number(): hex input number format") + << "VAR = $$format_number(13, ibase=16)" + << "VAR = 19" + << "" + << true; + + QTest::newRow("$$format_number(): hex output number format") + << "VAR = $$format_number(13, obase=16)" + << "VAR = d" + << "" + << true; + + QTest::newRow("$$format_number(): right aligned number format") + << "VAR = $$format_number(13, width=5)" + << "VAR = ' 13'" + << "" + << true; + + QTest::newRow("$$format_number(): left aligned number format") + << "VAR = $$format_number(13, width=5 leftalign)" + << "VAR = '13 '" + << "" + << true; + + QTest::newRow("$$format_number(): zero-padded number format") + << "VAR = $$format_number(13, width=5 zeropad)" + << "VAR = 00013" + << "" + << true; + + QTest::newRow("$$format_number(): always signed number format") + << "VAR = $$format_number(13, width=5 alwayssign)" + << "VAR = ' +13'" + << "" + << true; + + QTest::newRow("$$format_number(): zero-padded always signed number format") + << "VAR = $$format_number(13, width=5 alwayssign zeropad)" + << "VAR = +0013" + << "" + << true; + + QTest::newRow("$$format_number(): sign-padded number format") + << "VAR = $$format_number(13, width=5 padsign)" + << "VAR = ' 13'" + << "" + << true; + + QTest::newRow("$$format_number(): zero-padded sign-padded number format") + + << "VAR = $$format_number(13, width=5 padsign zeropad)" + << "VAR = ' 0013'" + << "" + << true; + + QTest::newRow("$$format_number(): bad number of arguments") + << "VAR = $$format_number(13, 1, 2)" + << "VAR =" + << "##:1: format_number(number[, options...]) requires one or two arguments." + << true; + + QTest::newRow("$$format_number(): invalid option") + << "VAR = $$format_number(13, foo=bar)" + << "VAR =" + << "##:1: format_number(): invalid format option foo=bar." + << true; + + QTest::newRow("$$join(): empty") + << "IN = \nVAR = $$join(IN, //)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$join(): multiple") + << "IN = one two three\nVAR = $$join(IN, //)" + << "VAR = one//two//three" + << "" + << true; + + QTest::newRow("$$join(): multiple surrounded") + << "IN = one two three\nVAR = $$join(IN, //, <<, >>)" + << "VAR = <>" + << "" + << true; + + QTest::newRow("$$join(): bad number of arguments") + << "VAR = $$join(1, 2, 3, 4, 5)" + << "VAR =" + << "##:1: join(var, glue, before, after) requires one to four arguments." + << true; + + QTest::newRow("$$split(): default sep") + << "IN = 'one/two three' 'four / five'\nVAR = $$split(IN)" + << "VAR = one/two three four / five" + << "" + << true; + + QTest::newRow("$$split(): specified sep") + << "IN = 'one/two three' 'four / five'\nVAR = $$split(IN, /)" + << "VAR = one 'two three' 'four ' ' five'" + << "" + << true; + + QTest::newRow("$$split(): bad number of arguments") + << "VAR = $$split(1, 2, 3)" + << "VAR =" + << "##:1: split(var, sep) requires one or two arguments." + << true; + + QTest::newRow("$$basename(): empty") + << "IN = \nVAR = $$basename(IN)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$basename(): bare") + << "IN = file\nVAR = $$basename(IN)" + << "VAR = file" + << "" + << true; + + QTest::newRow("$$basename(): relative") + << "IN = path/file\nVAR = $$basename(IN)" + << "VAR = file" + << "" + << true; + + QTest::newRow("$$basename(): absolute") + << "IN = \\\\path\\\\file\nVAR = $$basename(IN)" + << "VAR = file" + << "" + << true; + + QTest::newRow("$$basename(): bad number of arguments") + << "VAR = $$basename(1, 2)" + << "VAR =" + << "##:1: basename(var) requires one argument." + << true; + + QTest::newRow("$$dirname(): empty") + << "IN = \nVAR = $$dirname(IN)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$dirname(): bare") + << "IN = file\nVAR = $$dirname(IN)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$dirname(): relative") + << "IN = path/file\nVAR = $$dirname(IN)" + << "VAR = path" + << "" + << true; + + QTest::newRow("$$dirname(): absolute") + << "IN = \\\\path\\\\file\nVAR = $$dirname(IN)" + << "VAR = \\\\path" + << "" + << true; + + QTest::newRow("$$dirname(): bad number of arguments") + << "VAR = $$dirname(1, 2)" + << "VAR =" + << "##:1: dirname(var) requires one argument." + << true; + + QTest::newRow("$$section(): explicit end") + << "IN = one~two~three~four~five~six\nVAR = $$section(IN, ~, 2, 4)" + << "VAR = three~four~five" + << "" + << true; + + QTest::newRow("$$section(): implicit end") + << "IN = one~two~three~four~five~six\nVAR = $$section(IN, ~, 3)" + << "VAR = four~five~six" + << "" + << true; + + QTest::newRow("$$section(): bad number of arguments") + << "VAR = $$section(1, 2) \\\n$$section(1, 2, 3, 4, 5)" + << "VAR =" + << "##:1: section(var) section(var, sep, begin, end) requires three or four arguments.\n" + "##:2: section(var) section(var, sep, begin, end) requires three or four arguments." + << true; + + QTest::newRow("$$find()") + << "IN = foo bar baz blubb\nVAR = $$find(IN, ^ba)" + << "VAR = bar baz" + << "" + << true; + + QTest::newRow("$$find(): bad number of arguments") + << "VAR = $$find(1) \\\n$$find(1, 2, 3)" + << "VAR =" + << "##:1: find(var, str) requires two arguments.\n" + "##:2: find(var, str) requires two arguments." + << true; + + // FIXME: $$cat() & $$system(): There is no way to generate the newlines + // necessary for testing "multi-line" and "blob" mode adequately. + // Note: these functions have *different* splitting behavior. + + // This gives split_value_list() an exercise + QTest::newRow("$$cat(): default mode") + << "VAR = $$cat(" + qindir + "/cat/file2.txt)" + << "VAR = foo bar baz \"\\\"Hello, \\' world.\\\"\" post \"\\'Hello, \\\" world.\\'\" post \\\\\\\" \\\\\\' \\\\\\\\ \\\\a \\\\ nix \"\\\" \\\"\"" + << "" + << true; + + QTest::newRow("$$cat(): lines mode") + << "VAR = $$cat(" + qindir + "/cat/file1.txt, lines)" + << "VAR = '\"Hello, world.\"' 'foo bar baz'" + << "" + << true; + + QTest::newRow("$$cat(): bad number of arguments") + << "VAR = $$cat(1, 2, 3)" + << "VAR =" + << "##:1: cat(file, singleline=true) requires one or two arguments." + << true; + + QTest::newRow("$$system(): default mode") +#ifdef Q_OS_WIN + << "VAR = $$system('echo Hello, ^\"world.&& echo foo^\" bar baz')" +#else + << "VAR = $$system('echo Hello, \\\\\\\"world. && echo foo\\\\\\\" bar baz')" +#endif + << "VAR = Hello, '\"world. foo\"' bar baz" + << "" + << true; + + QTest::newRow("$$system(): lines mode") +#ifdef Q_OS_WIN + << "VAR = $$system('echo Hello, ^\"world.&& echo foo^\" bar baz', lines)" +#else + << "VAR = $$system('echo Hello, \\\\\\\"world. && echo foo\\\\\\\" bar baz', lines)" +#endif + << "VAR = 'Hello, \"world.' 'foo\" bar baz'" + << "" + << true; + + QTest::newRow("$$system(): bad number of arguments") + << "VAR = $$system(1, 2, 3)" + << "VAR =" + << "##:1: system(execute) requires one or two arguments." + << true; + + QTest::newRow("$$unique()") + << "IN = foo bar foo baz\nVAR = $$unique(IN)" + << "VAR = foo bar baz" + << "" + << true; + + QTest::newRow("$$unique(): bad number of arguments") + << "VAR = $$unique(1, 2)" + << "VAR =" + << "##:1: unique(var) requires one argument." + << true; + + QTest::newRow("$$reverse()") + << "IN = one two three\nVAR = $$reverse(IN)" + << "VAR = three two one" + << "" + << true; + + QTest::newRow("$$reverse(): bad number of arguments") + << "VAR = $$reverse(1, 2)" + << "VAR =" + << "##:1: reverse(var) requires one argument." + << true; + + QTest::newRow("$$quote()") + << "VAR = $$quote(foo bar, 'foo bar')" + << "VAR = 'foo bar' 'foo bar'" + << "" + << true; + + // FIXME: \n and \r go untested, because there is no way to get them into the + // expected result. And if there was one, this function would be unnecessary. + // In other news, the behavior of backslash escaping makes no sense. + QTest::newRow("$$escape_expand()") + << "VAR = $$escape_expand(foo\\\\ttab\\\\\\\\slash\\\\invalid, verbatim)" + << "VAR = 'foo\ttab\\\\\\\\slash\\\\invalid' verbatim" + << "" + << true; + + QTest::newRow("$$upper()") + << "VAR = $$upper(kEwL, STuff)" + << "VAR = KEWL STUFF" + << "" + << true; + + QTest::newRow("$$lower()") + << "VAR = $$lower(kEwL, STuff)" + << "VAR = kewl stuff" + << "" + << true; + + QTest::newRow("$$title()") + << "VAR = $$title(kEwL, STuff)" + << "VAR = Kewl Stuff" + << "" + << true; + + QTest::newRow("$$re_escape()") + << "VAR = $$re_escape(one, hey.*you[funny]+people)" + << "VAR = one hey\\\\.\\\\*you\\\\[funny\\\\]\\\\+people" + << "" + << true; + + QTest::newRow("$$val_escape()") + << "IN = easy \"less easy\" sca$${LITERAL_HASH}ry" + " crazy$$escape_expand(\\\\t\\\\r\\\\n)" + " $$escape_expand(\\\\t)stuff \\'no\\\"way\\\\here\n" + "VAR = $$val_escape(IN)" + << "VAR = easy '\\\"less easy\\\"' sca\\$\\${LITERAL_HASH}ry" + " crazy\\$\\$escape_expand(\\\\\\\\t\\\\\\\\r\\\\\\\\n)" + " \\$\\$escape_expand(\\\\\\\\t)stuff \\\\\\'no\\\\\\\"way\\\\\\\\here" + << "" + << true; + + QTest::newRow("$$val_escape(): bad number of arguments") + << "VAR = $$val_escape(1, 2)" + << "VAR =" + << "##:1: val_escape(var) requires one argument." + << true; + + QTest::newRow("$$files(): non-recursive") + << "VAR = $$files(" + qindir + "/files/file*.txt)" + << "VAR = " + qindir + "/files/file1.txt " + + qindir + "/files/file2.txt" + << "" + << true; + + QTest::newRow("$$files(): recursive") + << "VAR = $$files(" + qindir + "/files/file*.txt, true)" + << "VAR = " + qindir + "/files/file1.txt " + + qindir + "/files/file2.txt " + + qindir + "/files/dir/file1.txt " + + qindir + "/files/dir/file2.txt" + << "" + << true; + + QTest::newRow("$$files(): bad number of arguments") + << "VAR = $$files(1, 2, 3)" + << "VAR =" + << "##:1: files(pattern, recursive=false) requires one or two arguments." + << true; + +#if 0 + // FIXME: no emulated input layer + QTest::newRow("$$prompt()") + << "VAR = $$prompt(que)" + << "VAR = whatever" + << "Project PROMPT: que? " + << true; +#endif + + QTest::newRow("$$replace()") + << "IN = foo 'bar baz'\nVAR = $$replace(IN, \\\\bba, hello)" + << "VAR = foo 'hellor helloz'" + << "" + << true; + + QTest::newRow("$$replace(): bad number of arguments") + << "VAR = $$replace(1, 2) \\\n$$replace(1, 2, 3, 4)" + << "VAR =" + << "##:1: replace(var, before, after) requires three arguments.\n" + "##:2: replace(var, before, after) requires three arguments." + << true; + + QTest::newRow("$$sort_depends()") + << "foo.depends = bar baz\n" + "bar.depends = baz bak duck\n" + "baz.depends = bak\n" + "bak.depends = duck\n" + "VAR = $$sort_depends($$list(baz foo duck bar))" + << "VAR = foo bar baz duck" + << "" + << true; + + QTest::newRow("$$resolve_depends(): basic") + << "foo.depends = bar baz\n" + "bar.depends = baz bak duck\n" + "baz.depends = bak\n" + "bak.depends = duck\n" + "VAR = $$resolve_depends($$list(baz foo duck bar))" + << "VAR = foo bar baz bak duck" + << "" + << true; + + QTest::newRow("$$resolve_depends(): prefix and multiple suffixes") + << "MOD.foo.dep = bar baz\n" + "MOD.bar.dep = baz bak\n" + "MOD.bar.priv_dep = duck\n" + "MOD.baz.dep = bak\n" + "MOD.bak.dep = duck\n" + "VAR = $$resolve_depends($$list(baz foo duck bar), MOD., .dep .priv_dep)" + << "VAR = foo bar baz bak duck" + << "" + << true; + + QTest::newRow("$$resolve_depends(): priorities: b first") + << "MOD.a.depends =\n" + "MOD.b.depends =\n" + "MOD.b.priority = 1\n" + "MOD.c.depends = a b\n" + "VAR = $$resolve_depends($$list(c), MOD.)" + << "VAR = c b a" + << "" + << true; + + QTest::newRow("$$resolve_depends(): priorities: a first") + << "MOD.a.depends =\n" + "MOD.a.priority = 1\n" + "MOD.b.depends =\n" + "MOD.b.priority = 0\n" + "MOD.c.depends = a b\n" + "VAR = $$resolve_depends($$list(c), MOD.)" + << "VAR = c a b" + << "" + << true; + + QTest::newRow("$$resolve_depends(): priorities: custom suffix") + << "MOD.a.depends =\n" + "MOD.a.prrt = 1\n" + "MOD.b.depends =\n" + "MOD.b.prrt = 0\n" + "MOD.c.depends = a b\n" + "VAR = $$resolve_depends($$list(c), MOD., .depends, .prrt)" + << "VAR = c a b" + << "" + << true; + + QTest::newRow("$$resolve_depends(): bad number of arguments") + << "VAR = $$resolve_depends(1, 2, 3, 4, 5)" + << "VAR =" + << "##:1: resolve_depends(var, [prefix, [suffixes, [prio-suffix]]]) requires one to four arguments." + << true; + + QTest::newRow("$$enumerate_vars()") + << "V1 = foo\nV2 = bar\nVAR = $$enumerate_vars()\n" + "count(VAR, 2, >=):contains(VAR, V1):contains(VAR, V2): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("$$shadowed(): bare") + << "VAR = $$shadowed(test.txt)" + << "VAR = " + QMakeEvaluator::quoteValue(ProString(m_outdir + "/test.txt")) + << "" + << true; + + QTest::newRow("$$shadowed(): subdir") + << "VAR = $$shadowed(" + qindir + "/sub/test.txt)" + << "VAR = " + QMakeEvaluator::quoteValue(ProString(m_outdir + "/sub/test.txt")) + << "" + << true; + + QTest::newRow("$$shadowed(): outside source dir") + << "VAR = $$shadowed(/some/random/path)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$shadowed(): bad number of arguments") + << "VAR = $$shadowed(1, 2)" + << "VAR =" + << "##:1: shadowed(path) requires one argument." + << true; + + QTest::newRow("$$absolute_path(): relative file") + << "VAR = $$absolute_path(dir/file.ext)" + << "VAR = " + qindir + "/dir/file.ext" + << "" + << true; + + QTest::newRow("$$absolute_path(): file & path") + << "VAR = $$absolute_path(dir/file.ext, /root/sub)" + << "VAR = /root/sub/dir/file.ext" + << "" + << true; + + QTest::newRow("$$absolute_path(): absolute file & path") + << "VAR = $$absolute_path(/root/sub/dir/file.ext, /other)" + << "VAR = /root/sub/dir/file.ext" + << "" + << true; + + QTest::newRow("$$absolute_path(): empty file & path") + << "VAR = $$absolute_path('', /root/sub)" + << "VAR = /root/sub" + << "" + << true; + + QTest::newRow("$$absolute_path(): bad number of arguments") + << "VAR = $$absolute_path(1, 2, 3)" + << "VAR =" + << "##:1: absolute_path(path[, base]) requires one or two arguments." + << true; + + QTest::newRow("$$relative_path(): relative file") + << "VAR = $$relative_path(dir/file.ext)" + << "VAR = dir/file.ext" + << "" + << true; + + QTest::newRow("$$relative_path(): relative file to empty") + << "VAR = $$relative_path(dir/..)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$relative_path(): absolute file & path") + << "VAR = $$relative_path(/root/sub/dir/file.ext, /root/sub)" + << "VAR = dir/file.ext" + << "" + << true; + + QTest::newRow("$$relative_path(): empty file & path") + << "VAR = $$relative_path('', /root/sub)" + << "VAR =" + << "" + << true; + + QTest::newRow("$$relative_path(): bad number of arguments") + << "VAR = $$relative_path(1, 2, 3)" + << "VAR =" + << "##:1: relative_path(path[, base]) requires one or two arguments." + << true; + + QTest::newRow("$$clean_path()") +#ifdef Q_OS_WIN // This is actually kinda stupid. + << "VAR = $$clean_path(foo//bar\\\\../baz/)" +#else + << "VAR = $$clean_path(foo//bar/../baz/)" +#endif + << "VAR = foo/baz" + << "" + << true; + + QTest::newRow("$$clean_path(): bad number of arguments") + << "VAR = $$clean_path(1, 2)" + << "VAR =" + << "##:1: clean_path(path) requires one argument." + << true; + + QTest::newRow("$$system_path()") + << "VAR = $$system_path(foo/bar\\\\baz)" +#ifdef Q_OS_WIN + << "VAR = foo\\\\bar\\\\baz" +#else + << "VAR = foo/bar/baz" +#endif + << "" + << true; + + QTest::newRow("$$system_path(): bad number of arguments") + << "VAR = $$system_path(1, 2)" + << "VAR =" + << "##:1: system_path(path) requires one argument." + << true; + + // This is is effectively $$system_path() in this test, as we load no specs + QTest::newRow("$$shell_path()") + << "VAR = $$shell_path(foo/bar\\\\baz)" +#ifdef Q_OS_WIN + << "VAR = foo\\\\bar\\\\baz" +#else + << "VAR = foo/bar/baz" +#endif + << "" + << true; + + QTest::newRow("$$shell_path(): bad number of arguments") + << "VAR = $$shell_path(1, 2)" + << "VAR =" + << "##:1: shell_path(path) requires one argument." + << true; + + // The quoteArgs() test exercises this more thoroughly + QTest::newRow("$$system_quote()") + << "IN = \nVAR = $$system_quote(\"some nasty & ugly\\\" path & thing\\\\\")" +#ifdef Q_OS_WIN + << "VAR = \"\\\"some nasty & ugly\\\\\\\" path ^& thing\\\\\\\\^\\\"\"" +#else + << "VAR = \"'some nasty & ugly\\\" path & thing\\\\'\"" +#endif + << "" + << true; + + QTest::newRow("$$system_quote(): bad number of arguments") + << "VAR = $$system_quote(1, 2)" + << "VAR =" + << "##:1: system_quote(arg) requires one argument." + << true; + + // This is is effectively $$system_path() in this test, as we load no specs + QTest::newRow("$$shell_quote()") + << "IN = \nVAR = $$shell_quote(\"some nasty & ugly\\\" path & thing\\\\\")" +#ifdef Q_OS_WIN + << "VAR = \"\\\"some nasty & ugly\\\\\\\" path ^& thing\\\\\\\\^\\\"\"" +#else + << "VAR = \"'some nasty & ugly\\\" path & thing\\\\'\"" +#endif + << "" + << true; + + QTest::newRow("$$shell_quote(): bad number of arguments") + << "VAR = $$shell_quote(1, 2)" + << "VAR =" + << "##:1: shell_quote(arg) requires one argument." + << true; + + QTest::newRow("$$getenv()") + << "VAR = $$getenv(E1)" + << "VAR = 'env var'" + << "" + << true; + + QTest::newRow("$$getenv(): bad number of arguments") + << "VAR = $$getenv(1, 2)" + << "VAR =" + << "##:1: getenv(arg) requires one argument." + << true; +} + +void tst_qmakelib::addTestFunctions(const QString &qindir) +{ + QTest::newRow("defined(): found replace") + << "defineReplace(func) {}\ndefined(func): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("defined(): found test") + << "defineTest(func) {}\ndefined(func): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("defined(): not found") + << "defined(func): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("defined(replace): found") + << "defineReplace(func) {}\ndefined(func, replace): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("defined(replace): not found") + << "defineTest(func) {}\ndefined(func, replace): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("defined(test): found") + << "defineTest(func) {}\ndefined(func, test): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("defined(test): not found") + << "defineReplace(func) {}\ndefined(func, test): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("defined(var): found") + << "VAR = 1\ndefined(VAR, var): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("defined(var): not found") + << "defined(VAR, var): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("defined(): invalid type") + << "defined(VAR, nope): OK = 1" + << "OK = UNDEF" + << "##:1: defined(function, type): unexpected type [nope]." + << true; + + QTest::newRow("defined(): bad number of arguments") + << "defined(1, 2, 3): OK = 1" + << "OK = UNDEF" + << "##:1: defined(function, [\"test\"|\"replace\"|\"var\"]) requires one or two arguments." + << true; + + QTest::newRow("export()") + << "defineTest(func) {\n" + "VAR1 += different\nexport(VAR1)\n" + "unset(VAR2)\nexport(VAR2): OK = 1\nexport(OK)\n" + "VAR3 = new var\nexport(VAR3)\n" + "}\n" + "VAR1 = entirely\nVAR2 = set\nfunc()" + << "OK = 1\nVAR1 = entirely different\nVAR2 =\nVAR3 = new var" + << "" + << true; + + QTest::newRow("export(): bad number of arguments") + << "export(1, 2): OK = 1" + << "OK = UNDEF" + << "##:1: export(variable) requires one argument." + << true; + + QTest::newRow("infile(): found") + << "infile(" + qindir + "/fromfile/infile.prx, DEFINES): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("infile(): not found") + << "infile(" + qindir + "/fromfile/infile.prx, INCLUDES): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("infile(plain): found") + << "infile(" + qindir + "/fromfile/infile.prx, DEFINES, QT_DLL): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("infile(plain): not found") + << "infile(" + qindir + "/fromfile/infile.prx, DEFINES, NOPE): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("infile(regex): found") + << "infile(" + qindir + "/fromfile/infile.prx, DEFINES, QT_.*): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("infile(regex): not found") + << "infile(" + qindir + "/fromfile/infile.prx, DEFINES, NO.*): OK = 1" + << "OK = UNDEF" + << "" + << true; + + // The early return is debatable, esp. as it's inconsistent with $$fromfile() + QTest::newRow("infile(): bad file") + << "infile(" + qindir + "/fromfile/badfile.prx, DEFINES): OK = 1\nOKE = 1" + << "OK = UNDEF\nOKE = UNDEF" + << "Project ERROR: fail!" + << false; + + QTest::newRow("infile(): bad number of arguments") + << "infile(1): OK = 1\ninfile(1, 2, 3, 4): OK = 1" + << "OK = UNDEF" + << "##:1: infile(file, var, [values]) requires two or three arguments.\n" + "##:2: infile(file, var, [values]) requires two or three arguments." + << true; + + QTest::newRow("requires()") + << "requires(true, false, isEmpty(FOO), !isEmpty(BAR), true|false, true:false)" + << "QMAKE_FAILED_REQUIREMENTS = false !isEmpty(BAR) true:false" + << "" + << true; + + // The sparator semantics are *very* questionable. + // The return value semantics are rather questionable. + QTest::newRow("eval()") + << "eval(FOO = one, two$$escape_expand(\\\\n)BAR = blah$$escape_expand(\\\\n)error(fail)$$escape_expand(\\\\n)BAZ = nope)" + << "FOO = one two\nBAR = blah\nBAZ = UNDEF" + << "Project ERROR: fail" + << true; + + QTest::newRow("if(): true") + << "if(false|true): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("if(): true (space)") + << "if(false| true): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("if(): true (spaces)") + << "if( false | true ): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("if(): false") + << "if(false:true): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("if(): false (space)") + << "if(false: true): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("if(): false (spaces)") + << "if( false : true ): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("if(): bad number of arguments") + << "if(1, 2): OK = 1" + << "OK = UNDEF" + << "##:1: if(condition) requires one argument." + << true; + + QTest::newRow("CONFIG(simple): true") + << "CONFIG = debug release\nCONFIG(debug): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("CONFIG(simple): false") + << "CONFIG = debug release\nCONFIG(nope): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("CONFIG(alt): true") + << "CONFIG = debug release\nCONFIG(release, debug|release): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("CONFIG(alt): false (presence)") + << "CONFIG = not here\nCONFIG(debug, debug|release): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("CONFIG(alt): false (order)") + << "CONFIG = debug release\nCONFIG(debug, debug|release): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("CONFIG(): bad number of arguments") + << "CONFIG(1, 2, 3): OK = 1" + << "OK = UNDEF" + << "##:1: CONFIG(config) requires one or two arguments." + << true; + + QTest::newRow("contains(simple plain): true") + << "VAR = one two three\ncontains(VAR, two): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("contains(simple plain): false") + << "VAR = one two three\ncontains(VAR, four): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("contains(simple regex): true") + << "VAR = one two three\ncontains(VAR, tw.*): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("contains(simple regex): false") + << "VAR = one two three\ncontains(VAR, fo.*): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("contains(alt plain): true") + << "VAR = one two three\ncontains(VAR, three, two|three): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("contains(alt plain): false (presence)") + << "VAR = one four five\ncontains(VAR, three, two|three): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("contains(alt plain): false (order)") + << "VAR = one two three\ncontains(VAR, two, two|three): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("contains(alt regex): true") + << "VAR = one two three\ncontains(VAR, th.*, two|three): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("contains(alt regex): false (presence)") + << "VAR = one four five\ncontains(VAR, th.*, two|three): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("contains(alt regex): false (order)") + << "VAR = one two three\ncontains(VAR, tw.*, two|three): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("contains(): bad number of arguments") + << "contains(1): OK = 1\ncontains(1, 2, 3, 4): OK = 1" + << "OK = UNDEF" + << "##:1: contains(var, val) requires two or three arguments.\n" + "##:2: contains(var, val) requires two or three arguments." + << true; + + QTest::newRow("count(): true") + << "VAR = one two three\ncount(VAR, 3): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("count(): false") + << "VAR = one two three\ncount(VAR, 4): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("count(operators): true") + << "VAR = one two three\n" + "count(VAR, 3, equals): OKE1 = 1\n" + "count(VAR, 3, isEqual): OKE2 = 1\n" + "count(VAR, 3, =): OKE3 = 1\n" + "count(VAR, 3, ==): OKE4 = 1\n" + "count(VAR, 2, greaterThan): OKG1 = 1\n" + "count(VAR, 2, >): OKG2 = 1\n" + "count(VAR, 2, >=): OKGE = 1\n" + "count(VAR, 4, lessThan): OKL1 = 1\n" + "count(VAR, 4, <): OKL2 = 1\n" + "count(VAR, 4, <=): OKLE = 1\n" + << "OKE1 = 1\nOKE2 = 1\nOKE3 = 1\nOKE4 = 1\n" + "OKG1 = 1\nOKG2 = 1\nOKGE = 1\n" + "OKL1 = 1\nOKL2 = 1\nOKLE = 1" + << "" + << true; + + QTest::newRow("count(operators): false") + << "VAR = one two three\n" + "count(VAR, 4, equals): OKE1 = 1\n" + "count(VAR, 4, isEqual): OKE2 = 1\n" + "count(VAR, 4, =): OKE3 = 1\n" + "count(VAR, 4, ==): OKE4 = 1\n" + "count(VAR, 3, greaterThan): OKG1 = 1\n" + "count(VAR, 3, >): OKG2 = 1\n" + "count(VAR, 4, >=): OKGE = 1\n" + "count(VAR, 3, lessThan): OKL1 = 1\n" + "count(VAR, 3, <): OKL2 = 1\n" + "count(VAR, 2, <=): OKLE = 1\n" + << "OKE1 = UNDEF\nOKE2 = UNDEF\nOKE3 = UNDEF\nOKE4 = UNDEF\n" + "OKG1 = UNDEF\nOKG2 = UNDEF\nOKGE = UNDEF\n" + "OKL1 = UNDEF\nOKL2 = UNDEF\nOKLE = UNDEF" + << "" + << true; + + QTest::newRow("count(): bad operator") + << "VAR = one two three\ncount(VAR, 2, !!!): OK = 1" + << "OK = UNDEF" + << "##:2: Unexpected modifier to count(!!!)." + << true; + + QTest::newRow("count(): bad number of arguments") + << "count(1): OK = 1\ncount(1, 2, 3, 4): OK = 1" + << "OK = UNDEF" + << "##:1: count(var, count, op=\"equals\") requires two or three arguments.\n" + "##:2: count(var, count, op=\"equals\") requires two or three arguments." + << true; + + QTest::newRow("greaterThan(int): true") + << "VAR = 20\ngreaterThan(VAR, 3): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("greaterThan(int): false") + << "VAR = 3\ngreaterThan(VAR, 20): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("greaterThan(string): true") + << "VAR = foo 3\ngreaterThan(VAR, foo 20): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("greaterThan(string): false") + << "VAR = foo 20\ngreaterThan(VAR, foo 3): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("greaterThan(): bad number of arguments") + << "greaterThan(1): OK = 1\ngreaterThan(1, 2, 3): OK = 1" + << "OK = UNDEF" + << "##:1: greaterThan(variable, value) requires two arguments.\n" + "##:2: greaterThan(variable, value) requires two arguments." + << true; + + QTest::newRow("lessThan(int): true") + << "VAR = 3\nlessThan(VAR, 20): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("lessThan(int): false") + << "VAR = 20\nlessThan(VAR, 3): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("lessThan(string): true") + << "VAR = foo 20\nlessThan(VAR, foo 3): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("lessThan(string): false") + << "VAR = foo 3\nlessThan(VAR, foo 20): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("lessThan(): bad number of arguments") + << "lessThan(1): OK = 1\nlessThan(1, 2, 3): OK = 1" + << "OK = UNDEF" + << "##:1: lessThan(variable, value) requires two arguments.\n" + "##:2: lessThan(variable, value) requires two arguments." + << true; + + QTest::newRow("equals(): true") + << "VAR = foo\nequals(VAR, foo): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("equals(): false") + << "VAR = foo\nequals(VAR, bar): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("equals(): bad number of arguments") + << "equals(1): OK = 1\nequals(1, 2, 3): OK = 1" + << "OK = UNDEF" + << "##:1: equals(variable, value) requires two arguments.\n" + "##:2: equals(variable, value) requires two arguments." + << true; + + // That's just an alias, so don't test much. + QTest::newRow("isEqual(): true") + << "VAR = foo\nisEqual(VAR, foo): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("clear(): top-level") + << "VAR = there\nclear(VAR): OK = 1" + << "OK = 1\nVAR =" + << "" + << true; + + QTest::newRow("clear(): scoped") + << "defineTest(func) {\n" + "clear(VAR): OK = 1\nexport(OK)\n" + "equals(VAR, \"\"): OKE = 1\nexport(OKE)\n" + "}\n" + "VAR = there\nfunc()" + << "OK = 1\nOKE = 1" + << "" + << true; + + QTest::newRow("clear(): absent") + << "clear(VAR): OK = 1" + << "OK = UNDEF\nVAR = UNDEF" + << "" + << true; + + QTest::newRow("clear(): bad number of arguments") + << "clear(1, 2): OK = 1" + << "OK = UNDEF" + << "##:1: clear(variable) requires one argument." + << true; + + QTest::newRow("unset(): top-level") + << "VAR = there\nunset(VAR): OK = 1" + << "OK = 1\nVAR = UNDEF" + << "" + << true; + + QTest::newRow("unset(): scoped") + << "defineTest(func) {\n" + "unset(VAR): OK = 1\nexport(OK)\n" + "!defined(VAR, var): OKE = 1\nexport(OKE)\n" + "}\n" + "VAR = there\nfunc()" + << "OK = 1\nOKE = 1" + << "" + << true; + + QTest::newRow("unset(): absent") + << "unset(VAR): OK = 1" + << "OK = UNDEF\nVAR = UNDEF" + << "" + << true; + + QTest::newRow("unset(): bad number of arguments") + << "unset(1, 2): OK = 1" + << "OK = UNDEF" + << "##:1: unset(variable) requires one argument." + << true; + + // This function does not follow the established naming pattern. + QTest::newRow("parseJson()") + << "jsontext = \\\n" + " \"{\"\\\n" + " \" \\\"array\\\" : [\\\"arrayItem1\\\", \\\"arrayItem2\\\", \\\"arrayItem3\\\"],\"\\\n" + " \" \\\"object\\\" : { \\\"key1\\\" : \\\"objectValue1\\\", \\\"key2\\\" : \\\"objectValue2\\\" },\"\\\n" + " \" \\\"string\\\" : \\\"test string\\\",\"\\\n" + " \" \\\"number\\\" : 999,\"\\\n" + " \" \\\"true\\\" : true,\"\\\n" + " \" \\\"false\\\" :false,\"\"\\\n" + " \" \\\"null\\\" : null\"\"\\\n" + " \"}\"\n" + "parseJson(jsontext, json): OK = 1" + << "OK = 1\n" + "json._KEYS_ = array false null number object string true\n" + // array + "json.array._KEYS_ = 0 1 2\n" + "json.array.0 = arrayItem1\n" + "json.array.1 = arrayItem2\n" + "json.array.2 = arrayItem3\n" + // object + "json.object._KEYS_ = key1 key2\n" + "json.object.key1 = objectValue1\n" + "json.object.key1 = objectValue1\n" + // value types + "json.string = 'test string'\n" + "json.number = 999\n" + "json.true = true\n" + "json.false = false\n" + "json.null = UNDEF" + << "" + << true; + + QTest::newRow("parseJson(): bad input") + << "jsontext = not good\n" + "parseJson(jsontext, json): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("parseJson(): bad number of arguments") + << "parseJson(1): OK = 1\nparseJson(1, 2, 3): OK = 1" + << "OK = UNDEF" + << "##:1: parseJson(variable, into) requires two arguments.\n" + "##:2: parseJson(variable, into) requires two arguments." + << true; + + QTest::newRow("include()") + << "include(include/inc.pri): OK = 1\nfunc()" + << "OK = 1\nVAR = val\n.VAR = nope" + << "Project MESSAGE: say hi!" + << true; + + QTest::newRow("include(): fail") + << "include(include/nope.pri): OK = 1" + << "OK = UNDEF" + << "Cannot read " + m_indir + "/include/nope.pri: No such file or directory" + << true; + + QTest::newRow("include(): silent fail") + << "include(include/nope.pri, , true): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("include(into)") + << "SUB.MISS = 1\ninclude(include/inc.pri, SUB): OK = 1" + << "OK = 1\nSUB.VAR = val\nSUB..VAR = UNDEF\nSUB.MISS = UNDEF\n" + // As a side effect, we test some things that need full project setup + "SUB.MATCH = 1\nSUB.QMAKESPEC = " + qindir + "/mkspecs/fake-g++" + << "" + << true; + + QTest::newRow("include(): bad number of arguments") + << "include(1, 2, 3, 4): OK = 1" + << "OK = UNDEF" + << "##:1: include(file, [into, [silent]]) requires one, two or three arguments." + << true; + + QTest::newRow("load()") + << "load(testfeat): OK = 1" + << "OK = 1\nVAR = foo bar" + << "" + << true; + + QTest::newRow("load(): fail") + << "load(no_such_feature): OK = 1" + << "OK = UNDEF" + << "##:1: Cannot find feature no_such_feature" + << true; + + QTest::newRow("load(): silent fail") + << "load(no_such_feature, true): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("load(): bad number of arguments") + << "load(1, 2, 3): OK = 1" + << "OK = UNDEF" + << "##:1: load(feature) requires one or two arguments." + << true; + + // We don't test debug() and log(), because they print directly to stderr. + + QTest::newRow("message()") + << "message('Hello, World!'): OK = 1\nOKE = 1" + << "OK = 1\nOKE = 1" + << "Project MESSAGE: Hello, World!" + << true; + + // Don't test that for warning() and error(), as it's the same code path. + QTest::newRow("message(): bad number of arguments") + << "message(1, 2): OK = 1" + << "OK = UNDEF" + << "##:1: message(message) requires one argument." + << true; + + QTest::newRow("warning()") + << "warning('World, be warned!'): OK = 1\nOKE = 1" + << "OK = 1\nOKE = 1" + << "Project WARNING: World, be warned!" + << true; + + QTest::newRow("error()") + << "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 + "cd" +#else + "pwd" +#endif + "> '" + QMakeEvaluator::quoteValue(ProString(QDir::toNativeSeparators( + m_outdir + "/system_out.txt"))) + "): OK = 1\n" + "DIR = $$cat(" + QMakeEvaluator::quoteValue(ProString( + m_outdir + "/system_out.txt")) + ")" + << "OK = 1\nDIR = " + QMakeEvaluator::quoteValue(ProString(QDir::toNativeSeparators(m_indir))) + << "" + << true; + + QTest::newRow("system(): fail") +#ifdef Q_OS_WIN + << "system(no_such_cmd 2> NUL): OK = 1" +#else + << "system(no_such_cmd 2> /dev/null): OK = 1" +#endif + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("system(): bad number of arguments") + << "system(1, 2): OK = 1" + << "OK = UNDEF" + << "##:1: system(exec) requires one argument." + << true; + + QTest::newRow("isEmpty(): true (empty)") + << "VAR =\nisEmpty(VAR): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("isEmpty(): true (undef)") + << "isEmpty(VAR): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("isEmpty(): false") + << "VAR = val\nisEmpty(VAR): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("isEmpty(): bad number of arguments") + << "isEmpty(1, 2): OK = 1" + << "OK = UNDEF" + << "##:1: isEmpty(var) requires one argument." + << true; + + QTest::newRow("exists(plain): true") + << "exists(files/file1.txt): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("exists(plain): false") + << "exists(files/not_there.txt): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("exists(wildcard): true") + << "exists(files/fil*.txt): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("exists(wildcard): false") + << "exists(files/not_th*.txt): OK = 1" + << "OK = UNDEF" + << "" + << true; + + QTest::newRow("exists(): bad number of arguments") + << "exists(1, 2): OK = 1" + << "OK = UNDEF" + << "##:1: exists(file) requires one argument." + << true; + + QString wpath = QMakeEvaluator::quoteValue(ProString(m_outdir + "/outdir/written.txt")); + QTest::newRow("write_file(): create") + << "VAR = 'this is text' 'yet again'\n" + "write_file(" + wpath + ", VAR): OK = 1\n" + "OUT = $$cat(" + wpath + ", lines)" + << "OK = 1\nOUT = 'this is text' 'yet again'" + << "" + << true; + + QTest::newRow("write_file(): truncate") + << "VAR = 'other content'\n" + "write_file(" + wpath + ", VAR): OK = 1\n" + "OUT = $$cat(" + wpath + ", lines)" + << "OK = 1\nOUT = 'other content'" + << "" + << true; + + QTest::newRow("write_file(): append") + << "VAR = 'one more line'\n" + "write_file(" + wpath + ", VAR, append): OK = 1\n" + "OUT = $$cat(" + wpath + ", lines)" + << "OK = 1\nOUT = 'other content' 'one more line'" + << "" + << true; + + QString vpath = QMakeEvaluator::quoteValue(ProString(m_outdir)); + QTest::newRow("write_file(): fail") + << "write_file(" + vpath + "): OK = 1" + << "OK = UNDEF" +#ifdef Q_OS_WIN + << "##:1: Cannot write file " + QDir::toNativeSeparators(m_outdir) + ": Access is denied." +#else + << "##:1: Cannot write file " + m_outdir + ": Is a directory" +#endif + << true; + + QTest::newRow("write_file(): bad number of arguments") + << "write_file(1, 2, 3, 4): OK = 1" + << "OK = UNDEF" + << "##:1: write_file(name, [content var, [append]]) requires one to three arguments." + << true; + + // FIXME: This doesn't test whether it actually works. + QTest::newRow("touch()") + << "touch(" + wpath + ", files/other.txt): OK = 1" + << "OK = 1" + << "" + << true; + + QTest::newRow("touch(): missing target") + << "touch(/does/not/exist, files/other.txt): OK = 1" + << "OK = UNDEF" +#ifdef Q_OS_WIN + << "##:1: Cannot open /does/not/exist: The system cannot find the path specified." +#else + << "##:1: Cannot touch /does/not/exist: No such file or directory." +#endif + << true; + + QTest::newRow("touch(): missing reference") + << "touch(" + wpath + ", /does/not/exist): OK = 1" + << "OK = UNDEF" +#ifdef Q_OS_WIN + << "##:1: Cannot open reference file /does/not/exist: The system cannot find the path specified." +#else + << "##:1: Cannot stat() reference file /does/not/exist: No such file or directory." +#endif + << true; + + QTest::newRow("touch(): bad number of arguments") + << "touch(1): OK = 1\ntouch(1, 2, 3): OK = 1" + << "OK = UNDEF" + << "##:1: touch(file, reffile) requires two arguments.\n" + "##:2: touch(file, reffile) requires two arguments." + << true; + + QString apath = QMakeEvaluator::quoteValue(ProString(m_outdir + "/a/path")); + QTest::newRow("mkpath()") + << "mkpath(" + apath + "): OK = 1\n" + "exists(" + apath + "): OKE = 1" + << "OK = 1\nOKE = 1" + << "" + << true; + + QString bpath = QMakeEvaluator::quoteValue(ProString(m_outdir + "/fail_me")); + QTest::newRow("mkpath(): fail") + << "write_file(" + bpath + ")|error(FAIL)\n" + "mkpath(" + bpath + "): OK = 1" + << "OK = UNDEF" + << "##:2: Cannot create directory " + QDir::toNativeSeparators(m_outdir + "/fail_me") + '.' + << true; + + QTest::newRow("mkpath(): bad number of arguments") + << "mkpath(1, 2): OK = 1" + << "OK = UNDEF" + << "##:1: mkpath(file) requires one argument." + << true; + +#if 0 + // FIXME ... insanity lies ahead + QTest::newRow("cache()") + << "" + << "" + << "" + << true; +#endif +} + +void tst_qmakelib::proEval_data() +{ + QTest::addColumn("in"); + QTest::addColumn("out"); + QTest::addColumn("msgs"); + QTest::addColumn("ok"); + + QTest::newRow("empty") + << "" + << "VAR = UNDEF" + << "" + << true; + + addAssignments(); + addExpansions(); // Variable, etc. expansions on RHS + addControlStructs(); // Conditions, loops, custom functions + + QString qindir = QMakeEvaluator::quoteValue(ProString(m_indir)); + addReplaceFunctions(qindir); // Built-in replace functions + addTestFunctions(qindir); // Built-in test functions + + // Some compound tests that verify compatibility with odd Qt 4 edge cases + + QTest::newRow("empty (leading)") + << "defineTest(myMsg) { message(\"$$1\") }\n" + "XMPL = /this/is/a/test\n" + "message(split: $$split(XMPL, /))\n" + "message(split joined:$$split(XMPL, /))\n" + "message(\"split quoted: $$split(XMPL, /)\")\n" + "myMsg(my split: $$split(XMPL, /) :post)\n" + "myMsg(my split joined:$$split(XMPL, /):post)\n" + "myMsg(\"my split quoted: $$split(XMPL, /) post\")\n" + "OUT = word $$split(XMPL, /) done\n" + "message(\"assign split separate: $$OUT\")\n" + "OUT = word:$$split(XMPL, /):done\n" + "message(\"assign split joined: $$OUT\")\n" + "OUT = \"word $$split(XMPL, /) done\"\n" + "message(\"assign split quoted: $$OUT\")\n" + << "" + << "Project MESSAGE: split: this is a test\n" + "Project MESSAGE: split joined: this is a test\n" + "Project MESSAGE: split quoted: this is a test\n" + "Project MESSAGE: my split: this is a test :post\n" + "Project MESSAGE: my split joined: this is a test:post\n" + "Project MESSAGE: my split quoted: this is a test post\n" + "Project MESSAGE: assign split separate: word this is a test done\n" + "Project MESSAGE: assign split joined: word: this is a test:done\n" + "Project MESSAGE: assign split quoted: word this is a test done" + << true; + + QTest::newRow("empty (multiple)") + << "defineTest(myMsg) { message(\"$$1\") }\n" + "XMPL = //this///is/a/////test\n" + "message(split: $$split(XMPL, /) :post)\n" + "message(split joined:$$split(XMPL, /):post)\n" + "message(\"split quoted: $$split(XMPL, /) post\")\n" + "myMsg(my split: $$split(XMPL, /) :post)\n" + "myMsg(my split joined:$$split(XMPL, /):post)\n" + "myMsg(\"my split quoted: $$split(XMPL, /) post\")\n" + "OUT = word $$split(XMPL, /) done\n" + "message(\"assign split separate: $$OUT\")\n" + "OUT = word:$$split(XMPL, /):done\n" + "message(\"assign split joined: $$OUT\")\n" + "OUT = \"word $$split(XMPL, /) done\"\n" + "message(\"assign split quoted: $$OUT\")\n" + << "" + << "Project MESSAGE: split: this is a test :post\n" + "Project MESSAGE: split joined: this is a test:post\n" + "Project MESSAGE: split quoted: this is a test post\n" + "Project MESSAGE: my split: this is a test :post\n" + "Project MESSAGE: my split joined: this is a test:post\n" + "Project MESSAGE: my split quoted: this is a test post\n" + "Project MESSAGE: assign split separate: word this is a test done\n" + "Project MESSAGE: assign split joined: word: this is a test:done\n" + "Project MESSAGE: assign split quoted: word this is a test done" + << true; +} + +static QString formatValue(const ProStringList &vals) +{ + QString ret; + + foreach (const ProString &str, vals) { + ret += QLatin1Char(' '); + ret += QMakeEvaluator::quoteValue(str); + } + return ret; +} + +static void skipNoise(const ushort *&tokPtr) +{ + forever { + ushort tok = *tokPtr; + if (tok != TokLine) + break; + tokPtr += 2; + } +} + +static bool compareState(QMakeEvaluator *eval, ProFile *out) +{ + bool ret = true; + const ushort *tokPtr = out->tokPtr(); + forever { + skipNoise(tokPtr); + ushort tok = *tokPtr++; + if (!tok) + break; + if (tok != TokHashLiteral) { + qWarning("Expected output is malformed: not variable%s", + qPrintable(QMakeParser::formatProBlock(out->items()))); + return false; + } + const ProKey &var = out->getHashStr(tokPtr); + tok = *tokPtr++; + if (tok != TokAssign) { + qWarning("Expected output is malformed: not assignment%s", + qPrintable(QMakeParser::formatProBlock(out->items()))); + return false; + } + ProStringList value; + value.reserve(*tokPtr++); + forever { + skipNoise(tokPtr); + tok = *tokPtr++; + if (tok == TokValueTerminator) + break; + if (tok != (TokLiteral | TokNewStr)) { + qWarning("Expected output is malformed: not literal%s", + qPrintable(QMakeParser::formatProBlock(out->items()))); + return false; + } + value << out->getStr(tokPtr); + } + ProValueMap::Iterator it; + ProValueMap *vmap = eval->findValues(var, &it); + if (value.length() == 1 && value.at(0) == "UNDEF") { + if (vmap) { + qWarning("Value of %s is incorrect.\n Actual:%s\nExpected: ", + qPrintable(var.toQString()), + qPrintable(formatValue(*it))); + ret = false; + } + } else { + if (!vmap) { + qWarning("Value of %s is incorrect.\n Actual: \nExpected:%s", + qPrintable(var.toQString()), + qPrintable(formatValue(value))); + ret = false; + } else if (*it != value) { + qWarning("Value of %s is incorrect.\n Actual:%s\nExpected:%s", + qPrintable(var.toQString()), + qPrintable(formatValue(*it)), qPrintable(formatValue(value))); + ret = false; + } + } + } + return ret; +} + +void tst_qmakelib::proEval() +{ + QFETCH(QString, in); + QFETCH(QString, out); + QFETCH(QString, msgs); + QFETCH(bool, ok); + + QString infile = m_indir + "/test.pro"; + bool verified = true; + QMakeTestHandler handler; + handler.setExpectedMessages(msgs.replace("##:", infile + ':').split('\n', QString::SkipEmptyParts)); + QMakeVfs vfs; + QMakeParser parser(0, &vfs, &handler); + QMakeGlobals globals; + globals.do_cache = false; + globals.xqmakespec = "fake-g++"; + globals.environment = m_env; + globals.setProperties(m_prop); + globals.setDirectories(m_indir, m_outdir); + ProFile *outPro = parser.parsedProBlock(out, "out", 1, QMakeParser::FullGrammar); + if (!outPro->isOk()) { + qWarning("Expected output is malformed"); + verified = false; + } + ProFile *pro = parser.parsedProBlock(in, infile, 1, QMakeParser::FullGrammar); + QMakeEvaluator visitor(&globals, &parser, &vfs, &handler); + visitor.setOutputDir(m_outdir); +#ifdef Q_OS_WIN + visitor.m_dirSep = ProString("\\"); +#else + visitor.m_dirSep = ProString("/"); +#endif + QMakeEvaluator::VisitReturn ret + = visitor.visitProFile(pro, QMakeHandler::EvalAuxFile, QMakeEvaluator::LoadProOnly); + if (handler.printedMessages()) { + qWarning("Got unexpected message(s)"); + verified = false; + } + QStringList missingMsgs = handler.expectedMessages(); + if (!missingMsgs.isEmpty()) { + foreach (const QString &msg, missingMsgs) + qWarning("Missing message: %s", qPrintable(msg)); + verified = false; + } + if ((ret == QMakeEvaluator::ReturnTrue) != ok) { + static const char * const lbl[] = { "failure", "success" }; + qWarning("Expected %s, got %s", lbl[int(ok)], lbl[1 - int(ok)]); + verified = false; + } + if (!compareState(&visitor, outPro)) + verified = false; + pro->deref(); + outPro->deref(); + QVERIFY(verified); +} diff --git a/tests/auto/tools/qmakelib/parsertest.cpp b/tests/auto/tools/qmakelib/parsertest.cpp index 35c0d8261a..a7b7431a98 100644 --- a/tests/auto/tools/qmakelib/parsertest.cpp +++ b/tests/auto/tools/qmakelib/parsertest.cpp @@ -1956,7 +1956,7 @@ void tst_qmakelib::proParser() QFETCH(bool, ok); bool verified = true; - QMakeHandler handler; + QMakeTestHandler handler; handler.setExpectedMessages(msgs.split('\n', QString::SkipEmptyParts)); QMakeVfs vfs; QMakeParser parser(0, &vfs, &handler); diff --git a/tests/auto/tools/qmakelib/qmakelib.pro b/tests/auto/tools/qmakelib/qmakelib.pro index 41aae95068..f1b8dfef3d 100644 --- a/tests/auto/tools/qmakelib/qmakelib.pro +++ b/tests/auto/tools/qmakelib/qmakelib.pro @@ -12,9 +12,13 @@ HEADERS += \ SOURCES += \ tst_qmakelib.cpp \ parsertest.cpp \ + evaltest.cpp \ ioutils.cpp \ proitems.cpp \ qmakevfs.cpp \ - qmakeparser.cpp + qmakeparser.cpp \ + qmakeglobals.cpp \ + qmakebuiltins.cpp \ + qmakeevaluator.cpp -DEFINES += PROPARSER_DEBUG +DEFINES += PROPARSER_DEBUG PROEVALUATOR_FULL PROEVALUATOR_SETENV diff --git a/tests/auto/tools/qmakelib/testdata/cat/file1.txt b/tests/auto/tools/qmakelib/testdata/cat/file1.txt new file mode 100644 index 0000000000..e3e4cd41b6 --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/cat/file1.txt @@ -0,0 +1,2 @@ +"Hello, world." +foo bar baz diff --git a/tests/auto/tools/qmakelib/testdata/cat/file2.txt b/tests/auto/tools/qmakelib/testdata/cat/file2.txt new file mode 100644 index 0000000000..18483311e6 --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/cat/file2.txt @@ -0,0 +1,5 @@ +foo bar baz +"Hello, ' world." post +'Hello, " world.' post +\" \' \\ \a \ nix +" " diff --git a/tests/auto/tools/qmakelib/testdata/files/dir/file1.txt b/tests/auto/tools/qmakelib/testdata/files/dir/file1.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/tools/qmakelib/testdata/files/dir/file2.txt b/tests/auto/tools/qmakelib/testdata/files/dir/file2.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/tools/qmakelib/testdata/files/file1.txt b/tests/auto/tools/qmakelib/testdata/files/file1.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/tools/qmakelib/testdata/files/file2.txt b/tests/auto/tools/qmakelib/testdata/files/file2.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/tools/qmakelib/testdata/files/other.txt b/tests/auto/tools/qmakelib/testdata/files/other.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/tools/qmakelib/testdata/fromfile/badfile.prx b/tests/auto/tools/qmakelib/testdata/fromfile/badfile.prx new file mode 100644 index 0000000000..a916f21587 --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/fromfile/badfile.prx @@ -0,0 +1 @@ +error("fail!") diff --git a/tests/auto/tools/qmakelib/testdata/fromfile/infile.prx b/tests/auto/tools/qmakelib/testdata/fromfile/infile.prx new file mode 100644 index 0000000000..821cb5cb2c --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/fromfile/infile.prx @@ -0,0 +1 @@ +DEFINES = QT_DLL diff --git a/tests/auto/tools/qmakelib/testdata/include/inc.pri b/tests/auto/tools/qmakelib/testdata/include/inc.pri new file mode 100644 index 0000000000..1f1b3a287f --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/include/inc.pri @@ -0,0 +1,8 @@ +VAR = val +.VAR = nope + +fake-*: MATCH = 1 + +defineTest(func) { + message("say hi!") +} diff --git a/tests/auto/tools/qmakelib/testdata/mkspecs/fake-g++/qmake.conf b/tests/auto/tools/qmakelib/testdata/mkspecs/fake-g++/qmake.conf new file mode 100644 index 0000000000..d7a17d2429 --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/mkspecs/fake-g++/qmake.conf @@ -0,0 +1 @@ +# Nothing here diff --git a/tests/auto/tools/qmakelib/testdata/mkspecs/features/default_post.prf b/tests/auto/tools/qmakelib/testdata/mkspecs/features/default_post.prf new file mode 100644 index 0000000000..d7a17d2429 --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/mkspecs/features/default_post.prf @@ -0,0 +1 @@ +# Nothing here diff --git a/tests/auto/tools/qmakelib/testdata/mkspecs/features/default_pre.prf b/tests/auto/tools/qmakelib/testdata/mkspecs/features/default_pre.prf new file mode 100644 index 0000000000..d7a17d2429 --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/mkspecs/features/default_pre.prf @@ -0,0 +1 @@ +# Nothing here diff --git a/tests/auto/tools/qmakelib/testdata/mkspecs/features/spec_post.prf b/tests/auto/tools/qmakelib/testdata/mkspecs/features/spec_post.prf new file mode 100644 index 0000000000..d7a17d2429 --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/mkspecs/features/spec_post.prf @@ -0,0 +1 @@ +# Nothing here diff --git a/tests/auto/tools/qmakelib/testdata/mkspecs/features/spec_pre.prf b/tests/auto/tools/qmakelib/testdata/mkspecs/features/spec_pre.prf new file mode 100644 index 0000000000..d7a17d2429 --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/mkspecs/features/spec_pre.prf @@ -0,0 +1 @@ +# Nothing here diff --git a/tests/auto/tools/qmakelib/testdata/mkspecs/features/testfeat.prf b/tests/auto/tools/qmakelib/testdata/mkspecs/features/testfeat.prf new file mode 100644 index 0000000000..57c9a0d783 --- /dev/null +++ b/tests/auto/tools/qmakelib/testdata/mkspecs/features/testfeat.prf @@ -0,0 +1 @@ +VAR = foo bar diff --git a/tests/auto/tools/qmakelib/tst_qmakelib.cpp b/tests/auto/tools/qmakelib/tst_qmakelib.cpp index 5caa730a19..3da48815fb 100644 --- a/tests/auto/tools/qmakelib/tst_qmakelib.cpp +++ b/tests/auto/tools/qmakelib/tst_qmakelib.cpp @@ -37,6 +37,27 @@ using namespace QMakeInternal; +void tst_qmakelib::initTestCase() +{ + m_indir = QFINDTESTDATA("testdata"); + m_outdir = m_indir + QLatin1String("_build"); + m_env.insert(QStringLiteral("E1"), QStringLiteral("env var")); +#ifdef Q_OS_WIN + m_env.insert(QStringLiteral("COMSPEC"), qgetenv("COMSPEC")); +#endif + m_prop.insert(ProKey("P1"), ProString("prop val")); + m_prop.insert(ProKey("QT_HOST_DATA/get"), ProString(m_indir)); + + QVERIFY(!m_indir.isEmpty()); + QVERIFY(QDir(m_outdir).removeRecursively()); + QVERIFY(QDir().mkpath(m_outdir)); +} + +void tst_qmakelib::cleanupTestCase() +{ + QVERIFY(QDir(m_outdir).removeRecursively()); +} + void tst_qmakelib::proString() { QString qs1(QStringLiteral("this is a string")); @@ -225,21 +246,24 @@ void tst_qmakelib::pathUtils() QCOMPARE(IoUtils::resolvePath(fnbase, fn1), QStringLiteral("/a/unix/file/path")); } -void QMakeHandler::print(const QString &fileName, int lineNo, int type, const QString &msg) +void QMakeTestHandler::print(const QString &fileName, int lineNo, int type, const QString &msg) { QString pfx = ((type & QMakeParserHandler::CategoryMask) == QMakeParserHandler::WarningMessage) ? QString::fromLatin1("WARNING: ") : QString(); - QString out; if (lineNo) - out = QStringLiteral("%1%2:%3: %4").arg(pfx, fileName, QString::number(lineNo), msg); + doPrint(QStringLiteral("%1%2:%3: %4").arg(pfx, fileName, QString::number(lineNo), msg)); else - out = QStringLiteral("%1%2").arg(pfx, msg); - if (!expected.isEmpty() && expected.first() == out) { + doPrint(QStringLiteral("%1%2").arg(pfx, msg)); +} + +void QMakeTestHandler::doPrint(const QString &msg) +{ + if (!expected.isEmpty() && expected.first() == msg) { expected.removeAt(0); - return; + } else { + qWarning("%s", qPrintable(msg)); + printed = true; } - qWarning("%s", qPrintable(out)); - printed = true; } QTEST_MAIN(tst_qmakelib) diff --git a/tests/auto/tools/qmakelib/tst_qmakelib.h b/tests/auto/tools/qmakelib/tst_qmakelib.h index e84b1319d0..c4716ca65e 100644 --- a/tests/auto/tools/qmakelib/tst_qmakelib.h +++ b/tests/auto/tools/qmakelib/tst_qmakelib.h @@ -31,9 +31,10 @@ ** ****************************************************************************/ -#include +#include #include +#include #include class tst_qmakelib : public QObject @@ -45,6 +46,9 @@ public: virtual ~tst_qmakelib() {} private slots: + void initTestCase(); + void cleanupTestCase(); + void quoteArgUnix_data(); void quoteArgUnix(); void quoteArgWin_data(); @@ -57,6 +61,9 @@ private slots: void proParser_data(); void proParser(); + void proEval_data(); + void proEval(); + private: void addParseOperators(); void addParseValues(); @@ -65,14 +72,30 @@ private: void addParseBraces(); void addParseCustomFunctions(); void addParseAbuse(); + + void addAssignments(); + void addExpansions(); + void addControlStructs(); + void addReplaceFunctions(const QString &qindir); + void addTestFunctions(const QString &qindir); + + QProcessEnvironment m_env; + QHash m_prop; + QString m_indir, m_outdir; }; -class QMakeHandler : public QMakeParserHandler { +class QMakeTestHandler : public QMakeHandler { public: - QMakeHandler() : QMakeParserHandler(), printed(false) {} + QMakeTestHandler() : QMakeHandler(), printed(false) {} virtual void message(int type, const QString &msg, const QString &fileName, int lineNo) { print(fileName, lineNo, type, msg); } + virtual void fileMessage(const QString &msg) + { doPrint(msg); } + + virtual void aboutToEval(ProFile *, ProFile *, EvalFileType) {} + virtual void doneWithEval(ProFile *) {} + void setExpectedMessages(const QStringList &msgs) { expected = msgs; } QStringList expectedMessages() const { return expected; } @@ -80,7 +103,9 @@ public: private: void print(const QString &fileName, int lineNo, int type, const QString &msg); + void doPrint(const QString &msg); QStringList expected; bool printed; }; + -- cgit v1.2.3 From 8175e31bda60eb45ae867b0d2c4b6a4fb179c365 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 30 Apr 2015 16:52:21 +0200 Subject: remove now redundant tests the functionality is now covered by the qmakelib test. Change-Id: Id627f573fb247ff3b86558509e27b6a9862c1a59 Reviewed-by: Joerg Bornemann --- .../tools/qmake/testdata/comments/comments.pro | 31 ---- .../qmake/testdata/func_export/func_export.pro | 19 --- .../testdata/func_variables/func_variables.pro | 49 ------ tests/auto/tools/qmake/testdata/functions/1.cpp | 32 ---- tests/auto/tools/qmake/testdata/functions/2.cpp | 32 ---- .../tools/qmake/testdata/functions/functions.pro | 184 --------------------- .../tools/qmake/testdata/functions/infiletest.pro | 1 - .../auto/tools/qmake/testdata/functions/one/1.cpp | 32 ---- .../auto/tools/qmake/testdata/functions/one/2.cpp | 32 ---- tests/auto/tools/qmake/testdata/functions/textfile | 1 - .../qmake/testdata/functions/three/wildcard21.cpp | 32 ---- .../qmake/testdata/functions/three/wildcard22.cpp | 32 ---- .../auto/tools/qmake/testdata/functions/two/1.cpp | 32 ---- .../auto/tools/qmake/testdata/functions/two/2.cpp | 32 ---- .../tools/qmake/testdata/functions/wildcard21.cpp | 32 ---- .../tools/qmake/testdata/functions/wildcard22.cpp | 32 ---- .../testdata/include_function/existing_file.pri | 3 - .../include_function/include_existing_file.pro | 7 - .../include_function/include_missing_file.pro | 3 - .../include_function/include_missing_file2.pro | 3 - .../tools/qmake/testdata/include_function/main.cpp | 37 ----- tests/auto/tools/qmake/testdata/json/json.pro | 26 --- tests/auto/tools/qmake/testdata/json/test.json | 9 - .../tools/qmake/testdata/operators/operators.pro | 23 --- .../tools/qmake/testdata/variables/variables.pro | 12 -- tests/auto/tools/qmake/tst_qmake.cpp | 93 ----------- 26 files changed, 821 deletions(-) delete mode 100644 tests/auto/tools/qmake/testdata/comments/comments.pro delete mode 100644 tests/auto/tools/qmake/testdata/func_export/func_export.pro delete mode 100644 tests/auto/tools/qmake/testdata/func_variables/func_variables.pro delete mode 100644 tests/auto/tools/qmake/testdata/functions/1.cpp delete mode 100644 tests/auto/tools/qmake/testdata/functions/2.cpp delete mode 100644 tests/auto/tools/qmake/testdata/functions/functions.pro delete mode 100644 tests/auto/tools/qmake/testdata/functions/infiletest.pro delete mode 100644 tests/auto/tools/qmake/testdata/functions/one/1.cpp delete mode 100644 tests/auto/tools/qmake/testdata/functions/one/2.cpp delete mode 100644 tests/auto/tools/qmake/testdata/functions/textfile delete mode 100644 tests/auto/tools/qmake/testdata/functions/three/wildcard21.cpp delete mode 100644 tests/auto/tools/qmake/testdata/functions/three/wildcard22.cpp delete mode 100644 tests/auto/tools/qmake/testdata/functions/two/1.cpp delete mode 100644 tests/auto/tools/qmake/testdata/functions/two/2.cpp delete mode 100644 tests/auto/tools/qmake/testdata/functions/wildcard21.cpp delete mode 100644 tests/auto/tools/qmake/testdata/functions/wildcard22.cpp delete mode 100644 tests/auto/tools/qmake/testdata/include_function/existing_file.pri delete mode 100644 tests/auto/tools/qmake/testdata/include_function/include_existing_file.pro delete mode 100644 tests/auto/tools/qmake/testdata/include_function/include_missing_file.pro delete mode 100644 tests/auto/tools/qmake/testdata/include_function/include_missing_file2.pro delete mode 100644 tests/auto/tools/qmake/testdata/include_function/main.cpp delete mode 100644 tests/auto/tools/qmake/testdata/json/json.pro delete mode 100644 tests/auto/tools/qmake/testdata/json/test.json delete mode 100644 tests/auto/tools/qmake/testdata/operators/operators.pro delete mode 100644 tests/auto/tools/qmake/testdata/variables/variables.pro diff --git a/tests/auto/tools/qmake/testdata/comments/comments.pro b/tests/auto/tools/qmake/testdata/comments/comments.pro deleted file mode 100644 index 510ab95ab3..0000000000 --- a/tests/auto/tools/qmake/testdata/comments/comments.pro +++ /dev/null @@ -1,31 +0,0 @@ -LIST = 1 2 3 4 #a comment -!equals( LIST, 1 2 3 4 ) { - message( "FAILED: inline comment" ) -} - -LIST = 1 \ - 2 \ -# 3 \ - 4 -!equals( LIST, 1 2 4 ) { - message( "FAILED: commented out continuation" ) -} - -LIST = 1 \ - 2 \#comment - 3 \ - 4 -!equals( LIST, 1 2 3 4 ) { - message( "FAILED: comment at end of continuation") -} - - -LIST = 1 2 3 4#comment -!equals( LIST, 1 2 3 4 ) { - message( "FAILED: no space before comment" ) -} - -LIST = 1 2 3 4$${LITERAL_HASH}five -!equals( LIST, 1 2 3 4$${LITERAL_HASH}five ) { - message( "FAILED: using LITERAL_HASH" ) -} diff --git a/tests/auto/tools/qmake/testdata/func_export/func_export.pro b/tests/auto/tools/qmake/testdata/func_export/func_export.pro deleted file mode 100644 index fc3818985b..0000000000 --- a/tests/auto/tools/qmake/testdata/func_export/func_export.pro +++ /dev/null @@ -1,19 +0,0 @@ -defineTest(doExport) { - EXPORTED += $$1 - export(EXPORTED) -} - -defineTest(callDoExport) { - doExport(bar) - doExport(baz) - EXPORTED = oink - !isEqual(EXPORTED, "oink") { - message( "FAILED: function-scope exports [$$EXPORTED] != oink" ) - } -} - -doExport(foo) -callDoExport() -!isEqual(EXPORTED, "foo bar baz") { - message( "FAILED: global-scope exports [$$EXPORTED] != foo bar baz" ) -} diff --git a/tests/auto/tools/qmake/testdata/func_variables/func_variables.pro b/tests/auto/tools/qmake/testdata/func_variables/func_variables.pro deleted file mode 100644 index cc13437f4a..0000000000 --- a/tests/auto/tools/qmake/testdata/func_variables/func_variables.pro +++ /dev/null @@ -1,49 +0,0 @@ -defineTest(testVariable) { - varname=$$1 - value=$$eval($$varname) - RESULT=$$value - export(RESULT) -} - -defineTest(callTest) { - myvar=$$1 - testVariable(myvar) -} - -defineTest(callTestExport) { - myvar=$$1 - export(myvar) - testVariable(myvar) -} - -defineTest(callTestExportChange) { - myvar=foo - export(myvar) - myvar=$$1 - testVariable(myvar) -} - -value=direct -myvar=$$value -testVariable(myvar) -!isEqual(RESULT,$$value) { - message( "FAILED: result [$$RESULT] != $$value" ) -} - -value=export -callTestExport($$value) -!isEqual(RESULT,$$value) { - message( "FAILED: result [$$RESULT] != $$value" ) -} - -value=export_and_change -callTestExportChange($$value) -!isEqual(RESULT,$$value) { - message( "FAILED: result [$$RESULT] != $$value" ) -} - -value=local -callTest($$value) -!isEqual(RESULT,$$value) { - message( "FAILED: result [$$RESULT] != $$value" ) -} diff --git a/tests/auto/tools/qmake/testdata/functions/1.cpp b/tests/auto/tools/qmake/testdata/functions/1.cpp deleted file mode 100644 index 8bdc2e59e8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/1.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ diff --git a/tests/auto/tools/qmake/testdata/functions/2.cpp b/tests/auto/tools/qmake/testdata/functions/2.cpp deleted file mode 100644 index 8bdc2e59e8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/2.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ diff --git a/tests/auto/tools/qmake/testdata/functions/functions.pro b/tests/auto/tools/qmake/testdata/functions/functions.pro deleted file mode 100644 index 5db8036188..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/functions.pro +++ /dev/null @@ -1,184 +0,0 @@ -VAR = qt thread - -defineTest(testReplace) { - !isEqual(1, $$2):message("FAILED: $$3: got $$1, expected $${2}.") -} - -#count -!count( VAR, 2 ) { - message( "FAILED: count function: $$VAR" ) -} - -#contains -!contains( VAR, thread ) { - message( "FAILED: contains function: $$VAR" ) -} - -#exists -!exists( functions.pro ) { - message( "FAILED: exists function" ) -} - -#isEmpty -isEmpty( VAR ) { - message( "FAILED: isEmpty function: $VAR" ) -} - -#files -!equals($$list($$files(one/*.cpp)), "one/1.cpp one/2.cpp") { - message( "FAILED: files function: one/*.cpp" ) -} -!equals($$list($$files(one/1*.cpp)), "one/1.cpp") { - message( "FAILED: files function: one/1*.cpp" ) -} -!equals($$list($$files(two/*.cpp)), "two/1.cpp two/2.cpp") { - message( "FAILED: files function: two/*.cpp" ) -} -!equals($$list($$files(three/wildcard*.cpp)), "three/wildcard21.cpp three/wildcard22.cpp") { - message( "FAILED: files function: three/wildcard*.cpp" ) -} -!equals($$list($$files(*.cpp)), "1.cpp 2.cpp wildcard21.cpp wildcard22.cpp") { - message( "FAILED: files function: *.cpp" ) -} -!equals($$list($$files(wildcard*.cpp)), "wildcard21.cpp wildcard22.cpp") { - message( "FAILED: files function: wildcard*.cpp" ) -} - -#infile -!infile( infiletest.pro, DEFINES, QT_DLL ){ - message( "FAILED: infile function" ) -} - -#include -include( infiletest.pro, "", true ) -!contains( DEFINES, QT_DLL ) { - message( "FAILED: include function: $$DEFINES" ) -} - -#replace -VERSION=1.0.0 -VERSION_replaced=$$replace(VERSION,\\.,_) -!isEqual(VERSION_replaced, 1_0_0) { - message( "FAILED: replace function: $$VERSION_replaced" ) -} - -#test functions -defineTest(myTestFunction) { - RESULT = - list=$$1 - for(l, list) { - RESULT += $$l - } - export(RESULT) -} -myTestFunction(oink baa moo) -!equals($$list($$member(RESULT, 0)), "oink") { - message("FAILED: myTestFunction: $$RESULT") -} -myTestFunction("oink baa" moo) -!equals($$list($$member(RESULT, 0)), "oink baa") { - message("FAILED: myTestFunction: $$RESULT") -} -myTestFunction(oink "baa moo") -!equals($$list($$member(RESULT, 0)), "oink") { - message("FAILED: myTestFunction: $$RESULT") -} -myTestFunction("oink baa moo") -!equals($$list($$member(RESULT, 0)), "oink baa moo") { - message("FAILED: myTestFunction: $$RESULT") -} - -#recursive -defineReplace(myRecursiveReplaceFunction) { - RESULT = - list = $$1 - RESULT += $$member(list, 0) - list -= $$RESULT - !isEmpty(list):RESULT += $$myRecursiveReplaceFunction($$list) - return($$RESULT) -} -RESULT = $$myRecursiveReplaceFunction(oink baa moo) -!isEqual(RESULT, "oink baa moo") { - message( "FAILED: myRecursiveReplaceFunction [$$RESULT] != oink baa moo" ) -} - -moo = "this is a test" "for real" -fn = $$OUT_PWD/testdir/afile -write_file($$fn, moo)|message("FAILED: write_file() failed") -exists($$fn)|message("FAILED: write_file() didn't write anything") -mooout = $$cat($$fn, line) -equals(moo, $$mooout)|message("FAILED: write_file() wrote something wrong") -moo += "another line" -write_file($$fn, moo)|message("FAILED: write_file() failed (take 2)") -mooout = $$cat($$fn, line) -equals(moo, $$mooout)|message("FAILED: write_file() wrote something wrong (take 2)") -mooadd = "yet another line" -write_file($$fn, mooadd, append)|message("FAILED: write_file() failed (append)") -moo += $$mooadd -mooout = $$cat($$fn, line) -equals(moo, $$mooout)|message("FAILED: write_file() wrote something wrong when appending") - -pn = $$OUT_PWD/testpath/subdir -mkpath($$pn)|message("FAILED: mkpath() failed") -exists($$pn)|message("FAILED: mkpath() didn't create anything") - -in = easy "less easy" sca$${LITERAL_HASH}ry crazy$$escape_expand(\\t\\r\\n) $$escape_expand(\\t)shit \'no\"way\\here -out = "easy \"less easy\" sca\$\${LITERAL_HASH}ry crazy\$\$escape_expand(\\\\t\\\\r\\\\n) \$\$escape_expand(\\\\t)shit \\\'no\\\"way\\\\here" -testReplace($$val_escape(in), $$out, "val_escape") - -testReplace($$shadowed($$PWD/something), $$OUT_PWD/something, "shadowed") -testReplace($$shadowed($$PWD), $$OUT_PWD, "shadowed (take 2)") - -#format_number -spc = " " -testReplace($$format_number(13), 13, "simple number format") -testReplace($$format_number(-13), -13, "negative number format") -testReplace($$format_number(13, ibase=16), 19, "hex input number format") -testReplace($$format_number(13, obase=16), d, "hex output number format") -testReplace($$format_number(13, width=5), " $$spc 13", "right aligned number format") -testReplace($$format_number(13, width=5 leftalign), "13 $$spc ", "left aligned number format") -testReplace($$format_number(13, width=5 zeropad), "00013", "zero-padded number format") -testReplace($$format_number(13, width=5 alwayssign), "$$spc +13", "always signed number format") -testReplace($$format_number(13, width=5 alwayssign zeropad), "+0013", "zero-padded always signed number format") -testReplace($$format_number(13, width=5 padsign), " $$spc 13", "sign-padded number format") -testReplace($$format_number(13, width=5 padsign zeropad), " 0013", "zero-padded sign-padded number format") - -testReplace($$clean_path("c:$${DIR_SEPARATOR}crazy//path/../trolls"), "c:/crazy/trolls", "clean_path") - -testReplace($$shell_path("/crazy/trolls"), "$${QMAKE_DIR_SEP}crazy$${QMAKE_DIR_SEP}trolls", "shell_path") -testReplace($$system_path("/crazy/trolls"), "$${DIR_SEPARATOR}crazy$${DIR_SEPARATOR}trolls", "system_path") - -testReplace($$absolute_path("crazy/trolls"), "$$PWD/crazy/trolls", "absolute_path") -testReplace($$absolute_path("crazy/trolls", "/fake/path"), "/fake/path/crazy/trolls", "absolute_path with base") -testReplace($$absolute_path(""), "$$PWD", "absolute_path of empty") -testReplace($$relative_path($$_PRO_FILE_PWD_), $$basename($$_PRO_FILE_), "relative_path") -testReplace($$relative_path("/fake/trolls", "/fake/path"), "../trolls", "relative_path with base") -testReplace($$relative_path(""), "", "relative_path of empty") - -#this test is very rudimentary. the backend function is thoroughly tested in qt creator -in = "some nasty & ugly\" path & thing\\" -out_cmd = "\"some nasty & ugly\\\" path ^& thing\\\\^\"" -out_sh = "'some nasty & ugly\" path & thing\\'" -equals(QMAKE_HOST.os, Windows): \ - out = $$out_cmd -else: \ - out = $$out_sh -testReplace($$system_quote($$in), $$out, "system_quote") -!equals(QMAKE_DIR_SEP, /): \ - out = $$out_cmd -else: \ - out = $$out_sh -testReplace($$shell_quote($$in), $$out, "shell_quote") - -testReplace($$reverse($$list(one two three)), three two one, "reverse") - -testReplace($$cat(textfile), hi '"holla he"' 'hu!') - -MOD.a.depends = -MOD.b.depends = -MOD.b.priority = 1 -MOD.c.depends = a b -testReplace($$resolve_depends($$list(c), "MOD."), c b a) -MOD.a.priority = 1 -MOD.b.priority = 0 -testReplace($$resolve_depends($$list(c), "MOD."), c a b) diff --git a/tests/auto/tools/qmake/testdata/functions/infiletest.pro b/tests/auto/tools/qmake/testdata/functions/infiletest.pro deleted file mode 100644 index 821cb5cb2c..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/infiletest.pro +++ /dev/null @@ -1 +0,0 @@ -DEFINES = QT_DLL diff --git a/tests/auto/tools/qmake/testdata/functions/one/1.cpp b/tests/auto/tools/qmake/testdata/functions/one/1.cpp deleted file mode 100644 index 8bdc2e59e8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/one/1.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ diff --git a/tests/auto/tools/qmake/testdata/functions/one/2.cpp b/tests/auto/tools/qmake/testdata/functions/one/2.cpp deleted file mode 100644 index 8bdc2e59e8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/one/2.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ diff --git a/tests/auto/tools/qmake/testdata/functions/textfile b/tests/auto/tools/qmake/testdata/functions/textfile deleted file mode 100644 index a8248ed6f8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/textfile +++ /dev/null @@ -1 +0,0 @@ -hi "holla he" hu! diff --git a/tests/auto/tools/qmake/testdata/functions/three/wildcard21.cpp b/tests/auto/tools/qmake/testdata/functions/three/wildcard21.cpp deleted file mode 100644 index 8bdc2e59e8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/three/wildcard21.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ diff --git a/tests/auto/tools/qmake/testdata/functions/three/wildcard22.cpp b/tests/auto/tools/qmake/testdata/functions/three/wildcard22.cpp deleted file mode 100644 index 8bdc2e59e8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/three/wildcard22.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ diff --git a/tests/auto/tools/qmake/testdata/functions/two/1.cpp b/tests/auto/tools/qmake/testdata/functions/two/1.cpp deleted file mode 100644 index 8bdc2e59e8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/two/1.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ diff --git a/tests/auto/tools/qmake/testdata/functions/two/2.cpp b/tests/auto/tools/qmake/testdata/functions/two/2.cpp deleted file mode 100644 index 8bdc2e59e8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/two/2.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ diff --git a/tests/auto/tools/qmake/testdata/functions/wildcard21.cpp b/tests/auto/tools/qmake/testdata/functions/wildcard21.cpp deleted file mode 100644 index 8bdc2e59e8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/wildcard21.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ diff --git a/tests/auto/tools/qmake/testdata/functions/wildcard22.cpp b/tests/auto/tools/qmake/testdata/functions/wildcard22.cpp deleted file mode 100644 index 8bdc2e59e8..0000000000 --- a/tests/auto/tools/qmake/testdata/functions/wildcard22.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ diff --git a/tests/auto/tools/qmake/testdata/include_function/existing_file.pri b/tests/auto/tools/qmake/testdata/include_function/existing_file.pri deleted file mode 100644 index 8b9aaca340..0000000000 --- a/tests/auto/tools/qmake/testdata/include_function/existing_file.pri +++ /dev/null @@ -1,3 +0,0 @@ -QT = -CONFIG = console -SOURCES = main.cpp diff --git a/tests/auto/tools/qmake/testdata/include_function/include_existing_file.pro b/tests/auto/tools/qmake/testdata/include_function/include_existing_file.pro deleted file mode 100644 index 424062a9ac..0000000000 --- a/tests/auto/tools/qmake/testdata/include_function/include_existing_file.pro +++ /dev/null @@ -1,7 +0,0 @@ -# Test to see if include(), by default, succeeds when the specific file -# to include exists -include(existing_file.pri) - -# Test to see if by specifying full set of parameters to include() -# succeeds when the specified filed to include exists -include(existing_file.pri, "", false) diff --git a/tests/auto/tools/qmake/testdata/include_function/include_missing_file.pro b/tests/auto/tools/qmake/testdata/include_function/include_missing_file.pro deleted file mode 100644 index 0b59981240..0000000000 --- a/tests/auto/tools/qmake/testdata/include_function/include_missing_file.pro +++ /dev/null @@ -1,3 +0,0 @@ -# Test to see if include(), by default, fails when the specific file -# to include does not exist -include(missing_file.pri) diff --git a/tests/auto/tools/qmake/testdata/include_function/include_missing_file2.pro b/tests/auto/tools/qmake/testdata/include_function/include_missing_file2.pro deleted file mode 100644 index 542b9ff516..0000000000 --- a/tests/auto/tools/qmake/testdata/include_function/include_missing_file2.pro +++ /dev/null @@ -1,3 +0,0 @@ -# Specifying full set of parameters to include() to test that a warning -# is shown for this non-existing file. -include(missing_file.pri, "", false) diff --git a/tests/auto/tools/qmake/testdata/include_function/main.cpp b/tests/auto/tools/qmake/testdata/include_function/main.cpp deleted file mode 100644 index 68e9c98e77..0000000000 --- a/tests/auto/tools/qmake/testdata/include_function/main.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -int main(int /*argc*/, char ** /*argv*/) -{ - return 0; -} diff --git a/tests/auto/tools/qmake/testdata/json/json.pro b/tests/auto/tools/qmake/testdata/json/json.pro deleted file mode 100644 index 33440b3209..0000000000 --- a/tests/auto/tools/qmake/testdata/json/json.pro +++ /dev/null @@ -1,26 +0,0 @@ -jsontext = $$cat($$PWD/test.json) -parseJson(jsontext, json) - -# print all keys -message(json._KEYS_ $${json._KEYS_}) - -# print array -message(json.array._KEYS_ $${json.array._KEYS_}) -for(key, json.array._KEYS_): \ - message(json.array.$${key} $$eval(json.array.$${key})) - -# print object -message(json.object._KEYS_ $${json.object._KEYS_}) -for(key, json.object._KEYS_): \ - message(json.object.$${key} $$eval(json.object.$${key})) - -# print value tyes -message(json.string: $${json.string}) -message(json.number: $${json.number}) -message(json.true: $${json.true}) -message(json.false: $${json.false}) -message(json.null: $${json.null}) - -# check that booleans work -$${json.true}: message(json.true is true) -!$${json.false}: message(json.false is false) diff --git a/tests/auto/tools/qmake/testdata/json/test.json b/tests/auto/tools/qmake/testdata/json/test.json deleted file mode 100644 index cc82908eba..0000000000 --- a/tests/auto/tools/qmake/testdata/json/test.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "array" : ["arrayItem1", "arrayItem2", "arrayItem3"], - "object" : { "key1" : "objectValue1", "key2" : "objectValue2" }, - "string" : "test string", - "number" : 999, - "true" : true, - "false" :false, - "null" : null -} diff --git a/tests/auto/tools/qmake/testdata/operators/operators.pro b/tests/auto/tools/qmake/testdata/operators/operators.pro deleted file mode 100644 index 463fa73d81..0000000000 --- a/tests/auto/tools/qmake/testdata/operators/operators.pro +++ /dev/null @@ -1,23 +0,0 @@ -VAR = qt thread - -VAR += debug -!contains( VAR, debug ) { - message( "FAILED: +=" ) -} - -VAR -= thread -contains( VAR, thread ) { - message( "FAILED: -=" ) -} - -VAR = thread -VAR *= thread -!count( VAR, 1 ) { - message( "FAILED: *=" ) -} - -VAR = thread QT_DLL debug -VAR ~= s/QT_+/Q_ -!contains( VAR, Q_DLL ) { - message( "FAILED: ~=" ) -} diff --git a/tests/auto/tools/qmake/testdata/variables/variables.pro b/tests/auto/tools/qmake/testdata/variables/variables.pro deleted file mode 100644 index e4b9eaa884..0000000000 --- a/tests/auto/tools/qmake/testdata/variables/variables.pro +++ /dev/null @@ -1,12 +0,0 @@ -VAR = 1 2 3 4 5 -JOINEDVAR = $$join( VAR, "-GLUE-", "-BEFORE-", "-AFTER-" ) -!contains( JOINEDVAR, -BEFORE-1-GLUE-2-GLUE-3-GLUE-4-GLUE-5-AFTER- ) { - message( "FAILED: join [$$JOINEDVAR != -BEFORE-1-GLUE-2-GLUE-3-GLUE-4-GLUE-5-AFTER-]" ) -} - -# To test member we need to use join -NEWVAR = $$member( VAR, 4 ) $$member( VAR, 3 ) $$member( VAR, 2 ) -JOINEDNEWVAR = $$join( NEWVAR, "-" ) -!contains( JOINEDNEWVAR, 5-4-3 ) { - message( "FAILED: member [$$JOINEDNEWVAR != 5-4-3]" ) -} diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp index 8d7f7bbc68..da5314c83b 100644 --- a/tests/auto/tools/qmake/tst_qmake.cpp +++ b/tests/auto/tools/qmake/tst_qmake.cpp @@ -60,12 +60,6 @@ private slots: void simple_dll(); void subdirs(); void subdir_via_pro_file_extra_target(); - void functions(); - void operators(); - void variables(); - void func_export(); - void func_variables(); - void comments(); void duplicateLibraryEntries(); void export_across_file_boundaries(); void include_dir(); @@ -80,11 +74,9 @@ private slots: #if defined(Q_OS_MAC) void bundle_spaces(); #endif - void includefunction(); void substitutes(); void project(); void proFileCache(); - void json(); private: TestCompiler test_compiler; @@ -253,43 +245,6 @@ void tst_qmake::subdir_via_pro_file_extra_target() QVERIFY( test_compiler.make( workDir, "extratarget" )); } -void tst_qmake::functions() -{ - QString workDir = base_path + "/testdata/functions"; - QString buildDir = base_path + "/testdata/functions_build"; - QVERIFY( test_compiler.qmake( workDir, "functions", buildDir )); -} - -void tst_qmake::operators() -{ - QString workDir = base_path + "/testdata/operators"; - QVERIFY( test_compiler.qmake( workDir, "operators" )); -} - -void tst_qmake::variables() -{ - QString workDir = base_path + "/testdata/variables"; - QVERIFY(test_compiler.qmake( workDir, "variables" )); -} - -void tst_qmake::func_export() -{ - QString workDir = base_path + "/testdata/func_export"; - QVERIFY(test_compiler.qmake( workDir, "func_export" )); -} - -void tst_qmake::func_variables() -{ - QString workDir = base_path + "/testdata/func_variables"; - QVERIFY(test_compiler.qmake( workDir, "func_variables" )); -} - -void tst_qmake::comments() -{ - QString workDir = base_path + "/testdata/comments"; - QVERIFY(test_compiler.qmake( workDir, "comments" )); -} - void tst_qmake::duplicateLibraryEntries() { QVERIFY(true); @@ -490,26 +445,6 @@ void tst_qmake::bundle_spaces() } #endif // defined(Q_OS_MAC) -void tst_qmake::includefunction() -{ - QString workDir = base_path + "/testdata/include_function"; - QRegExp warningMsg("Cannot read .*: No such file or directory"); - QVERIFY(test_compiler.qmake( workDir, "include_existing_file")); - QVERIFY(!test_compiler.commandOutput().contains(warningMsg)); - - // test include() usage on a missing file - test_compiler.clearCommandOutput(); - workDir = base_path + "/testdata/include_function"; - QVERIFY(test_compiler.qmake( workDir, "include_missing_file" )); - QVERIFY(test_compiler.commandOutput().contains(warningMsg)); - - // test include() usage on a missing file when all function parameters are used - test_compiler.clearCommandOutput(); - workDir = base_path + "/testdata/include_function"; - QVERIFY(test_compiler.qmake( workDir, "include_missing_file2" )); - QVERIFY(test_compiler.commandOutput().contains(warningMsg)); -} - void tst_qmake::substitutes() { QString workDir = base_path + "/testdata/substitutes"; @@ -555,33 +490,5 @@ void tst_qmake::proFileCache() QVERIFY( test_compiler.qmake( workDir, "pro_file_cache" )); } -void tst_qmake::json() -{ - QString workDir = base_path + "/testdata/json"; - QVERIFY( test_compiler.qmake( workDir, "json.pro" )); - QString output = test_compiler.commandOutput(); - - // all keys - QVERIFY(output.contains("json._KEYS_ array false null number object string true")); - // array - QVERIFY(output.contains("json.array._KEYS_ 0 1 2")); - QVERIFY(output.contains("json.array.0 arrayItem1")); - QVERIFY(output.contains("json.array.1 arrayItem2")); - QVERIFY(output.contains("json.array.2 arrayItem3")); - // object - QVERIFY(output.contains("json.object._KEYS_ key1 key2")); - QVERIFY(output.contains("json.object.key1 objectValue1")); - QVERIFY(output.contains("json.object.key1 objectValue1")); - // value types - QVERIFY(output.contains("json.string: test string")); - QVERIFY(output.contains("json.number: 999")); - QVERIFY(output.contains("json.true: true")); - QVERIFY(output.contains("json.false: false")); - QVERIFY(output.contains("json.null:")); - // functional booleans - QVERIFY(output.contains("json.true is true")); - QVERIFY(output.contains("json.false is false")); -} - QTEST_MAIN(tst_qmake) #include "tst_qmake.moc" -- cgit v1.2.3 From 6e3ba36a067f180c530f6c2116a97f78b1bf7cc8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 20 May 2015 10:46:09 +0200 Subject: bundles: create Versions/Current only if versioned resources are present QMAKE_FRAMEWORK_VERSION has a fallback to VER_MAJ (which derives from VERSION), so it's pretty much always set, thus defeating the previous check. amends 6cb495de. Task-number: QTBUG-46215 Change-Id: I2c5560c469617ebeab978e4de78df00baf38d49d Reviewed-by: Joerg Bornemann --- qmake/generators/unix/unixmake2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 9b9e54c461..98a01b21aa 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -932,7 +932,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << mkdir_p_asstring(bundle_dir) << "\n\t" << "@$(SYMLINK) " << escapeFilePath(symIt.value()) << ' ' << bundle_dir_f << endl; } - if (!project->first("QMAKE_FRAMEWORK_VERSION").isEmpty()) { + if (!symlinks.isEmpty()) { QString currentLink = bundle_dir + "Versions/Current"; QString currentLink_f = escapeDependencyPath(currentLink); bundledFiles << currentLink; -- cgit v1.2.3 From 12106b66b927749d0c81d59535d854520e8f26ba Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 20 May 2015 10:48:20 +0200 Subject: move symlinking loop into the symlink container emptiness conditional it obviously makes no sense to set up the loop if the container is empty. as we now have that conditional anyway ... Change-Id: I6d95c0102734852443c188012bfcb076d879581e Reviewed-by: Joerg Bornemann --- qmake/generators/unix/unixmake2.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 98a01b21aa..92a7876784 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -922,17 +922,18 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } } } - QString bundle_dir_f = escapeFilePath(bundle_dir); - QHash::ConstIterator symIt = symlinks.constBegin(), - symEnd = symlinks.constEnd(); - for (; symIt != symEnd; ++symIt) { - bundledFiles << symIt.key(); - alldeps << symIt.key(); - t << escapeDependencyPath(symIt.key()) << ":\n\t" - << mkdir_p_asstring(bundle_dir) << "\n\t" - << "@$(SYMLINK) " << escapeFilePath(symIt.value()) << ' ' << bundle_dir_f << endl; - } if (!symlinks.isEmpty()) { + QString bundle_dir_f = escapeFilePath(bundle_dir); + QHash::ConstIterator symIt = symlinks.constBegin(), + symEnd = symlinks.constEnd(); + for (; symIt != symEnd; ++symIt) { + bundledFiles << symIt.key(); + alldeps << symIt.key(); + t << escapeDependencyPath(symIt.key()) << ":\n\t" + << mkdir_p_asstring(bundle_dir) << "\n\t" + << "@$(SYMLINK) " << escapeFilePath(symIt.value()) << ' ' << bundle_dir_f << endl; + } + QString currentLink = bundle_dir + "Versions/Current"; QString currentLink_f = escapeDependencyPath(currentLink); bundledFiles << currentLink; -- cgit v1.2.3 From d88df1ca6afd9a4a2f1faac4034f5c9539720815 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 20 May 2015 13:30:54 +0200 Subject: allow modules to declare that they have generated private includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ifbd561aab9c6a6634930b525aa1d51b9ad792a09 Reviewed-by: Jørgen Lind --- mkspecs/features/qt_module_pris.prf | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf index 4ce03f4327..1d727847e2 100644 --- a/mkspecs/features/qt_module_pris.prf +++ b/mkspecs/features/qt_module_pris.prf @@ -91,15 +91,22 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri MODULE_PRIVATE_INCLUDES = \$\$QT_MODULE_INCLUDE_BASE/$$MODULE_INCNAME/$$VERSION \ \$\$QT_MODULE_INCLUDE_BASE/$$MODULE_INCNAME/$$VERSION/$$MODULE_INCNAME } - split_incpath: \ + split_incpath { MODULE_SHADOW_INCLUDES = $$replace(MODULE_INCLUDES, ^\\\$\\\$QT_MODULE_INCLUDE_BASE, \ $$MODULE_BASE_OUTDIR/include) + generated_privates: \ + MODULE_SHADOW_PRIVATE_INCLUDES = $$replace(MODULE_PRIVATE_INCLUDES, ^\\\$\\\$QT_MODULE_INCLUDE_BASE, \ + $$MODULE_BASE_OUTDIR/include) + } MODULE_INCLUDES += $$MODULE_AUX_INCLUDES MODULE_PRIVATE_INCLUDES += $$MODULE_PRIVATE_AUX_INCLUDES internal_module: \ MODULE_INCLUDES += $$MODULE_PRIVATE_INCLUDES - split_incpath: \ + split_incpath { MODULE_FWD_PRI_CONT_SUFFIX += "QT.$${MODULE_ID}.includes += $$val_escape(MODULE_SHADOW_INCLUDES)" + generated_privates: \ + MODULE_FWD_PRI_CONT_SUFFIX += "QT.$${MODULE}_private.includes += $$val_escape(MODULE_SHADOW_PRIVATE_INCLUDES)" + } MODULE_PRI_CONT = \ "QT.$${MODULE_ID}.VERSION = $${VERSION}" \ "QT.$${MODULE_ID}.MAJOR_VERSION = $$section(VERSION, ., 0, 0)" \ -- cgit v1.2.3 From b3f7b2329402f548694711acd209455316aa9c6c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 20 May 2015 15:56:14 +0200 Subject: Unclutter debug operators of gestures. Use the helpers in qdebug_p.h to suppress class and enum names. Change-Id: Ib71f0a1e5b3c22f44d68a7930fef38384f037204 Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qgesture.cpp | 50 +++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/widgets/kernel/qgesture.cpp b/src/widgets/kernel/qgesture.cpp index 713a019cc3..7b7d465070 100644 --- a/src/widgets/kernel/qgesture.cpp +++ b/src/widgets/kernel/qgesture.cpp @@ -36,7 +36,7 @@ #include "private/qstandardgestures_p.h" #include "qgraphicsview.h" -#include +#include #ifndef QT_NO_GESTURES QT_BEGIN_NAMESPACE @@ -1091,9 +1091,12 @@ QPointF QGestureEvent::mapToGraphicsScene(const QPointF &gesturePoint) const static void formatGestureHeader(QDebug d, const char *className, const QGesture *gesture) { - d << className << "(state=" << gesture->state(); - if (gesture->hasHotSpot()) - d << ",hotSpot=" << gesture->hotSpot(); + d << className << "(state="; + QtDebugUtils::formatQEnum(d, gesture->state()); + if (gesture->hasHotSpot()) { + d << ",hotSpot="; + QtDebugUtils::formatQPoint(d, gesture->hotSpot()); + } } Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QGesture *gesture) @@ -1103,31 +1106,42 @@ Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QGesture *gesture) switch (gesture->gestureType()) { case Qt::TapGesture: formatGestureHeader(d, "QTapGesture", gesture); - d << ",position=" << static_cast(gesture)->position() << ')'; + d << ",position="; + QtDebugUtils::formatQPoint(d, static_cast(gesture)->position()); + d << ')'; break; case Qt::TapAndHoldGesture: { const QTapAndHoldGesture *tap = static_cast(gesture); formatGestureHeader(d, "QTapAndHoldGesture", tap); - d << ",position=" << tap->position() << ",timeout=" << tap->timeout() << ')'; + d << ",position="; + QtDebugUtils::formatQPoint(d, tap->position()); + d << ",timeout=" << tap->timeout() << ')'; } break; case Qt::PanGesture: { const QPanGesture *pan = static_cast(gesture); formatGestureHeader(d, "QPanGesture", pan); - d << ",lastOffset=" << pan->lastOffset() << ",offset=" << pan->offset() - << ",acceleration=" << pan->acceleration() - << ",delta=" << pan->delta() << ')'; + d << ",lastOffset="; + QtDebugUtils::formatQPoint(d, pan->lastOffset()); + d << pan->lastOffset(); + d << ",offset="; + QtDebugUtils::formatQPoint(d, pan->offset()); + d << ",acceleration=" << pan->acceleration() << ",delta="; + QtDebugUtils::formatQPoint(d, pan->delta()); + d << ')'; } break; case Qt::PinchGesture: { const QPinchGesture *pinch = static_cast(gesture); formatGestureHeader(d, "QPinchGesture", pinch); d << ",totalChangeFlags=" << pinch->totalChangeFlags() - << ",changeFlags=" << pinch->changeFlags() - << ",startCenterPoint=" << pinch->startCenterPoint() - << ",lastCenterPoint=" << pinch->lastCenterPoint() - << ",centerPoint=" << pinch->centerPoint() - << ",totalScaleFactor=" << pinch->totalScaleFactor() + << ",changeFlags=" << pinch->changeFlags() << ",startCenterPoint="; + QtDebugUtils::formatQPoint(d, pinch->startCenterPoint()); + d << ",lastCenterPoint="; + QtDebugUtils::formatQPoint(d, pinch->lastCenterPoint()); + d << ",centerPoint="; + QtDebugUtils::formatQPoint(d, pinch->centerPoint()); + d << ",totalScaleFactor=" << pinch->totalScaleFactor() << ",lastScaleFactor=" << pinch->lastScaleFactor() << ",scaleFactor=" << pinch->scaleFactor() << ",totalRotationAngle=" << pinch->totalRotationAngle() @@ -1138,9 +1152,11 @@ Q_WIDGETS_EXPORT QDebug operator<<(QDebug d, const QGesture *gesture) case Qt::SwipeGesture: { const QSwipeGesture *swipe = static_cast(gesture); formatGestureHeader(d, "QSwipeGesture", swipe); - d << ",horizontalDirection=" << swipe->horizontalDirection() - << ",verticalDirection=" << swipe->verticalDirection() - << ",swipeAngle=" << swipe->swipeAngle() << ')'; + d << ",horizontalDirection="; + QtDebugUtils::formatQEnum(d, swipe->horizontalDirection()); + d << ",verticalDirection="; + QtDebugUtils::formatQEnum(d, swipe->verticalDirection()); + d << ",swipeAngle=" << swipe->swipeAngle() << ')'; } break; default: -- cgit v1.2.3 From fc78456fba8d568e8852032f66b6ede14973ffea Mon Sep 17 00:00:00 2001 From: Jani Heikkinen Date: Wed, 20 May 2015 13:22:02 +0300 Subject: Updated WinRT license headers to use LGPLv3 instead of LGPLv21 From 5.5.0 -> WinRT port is licensed with LGPLv3, see http://blog.qt.io/blog/2015/04/29/windows-10-support-in-qt/ Change-Id: I7e42564276af3fdbd0d4c61e2736610fa698b11c Reviewed-by: Tuukka Turunen Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/winrt/main.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtbackingstore.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtbackingstore.h | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtcursor.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtcursor.h | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrteglcontext.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrteglcontext.h | 23 ++++++++++++---------- .../platforms/winrt/qwinrteventdispatcher.cpp | 23 ++++++++++++---------- .../platforms/winrt/qwinrteventdispatcher.h | 23 ++++++++++++---------- .../platforms/winrt/qwinrtfiledialoghelper.cpp | 23 ++++++++++++---------- .../platforms/winrt/qwinrtfiledialoghelper.h | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtfileengine.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtfileengine.h | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtfontdatabase.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtfontdatabase.h | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtinputcontext.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtinputcontext.h | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtintegration.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtintegration.h | 23 ++++++++++++---------- .../platforms/winrt/qwinrtmessagedialoghelper.cpp | 23 ++++++++++++---------- .../platforms/winrt/qwinrtmessagedialoghelper.h | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtscreen.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtscreen.h | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtservices.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtservices.h | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrttheme.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrttheme.h | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtwindow.cpp | 23 ++++++++++++---------- src/plugins/platforms/winrt/qwinrtwindow.h | 23 ++++++++++++---------- 29 files changed, 377 insertions(+), 290 deletions(-) diff --git a/src/plugins/platforms/winrt/main.cpp b/src/plugins/platforms/winrt/main.cpp index 128e0b78b6..d1cf08887f 100644 --- a/src/plugins/platforms/winrt/main.cpp +++ b/src/plugins/platforms/winrt/main.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp index b55551e820..dcf8239538 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h index 69bd3c397c..20b27a3865 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.h +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp index e86590c260..94ce23bd2c 100644 --- a/src/plugins/platforms/winrt/qwinrtcursor.cpp +++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtcursor.h b/src/plugins/platforms/winrt/qwinrtcursor.h index de951b1844..9c9b9e93ef 100644 --- a/src/plugins/platforms/winrt/qwinrtcursor.h +++ b/src/plugins/platforms/winrt/qwinrtcursor.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index 0832fbb586..42ffe8f716 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h index 9b1ef37d1b..958d623c4c 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.h +++ b/src/plugins/platforms/winrt/qwinrteglcontext.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp b/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp index 7f77b79660..716681c905 100644 --- a/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp +++ b/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrteventdispatcher.h b/src/plugins/platforms/winrt/qwinrteventdispatcher.h index 35e637eba5..ecbdde34bd 100644 --- a/src/plugins/platforms/winrt/qwinrteventdispatcher.h +++ b/src/plugins/platforms/winrt/qwinrteventdispatcher.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp index 417befeb63..e1b2a07d5f 100644 --- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp +++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h index 13abf6e2b8..51b79c84ef 100644 --- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h +++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp index 719bb18dd6..858cb841b9 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp +++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.h b/src/plugins/platforms/winrt/qwinrtfileengine.h index c31bf741fa..86721d8578 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.h +++ b/src/plugins/platforms/winrt/qwinrtfileengine.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp index 8a3205220b..09edea52e7 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h index eb643d4930..7b3f402c13 100644 --- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h +++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp index f0de578db6..c94b53ef1c 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h index 761908a9cb..ce7fbabf49 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.h +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 015ebaadb5..70ee6dbe6a 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h index 1ec44cd46a..bbd6c1e41b 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.h +++ b/src/plugins/platforms/winrt/qwinrtintegration.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp index c5d3634523..4fc1fea626 100644 --- a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp +++ b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h index fc510fe34e..2f473a05f7 100644 --- a/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h +++ b/src/plugins/platforms/winrt/qwinrtmessagedialoghelper.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index c4512b4d2d..1d36bb31f6 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index cbef9543a9..d34ce75748 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp index 1faa3945a7..cb04f670d2 100644 --- a/src/plugins/platforms/winrt/qwinrtservices.cpp +++ b/src/plugins/platforms/winrt/qwinrtservices.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtservices.h b/src/plugins/platforms/winrt/qwinrtservices.h index 3551803b79..585eb2f010 100644 --- a/src/plugins/platforms/winrt/qwinrtservices.h +++ b/src/plugins/platforms/winrt/qwinrtservices.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp index c42368cc87..a0fa2798a8 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.cpp +++ b/src/plugins/platforms/winrt/qwinrttheme.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrttheme.h b/src/plugins/platforms/winrt/qwinrttheme.h index 73dcd6cdf4..2e159cbd55 100644 --- a/src/plugins/platforms/winrt/qwinrttheme.h +++ b/src/plugins/platforms/winrt/qwinrttheme.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index b96f4255c2..adc5dfb776 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/plugins/platforms/winrt/qwinrtwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h index eee95d6bd3..3cfe346ab2 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.h +++ b/src/plugins/platforms/winrt/qwinrtwindow.h @@ -5,7 +5,7 @@ ** ** This file is part of the plugins of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** -- cgit v1.2.3 From 2858a3c91b745357c1fa99b49b24705a155c6609 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Fri, 15 May 2015 14:19:02 +0300 Subject: Don't propagate single touch events only from touchpads on OS X This way the tests that send fake touchscreen events can work. Change-Id: I997ef015d0096249c4549dbd21b99d0248e0c987 Task-number: QTBUG-46111 Reviewed-by: Friedemann Kleint Reviewed-by: Caroline Chao Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qapplication.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index d61277f990..d61737efc9 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -4358,8 +4358,10 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window, #ifdef Q_OS_OSX // Single-touch events are normally not sent unless WA_TouchPadAcceptSingleTouchEvents is set. - // In Qt 4 this check was in OS X-only coode. That behavior is preserved here by the #ifdef. - if (touchPoints.count() == 1 && !targetWidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents)) + // In Qt 4 this check was in OS X-only code. That behavior is preserved here by the #ifdef. + if (touchPoints.count() == 1 + && device->type() == QTouchDevice::TouchPad + && !targetWidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents)) continue; #endif -- cgit v1.2.3 From d8bfd812c3383e24196588f5d3e1de4719fcac02 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 19 May 2015 12:36:55 +0200 Subject: D-Bus system tray icon: submenus can be created after context menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QMenuPrivate::init() calls QPlatformTheme::createPlatformMenu() to create a platform menu, but on Linux, that returns null for now. QSystemTrayIcon::setContextMenu() results in recursive calls to QSystemTrayIconPrivate::addPlatformMenu() which then calls QDBusTrayIcon::createMenu() for the context menu and each submenu. However if a submenu is added afterwards, a corresponding platform menu is not immediately created. Now copyActionToPlatformItem() will detect and create the missing platform submenu, by calling a new method: DBusPlatformMenu::createSubMenu(). This is because there is no way of knowing that it's a tray-specific context menu (which is so far the only case in which we use DBusPlatformMenu). So, QPlatformMenu::createSubMenu() needs to exist as a new QPA interface for this use case. Task-number: QTBUG-45803 Change-Id: Ib319e873082196515ea0580d70d069099cf2c175 Reviewed-by: Jørgen Lind --- src/gui/kernel/qplatformmenu.cpp | 5 +++++ src/gui/kernel/qplatformmenu.h | 1 + src/platformsupport/dbusmenu/qdbusplatformmenu.cpp | 9 ++++++++- src/platformsupport/dbusmenu/qdbusplatformmenu_p.h | 4 +++- src/widgets/widgets/qmenu.cpp | 12 +++++++----- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qplatformmenu.cpp b/src/gui/kernel/qplatformmenu.cpp index cb311b8d13..da65381931 100644 --- a/src/gui/kernel/qplatformmenu.cpp +++ b/src/gui/kernel/qplatformmenu.cpp @@ -44,4 +44,9 @@ QPlatformMenuItem *QPlatformMenu::createMenuItem() const return QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem(); } +QPlatformMenu *QPlatformMenu::createSubMenu() const +{ + return QGuiApplicationPrivate::platformTheme()->createPlatformMenu(); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h index baa1e460d7..1022d0ed4a 100644 --- a/src/gui/kernel/qplatformmenu.h +++ b/src/gui/kernel/qplatformmenu.h @@ -123,6 +123,7 @@ public: virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const = 0; virtual QPlatformMenuItem *createMenuItem() const; + virtual QPlatformMenu *createSubMenu() const; Q_SIGNALS: void aboutToShow(); void aboutToHide(); diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp index 93c822cefb..a64e107e71 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -75,6 +75,9 @@ void QDBusPlatformMenuItem::setIcon(const QIcon &icon) m_icon = icon; } +/*! + Set a submenu under this menu item. +*/ void QDBusPlatformMenuItem::setMenu(QPlatformMenu *menu) { m_subMenu = static_cast(menu); @@ -242,8 +245,12 @@ const QList QDBusPlatformMenu::items() const QPlatformMenuItem *QDBusPlatformMenu::createMenuItem() const { QDBusPlatformMenuItem *ret = new QDBusPlatformMenuItem(); - ret->setMenu(const_cast(this)); return ret; } +QPlatformMenu *QDBusPlatformMenu::createSubMenu() const +{ + return new QDBusPlatformMenu; +} + QT_END_NAMESPACE diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h index 2519533e32..16bb4f195c 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h @@ -124,7 +124,7 @@ public: quintptr tag()const Q_DECL_OVERRIDE { return m_tag; } void setTag(quintptr tag) Q_DECL_OVERRIDE; - const QString text() { return m_text; } + const QString text() const { return m_text; } void setText(const QString &text) Q_DECL_OVERRIDE; void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; void setEnabled(bool enabled) Q_DECL_OVERRIDE; @@ -150,6 +150,7 @@ public: const QList items() const; QPlatformMenuItem *createMenuItem() const Q_DECL_OVERRIDE; + QPlatformMenu *createSubMenu() const Q_DECL_OVERRIDE; bool operator==(const QDBusPlatformMenu& other) { return m_tag == other.m_tag; } @@ -175,6 +176,7 @@ private: uint m_revision; QHash m_itemsByTag; QList m_items; + QDBusPlatformMenuItem *m_containingMenuItem; static QList m_topLevelMenus; }; diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 1749f9d8c7..2f0dcc49d1 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -183,7 +183,7 @@ void QMenuPrivate::setPlatformMenu(QPlatformMenu *menu) } // forward declare function -static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem* item); +static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item, QPlatformMenu *itemsMenu); void QMenuPrivate::syncPlatformMenu() { @@ -200,7 +200,7 @@ void QMenuPrivate::syncPlatformMenu() menuItem->setTag(reinterpret_cast(action)); QObject::connect(menuItem, SIGNAL(activated()), action, SLOT(trigger()), Qt::QueuedConnection); QObject::connect(menuItem, SIGNAL(hovered()), action, SIGNAL(hovered()), Qt::QueuedConnection); - copyActionToPlatformItem(action, menuItem); + copyActionToPlatformItem(action, menuItem, platformMenu.data()); platformMenu->insertMenuItem(menuItem, beforeItem); beforeItem = menuItem; } @@ -3105,7 +3105,7 @@ QMenu::timerEvent(QTimerEvent *e) } } -static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem* item) +static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem *item, QPlatformMenu *itemsMenu) { item->setText(action->text()); item->setIsSeparator(action->isSeparator()); @@ -3131,6 +3131,8 @@ static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem* i item->setEnabled(action->isEnabled()); if (action->menu()) { + if (!action->menu()->platformMenu()) + action->menu()->setPlatformMenu(itemsMenu->createSubMenu()); item->setMenu(action->menu()->platformMenu()); } else { item->setMenu(0); @@ -3185,7 +3187,7 @@ void QMenu::actionEvent(QActionEvent *e) menuItem->setTag(reinterpret_cast(e->action())); QObject::connect(menuItem, SIGNAL(activated()), e->action(), SLOT(trigger())); QObject::connect(menuItem, SIGNAL(hovered()), e->action(), SIGNAL(hovered())); - copyActionToPlatformItem(e->action(), menuItem); + copyActionToPlatformItem(e->action(), menuItem, d->platformMenu); QPlatformMenuItem* beforeItem = d->platformMenu->menuItemForTag(reinterpret_cast(e->before())); d->platformMenu->insertMenuItem(menuItem, beforeItem); } else if (e->type() == QEvent::ActionRemoved) { @@ -3195,7 +3197,7 @@ void QMenu::actionEvent(QActionEvent *e) } else if (e->type() == QEvent::ActionChanged) { QPlatformMenuItem *menuItem = d->platformMenu->menuItemForTag(reinterpret_cast(e->action())); if (menuItem) { - copyActionToPlatformItem(e->action(), menuItem); + copyActionToPlatformItem(e->action(), menuItem, d->platformMenu); d->platformMenu->syncMenuItem(menuItem); } } -- cgit v1.2.3 From 01d78ba86a631386a4d47b7c12d2a359da28f517 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 6 Mar 2015 16:05:20 +0100 Subject: Android: generate QTabletEvents for stylus devices such as the S Pen For example the Galaxy Note series of devices. This makes possible drawing applications which handle stylus events differently from touch or mouse. As on any other platform, if the application does not accept the QTabletEvent, a QMouseEvent will be synthesized. Also fix the tablet manual test to show larger circles on hidpi devices. [ChangeLog][Android] stylus devices such as the S Pen generate QTabletEvents Task-number: QTBUG-38379 Change-Id: Ib594f453b8403cc06aa4e440a76f07afa3bac38c Reviewed-by: Paul Olav Tvete --- .../src/org/qtproject/qt5/android/QtNative.java | 64 +++++++++++++++------- src/plugins/platforms/android/androidjniinput.cpp | 47 ++++++++++++++++ tests/manual/qtabletevent/regular_widgets/main.cpp | 10 ++-- 3 files changed, 96 insertions(+), 25 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index b2480618f8..80f7fb5c85 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -43,6 +43,7 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.text.ClipboardManager; +import android.os.Build; import android.util.Log; import android.view.ContextMenu; import android.view.Menu; @@ -301,32 +302,49 @@ public class QtNative static public void sendTouchEvent(MotionEvent event, int id) { - //@ANDROID-5 - touchBegin(id); - for (int i=0;i= 14) { + switch (event.getToolType(0)) { + case MotionEvent.TOOL_TYPE_STYLUS: + pointerType = 1; // QTabletEvent::Pen break; - - case MotionEvent.ACTION_UP: - touchEnd(id,2); + case MotionEvent.TOOL_TYPE_ERASER: + pointerType = 3; // QTabletEvent::Eraser break; + // TODO TOOL_TYPE_MOUSE + } + } - default: - touchEnd(id,1); + if (pointerType != 0) { + tabletEvent(id, event.getDeviceId(), event.getEventTime(), event.getAction(), pointerType, + event.getButtonState(), event.getX(), event.getY(), event.getPressure()); + } else { + touchBegin(id); + for (int i = 0; i < event.getPointerCount(); ++i) { + touchAdd(id, + event.getPointerId(i), + getAction(i, event), + i == 0, + (int)event.getX(i), + (int)event.getY(i), + event.getSize(i), + event.getPressure(i)); + } + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + touchEnd(id, 0); + break; + + case MotionEvent.ACTION_UP: + touchEnd(id, 2); + break; + + default: + touchEnd(id, 1); + } } - //@ANDROID-5 } static public void sendTrackballEvent(MotionEvent event, int id) @@ -592,6 +610,10 @@ public class QtNative public static native void longPress(int winId, int x, int y); // pointer methods + // tablet methods + public static native void tabletEvent(int winId, int deviceId, long time, int action, int pointerType, int buttonState, float x, float y, float pressure); + // tablet methods + // keyboard methods public static native void keyDown(int key, int unicode, int modifier, boolean autoRepeat); public static native void keyUp(int key, int unicode, int modifier, boolean autoRepeat); diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp index 8ee3ff88d1..be5e969d2b 100644 --- a/src/plugins/platforms/android/androidjniinput.cpp +++ b/src/plugins/platforms/android/androidjniinput.cpp @@ -238,6 +238,52 @@ namespace QtAndroidInput QWindowSystemInterface::handleTouchEvent(window, touchDevice, m_touchPoints); } + static void tabletEvent(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint deviceId, jlong time, jint action, + jint pointerType, jint buttonState, jfloat x, jfloat y, jfloat pressure) + { + QPointF globalPosF(x, y); + QPoint globalPos((int)x, (int)y); + QWindow *tlw = topLevelWindowAt(globalPos); + QPointF localPos = tlw ? (globalPosF - tlw->position()) : globalPosF; + + // Galaxy Note with plain Android: + // 0 1 0 stylus press + // 2 1 0 stylus drag + // 1 1 0 stylus release + // 0 1 2 stylus press with side-button held + // 2 1 2 stylus drag with side-button held + // 1 1 2 stylus release with side-button held + // Galaxy Note 4 with Samsung firmware: + // 0 1 0 stylus press + // 2 1 0 stylus drag + // 1 1 0 stylus release + // 211 1 2 stylus press with side-button held + // 213 1 2 stylus drag with side-button held + // 212 1 2 stylus release with side-button held + // when action == ACTION_UP (1) it's a release; otherwise we say which button is pressed + Qt::MouseButtons buttons = Qt::NoButton; + switch (action) { + case 1: // ACTION_UP + case 212: // stylus release while side-button held on Galaxy Note 4 + buttons = Qt::NoButton; + break; + default: // action is press or drag + if (buttonState == 0) + buttons = Qt::LeftButton; + else // 2 means RightButton + buttons = Qt::MouseButtons(buttonState); + break; + } + +#ifdef QT_DEBUG_ANDROID_STYLUS + qDebug() << action << pointerType << buttonState << "@" << x << y << "pressure" << pressure << ": buttons" << buttons; +#endif + + QWindowSystemInterface::handleTabletEvent(tlw, ulong(time), + localPos, globalPosF, QTabletEvent::Stylus, pointerType, + buttons, pressure, 0, 0, 0., 0., 0, deviceId, Qt::NoModifier); + } + static int mapAndroidKey(int key) { // 0--9 0x00000007 -- 0x00000010 @@ -702,6 +748,7 @@ namespace QtAndroidInput {"mouseUp", "(III)V", (void *)mouseUp}, {"mouseMove", "(III)V", (void *)mouseMove}, {"longPress", "(III)V", (void *)longPress}, + {"tabletEvent", "(IIJIIIFFF)V", (void *)tabletEvent}, {"keyDown", "(IIIZ)V", (void *)keyDown}, {"keyUp", "(IIIZ)V", (void *)keyUp}, {"keyboardVisibilityChanged", "(Z)V", (void *)keyboardVisibilityChanged} diff --git a/tests/manual/qtabletevent/regular_widgets/main.cpp b/tests/manual/qtabletevent/regular_widgets/main.cpp index 5a83decfa2..c8353a40c0 100644 --- a/tests/manual/qtabletevent/regular_widgets/main.cpp +++ b/tests/manual/qtabletevent/regular_widgets/main.cpp @@ -100,17 +100,19 @@ EventReportWidget::EventReportWidget() void EventReportWidget::paintEvent(QPaintEvent *) { QPainter p(this); + int lineSpacing = fontMetrics().lineSpacing(); + int halfLineSpacing = lineSpacing / 2; const QRectF geom = QRectF(QPoint(0, 0), size()); p.fillRect(geom, Qt::white); p.drawRect(QRectF(geom.topLeft(), geom.bottomRight() - QPointF(1,1))); p.setPen(Qt::white); QPainterPath ellipse; - ellipse.addEllipse(0, 0, 50, 10); + ellipse.addEllipse(0, 0, halfLineSpacing * 5, halfLineSpacing); foreach (const TabletPoint &t, m_points) { if (geom.contains(t.pos)) { QPainterPath pp; - pp.addEllipse(t.pos, 8, 8); - QRectF pointBounds(t.pos.x() - 10, t.pos.y() - 10, 20, 20); + pp.addEllipse(t.pos, halfLineSpacing, halfLineSpacing); + QRectF pointBounds(t.pos.x() - halfLineSpacing, t.pos.y() - halfLineSpacing, lineSpacing, lineSpacing); switch (t.type) { case TabletButtonPress: p.fillPath(pp, Qt::darkGreen); @@ -133,7 +135,7 @@ void EventReportWidget::paintEvent(QPaintEvent *) p.drawPath(ellipse); p.restore(); } else { - p.drawEllipse(t.pos, t.pressure * 10.0, t.pressure * 10.0); + p.drawEllipse(t.pos, t.pressure * halfLineSpacing, t.pressure * halfLineSpacing); } p.setPen(Qt::white); } else { -- cgit v1.2.3 From d4a296b538da93f5c915fc7e886c6995f1b41169 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 20 May 2015 13:35:07 +0200 Subject: Do not modify decoder when determining image-format We should not configure the decoder when just determining the image- format. Doing so can cause all versions of libpng to print a warning, and some versions to fail to decode. The code appears to be a leftover from when the image-format logic was copied out of the introduction of the decoding method, where the proper settings are still applied. Task-number: QTBUG-46233 Change-Id: I6619728804f040ae6c9d637c7298a8586e22499e Reviewed-by: Andy Shaw Reviewed-by: aavit --- src/gui/image/qpnghandler.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 17a0dd3eb9..304ab0cf3e 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -674,16 +674,9 @@ QImage::Format QPngHandlerPrivate::readImageFormat() && num_palette <= 256) { // 1-bit and 8-bit color - if (bit_depth != 1) - png_set_packing(png_ptr); - png_read_update_info(png_ptr, info_ptr); - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8; } else { // 32-bit - if (bit_depth == 16) - png_set_strip_16(png_ptr); - format = QImage::Format_ARGB32; // Only add filler if no alpha, or we can get 5 channel data. if (!(color_type & PNG_COLOR_MASK_ALPHA) -- cgit v1.2.3 From 6794319bbdba69beb7baaff46520f3be15a1d490 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 May 2015 15:45:41 +0200 Subject: Fix a crash in tst_QTouchEvent::deleteInRawEventTranslation(). The test deletes a widget in QEvent::TouchBegin. This is part of a series of patches to revive the test; it is currently not run since tests/auto/gui/kernel/qtouchevent/qtouchevent.pro is missing CONFIG += testcase. Task-number: QTBUG-46266 Change-Id: I65c0a431ff1807133438764dd8b3c16bb9cb6743 Reviewed-by: Caroline Chao --- src/widgets/kernel/qapplication.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index d61737efc9..aa7940b623 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -4377,7 +4377,7 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window, QHash::ConstIterator it = widgetsNeedingEvents.constBegin(); const QHash::ConstIterator end = widgetsNeedingEvents.constEnd(); for (; it != end; ++it) { - QWidget *widget = it.key(); + const QPointer widget = it.key(); if (!QApplicationPrivate::tryModalHelper(widget, 0)) continue; @@ -4417,7 +4417,8 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window, // has been implicitly accepted and continue to send touch events if (QApplication::sendSpontaneousEvent(widget, &touchEvent) && touchEvent.isAccepted()) { accepted = true; - widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent); + if (!widget.isNull()) + widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent); } break; } -- cgit v1.2.3 From 97e75b2763cd4e36a20a97eaa9a966541add6b6d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 May 2015 12:22:45 +0200 Subject: Make QTouchDevice a Q_GADGET and introduce Q_ENUM/Q_FLAG. Make it possible to stream the enumerations to a debug stream.# Change-Id: I0add2dcd835333a8d6cebf779252f22c1418faf3 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Shawn Rutledge --- src/gui/kernel/qtouchdevice.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/kernel/qtouchdevice.h b/src/gui/kernel/qtouchdevice.h index f2157ce2d6..90f0f25d2f 100644 --- a/src/gui/kernel/qtouchdevice.h +++ b/src/gui/kernel/qtouchdevice.h @@ -43,11 +43,13 @@ class QTouchDevicePrivate; class Q_GUI_EXPORT QTouchDevice { + Q_GADGET public: enum DeviceType { TouchScreen, TouchPad }; + Q_ENUM(DeviceType) enum CapabilityFlag { Position = 0x0001, @@ -58,6 +60,7 @@ public: NormalizedPosition = 0x0020, MouseEmulation = 0x0040 }; + Q_FLAG(CapabilityFlag) Q_DECLARE_FLAGS(Capabilities, CapabilityFlag) QTouchDevice(); -- cgit v1.2.3 From b0a1a134c2a41b7894f70ed72a4c3f8ddc1066de Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 May 2015 13:26:46 +0200 Subject: Add debug operator for QTouchDevice. Produces: QTouchDevice("", type=TouchScreen, capabilities=Position|Area|NormalizedPosition|MouseEmulation, maximumTouchPoints=10) Remove operator from manual test. Change-Id: I6b792665031902d5f822c80807a400a334c27526 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qtouchdevice.cpp | 23 +++++++++++++++++++++++ src/gui/kernel/qtouchdevice.h | 6 +++++- tests/manual/touch/main.cpp | 18 ------------------ 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp index 8737825de0..1a6e9deba8 100644 --- a/src/gui/kernel/qtouchdevice.cpp +++ b/src/gui/kernel/qtouchdevice.cpp @@ -37,6 +37,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE /*! @@ -239,4 +241,25 @@ void QTouchDevicePrivate::registerDevice(QTouchDevice *dev) deviceList()->append(dev); } +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QTouchDevice *device) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + debug.noquote(); + debug << "QTouchDevice("; + if (device) { + debug << '"' << device->name() << "\", type="; + QtDebugUtils::formatQEnum(debug, device->type()); + debug << ", capabilities="; + QtDebugUtils::formatQFlags(debug, device->capabilities()); + debug << ", maximumTouchPoints=" << device->maximumTouchPoints(); + } else { + debug << '0'; + } + debug << ')'; + return debug; +} +#endif // !QT_NO_DEBUG_STREAM + QT_END_NAMESPACE diff --git a/src/gui/kernel/qtouchdevice.h b/src/gui/kernel/qtouchdevice.h index 90f0f25d2f..1c1fcc63aa 100644 --- a/src/gui/kernel/qtouchdevice.h +++ b/src/gui/kernel/qtouchdevice.h @@ -38,7 +38,7 @@ QT_BEGIN_NAMESPACE - +class QDebug; class QTouchDevicePrivate; class Q_GUI_EXPORT QTouchDevice @@ -84,6 +84,10 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QTouchDevice::Capabilities) +#ifndef QT_NO_DEBUG_STREAM +Q_GUI_EXPORT QDebug operator<<(QDebug, const QTouchDevice *); +#endif + QT_END_NAMESPACE #endif // QTOUCHDEVICE_H diff --git a/tests/manual/touch/main.cpp b/tests/manual/touch/main.cpp index f4c9f6bf8b..e1114d7f57 100644 --- a/tests/manual/touch/main.cpp +++ b/tests/manual/touch/main.cpp @@ -47,24 +47,6 @@ #include #include -QDebug operator<<(QDebug debug, const QTouchDevice *d) -{ - QDebugStateSaver saver(debug); - debug.nospace(); - debug << "QTouchDevice(" << d->name() << ','; - switch (d->type()) { - case QTouchDevice::TouchScreen: - debug << "TouchScreen"; - break; - case QTouchDevice::TouchPad: - debug << "TouchPad"; - break; - } - debug << ", capabilities=" << d->capabilities() - << ", maximumTouchPoints=" << d->maximumTouchPoints() << ')'; - return debug; -} - typedef QVector EventTypeVector; class EventFilter : public QObject { -- cgit v1.2.3 From 9d9450f5f962059a405a66a08274ec51a0537c31 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 May 2015 14:58:33 +0200 Subject: Add CONFIG += testcase to test qglobalstatic. Otherwise, make check does nothing, always succeeding. Change-Id: I0fe04697e02ab0f33cd9aebb550777e200c70804 Reviewed-by: Simon Hausmann --- tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro b/tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro index 21cab8f67d..7b374505ce 100644 --- a/tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro +++ b/tests/auto/corelib/global/qglobalstatic/qglobalstatic.pro @@ -1,3 +1,4 @@ +CONFIG += testcase QT += testlib core-private QT -= gui -- cgit v1.2.3 From ad9698713f91a2e706fcd391f9806057649632ff Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 20 May 2015 18:22:40 +0200 Subject: Adjust curveThreshold based on strokeWidth Currently curveThreshold is relative to pen width, this allows wide pen to be increasingly off target. This patch adjust the curveThreshold relative to stroke width, thereby ensuring wide pens stays on the curve. Task-number: QTBUG-46151 Change-Id: Ifd4371aa2853331d02e3c6f6565c243eb1b7ed2e Reviewed-by: Gunnar Sletta --- src/gui/painting/qstroker_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index eda65b8e2f..f967c091df 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -201,7 +201,7 @@ public: QStroker(); ~QStroker(); - void setStrokeWidth(qfixed width) { m_strokeWidth = width; } + void setStrokeWidth(qfixed width) { m_strokeWidth = width; m_curveThreshold = width >= 1 ? 1.0/width : 0.5;} qfixed strokeWidth() const { return m_strokeWidth; } void setCapStyle(Qt::PenCapStyle capStyle) { m_capStyle = joinModeForCap(capStyle); } -- cgit v1.2.3 From e96ad10fd8f1d6badfe8ff7befbd397d5cbfe2b4 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 20 May 2015 19:28:44 +0200 Subject: Ensure the same behavior on Win as Unix re the host in isApparentlyStale When the hostname is empty then it is assumed that the lock file is from the same host as the one running the application. Change-Id: Iba8aefc171a209294371dc2022d93ede3035b242 Reviewed-by: Will Wagner Reviewed-by: David Faure --- src/corelib/io/qlockfile_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index 3587c7bffe..21ab8f8fea 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -120,7 +120,7 @@ bool QLockFilePrivate::isApparentlyStale() const // processes due to sandboxing #ifndef Q_OS_WINRT if (getLockInfo(&pid, &hostname, &appname)) { - if (hostname == QString::fromLocal8Bit(localHostName())) { + if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (!procHandle) return true; -- cgit v1.2.3 From 05cd8d3bfed7a61596f3b51b8b50505e7126de73 Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik Date: Wed, 20 May 2015 12:56:41 +0200 Subject: qiosintegration: Set PasswordMaskDelay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This may introduce a privacy issue, however, there does not seem to be a way to disable this behavior on iOS - there would probably be a setting if they considered that an issue - so we might as well do the same. Change-Id: I7a5a6552c36d69b98064b50875562f586b10c0ee Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 7cd4280f5e..986fef7725 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -208,6 +208,10 @@ QPlatformServices *QIOSIntegration::services() const QVariant QIOSIntegration::styleHint(StyleHint hint) const { switch (hint) { + case PasswordMaskDelay: + // this number is based on timing the native delay + // since there is no API to get it + return 2000; case ShowIsMaximized: return true; case SetFocusOnTouchRelease: -- cgit v1.2.3 From 97a6f28200f7c4c3c7285ac687aee542ae290c28 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 22 May 2015 09:13:21 +0200 Subject: Fixed compilation of auto tests using vc(x)proj files As the defines looked like -DQT_TESTCASE_BUILDDIR=""C:\..."" compilation from Visual Studio (vcxproj) failed due to the two quotation marks at the beginning/end of the actual path. So for the vc(x)proj we do not use shell_quote but add the quotes manually. Change-Id: I186258d82a56928cd0316bff1ec9f60147044165 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/testlib_defines.prf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/testlib_defines.prf b/mkspecs/features/testlib_defines.prf index 9176beb9dd..901e03a91d 100644 --- a/mkspecs/features/testlib_defines.prf +++ b/mkspecs/features/testlib_defines.prf @@ -1 +1,2 @@ -DEFINES += QT_TESTCASE_BUILDDIR=$$shell_quote(\"$$OUT_PWD\") +contains(TEMPLATE, vc.*): DEFINES += QT_TESTCASE_BUILDDIR=\"$$OUT_PWD\" +else: DEFINES += QT_TESTCASE_BUILDDIR=$$shell_quote(\"$$OUT_PWD\") -- cgit v1.2.3 From 7c7c815a1adddfb5a958eefe44724c7395b1a15b Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 20 May 2015 09:29:11 +0200 Subject: MSVC2015: Compile fix Q_DECL_NOTHROW needs to be present at the definition as well in VS2015. Change-Id: I8a6def607aa4ae9c9fe64386a38fc1c728edd8d1 Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/network/ssl/qsslellipticcurve_dummy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/ssl/qsslellipticcurve_dummy.cpp b/src/network/ssl/qsslellipticcurve_dummy.cpp index d05c920a49..16b7a3cd00 100644 --- a/src/network/ssl/qsslellipticcurve_dummy.cpp +++ b/src/network/ssl/qsslellipticcurve_dummy.cpp @@ -57,7 +57,7 @@ QSslEllipticCurve QSslEllipticCurve::fromLongName(const QString &name) return QSslEllipticCurve(); } -bool QSslEllipticCurve::isTlsNamedCurve() const +bool QSslEllipticCurve::isTlsNamedCurve() const Q_DECL_NOTHROW { return false; } -- cgit v1.2.3 From 11838622e53537dae61245cb51f100cae9f77b9b Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Wed, 6 May 2015 12:42:28 +0200 Subject: Fix compile error with VS 2015 Change-Id: Ib3b61de27feccb980e5efdf02f0372602d7ffb5a Task-number: QTBUG-45961 Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/windows/accessible/iaccessible2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 99c44c69ef..5ed8d30e67 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -102,7 +102,7 @@ HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitName(/* [retval][out HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitVersion(/* [retval][out] */ BSTR *version) { - *version = ::SysAllocString(QT_UNICODE_LITERAL(QT_VERSION_STR)); + *version = ::SysAllocString(TEXT(QT_VERSION_STR)); return S_OK; } -- cgit v1.2.3 From 6a72afa5f7f362c7053f707b94528e7c01460a19 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 22 May 2015 11:03:19 +0200 Subject: Blacklist tst_qwindow tests that are failing on Ubuntu 14.04 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should allow us to make the rest of 14.04 enforcing Change-Id: I37f6751e8b966b047d1bd2e49ba9482e5846acb1 Reviewed-by: Tony Sarajärvi --- tests/auto/gui/kernel/qwindow/BLACKLIST | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tests/auto/gui/kernel/qwindow/BLACKLIST diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST new file mode 100644 index 0000000000..ee9709e68b --- /dev/null +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -0,0 +1,6 @@ +[positioning:default] +ubuntu-14.04 +[modalWindowPosition] +ubuntu-14.04 +[modalWithChildWindow] +ubuntu-14.04 -- cgit v1.2.3 From 21b5298d15755258bdedd5ab6c38acbd67c41b5f Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 21 May 2015 12:04:53 +0200 Subject: WinRT: Windows 10 compilation fix Header is required for successful compilation. Change-Id: I401b7c6fbc594b3cd0c9a4b25afc8ff918d8bddd Reviewed-by: Andrew Knight --- src/network/socket/qnativesocketengine_winrt_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 361fcf7ca2..42920c96f2 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -46,6 +46,7 @@ // #include #include +#include #include "QtNetwork/qhostaddress.h" #include "private/qabstractsocketengine_p.h" #include -- cgit v1.2.3 From 79ad3de7bfdb5da56e815993216852a6f3db2809 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 21 May 2015 17:11:26 +0200 Subject: QCoreWlanEngine - null the pointer QCoreWlanEngine is using a global variable but fails to reset it to nil when deleted, thus re-creating this WLAN manager we use a dangling pointer (found in qnetworkconfigurationmanagerqappless). Since our API allows to (re)create object(s) of these class, the pointer must be set to nil after -release call. Ideally, of course, this class has to be re-factored. Change-Id: I08662f55dc6cd2ceb0e0cad2574ee3dee6b8e3fd Reviewed-by: Alex Blasche --- src/plugins/bearer/corewlan/qcorewlanengine.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 9530dd83d0..a30d8f69c4 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -85,8 +85,11 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time return self; } +static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0; + -(void)dealloc { + listener = nil; [super dealloc]; } @@ -117,7 +120,6 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time } @end -static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0; QT_BEGIN_NAMESPACE -- cgit v1.2.3 From c200ef633e6d864a83b338d29782081e46a2cfcb Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 20 May 2015 10:17:28 +0200 Subject: Fix table view test The resizeColumnsToContents test would fail on some machines, as the requested 40 pixels where to small to accommodate the header size hint as well. Raising it to 60 pixels helps make the test pass. Change-Id: I2a5026fd18425e236849a1cef25ba8d899c7ae5a Reviewed-by: Simon Hausmann --- tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index 75f77f8107..9b3a6f6831 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -2249,11 +2249,11 @@ void tst_QTableView::resizeColumnsToContents_data() QTest::addColumn("rowHeight"); QTest::addColumn("columnWidth"); - QTest::newRow("10x10 grid shown 40x40") - << 10 << 10 << false << 40 << 40 << 40 << 40; + QTest::newRow("10x10 grid not shown 60x60") + << 10 << 10 << false << 60 << 60 << 60 << 60; - QTest::newRow("10x10 grid not shown 40x40") - << 10 << 10 << true << 40 << 40 << 41 << 41; + QTest::newRow("10x10 grid shown 60x60") + << 10 << 10 << true << 60 << 60 << 61 << 61; } void tst_QTableView::resizeColumnsToContents() -- cgit v1.2.3 From 35a161212c2d76f3fb98db06af822db2c05d19c1 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 20 May 2015 10:19:19 +0200 Subject: Fix blacklisting The test fails on all ubuntu versions, not only 14.04 as far as I can tell. Change-Id: I1e204f68bbb791eef25338f0ed007942a2eb22ff Reviewed-by: Simon Hausmann --- tests/auto/widgets/kernel/qaction/BLACKLIST | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/widgets/kernel/qaction/BLACKLIST b/tests/auto/widgets/kernel/qaction/BLACKLIST index f67a3c471e..a2afc905ba 100644 --- a/tests/auto/widgets/kernel/qaction/BLACKLIST +++ b/tests/auto/widgets/kernel/qaction/BLACKLIST @@ -1,2 +1,2 @@ [setStandardKeys] -ubuntu-14.04 +ubuntu -- cgit v1.2.3 From 1e2829f5bff1dd50603b9bed48b387a00f208774 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 May 2015 12:06:23 +0200 Subject: remove vestiges of .private_depends amends 16f4bc5b6. Change-Id: I5a9acb2fb57e92a152656be196e55c830031988e Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_functions.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 78be2e8473..a1c499610b 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -185,7 +185,7 @@ defineTest(qtAddRpathLink) { # paths OTOH need to be put there. pubqt = $$replace(1, -private$, _private) pubdep = $$resolve_depends(pubqt, "QT.") - privdep = $$resolve_depends(pubqt, "QT.", ".depends" ".private_depends" ".run_depends") + privdep = $$resolve_depends(pubqt, "QT.", ".depends" ".run_depends") privdep -= $$pubdep rpaths = for(dep, privdep): \ @@ -259,7 +259,7 @@ defineTest(qtAddToolEnv) { # target variable, dependency var name, [non-empty: prepare for system(), not make] defineTest(qtAddTargetEnv) { deps = $$replace($$2, -private$, _private) - deps = $$resolve_depends(deps, "QT.", ".depends" ".private_depends" ".run_depends") + deps = $$resolve_depends(deps, "QT.", ".depends" ".run_depends") !isEmpty(deps) { ptypes = for(dep, deps) { -- cgit v1.2.3 From bcf3a3c113321bcfc547894539ed976ad525b7eb Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 May 2015 14:03:01 +0200 Subject: fix quoting of qmake parameters in 'qmake' target we need to do full shell quoting, not the limited whitespace quoting. Task-number: QTBUG-46224 Change-Id: I41bc9aee556ca680dce0875b58159a31db962452 Reviewed-by: Joerg Bornemann --- qmake/generators/makefile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 728be67acc..4a03fafd77 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2240,7 +2240,7 @@ QString MakefileGenerator::buildArgs() QString ret; foreach (const QString &arg, Option::globals->qmake_args) - ret += " " + escapeFilePath(arg); + ret += " " + shellQuote(arg); return ret; } -- cgit v1.2.3 From 8e797477b9dae664a7d0009dd635435741bb8852 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 May 2015 21:07:23 +0200 Subject: remove vestiges of -prebind magic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit since commit 22edeb3f4 (private; anno 2002), the generator would extract -prebind and translate it into a PREBINDING property in the pbx file. the writeout to the pbx file got lost in the rewrite for Xcode 3.2 (commit 66f6e5b1; anno 2012). this isn't particularly bad, as prebinding is obsolete since OS X 10.3.4. we now go the last mile and remove the handling of the flag. that means that remaining projects which still use it (meaninglessly) will get a warning from Xcode, which is kinda what we want. QMAKE_LFLAGS should have never been part of the library iteration loop. it was added there in the prebind handling commit, so we can get rid of it again now. Change-Id: Id7dee2b1e248bb2bd7aa7a3e66f82057921afffd Reviewed-by: Tor Arne Vestbø --- qmake/generators/mac/pbuilder_pbx.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index d9eb149177..adf6ca5fb0 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -810,7 +810,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES ProStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"), &frameworkdirs = project->values("QMAKE_FRAMEWORKPATH"); - static const char * const libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; + static const char * const libs[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; for (int i = 0; libs[i]; i++) { tmp = project->values(libs[i]); for(int x = 0; x < tmp.count();) { @@ -821,9 +821,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString r = opt.mid(2).toQString(); fixForOutput(r); libdirs.append(r); - } else if(opt == "-prebind") { - project->values("QMAKE_DO_PREBINDING").append("TRUE"); - remove = true; } else if(opt.startsWith("-l")) { name = opt.mid(2).toQString(); QString lib("lib" + name); -- cgit v1.2.3 From b5af68d97846abf633227a3d445ef2b4b733b3a7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 20 May 2015 18:44:15 +0200 Subject: Make QSystemError const-correct Change-Id: I8688d6ebd9c4773136e2303cddf96ad997b0cfae Reviewed-by: Thiago Macieira --- src/corelib/kernel/qsystemerror.cpp | 2 +- src/corelib/kernel/qsystemerror_p.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp index 19d84c2b3e..e333104add 100644 --- a/src/corelib/kernel/qsystemerror.cpp +++ b/src/corelib/kernel/qsystemerror.cpp @@ -145,7 +145,7 @@ static QString standardLibraryErrorString(int errorCode) return ret.trimmed(); } -QString QSystemError::toString() +QString QSystemError::toString() const { switch(errorScope) { case NativeError: diff --git a/src/corelib/kernel/qsystemerror_p.h b/src/corelib/kernel/qsystemerror_p.h index e7efb9bbf3..29e9e440e4 100644 --- a/src/corelib/kernel/qsystemerror_p.h +++ b/src/corelib/kernel/qsystemerror_p.h @@ -62,9 +62,9 @@ public: inline QSystemError(int error, ErrorScope scope); inline QSystemError(); - QString toString(); - inline ErrorScope scope(); - inline int error(); + QString toString() const; + inline ErrorScope scope() const; + inline int error() const; //data members int errorCode; @@ -83,12 +83,12 @@ QSystemError::QSystemError() } -QSystemError::ErrorScope QSystemError::scope() +QSystemError::ErrorScope QSystemError::scope() const { return errorScope; } -int QSystemError::error() +int QSystemError::error() const { return errorCode; } -- cgit v1.2.3 From 4476966e0469dfdf372f6b1c119407acef37a6f2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 22 May 2015 11:56:23 +0200 Subject: Direct2D: Fix MSVC2015 warnings. qwindowsdirect2dpaintengine.cpp(365): warning C4838: conversion from 'const qreal' to 'FLOAT' requires a narrowing conversion qwindowsdirect2dpaintengine.cpp(928): warning C4838: conversion from 'const qreal' to 'FLOAT' requires a narrowing conversion qwindowsdirect2dpaintengine.cpp(928): warning C4838: conversion from 'int' to 'UINT32' requires a narrowing conversion qwindowsdirect2dpaintengine.cpp(1398): warning C4838: conversion from 'qreal' to 'FLOAT' requires a narrowing conversion qwindowsdirect2dpaintengine.cpp(1426): warning C4838: conversion from 'double' to 'FLOAT' requires a narrowing conversion qwindowsdirect2dbitmap.cpp(78): warning C4838: conversion from 'int' to 'UINT32' requires a narrowing conversion qwindowsdirect2dwindow.cpp(166): warning C4838: conversion from 'double' to 'BYTE' requires a narrowing conversion Change-Id: I6992260ed2696fa4c47c1c0dd666f448f115879a Reviewed-by: Joerg Bornemann --- .../direct2d/qwindowsdirect2dpaintengine.cpp | 22 +++++++++++----------- .../platforms/direct2d/qwindowsdirect2dwindow.cpp | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index d439196dc1..16c05329de 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -358,10 +358,10 @@ public: } else if (path.isRect() && (q->state()->matrix.type() <= QTransform::TxScale)) { const qreal * const points = path.points(); D2D_RECT_F rect = { - points[0], // left - points[1], // top - points[2], // right, - points[5] // bottom + FLOAT(points[0]), // left + FLOAT(points[1]), // top + FLOAT(points[2]), // right, + FLOAT(points[5]) // bottom }; dc()->PushAxisAlignedClip(rect, antialiasMode()); @@ -918,13 +918,13 @@ public: DWRITE_GLYPH_RUN glyphRun = { fontFace, // IDWriteFontFace *fontFace; - fontDef.pixelSize, // FLOAT fontEmSize; - numGlyphs, // UINT32 glyphCount; + FLOAT(fontDef.pixelSize), // FLOAT fontEmSize; + UINT32(numGlyphs), // UINT32 glyphCount; glyphIndices, // const UINT16 *glyphIndices; glyphAdvances, // const FLOAT *glyphAdvances; glyphOffsets, // const DWRITE_GLYPH_OFFSET *glyphOffsets; FALSE, // BOOL isSideways; - rtl ? 1 : 0 // UINT32 bidiLevel; + rtl ? 1u : 0u // UINT32 bidiLevel; }; const bool antiAlias = bool((q->state()->renderHints & QPainter::TextAntialiasing) @@ -1393,8 +1393,8 @@ void QWindowsDirect2DPaintEngine::drawEllipse(const QRectF &r) D2D1_ELLIPSE ellipse = { to_d2d_point_2f(p), - r.width() / 2.0, - r.height() / 2.0 + FLOAT(r.width() / 2.0), + FLOAT(r.height() / 2.0) }; if (d->brush.brush) @@ -1421,8 +1421,8 @@ void QWindowsDirect2DPaintEngine::drawEllipse(const QRect &r) D2D1_ELLIPSE ellipse = { to_d2d_point_2f(p), - r.width() / 2.0, - r.height() / 2.0 + FLOAT(r.width() / 2.0), + FLOAT(r.height() / 2.0) }; if (d->brush.brush) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp index e762eab711..ba23526447 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp @@ -163,7 +163,7 @@ void QWindowsDirect2DWindow::present(const QRegion ®ion) const SIZE size = { bounds.width(), bounds.height() }; const POINT ptDst = { bounds.x(), bounds.y() }; const POINT ptSrc = { 0, 0 }; - const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255.0 * opacity(), AC_SRC_ALPHA }; + const BLENDFUNCTION blend = { AC_SRC_OVER, 0, BYTE(255.0 * opacity()), AC_SRC_ALPHA }; const QRect r = region.boundingRect(); const RECT dirty = { r.left(), r.top(), r.left() + r.width(), r.top() + r.height() }; UPDATELAYEREDWINDOWINFO info = { sizeof(UPDATELAYEREDWINDOWINFO), NULL, -- cgit v1.2.3 From cab7e7858ae97eedc122fdfa7df082cbdb590d7c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 18 May 2015 10:31:33 +0200 Subject: Make OpenGL legacy examples hellogl and overpainting work with Dynamic GL. Call GL functions using QOpenGLFunctions_1_1. Task-number: QTBUG-46103 Change-Id: I1cbacf9c192c17d96d96aa861bb16e2918a0c053 Reviewed-by: Laszlo Agocs --- examples/opengl/legacy/hellogl/glwidget.cpp | 4 ++- examples/opengl/legacy/hellogl/glwidget.h | 3 +- examples/opengl/legacy/hellogl/hellogl.pro | 2 +- examples/opengl/legacy/overpainting/glwidget.cpp | 4 ++- examples/opengl/legacy/overpainting/glwidget.h | 3 +- .../opengl/legacy/overpainting/overpainting.pro | 2 +- examples/opengl/legacy/shared/qtlogo.cpp | 37 +++++++++++----------- examples/opengl/legacy/shared/qtlogo.h | 3 +- 8 files changed, 33 insertions(+), 25 deletions(-) diff --git a/examples/opengl/legacy/hellogl/glwidget.cpp b/examples/opengl/legacy/hellogl/glwidget.cpp index 02501cd99e..122f7ddfe1 100644 --- a/examples/opengl/legacy/hellogl/glwidget.cpp +++ b/examples/opengl/legacy/hellogl/glwidget.cpp @@ -128,6 +128,8 @@ void GLWidget::setZRotation(int angle) //! [6] void GLWidget::initializeGL() { + initializeOpenGLFunctions(); + qglClearColor(qtPurple.dark()); logo = new QtLogo(this, 64); @@ -153,7 +155,7 @@ void GLWidget::paintGL() glRotatef(xRot / 16.0, 1.0, 0.0, 0.0); glRotatef(yRot / 16.0, 0.0, 1.0, 0.0); glRotatef(zRot / 16.0, 0.0, 0.0, 1.0); - logo->draw(); + logo->draw(static_cast(this)); } //! [7] diff --git a/examples/opengl/legacy/hellogl/glwidget.h b/examples/opengl/legacy/hellogl/glwidget.h index 994e38e13d..9aca4451df 100644 --- a/examples/opengl/legacy/hellogl/glwidget.h +++ b/examples/opengl/legacy/hellogl/glwidget.h @@ -42,11 +42,12 @@ #define GLWIDGET_H #include +#include class QtLogo; //! [0] -class GLWidget : public QGLWidget +class GLWidget : public QGLWidget, public QOpenGLFunctions_1_1 { Q_OBJECT diff --git a/examples/opengl/legacy/hellogl/hellogl.pro b/examples/opengl/legacy/hellogl/hellogl.pro index bb75b07200..c211242fd2 100644 --- a/examples/opengl/legacy/hellogl/hellogl.pro +++ b/examples/opengl/legacy/hellogl/hellogl.pro @@ -14,4 +14,4 @@ QT += opengl widgets target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/hellogl INSTALLS += target -contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") +contains(QT_CONFIG, opengles.|angle):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/overpainting/glwidget.cpp b/examples/opengl/legacy/overpainting/glwidget.cpp index b41bc31126..52b6c35801 100644 --- a/examples/opengl/legacy/overpainting/glwidget.cpp +++ b/examples/opengl/legacy/overpainting/glwidget.cpp @@ -115,6 +115,8 @@ void GLWidget::setZRotation(int angle) //! [2] void GLWidget::initializeGL() { + initializeOpenGLFunctions(); + glEnable(GL_MULTISAMPLE); logo = new QtLogo(this); @@ -173,7 +175,7 @@ void GLWidget::paintEvent(QPaintEvent *event) glRotatef(yRot / 16.0, 0.0, 1.0, 0.0); glRotatef(zRot / 16.0, 0.0, 0.0, 1.0); - logo->draw(); + logo->draw(static_cast(this)); //! [7] //! [8] diff --git a/examples/opengl/legacy/overpainting/glwidget.h b/examples/opengl/legacy/overpainting/glwidget.h index dd5c0ba9ff..7e62a00170 100644 --- a/examples/opengl/legacy/overpainting/glwidget.h +++ b/examples/opengl/legacy/overpainting/glwidget.h @@ -42,13 +42,14 @@ #define GLWIDGET_H #include +#include #include class Bubble; class QtLogo; //! [0] -class GLWidget : public QGLWidget +class GLWidget : public QGLWidget, public QOpenGLFunctions_1_1 { Q_OBJECT diff --git a/examples/opengl/legacy/overpainting/overpainting.pro b/examples/opengl/legacy/overpainting/overpainting.pro index cbed7eed2b..cc46f18889 100644 --- a/examples/opengl/legacy/overpainting/overpainting.pro +++ b/examples/opengl/legacy/overpainting/overpainting.pro @@ -16,4 +16,4 @@ SOURCES = bubble.cpp \ target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/overpainting INSTALLS += target -contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") +contains(QT_CONFIG, opengles.|angle):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/shared/qtlogo.cpp b/examples/opengl/legacy/shared/qtlogo.cpp index efe3fb0201..0d960dd4b6 100644 --- a/examples/opengl/legacy/shared/qtlogo.cpp +++ b/examples/opengl/legacy/shared/qtlogo.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -60,7 +61,7 @@ struct Geometry void appendSmooth(const QVector3D &a, const QVector3D &n, int from); void appendFaceted(const QVector3D &a, const QVector3D &n); void finalize(); - void loadArrays() const; + void loadArrays(QOpenGLFunctions_1_1 *functions) const; }; //! [0] @@ -73,7 +74,7 @@ public: void setSmoothing(Smoothing s) { sm = s; } void translate(const QVector3D &t); void rotate(qreal deg, QVector3D axis); - void draw() const; + void draw(QOpenGLFunctions_1_1 *functions) const; void addTri(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &n); void addQuad(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &d); @@ -96,10 +97,10 @@ static inline void qSetColor(float colorVec[], QColor c) colorVec[3] = c.alphaF(); } -void Geometry::loadArrays() const +void Geometry::loadArrays(QOpenGLFunctions_1_1 *functions) const { - glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); - glNormalPointer(GL_FLOAT, 0, normals.constData()); + functions->glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); + functions->glNormalPointer(GL_FLOAT, 0, normals.constData()); } void Geometry::finalize() @@ -170,15 +171,15 @@ void Patch::translate(const QVector3D &t) } //! [2] -void Patch::draw() const +void Patch::draw(QOpenGLFunctions_1_1 *functions) const { - glPushMatrix(); - glMultMatrixf(mat.constData()); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor); + functions->glPushMatrix(); + functions->glMultMatrixf(mat.constData()); + functions->glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor); const GLushort *indices = geom->faces.constData(); - glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices + start); - glPopMatrix(); + functions->glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices + start); + functions->glPopMatrix(); } //! [2] @@ -371,17 +372,17 @@ void QtLogo::buildGeometry(int divisions, qreal scale) //! [3] //! [4] -void QtLogo::draw() const +void QtLogo::draw(QOpenGLFunctions_1_1 *functions) const { - geom->loadArrays(); + geom->loadArrays(functions); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); + functions->glEnableClientState(GL_VERTEX_ARRAY); + functions->glEnableClientState(GL_NORMAL_ARRAY); for (int i = 0; i < parts.count(); ++i) - parts[i]->draw(); + parts[i]->draw(functions); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + functions->glDisableClientState(GL_VERTEX_ARRAY); + functions->glDisableClientState(GL_NORMAL_ARRAY); } //! [4] diff --git a/examples/opengl/legacy/shared/qtlogo.h b/examples/opengl/legacy/shared/qtlogo.h index 562435daed..9bd15a1431 100644 --- a/examples/opengl/legacy/shared/qtlogo.h +++ b/examples/opengl/legacy/shared/qtlogo.h @@ -44,6 +44,7 @@ #include #include +class QOpenGLFunctions_1_1; class Patch; struct Geometry; @@ -54,7 +55,7 @@ public: explicit QtLogo(QObject *parent, int d = 64, qreal s = 1.0); ~QtLogo(); void setColor(QColor c); - void draw() const; + void draw(QOpenGLFunctions_1_1 *functions) const; private: void buildGeometry(int d, qreal s); -- cgit v1.2.3 From 06de0da1e8429f8174cfa78b644a09c0c23c478d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 18 May 2015 16:19:48 +0200 Subject: Make warnings of QIODevice more verbose. Include class name, object name and file name when available. For the bug in question: QIODevice::read: device not open becomes QIODevice::read (QTcpSocket, "QFtpDTP Passive state socket"): device not open Adding a static function also makes it easier to set a breakpoint and find the culprit. Task-number: QTBUG-46112 Change-Id: Ic181d8ab292912d1acbcc3cb84d9679fe4842ca0 Reviewed-by: Laszlo Papp Reviewed-by: Alex Trotsenko Reviewed-by: Kai Koehne --- src/corelib/io/qiodevice.cpp | 40 ++++++++++++++++------ tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp | 2 +- tests/auto/corelib/io/qfile/tst_qfile.cpp | 4 +-- tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp | 2 +- .../auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 10 +++--- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index e73a200fb4..872e004d2f 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -38,6 +38,7 @@ #include "qiodevice_p.h" #include "qfile.h" #include "qstringlist.h" +#include "qdir.h" #include #include @@ -80,10 +81,29 @@ void debugBinaryString(const char *data, qint64 maxlen) #define Q_VOID +static void checkWarnMessage(const QIODevice *device, const char *function, const char *what) +{ + QDebug d = qWarning(); + d.noquote(); + d.nospace(); + d << "QIODevice::" << function; +#ifndef QT_NO_QOBJECT + d << " (" << device->metaObject()->className(); + if (!device->objectName().isEmpty()) + d << ", \"" << device->objectName() << '"'; + if (const QFile *f = qobject_cast(device)) + d << ", \"" << QDir::toNativeSeparators(f->fileName()) << '"'; + d << ')'; +#else + Q_UNUSED(device) +#endif // !QT_NO_QOBJECT + d << ": " << what; +} + #define CHECK_MAXLEN(function, returnType) \ do { \ if (maxSize < 0) { \ - qWarning("QIODevice::"#function": Called with maxSize < 0"); \ + checkWarnMessage(this, #function, "Called with maxSize < 0"); \ return returnType; \ } \ } while (0) @@ -92,10 +112,10 @@ void debugBinaryString(const char *data, qint64 maxlen) do { \ if ((d->openMode & WriteOnly) == 0) { \ if (d->openMode == NotOpen) { \ - qWarning("QIODevice::"#function": device not open"); \ + checkWarnMessage(this, #function, "device not open"); \ return returnType; \ } \ - qWarning("QIODevice::"#function": ReadOnly device"); \ + checkWarnMessage(this, #function, "ReadOnly device"); \ return returnType; \ } \ } while (0) @@ -104,10 +124,10 @@ void debugBinaryString(const char *data, qint64 maxlen) do { \ if ((d->openMode & ReadOnly) == 0) { \ if (d->openMode == NotOpen) { \ - qWarning("QIODevice::"#function": device not open"); \ + checkWarnMessage(this, #function, "device not open"); \ return returnType; \ } \ - qWarning("QIODevice::"#function": WriteOnly device"); \ + checkWarnMessage(this, #function, "WriteOnly device"); \ return returnType; \ } \ } while (0) @@ -462,7 +482,7 @@ void QIODevice::setTextModeEnabled(bool enabled) { Q_D(QIODevice); if (!isOpen()) { - qWarning("QIODevice::setTextModeEnabled: The device is not open"); + checkWarnMessage(this, "setTextModeEnabled", "The device is not open"); return; } if (enabled) @@ -621,11 +641,11 @@ bool QIODevice::seek(qint64 pos) { Q_D(QIODevice); if (d->isSequential()) { - qWarning("QIODevice::seek: Cannot call seek on a sequential device"); + checkWarnMessage(this, "seek", "Cannot call seek on a sequential device"); return false; } if (d->openMode == NotOpen) { - qWarning("QIODevice::seek: The device is not open"); + checkWarnMessage(this, "seek", "The device is not open"); return false; } if (pos < 0) { @@ -923,7 +943,7 @@ QByteArray QIODevice::read(qint64 maxSize) #endif if (maxSize != qint64(int(maxSize))) { - qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit"); + checkWarnMessage(this, "read", "maxSize argument exceeds QByteArray size limit"); maxSize = INT_MAX; } @@ -1055,7 +1075,7 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize) { Q_D(QIODevice); if (maxSize < 2) { - qWarning("QIODevice::readLine: Called with maxSize < 2"); + checkWarnMessage(this, "readLine", "Called with maxSize < 2"); return qint64(-1); } diff --git a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp index f792b34d48..3b730d97f9 100644 --- a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp +++ b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp @@ -151,7 +151,7 @@ void tst_QBuffer::readBlock() QCOMPARE(b.bytesAvailable(), (qint64) arraySize); b.open(QIODevice::WriteOnly); QCOMPARE(b.bytesAvailable(), (qint64) arraySize); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::read (QBuffer): WriteOnly device"); QCOMPARE(b.read(a, arraySize), (qint64) -1); // no read access b.close(); diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 98963108be..5025dd38db 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -2334,7 +2334,7 @@ void tst_QFile::readFromWriteOnlyFile() QFile file("writeonlyfile"); QVERIFY(file.open(QFile::WriteOnly)); char c; - QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::read (QFile, \"writeonlyfile\"): WriteOnly device"); QCOMPARE(file.read(&c, 1), qint64(-1)); } @@ -2343,7 +2343,7 @@ void tst_QFile::writeToReadOnlyFile() QFile file("readonlyfile"); QVERIFY(file.open(QFile::ReadOnly)); char c = 0; - QTest::ignoreMessage(QtWarningMsg, "QIODevice::write: ReadOnly device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::write (QFile, \"readonlyfile\"): ReadOnly device"); QCOMPARE(file.write(&c, 1), qint64(-1)); } diff --git a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp index f756588e80..565ca18899 100644 --- a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp +++ b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp @@ -224,7 +224,7 @@ void tst_QIODevice::unget() buf[0] = '@'; buf[1] = '@'; QTest::ignoreMessage(QtWarningMsg, - "QIODevice::readLine: Called with maxSize < 2"); + "QIODevice::readLine (QBuffer): Called with maxSize < 2"); QCOMPARE(buffer.readLine(buf, 1), qint64(-1)); QCOMPARE(buffer.readLine(buf, 2), qint64(i < 4 ? 1 : -1)); switch (i) { diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index f4d3555531..b0a19a6c2d 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -401,8 +401,8 @@ void tst_QSslSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthent void tst_QSslSocket::constructing() { - const char readNotOpenMessage[] = "QIODevice::read: device not open"; - const char writeNotOpenMessage[] = "QIODevice::write: device not open"; + const char readNotOpenMessage[] = "QIODevice::read (QSslSocket): device not open"; + const char writeNotOpenMessage[] = "QIODevice::write (QSslSocket): device not open"; if (!QSslSocket::supportsSsl()) return; @@ -440,13 +440,13 @@ void tst_QSslSocket::constructing() QCOMPARE(socket.read(0, 0), qint64(-1)); QTest::ignoreMessage(QtWarningMsg, readNotOpenMessage); QVERIFY(socket.readAll().isEmpty()); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine: Called with maxSize < 2"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine (QSslSocket): Called with maxSize < 2"); QCOMPARE(socket.readLine(0, 0), qint64(-1)); char buf[10]; QCOMPARE(socket.readLine(buf, sizeof(buf)), qint64(-1)); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: Cannot call seek on a sequential device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek (QSslSocket): Cannot call seek on a sequential device"); QVERIFY(!socket.reset()); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: Cannot call seek on a sequential device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek (QSslSocket): Cannot call seek on a sequential device"); QVERIFY(!socket.seek(2)); QCOMPARE(socket.size(), qint64(0)); QVERIFY(!socket.waitForBytesWritten(10)); -- cgit v1.2.3 From 0c85cdb8c2601981ce313f262f7d6db951bf61ac Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 19 May 2015 15:25:14 +0200 Subject: QFtp: Suppress warning about reading from closed QIODevice. Clear bytesFromSocket when the socket is not open instead of reading in QFtpDTP::socketConnectionClosed(), which is connected to QTcpSocket::disconnected(). Task-number: QTBUG-46112 Change-Id: I0e5e47448f88601eb5c62fe9ba92e1a461323364 Reviewed-by: Timur Pocheptsov --- src/network/access/qftp.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index bb89eece4b..a83d56f31f 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -736,7 +736,10 @@ void QFtpDTP::socketConnectionClosed() clearData(); } - bytesFromSocket = socket->readAll(); + if (socket->isOpen()) + bytesFromSocket = socket->readAll(); + else + bytesFromSocket.clear(); #if defined(QFTPDTP_DEBUG) qDebug("QFtpDTP::connectState(CsClosed)"); #endif -- cgit v1.2.3 From 431e5d9f47515b51dfde582f28ea6bfed5bf82dd Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Thu, 14 May 2015 18:45:33 +0300 Subject: fingerpaint example: Use the maximum diameter for the touch spot by default The result doesn't look good when you paint with the MinimumDiameter (3 px). Also don't paint released touch points, because we can't get neither the touch rect not the pressure for them. Change-Id: I8d17c4884ae41545b2cd3f208afa73262133456c Reviewed-by: Laszlo Agocs --- examples/touch/fingerpaint/scribblearea.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/touch/fingerpaint/scribblearea.cpp b/examples/touch/fingerpaint/scribblearea.cpp index 469c6b1a70..05598c134c 100644 --- a/examples/touch/fingerpaint/scribblearea.cpp +++ b/examples/touch/fingerpaint/scribblearea.cpp @@ -187,13 +187,14 @@ bool ScribbleArea::event(QEvent *event) foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) { switch (touchPoint.state()) { case Qt::TouchPointStationary: - // don't do anything if this touch point hasn't moved + case Qt::TouchPointReleased: + // don't do anything if this touch point hasn't moved or has been released continue; default: { QRectF rect = touchPoint.rect(); if (rect.isEmpty()) { - qreal diameter = MinimumDiameter; + qreal diameter = MaximumDiameter; if (touch->device()->capabilities() & QTouchDevice::Pressure) diameter = MinimumDiameter + (MaximumDiameter - MinimumDiameter) * touchPoint.pressure(); rect.setSize(QSizeF(diameter, diameter)); -- cgit v1.2.3 From d0b1c646b4a351f7eea2137c68993ae63b2b6bab Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Fri, 15 May 2015 13:12:45 +0300 Subject: xcb: Properly calculate the size of the touch rect ABS_MT_TOUCH_MAJOR is given in surface units rather than in finger units. Also it's not the width of the touch rect but the length of the major axis of the contact. Currently we don't support the orientation of touch rects, so report square rects with side length of ABS_MT_TOUCH_MAJOR. Change-Id: I16c861f30128438ec4a1cae983700f8da4b7b4b7 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index c43816fa05..1848fc14f0 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -43,7 +43,6 @@ #include #include -#define FINGER_MAX_WIDTH_MM 10 struct XInput2TouchDeviceData { XInput2TouchDeviceData() @@ -517,7 +516,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) QWindowSystemInterface::TouchPoint &touchPoint = m_touchPoints[xiDeviceEvent->detail]; qreal x = fixed1616ToReal(xiDeviceEvent->root_x); qreal y = fixed1616ToReal(xiDeviceEvent->root_y); - qreal nx = -1.0, ny = -1.0, w = 0.0, h = 0.0; + qreal nx = -1.0, ny = -1.0, d = 0.0; QXcbScreen* screen = m_screens.at(0); for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; @@ -543,13 +542,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) { ny = valuatorNormalized(value, vci); } else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) { - // Convert the value within its range as a fraction of a finger's max (contact patch) - // width in mm, and from there to pixels depending on screen resolution - w = valuatorNormalized(value, vci) * FINGER_MAX_WIDTH_MM * - screen->geometry().width() / screen->physicalSize().width(); - } else if (vci->label == atom(QXcbAtom::AbsMTTouchMinor)) { - h = valuatorNormalized(value, vci) * FINGER_MAX_WIDTH_MM * - screen->geometry().height() / screen->physicalSize().height(); + d = valuatorNormalized(value, vci) * screen->geometry().width(); } else if (vci->label == atom(QXcbAtom::AbsMTPressure) || vci->label == atom(QXcbAtom::AbsPressure)) { touchPoint.pressure = valuatorNormalized(value, vci); @@ -566,10 +559,8 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) ny = y / screen->geometry().height(); } if (xiEvent->evtype != XI_TouchEnd) { - if (w == 0.0) - w = touchPoint.area.width(); - if (h == 0.0) - h = touchPoint.area.height(); + if (d == 0.0) + d = touchPoint.area.width(); } switch (xiEvent->evtype) { @@ -606,7 +597,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) } dev->pointPressedPosition.remove(touchPoint.id); } - touchPoint.area = QRectF(x - w/2, y - h/2, w, h); + touchPoint.area = QRectF(x - d/2, y - d/2, d, d); touchPoint.normalPosition = QPointF(nx, ny); if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) -- cgit v1.2.3 From cf5f961064433df4774824cef8c9482f49c5e788 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 22 May 2015 15:11:29 +0200 Subject: stabilize qwidget autotest These changes are required to make event delivery from test lib synchronous. Change-Id: I8f7093a2bfe01dfa1b0315620d672e7346a7a23a Reviewed-by: Simon Hausmann --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 11d41d9b20..10c553bd3e 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -3444,7 +3444,8 @@ void tst_QWidget::testDeletionInEventHandlers() w = new Widget; w->show(); w->deleteThis = true; - QTest::mouseRelease(w, Qt::LeftButton); + QMouseEvent me(QEvent::MouseButtonRelease, QPoint(1, 1), Qt::LeftButton, Qt::LeftButton, 0); + qApp->notify(w, &me); QVERIFY(w == 0); delete w; @@ -3482,7 +3483,7 @@ void tst_QWidget::testDeletionInEventHandlers() w->setMouseTracking(true); w->show(); w->deleteThis = true; - QMouseEvent me(QEvent::MouseMove, QPoint(0, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier); + me = QMouseEvent(QEvent::MouseMove, QPoint(0, 0), Qt::NoButton, Qt::NoButton, Qt::NoModifier); QApplication::sendEvent(w, &me); QVERIFY(w == 0); delete w; @@ -8957,7 +8958,7 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave() int numEnterEvents, numMouseMoveEvents; }; - QCursor::setPos(QPoint(0,0)); + QCursor::setPos(QPoint(0,0)); SELParent parent; parent.move(200, 200); @@ -8965,8 +8966,7 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave() SELChild child(&parent); child.resize(200, 200); parent.show(); - QVERIFY(QTest::qWaitForWindowExposed(&parent)); - QTest::qWait(150); + QVERIFY(QTest::qWaitForWindowActive(&parent)); QCursor::setPos(child.mapToGlobal(QPoint(100, 100))); // Make sure the cursor has entered the child. @@ -9714,8 +9714,9 @@ void tst_QWidget::grabMouse() QVERIFY(QTest::qWaitForWindowActive(&w)); QStringList expectedLog; - grabber->grabMouse(); QPoint mousePos = QPoint(w.width() / 2, 10); + QTest::mouseMove(w.windowHandle(), mousePos); + grabber->grabMouse(); const int step = w.height() / 5; for ( ; mousePos.y() < w.height() ; mousePos.ry() += step) { QTest::mouseClick(w.windowHandle(), Qt::LeftButton, 0, mousePos); @@ -10333,6 +10334,9 @@ public: void tst_QWidget::keyboardModifiers() { KeyboardWidget w; + w.resize(300, 300); + w.show(); + QVERIFY(QTest::qWaitForWindowActive(&w)); QTest::mouseClick(&w, Qt::LeftButton, Qt::ControlModifier); QCOMPARE(w.m_eventCounter, 1); QCOMPARE(int(w.m_modifiers), int(Qt::ControlModifier)); -- cgit v1.2.3 From b0992b5998636b7c2464c387284638b4e93f0389 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 22 May 2015 13:18:36 +0200 Subject: Fix autotest on xcb and make it significant again Change-Id: Ia7c0fb715a66b8d865481a73e16dcd0d3bdf4988 Reviewed-by: Simon Hausmann --- .../widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro | 1 - .../graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro index d9d9818d6c..38fef51394 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/qgraphicsproxywidget.pro @@ -6,5 +6,4 @@ QT += core-private gui-private SOURCES += tst_qgraphicsproxywidget.cpp -contains(QT_CONFIG,xcb):CONFIG+=insignificant_test # QTBUG-25294 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index f8d852888c..05a97dc2f3 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -1223,6 +1223,7 @@ void tst_QGraphicsProxyWidget::mousePressReleaseEvent() QGraphicsScene scene; QGraphicsView view(&scene); + view.resize(500, 500); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); @@ -1231,7 +1232,6 @@ void tst_QGraphicsProxyWidget::mousePressReleaseEvent() QPushButton *widget = new QPushButton; QSignalSpy spy(widget, SIGNAL(clicked())); widget->resize(50, 50); - view.resize(100, 100); if (hasWidget) { proxy->setWidget(widget); proxy->show(); -- cgit v1.2.3 From 66050f2ac875d451bec31e0d8ff507795b5b18d6 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 21 May 2015 15:12:21 +0200 Subject: Make event delivery from testlib synchronous Directly process events delivered from testlib in QGuiApplication. The old code put these events into the QPA event queue leading to race conditions with plugins delivering native events from a secondary thread. Change-Id: I5646b1014f681593d487c9d1e65053ba06206411 Reviewed-by: Simon Hausmann --- src/gui/kernel/qwindowsysteminterface.cpp | 70 +++++++++++++++++++------------ 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 629bd02cd2..de8e5fbe64 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -811,12 +811,25 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPo #endif Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier) { - QWindowSystemInterface::handleMouseEvent(w, local, global, b, mods); + unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed(); + QWindowSystemInterfacePrivate::MouseEvent e(w, timestamp, local, global, b, mods, Qt::MouseEventNotSynthesized); + QGuiApplicationPrivate::processWindowSystemEvent(&e); } Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1) { - QWindowSystemInterface::handleKeyEvent(w, t, k, mods, text, autorep, count); + unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed(); + + // This is special handling needed for OS X which eventually will call sendEvent(), on other platforms + // this might not be safe, e.g., on Android. See: QGuiApplicationPrivate::processKeyEvent() for + // shortcut overriding on other platforms. +#if defined(Q_OS_OSX) + if (t == QEvent::KeyPress && QWindowSystemInterface::tryHandleShortcutEvent(w, timestamp, k, mods, text)) + return; +#endif // Q_OS_OSX + + QWindowSystemInterfacePrivate::KeyEvent e(w, timestamp, t, k, mods, text, autorep, count); + QGuiApplicationPrivate::processWindowSystemEvent(&e); } Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1) @@ -824,35 +837,38 @@ Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int return QWindowSystemInterface::tryHandleShortcutEventToObject(o, timestamp, k, mods, text, autorep, count); } -static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt) -{ - QWindowSystemInterface::TouchPoint p; - p.id = pt.id(); - p.flags = pt.flags(); - p.normalPosition = pt.normalizedPos(); - p.area = pt.screenRect(); - p.pressure = pt.pressure(); - p.state = pt.state(); - p.velocity = pt.velocity(); - p.rawPositions = pt.rawScreenPositions(); - return p; -} -static QList touchPointList(const QList& pointList) -{ - QList newList; - - Q_FOREACH (QTouchEvent::TouchPoint p, pointList) - { - newList.append(touchPoint(p)); - } - return newList; -} -Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device, +Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device, const QList &points, Qt::KeyboardModifiers mods = Qt::NoModifier) { - QWindowSystemInterface::handleTouchEvent(w, device, touchPointList(points), mods); + unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed(); + + if (!points.size()) // Touch events must have at least one point + return; + + if (!QTouchDevicePrivate::isRegistered(device)) // Disallow passing bogus, non-registered devices. + return; + + QEvent::Type type; + Qt::TouchPointStates states; + + QList::const_iterator point = points.constBegin(); + QList::const_iterator end = points.constEnd(); + while (point != end) { + states |= point->state(); + ++point; + } + + // Determine the event type based on the combined point states. + type = QEvent::TouchUpdate; + if (states == Qt::TouchPointPressed) + type = QEvent::TouchBegin; + else if (states == Qt::TouchPointReleased) + type = QEvent::TouchEnd; + + QWindowSystemInterfacePrivate::TouchEvent e(w, timestamp, type, device, points, mods); + QGuiApplicationPrivate::processWindowSystemEvent(&e); } QWindowSystemEventHandler::~QWindowSystemEventHandler() -- cgit v1.2.3 From 75af24a2d121ab56c5b60524bf1d7f2af1613025 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Sat, 23 May 2015 14:04:09 +0200 Subject: QMetaType: Do not automatically register types that derives from a Q_GADGET Otherwise the type is registered with the wrong name Change-Id: I68ec3a05e2528816626e648b46ccc9d70b004866 Reviewed-by: Simon Hausmann --- src/corelib/kernel/qmetatype.h | 12 ++++++++---- src/corelib/kernel/qobjectdefs.h | 1 + tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 2 ++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index b854dc16fd..9ad8702e79 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1357,12 +1357,16 @@ namespace QtPrivate enum { Value = sizeof(checkType(static_cast(0))) == sizeof(yes_type) }; }; + template + struct IsGadgetHelper { enum { Value = false }; }; + template - struct IsGadgetHelper + struct IsGadgetHelper { - template static typename X::QtGadgetHelper *checkType(X*); - static char checkType(void*); - enum { Value = sizeof(checkType(static_cast(0))) == sizeof(void*) }; + template + static char checkType(void (X::*)()); + static void *checkType(void (T::*)()); + enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; }; diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 31e8a670e9..4d01264906 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -172,6 +172,7 @@ private: \ #define Q_GADGET \ public: \ static const QMetaObject staticMetaObject; \ + void qt_check_for_QGADGET_macro(); \ typedef void QtGadgetHelper; \ private: \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index b3333c6d68..691a4e819d 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -144,6 +144,7 @@ class CustomGadget { }; class CustomNonQObject {}; +class GadgetDerived : public CustomGadget {}; void tst_QMetaType::defined() { @@ -153,6 +154,7 @@ void tst_QMetaType::defined() QCOMPARE(int(QMetaTypeId2::Defined), 0); QCOMPARE(int(QMetaTypeId2::Defined), 1); QCOMPARE(int(QMetaTypeId2::Defined), 1); + QVERIFY(!QMetaTypeId2::Defined); QVERIFY(int(QMetaTypeId2::Defined)); QVERIFY(!QMetaTypeId2::Defined); QVERIFY(!QMetaTypeId2::Defined); -- cgit v1.2.3 From 5926d7422ee6631fcef958a69720e9bc3c45bb8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 22 May 2015 14:43:39 +0200 Subject: iOS: Clean up style in Objective-C message signatures - Space between class/instance signifier - No space between return type and message name - No space in message arguments Change-Id: Ie25e0be3c134586c44bb82bf7075f6eb153388a9 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Jake Petroules --- src/plugins/platforms/ios/qiosapplicationstate.mm | 12 +++++----- src/plugins/platforms/ios/qiosclipboard.mm | 4 ++-- src/plugins/platforms/ios/qioseventdispatcher.mm | 6 ++--- src/plugins/platforms/ios/qiosglobal.h | 2 +- src/plugins/platforms/ios/qiosglobal.mm | 4 ++-- src/plugins/platforms/ios/qiosmenu.mm | 4 ++-- src/plugins/platforms/ios/qiosscreen.mm | 8 +++---- src/plugins/platforms/ios/qiostextresponder.mm | 16 ++++++------- src/plugins/platforms/ios/qiosviewcontroller.mm | 6 ++--- .../platforms/ios/quiaccessibilityelement.h | 4 ++-- .../platforms/ios/quiaccessibilityelement.mm | 26 +++++++++++----------- src/plugins/platforms/ios/quiview.mm | 4 ++-- 12 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm index 92799f80c1..7a37e213bd 100644 --- a/src/plugins/platforms/ios/qiosapplicationstate.mm +++ b/src/plugins/platforms/ios/qiosapplicationstate.mm @@ -43,7 +43,7 @@ @implementation QIOSApplicationStateListener -- (id) init +- (id)init { self = [super init]; if (self) { @@ -75,7 +75,7 @@ return self; } -- (void) dealloc +- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self @@ -92,12 +92,12 @@ [super dealloc]; } -- (void) applicationDidBecomeActive +- (void)applicationDidBecomeActive { [self handleApplicationStateChanged:UIApplicationStateActive]; } -- (void) applicationWillResignActive +- (void)applicationWillResignActive { // Note that UIApplication is still UIApplicationStateActive at this // point, but since there is no separate notification for the inactive @@ -105,12 +105,12 @@ [self handleApplicationStateChanged:UIApplicationStateInactive]; } -- (void) applicationDidEnterBackground +- (void)applicationDidEnterBackground { [self handleApplicationStateChanged:UIApplicationStateBackground]; } -- (void) handleApplicationStateChanged:(UIApplicationState) uiApplicationState +- (void)handleApplicationStateChanged:(UIApplicationState)uiApplicationState { // We may receive application state changes after QCoreApplication has // gone down, as the block we schedule on the main queue keeps the diff --git a/src/plugins/platforms/ios/qiosclipboard.mm b/src/plugins/platforms/ios/qiosclipboard.mm index 192ee67689..e0c6ec5d72 100644 --- a/src/plugins/platforms/ios/qiosclipboard.mm +++ b/src/plugins/platforms/ios/qiosclipboard.mm @@ -62,7 +62,7 @@ @implementation QUIClipboard --(id)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard +- (id)initWithQIOSClipboard:(QIOSClipboard *)qiosClipboard { self = [super init]; if (self) { @@ -87,7 +87,7 @@ return self; } --(void)dealloc +- (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm index fc12e83a81..8e4b4c5875 100644 --- a/src/plugins/platforms/ios/qioseventdispatcher.mm +++ b/src/plugins/platforms/ios/qioseventdispatcher.mm @@ -293,7 +293,7 @@ static bool rootLevelRunLoopIntegration() @implementation QIOSApplicationStateTracker -+ (void) load ++ (void)load { [[NSNotificationCenter defaultCenter] addObserver:self @@ -323,7 +323,7 @@ static bool rootLevelRunLoopIntegration() # error "Unknown processor family" #endif -+ (void) applicationDidFinishLaunching ++ (void)applicationDidFinishLaunching { if (!isQtApplication()) return; @@ -377,7 +377,7 @@ static bool rootLevelRunLoopIntegration() // four bits of the exit code (exit(3) will only pass on the lower 8 bits). static const char kApplicationWillTerminateExitCode = SIGTERM | 0x80; -+ (void) applicationWillTerminate ++ (void)applicationWillTerminate { if (!isQtApplication()) return; diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 86b784618f..544f9e0a42 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -68,7 +68,7 @@ int infoPlistValue(NSString* key, int defaultValue); QT_END_NAMESPACE @interface UIResponder (QtFirstResponder) -+(id)currentFirstResponder; ++ (id)currentFirstResponder; @end class FirstResponderCandidate : public QScopedValueRollback diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index ef24abbfd9..f5b971391d 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -133,7 +133,7 @@ int infoPlistValue(NSString* key, int defaultValue) @end @implementation QtFirstResponderEvent -- (void) dealloc +- (void)dealloc { self.firstResponder = 0; [super dealloc]; @@ -158,7 +158,7 @@ int infoPlistValue(NSString* key, int defaultValue) @implementation UIResponder (QtFirstResponder) -+(id)currentFirstResponder ++ (id)currentFirstResponder { QtFirstResponderEvent *event = [[[QtFirstResponderEvent alloc] init] autorelease]; [[UIApplication sharedApplication] sendAction:@selector(qt_findFirstResponder:event:) to:nil from:nil forEvent:event]; diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index 08fc8a5e9c..045d39e328 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -165,7 +165,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; [self reloadAllComponents]; } --(void)listenForKeyboardWillHideNotification:(BOOL)listen +- (void)listenForKeyboardWillHideNotification:(BOOL)listen { if (listen) { [[NSNotificationCenter defaultCenter] @@ -179,7 +179,7 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; } } --(void)dealloc +- (void)dealloc { [self listenForKeyboardWillHideNotification:NO]; self.toolbar = 0; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 324133074b..3e16efcd22 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -104,12 +104,12 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) @public QIOSScreen *m_screen; } -- (id) initWithQIOSScreen:(QIOSScreen *)screen; +- (id)initWithQIOSScreen:(QIOSScreen *)screen; @end @implementation QIOSOrientationListener -- (id) initWithQIOSScreen:(QIOSScreen *)screen +- (id)initWithQIOSScreen:(QIOSScreen *)screen { self = [super init]; if (self) { @@ -123,7 +123,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) return self; } -- (void) dealloc +- (void)dealloc { [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] @@ -132,7 +132,7 @@ static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen) [super dealloc]; } -- (void) orientationChanged:(NSNotification *)notification +- (void)orientationChanged:(NSNotification *)notification { Q_UNUSED(notification); m_screen->updateProperties(); diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 3d0bac82c8..c7356d7abd 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -92,12 +92,12 @@ return [QUITextPosition positionWithIndex:(self.range.location + self.range.length)]; } -- (NSRange) range +- (NSRange)range { return _range; } --(BOOL)isEmpty +- (BOOL)isEmpty { return (self.range.length == 0); } @@ -111,7 +111,7 @@ @implementation WrapperView --(id)initWithView:(UIView *)view +- (id)initWithView:(UIView *)view { if (self = [self init]) { [self addSubview:view]; @@ -143,7 +143,7 @@ // retained, we ensure that all messages sent to the view during // its lifetime in a window hierarcy will be able to traverse the // responder chain. --(void)willMoveToWindow:(UIWindow *)window +- (void)willMoveToWindow:(UIWindow *)window { if (window) [[self nextResponder] retain]; @@ -383,17 +383,17 @@ return m_inputContext->imeState().currentState.value(query); } --(id)tokenizer +- (id)tokenizer { return [[[UITextInputStringTokenizer alloc] initWithTextInput:id(self)] autorelease]; } --(UITextPosition *)beginningOfDocument +- (UITextPosition *)beginningOfDocument { return [QUITextPosition positionWithIndex:0]; } --(UITextPosition *)endOfDocument +- (UITextPosition *)endOfDocument { int endPosition = [self currentImeState:Qt::ImSurroundingText].toString().length(); return [QUITextPosition positionWithIndex:endPosition]; @@ -659,7 +659,7 @@ return [NSDictionary dictionaryWithObject:uifont forKey:UITextInputTextFontKey]; } --(NSDictionary *)markedTextStyle +- (NSDictionary *)markedTextStyle { return [NSDictionary dictionary]; } diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 6667ec3dd8..4ea5fc7de1 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -288,13 +288,13 @@ // ------------------------------------------------------------------------- --(BOOL)shouldAutorotate +- (BOOL)shouldAutorotate { return m_screen && m_screen->uiScreen() == [UIScreen mainScreen] && !self.lockedOrientation; } #if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_6_0) --(NSUInteger)supportedInterfaceOrientations +- (NSUInteger)supportedInterfaceOrientations { // As documented by Apple in the iOS 6.0 release notes, setStatusBarOrientation:animated: // only works if the supportedInterfaceOrientations of the view controller is 0, making @@ -307,7 +307,7 @@ #endif #if QT_IOS_DEPLOYMENT_TARGET_BELOW(__IPHONE_6_0) --(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { Q_UNUSED(interfaceOrientation); return [self shouldAutorotate]; diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.h b/src/plugins/platforms/ios/quiaccessibilityelement.h index a690e12c7d..c76e3a6a1e 100644 --- a/src/plugins/platforms/ios/quiaccessibilityelement.h +++ b/src/plugins/platforms/ios/quiaccessibilityelement.h @@ -42,8 +42,8 @@ @property (readonly) QAccessible::Id axid; -- (id) initWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view; -+ (QMacAccessibilityElement *) elementWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view; +- (id)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view; ++ (QMacAccessibilityElement *)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view; @end diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.mm b/src/plugins/platforms/ios/quiaccessibilityelement.mm index 2cecfc1126..3bac1ca88d 100644 --- a/src/plugins/platforms/ios/quiaccessibilityelement.mm +++ b/src/plugins/platforms/ios/quiaccessibilityelement.mm @@ -37,7 +37,7 @@ @implementation QMacAccessibilityElement -- (id) initWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view +- (id)initWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view { Q_ASSERT((int)anId < 0); self = [super initWithAccessibilityContainer: view]; @@ -47,7 +47,7 @@ return self; } -+ (id) elementWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view ++ (id)elementWithId:(QAccessible::Id)anId withAccessibilityContainer:(id)view { Q_ASSERT(anId); if (!anId) @@ -64,17 +64,17 @@ return element; } -- (void) invalidate +- (void)invalidate { [self release]; } -- (BOOL) isAccessibilityElement +- (BOOL)isAccessibilityElement { return YES; } -- (NSString*) accessibilityLabel +- (NSString*)accessibilityLabel { QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid); if (!iface) { @@ -85,7 +85,7 @@ return iface->text(QAccessible::Name).toNSString(); } -- (NSString*) accessibilityHint +- (NSString*)accessibilityHint { QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid); if (!iface) { @@ -95,7 +95,7 @@ return iface->text(QAccessible::Description).toNSString(); } -- (NSString*) accessibilityValue +- (NSString*)accessibilityValue { QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid); if (!iface) { @@ -119,7 +119,7 @@ return [super accessibilityHint]; } -- (CGRect) accessibilityFrame +- (CGRect)accessibilityFrame { QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid); if (!iface) { @@ -131,7 +131,7 @@ return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); } -- (UIAccessibilityTraits) accessibilityTraits +- (UIAccessibilityTraits)accessibilityTraits { UIAccessibilityTraits traits = UIAccessibilityTraitNone; @@ -156,7 +156,7 @@ return traits; } -- (BOOL) accessibilityActivate +- (BOOL)accessibilityActivate { QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid); if (QAccessibleActionInterface *action = iface->actionInterface()) { @@ -171,21 +171,21 @@ return NO; // fall back to sending mouse clicks } -- (void) accessibilityIncrement +- (void)accessibilityIncrement { QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid); if (QAccessibleActionInterface *action = iface->actionInterface()) action->doAction(QAccessibleActionInterface::increaseAction()); } -- (void) accessibilityDecrement +- (void)accessibilityDecrement { QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid); if (QAccessibleActionInterface *action = iface->actionInterface()) action->doAction(QAccessibleActionInterface::decreaseAction()); } -- (BOOL) accessibilityScroll : (UIAccessibilityScrollDirection) direction +- (BOOL)accessibilityScroll:(UIAccessibilityScrollDirection)direction { QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid); QAccessibleActionInterface *action = iface->actionInterface(); diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 8be3515cb5..3039b89a1a 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -50,7 +50,7 @@ return [CAEAGLLayer class]; } --(id)initWithQIOSWindow:(QIOSWindow *)window +- (id)initWithQIOSWindow:(QIOSWindow *)window { if (self = [self initWithFrame:toCGRect(window->geometry())]) m_qioswindow = window; @@ -310,7 +310,7 @@ } } -- (void) sendTouchEventWithTimestamp:(ulong)timeStamp +- (void)sendTouchEventWithTimestamp:(ulong)timeStamp { // Send touch event synchronously QIOSIntegration *iosIntegration = QIOSIntegration::instance(); -- cgit v1.2.3 From 34adfc13722949f02d259251cd75c3ac77792ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 12 May 2015 14:01:14 +0200 Subject: qmake: Place Info.plist in correct location for plugin bundles Like application bundles on OSX, the plugin bundle has its Info.plist in the Contents directory. Change-Id: I216fa79857924beb0e9c5fcc4a8d06b197a3f383 Reviewed-by: Oswald Buddenhagen --- qmake/generators/unix/unixmake2.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 9b9e54c461..7c5f4b13ea 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -807,11 +807,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } else { info_plist = escapeFilePath(fileFixify(info_plist)); } - bool isApp = (project->first("TEMPLATE") == "app"); - QString info_plist_out = - bundle_dir + (isApp ? "Contents/Info.plist" - : "Versions/" + project->first("QMAKE_FRAMEWORK_VERSION") - + "/Resources/Info.plist"); + bool isFramework = project->first("TEMPLATE") == "lib" && project->isActiveConfig("lib_bundle"); + QString info_plist_out = bundle_dir + + (isFramework ? ("Versions/" + project->first("QMAKE_FRAMEWORK_VERSION") + "/Resources/Info.plist") + : "Contents/Info.plist"); bundledFiles << info_plist_out; alldeps << info_plist_out; QString destdir = info_plist_out.section(Option::dir_sep, 0, -2); @@ -842,7 +841,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) bundleIdentifier.chop(10); commonSedArgs << "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" "; - if (isApp) { + if (!isFramework) { QString icon = fileFixify(var("ICON")); t << "@$(DEL_FILE) " << info_plist_out << "\n\t" << "@sed "; @@ -850,6 +849,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << arg; t << "-e \"s,@ICON@," << icon.section(Option::dir_sep, -1) << ",g\" " << "-e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET") << ",g\" " + << "-e \"s,@LIBRARY@," << var("QMAKE_ORIG_TARGET") << ",g\" " << "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" " << "" << info_plist << " >" << info_plist_out << endl; -- cgit v1.2.3 From decd18536c1b021bc1f879a32be83372463a7f5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 11 May 2015 18:43:47 +0200 Subject: Ensure that CONFIG += plugin_bundle will create Mach-O bundles on OSX/iOS The makespec inits QMAKE_LFLAGS_PLUGIN to the same as QMAKE_LFLAGS_SHLIB, which will create a dynamic library by passing -dynamiclib. The advantage of creating a proper bundle (MH_BUNDLE) instead of a dynamic library (MH_DYLIB) is that bundles can be unloaded completely by the host application. Change-Id: I03b39b704c09213f40a4cb84f5794bf6b3669fc0 Reviewed-by: Jake Petroules --- mkspecs/features/plugin_bundle.prf | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 mkspecs/features/plugin_bundle.prf diff --git a/mkspecs/features/plugin_bundle.prf b/mkspecs/features/plugin_bundle.prf new file mode 100644 index 0000000000..f3e7294c90 --- /dev/null +++ b/mkspecs/features/plugin_bundle.prf @@ -0,0 +1,2 @@ +# Override mkspec default which creates a shared library +mac: QMAKE_LFLAGS_PLUGIN = -bundle -- cgit v1.2.3 From 8458b4054a8e5a2f90238d7973050a8d797fea7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sun, 24 May 2015 00:33:18 +0100 Subject: QWidgetWindow: Avoid using global static non-trivial type. Don't initialize it before main, instead, do it whenever QWidgetWindow::handleTabletEvent() is called, which is seldomly. Change-Id: I16935e223d4f9879257e7be026fee0215b9dde22 Reviewed-by: Marc Mutz --- src/widgets/kernel/qwidgetwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index d715438bfe..01d6d89857 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -51,7 +51,6 @@ QT_BEGIN_NAMESPACE Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets(); QWidget *qt_button_down = 0; // widget got last button-down -static QPointer qt_tablet_target = 0; // popup control QWidget *qt_popup_down = 0; // popup that contains the pressed widget @@ -873,6 +872,7 @@ bool QWidgetWindow::nativeEvent(const QByteArray &eventType, void *message, long #ifndef QT_NO_TABLETEVENT void QWidgetWindow::handleTabletEvent(QTabletEvent *event) { + static QPointer qt_tablet_target = 0; if (event->type() == QEvent::TabletPress) { QWidget *widget = m_widget->childAt(event->pos()); if (!widget) -- cgit v1.2.3 From 7a4f3645f44bae78987facbf4e39231d0d2882ef Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Sat, 23 May 2015 12:11:09 +0100 Subject: Avoid false positives from google by storing OpenSSL version as Unicode. Google scan play store apps for the openssl version string which leads to false positives since we record the version we were compiled against even though we don't link it directly. Task-number: QTBUG-46265 Change-Id: Iefd0e0954149c17350d49f57f9f374938124d7b8 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/network/ssl/qsslsocket_openssl.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index b132aec038..ac4336afcc 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -588,7 +588,10 @@ long QSslSocketPrivate::sslLibraryBuildVersionNumber() QString QSslSocketPrivate::sslLibraryBuildVersionString() { - return QLatin1String(OPENSSL_VERSION_TEXT); + // Using QStringLiteral to store the version string as unicode and + // avoid false positives from Google searching the playstore for old + // SSL versions. See QTBUG-46265 + return QStringLiteral(OPENSSL_VERSION_TEXT); } /*! -- cgit v1.2.3 From ab156fcedd4c2d2856c0b46699c32926288be292 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 17 Apr 2015 08:04:04 +0200 Subject: Use the new non-obsoleted functions for getting the paper details This fixes a problem with the margins not being correctly respected as the functions introduced previously would set a different property to what was being queried in this case. Change-Id: I3458c8e46239276a296d17aa80da7330c85fcf0a Reviewed-by: Friedemann Kleint --- src/printsupport/widgets/qprintpreviewwidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/printsupport/widgets/qprintpreviewwidget.cpp b/src/printsupport/widgets/qprintpreviewwidget.cpp index 208ad5e0f3..7898dc9352 100644 --- a/src/printsupport/widgets/qprintpreviewwidget.cpp +++ b/src/printsupport/widgets/qprintpreviewwidget.cpp @@ -335,8 +335,8 @@ void QPrintPreviewWidgetPrivate::populateScene() pages.clear(); int numPages = pictures.count(); - QSize paperSize = printer->paperRect().size(); - QRect pageRect = printer->pageRect(); + QSize paperSize = printer->pageLayout().fullRectPixels(printer->resolution()).size(); + QRect pageRect = printer->pageLayout().paintRectPixels(printer->resolution()); for (int i = 0; i < numPages; i++) { PageItem* item = new PageItem(i+1, pictures.at(i), paperSize, pageRect); -- cgit v1.2.3 From 79be2601225bdb50cab72e2502b7d7f9ee81e94f Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 17 Apr 2015 08:10:10 +0200 Subject: Fix documentation of obsoleted functions to show the right replacement Change-Id: Ib008a5544d68d93e1f96ff6b7504e9a7ea4bb192 Reviewed-by: Friedemann Kleint --- src/printsupport/kernel/qprinter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index 8ed2732c1e..d7df796afb 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -1764,7 +1764,7 @@ QRectF QPrinter::paperRect(Unit unit) const } /*! - \obsolete Use pageLayout().paintRect() instead. + \obsolete Use pageLayout().paintRectPixels(resolution()) instead. Returns the page's rectangle; this is usually smaller than the paperRect() since the page normally has margins between its @@ -1781,7 +1781,7 @@ QRect QPrinter::pageRect() const } /*! - \obsolete Use pageLayout().fullPageRect() instead. + \obsolete Use pageLayout().fullRectPixels(resolution()) instead. Returns the paper's rectangle; this is usually larger than the pageRect(). -- cgit v1.2.3 From bd1f5b268a1095ec6a4856cef46bc8550a8a8af8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 19 May 2015 11:56:24 -0700 Subject: Make sure we don't call dbus_connection_can_send_type on too old libdbus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function was introduced alongside the support for Unix file descriptors, so it's a good indicator of whether Unix FDs are supported. Ever since dbus_minimal_p.h, however, DBUS_TYPE_UNIX_FD may be defined even if the system libs don't support it. In order to fix this issue, I had to fix what was apparently a merge conflict resolution mistake and remove the #ifdef around the test. Doing the latter is a good idea due to moc being unable to find . This was tested with both linked and dynamically-loaded libdbus-1. Task-number: QTBUG-46199 Change-Id: I66a35ce5f88941f29aa6ffff13dfb4b5438613a3 Reviewed-by: Jani Vähäkangas Reviewed-by: Alex Blasche --- src/dbus/qdbus_symbols_p.h | 3 -- .../auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp | 33 ++++++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h index cec8ad62cb..32b76ee5bd 100644 --- a/src/dbus/qdbus_symbols_p.h +++ b/src/dbus/qdbus_symbols_p.h @@ -183,9 +183,6 @@ DEFINEFUNC(dbus_bool_t , dbus_connection_add_filter, (DBusConnection void *user_data, DBusFreeFunction free_data_function), (connection, function, user_data, free_data_function), return) -DEFINEFUNC(dbus_bool_t , dbus_connection_can_send_type, (DBusConnection *connection, - int type), - (connection, type), return) DEFINEFUNC(void , dbus_connection_close, (DBusConnection *connection), (connection), return) DEFINEFUNC(DBusDispatchStatus , dbus_connection_dispatch, (DBusConnection *connection), diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp index 76e740dc5f..16314a5dc5 100644 --- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp @@ -39,10 +39,7 @@ #include #include - -#define QT_LINKED_LIBDBUS -#include -#include +#include static const char serviceName[] = "org.qtproject.autotests.qpong"; static const char objectPath[] = "/org/qtproject/qpong"; @@ -85,10 +82,8 @@ private slots: void sendCallErrors_data(); void sendCallErrors(); -#ifdef DBUS_TYPE_UNIX_FD void receiveUnknownType_data(); void receiveUnknownType(); -#endif void demarshallPrimitives_data(); void demarshallPrimitives(); @@ -1017,7 +1012,6 @@ void tst_QDBusMarshall::sendCallErrors() QCOMPARE(reply.errorMessage(), errorMsg); } -#ifdef DBUS_TYPE_UNIX_FD // If DBUS_TYPE_UNIX_FD is not defined, it means the current system's D-Bus library is too old for this test void tst_QDBusMarshall::receiveUnknownType_data() { @@ -1075,6 +1069,27 @@ public: } }; +// mostly the same as qdbusintegrator.cpp:connectionCapabilies +static bool canSendUnixFd(DBusConnection *connection) +{ + typedef dbus_bool_t (*can_send_type_t)(DBusConnection *, int); + static can_send_type_t can_send_type = 0; + +#if defined(QT_LINKED_LIBDBUS) +# if DBUS_VERSION-0 >= 0x010400 + can_send_type = dbus_connection_can_send_type; +# endif +#else + // run-time check if the next functions are available + can_send_type = (can_send_type_t)qdbus_resolve_conditionally("dbus_connection_can_send_type"); +#endif + +#ifndef DBUS_TYPE_UNIX_FD +# define DBUS_TYPE_UNIX_FD int('h') +#endif + return can_send_type && can_send_type(connection, DBUS_TYPE_UNIX_FD); +} + void tst_QDBusMarshall::receiveUnknownType() { QDBusConnection con = QDBusConnection::sessionBus(); @@ -1088,7 +1103,8 @@ void tst_QDBusMarshall::receiveUnknownType() QVERIFY2(rawcon.data(), error.name); // check if this bus supports passing file descriptors - if (!q_dbus_connection_can_send_type(rawcon.data(), DBUS_TYPE_UNIX_FD)) + + if (!canSendUnixFd(rawcon.data())) QSKIP("Your session bus does not allow sending Unix file descriptors"); // make sure this QDBusConnection won't handle Unix file descriptors @@ -1184,7 +1200,6 @@ void tst_QDBusMarshall::receiveUnknownType() QCOMPARE(spy.list.at(0).arguments().at(0).userType(), receivedTypeId); } } -#endif void tst_QDBusMarshall::demarshallPrimitives_data() { -- cgit v1.2.3 From 59cc316620a2169d48e00822c97a96bd03079eed Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Fri, 5 Dec 2014 16:08:28 +0300 Subject: Allow horizontal scrolling with a mouse wheel for QListView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert vertical wheel events to horizontal for two cases of the items layout when vertical scrolling is impossible: 1) TopToBottom flow with wrapping 2) LeftToRight flow without wrapping Do it only for pure vertical events to avoid a mess for such devices as touchpads or Apple Mouse. [ChangeLog][QtWidgets][Important Behavior Changes] Allow horizontal scrolling with a vertical mouse wheel for QListView. Task-number: QTBUG-37007 Change-Id: Ie2525153fa7b443d27ca08cc5f5d4d7ecdb8c183 Reviewed-by: Thorbjørn Lund Martsum Reviewed-by: Giuseppe D'Angelo --- src/widgets/itemviews/qlistview.cpp | 31 ++++++++++++++ src/widgets/itemviews/qlistview.h | 3 ++ .../widgets/itemviews/qlistview/tst_qlistview.cpp | 49 ++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index b7a4ec3925..29a6629bcd 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -53,6 +53,8 @@ QT_BEGIN_NAMESPACE +extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); + /*! \class QListView @@ -796,6 +798,35 @@ void QListView::mouseReleaseEvent(QMouseEvent *e) } } +#ifndef QT_NO_WHEELEVENT +/*! + \reimp +*/ +void QListView::wheelEvent(QWheelEvent *e) +{ + Q_D(QListView); + if (e->orientation() == Qt::Vertical) { + if (e->angleDelta().x() == 0 + && ((d->flow == TopToBottom && d->wrap) || (d->flow == LeftToRight && !d->wrap)) + && d->vbar->minimum() == 0 && d->vbar->maximum() == 0) { + QPoint pixelDelta(e->pixelDelta().y(), e->pixelDelta().x()); + QPoint angleDelta(e->angleDelta().y(), e->angleDelta().x()); + QWheelEvent hwe(e->pos(), e->globalPos(), pixelDelta, angleDelta, e->delta(), + Qt::Horizontal, e->buttons(), e->modifiers(), e->phase()); + if (e->spontaneous()) + qt_sendSpontaneousEvent(d->hbar, &hwe); + else + QApplication::sendEvent(d->hbar, &hwe); + e->setAccepted(hwe.isAccepted()); + } else { + QApplication::sendEvent(d->vbar, e); + } + } else { + QApplication::sendEvent(d->hbar, e); + } +} +#endif // QT_NO_WHEELEVENT + /*! \reimp */ diff --git a/src/widgets/itemviews/qlistview.h b/src/widgets/itemviews/qlistview.h index f62c96067f..ac65a47d9f 100644 --- a/src/widgets/itemviews/qlistview.h +++ b/src/widgets/itemviews/qlistview.h @@ -146,6 +146,9 @@ protected: void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE; +#ifndef QT_NO_WHEELEVENT + void wheelEvent(QWheelEvent *e) Q_DECL_OVERRIDE; +#endif void timerEvent(QTimerEvent *e) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE; diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index cea08435c9..22245707cc 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -148,6 +149,7 @@ private slots: void testScrollToWithHidden(); void testViewOptions(); void taskQTBUG_39902_mutualScrollBars(); + void horizontalScrollingByVerticalWheelEvents(); }; // Testing get/set functions @@ -2372,5 +2374,52 @@ void tst_QListView::taskQTBUG_39902_mutualScrollBars() QTest::qWait(100); } +void tst_QListView::horizontalScrollingByVerticalWheelEvents() +{ + QListView lv; + lv.setWrapping(true); + + TestDelegate *delegate = new TestDelegate(&lv); + delegate->m_sizeHint = QSize(100, 100); + lv.setItemDelegate(delegate); + + QtTestModel model; + model.colCount = 1; + model.rCount = 100; + + lv.setModel(&model); + + lv.resize(300, 300); + lv.show(); + QTest::qWaitForWindowExposed(&lv); + + QPoint globalPos = lv.geometry().center(); + QPoint pos = lv.viewport()->geometry().center(); + + QWheelEvent wheelDownEvent(pos, globalPos, QPoint(0, 0), QPoint(0, -120), -120, Qt::Vertical, 0, 0); + QWheelEvent wheelUpEvent(pos, globalPos, QPoint(0, 0), QPoint(0, 120), 120, Qt::Vertical, 0, 0); + QWheelEvent wheelLeftDownEvent(pos, globalPos, QPoint(0, 0), QPoint(120, -120), -120, Qt::Vertical, 0, 0); + + int hValue = lv.horizontalScrollBar()->value(); + QApplication::sendEvent(lv.viewport(), &wheelDownEvent); + QVERIFY(lv.horizontalScrollBar()->value() > hValue); + + QApplication::sendEvent(lv.viewport(), &wheelUpEvent); + QVERIFY(lv.horizontalScrollBar()->value() == hValue); + + QApplication::sendEvent(lv.viewport(), &wheelLeftDownEvent); + QVERIFY(lv.horizontalScrollBar()->value() == hValue); + + // ensure that vertical wheel events are not converted when vertical + // scroll bar is not visible but vertical scrolling is possible + lv.setWrapping(false); + lv.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + QApplication::processEvents(); + + int vValue = lv.verticalScrollBar()->value(); + QApplication::sendEvent(lv.viewport(), &wheelDownEvent); + QVERIFY(lv.verticalScrollBar()->value() > vValue); +} + QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc" -- cgit v1.2.3 From ee336c2096618782d5f30245a055bdeae56ecd2f Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Tue, 26 May 2015 12:43:02 +0300 Subject: QAbstractSocket: remove unused member Change-Id: I0fa3d9e1b00f38a1b04dddd09ec8c04199ad1f34 Reviewed-by: Friedemann Kleint Reviewed-by: Allan Sandfeld Jensen --- src/network/socket/qabstractsocket.cpp | 1 - src/network/socket/qabstractsocket_p.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 67dea74436..d6a3822422 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -559,7 +559,6 @@ QAbstractSocketPrivate::QAbstractSocketPrivate() readBufferMaxSize(0), writeBuffer(QABSTRACTSOCKET_BUFFERSIZE), isBuffered(false), - blockingTimeout(30000), connectTimer(0), disconnectTimer(0), connectTimeElapsed(0), diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h index 1c04277f49..85e82aef47 100644 --- a/src/network/socket/qabstractsocket_p.h +++ b/src/network/socket/qabstractsocket_p.h @@ -140,7 +140,6 @@ public: QRingBuffer writeBuffer; bool isBuffered; - int blockingTimeout; QTimer *connectTimer; QTimer *disconnectTimer; -- cgit v1.2.3 From a0e5210d8b6b21d33800e1fac30efbf2868f9f5b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 Apr 2015 12:34:16 +0200 Subject: Windows: Clean Qt::WindowFullscreenButtonHint in fixTopLevelWindowFlags(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do the correction of top level window flags also in case Qt::Window|Qt::WindowFullscreenButtonHint is passed, since it is not supported by the platform anyways. Task-number: QTBUG-31111 Change-Id: If035d7086e48174873b6b91acf90f730ea40b5a8 Reviewed-by: Morten Johan Sørvig Reviewed-by: J-P Nurmi --- src/plugins/platforms/windows/qwindowswindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 923040fd71..543c08135f 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -438,6 +438,8 @@ QDebug operator<<(QDebug debug, const WindowCreationData &d) // Fix top level window flags in case only the type flags are passed. static inline void fixTopLevelWindowFlags(Qt::WindowFlags &flags) { + // Not supported on Windows, also do correction when it is set. + flags &= ~Qt::WindowFullscreenButtonHint; switch (flags) { case Qt::Window: flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint -- cgit v1.2.3 From 80c8d324b335753d5b1758f29775b844904bb2c6 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 29 Apr 2015 14:36:24 +0200 Subject: take process name into account for QLockFile's pid clash resolution To cover the situation that the process ID got reused, the current process name is compared to the name of the process that corresponds to the process ID from the lock file. If the process names differ, the lock file is considered stale. [ChangeLog][QtCore][QLockFile] Detection of stale lock files got more robust and takes the name of the process that belongs to the stored PID into account. Task-number: QTBUG-45497 Change-Id: Ic3c0d7e066435451203e77b9b9ce2d70bfb9c570 Reviewed-by: Friedemann Kleint Reviewed-by: David Faure --- src/corelib/io/qlockfile.cpp | 12 ++++-- src/corelib/io/qlockfile_p.h | 1 + src/corelib/io/qlockfile_unix.cpp | 48 +++++++++++++++++++++++ src/corelib/io/qlockfile_win.cpp | 45 +++++++++++++++++++++ tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp | 48 +++++++++++++++++++++++ 5 files changed, 150 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index 4f5aeff395..2bd996d213 100644 --- a/src/corelib/io/qlockfile.cpp +++ b/src/corelib/io/qlockfile.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -66,9 +67,12 @@ QT_BEGIN_NAMESPACE If the process holding the lock crashes, the lock file stays on disk and can prevent any other process from accessing the shared resource, ever. For this reason, QLockFile - tries to detect such a "stale" lock file, based on the process ID written into the file, - and (in case that process ID got reused meanwhile), on the last modification time of - the lock file (30s by default, for the use case of a short-lived operation). + tries to detect such a "stale" lock file, based on the process ID written into the file. + To cover the situation that the process ID got reused meanwhile, the current process name is + compared to the name of the process that corresponds to the process ID from the lock file. + If the process names differ, the lock file is considered stale. + Additionally, the last modification time of the lock file (30s by default, for the use case of a + short-lived operation) is taken into account. If the lock file is found to be stale, it will be deleted. For the use case of protecting a resource over a long time, you should therefore call @@ -122,7 +126,7 @@ QLockFile::~QLockFile() The value of \a staleLockTime is used by lock() and tryLock() in order to determine when an existing lock file is considered stale, i.e. left over by a crashed process. This is useful for the case where the PID got reused - meanwhile, so the only way to detect a stale lock file is by the fact that + meanwhile, so one way to detect a stale lock file is by the fact that it has been around for a long time. \sa staleLockTime() diff --git a/src/corelib/io/qlockfile_p.h b/src/corelib/io/qlockfile_p.h index 0cfaa42849..168062f467 100644 --- a/src/corelib/io/qlockfile_p.h +++ b/src/corelib/io/qlockfile_p.h @@ -75,6 +75,7 @@ public: // Returns \c true if the lock belongs to dead PID, or is old. // The attempt to delete it will tell us if it was really stale or not, though. bool isApparentlyStale() const; + static QString processNameByPid(qint64 pid); #ifdef Q_OS_UNIX static int checkFcntlWorksAfterFlock(); diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index d1804f2cb6..d6ea2f1f2d 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -48,6 +49,15 @@ #include // kill #include // gethostname +#if defined(Q_OS_OSX) +# include +#elif defined(Q_OS_LINUX) +# include +# include +#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) +# include +#endif + QT_BEGIN_NAMESPACE static QByteArray localHostName() // from QHostInfo::localHostName(), modified to return a QByteArray @@ -189,12 +199,50 @@ bool QLockFilePrivate::isApparentlyStale() const if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { if (::kill(pid, 0) == -1 && errno == ESRCH) return true; // PID doesn't exist anymore + const QString processName = processNameByPid(pid); + if (!processName.isEmpty()) { + QFileInfo fi(appname); + if (fi.isSymLink()) + fi.setFile(fi.symLinkTarget()); + if (processName != fi.fileName()) + return true; // PID got reused by a different application. + } } } const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); return staleLockTime > 0 && age > staleLockTime; } +QString QLockFilePrivate::processNameByPid(qint64 pid) +{ +#if defined(Q_OS_OSX) + char name[1024]; + proc_name(pid, name, sizeof(name) / sizeof(char)); + return QString::fromUtf8(name); +#elif defined(Q_OS_LINUX) + if (!QFile::exists(QStringLiteral("/proc/version"))) + return QString(); + char exePath[64]; + char buf[PATH_MAX]; + memset(buf, 0, sizeof(buf)); + sprintf(exePath, "/proc/%lld/exe", pid); + if (readlink(exePath, buf, sizeof(buf)) < 0) { + // The pid is gone. Return some invalid process name to fail the test. + return QStringLiteral("/ERROR/"); + } + return QFileInfo(QString::fromUtf8(buf)).fileName(); +#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) + kinfo_proc *proc = kinfo_getproc(pid); + if (!proc) + return QString(); + QString name = QString::fromUtf8(proc->ki_comm); + free(proc); + return name; +#else + return QString(); +#endif +} + void QLockFile::unlock() { Q_D(QLockFile); diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index 4e0d8134ec..8cbe0a9dfd 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -140,6 +141,9 @@ bool QLockFilePrivate::isApparentlyStale() const ::CloseHandle(procHandle); if (dwR == WAIT_TIMEOUT) return true; + const QString processName = processNameByPid(pid); + if (!processName.isEmpty() && processName != appname) + return true; // PID got reused by a different application. } } #else // !Q_OS_WINRT @@ -151,6 +155,47 @@ bool QLockFilePrivate::isApparentlyStale() const return staleLockTime > 0 && age > staleLockTime; } +QString QLockFilePrivate::processNameByPid(qint64 pid) +{ +#if !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) + typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD); + + HMODULE hPsapi = LoadLibraryA("psapi"); + if (!hPsapi) + return QString(); + + GetModuleFileNameExFunc qGetModuleFileNameEx + = (GetModuleFileNameExFunc)GetProcAddress(hPsapi, "GetModuleFileNameExW"); + if (!qGetModuleFileNameEx) { + FreeLibrary(hPsapi); + return QString(); + } + + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, DWORD(pid)); + if (!hProcess) { + FreeLibrary(hPsapi); + return QString(); + } + wchar_t buf[MAX_PATH]; + const DWORD length = qGetModuleFileNameEx(hProcess, NULL, buf, sizeof(buf) / sizeof(wchar_t)); + CloseHandle(hProcess); + FreeLibrary(hPsapi); + if (!length) + return QString(); + QString name = QString::fromWCharArray(buf, length); + int i = name.lastIndexOf(QLatin1Char('\\')); + if (i >= 0) + name.remove(0, i + 1); + i = name.lastIndexOf(QLatin1Char('.')); + if (i >= 0) + name.truncate(i); + return name; +#else + Q_UNUSED(pid); + return QString(); +#endif +} + void QLockFile::unlock() { Q_D(QLockFile); diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp index 8d890e81fa..27614e0eb8 100644 --- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp +++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp @@ -57,6 +57,7 @@ private slots: void waitForLock(); void staleLockFromCrashedProcess_data(); void staleLockFromCrashedProcess(); + void staleLockFromCrashedProcessReusedPid(); void staleShortLockFromBusyProcess(); void staleLongLockFromBusyProcess(); void staleLockRace(); @@ -64,6 +65,9 @@ private slots: void noPermissionsWindows(); void corruptedLockFile(); +private: + static bool overwritePidInLockFile(const QString &filePath, qint64 pid); + public: QString m_helperApp; QTemporaryDir dir; @@ -277,6 +281,30 @@ void tst_QLockFile::staleLockFromCrashedProcess() #endif // !QT_NO_PROCESS } +void tst_QLockFile::staleLockFromCrashedProcessReusedPid() +{ +#if defined(QT_NO_PROCESS) + QSKIP("This test requires QProcess support"); +#elif defined(Q_OS_WINRT) || defined(Q_OS_WINCE) || defined(Q_OS_IOS) + QSKIP("We cannot retrieve information about other processes on this platform."); +#else + const QString fileName = dir.path() + "/staleLockFromCrashedProcessReusedPid"; + + int ret = QProcess::execute(m_helperApp, QStringList() << fileName << "-crash"); + QCOMPARE(ret, int(QLockFile::NoError)); + QVERIFY(QFile::exists(fileName)); + QVERIFY(overwritePidInLockFile(fileName, QCoreApplication::applicationPid())); + + QLockFile secondLock(fileName); + qint64 pid = 0; + secondLock.getLockInfo(&pid, 0, 0); + QCOMPARE(pid, QCoreApplication::applicationPid()); + secondLock.setStaleLockTime(0); + QVERIFY(secondLock.tryLock()); + QCOMPARE(int(secondLock.error()), int(QLockFile::NoError)); +#endif // !QT_NO_PROCESS +} + void tst_QLockFile::staleShortLockFromBusyProcess() { #ifdef QT_NO_PROCESS @@ -497,5 +525,25 @@ void tst_QLockFile::corruptedLockFile() QCOMPARE(int(secondLock.error()), int(QLockFile::NoError)); } +bool tst_QLockFile::overwritePidInLockFile(const QString &filePath, qint64 pid) +{ + QFile f(filePath); + if (!f.open(QFile::ReadWrite)) { + qWarning("Cannot open %s.", qPrintable(filePath)); + return false; + } + QByteArray buf = f.readAll(); + int i = buf.indexOf('\n'); + if (i < 0) { + qWarning("Unexpected lockfile content."); + return false; + } + buf.remove(0, i); + buf.prepend(QByteArray::number(pid)); + f.seek(0); + f.resize(buf.size()); + return f.write(buf) == buf.size(); +} + QTEST_MAIN(tst_QLockFile) #include "tst_qlockfile.moc" -- cgit v1.2.3 From 99b08dd9d2a9030fe44c3e634b0baf38c163dcc2 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 17 Apr 2015 02:53:28 -0700 Subject: WinRT: Add qmake support for Windows 10 This allows creation of applications for - x86 - x64 - arm While the arm build theoretically also allows to launch on a mobile, it currently asserts on runtime. Either we will create a new mkspec for Windows 10 Mobile in the future, or do runtime checks for the environment. That also depends on whether there will be a separate SDK by Microsoft. Change-Id: I510bfc88410a5b5a1eb7c37f7f43888d1e5dda0d Reviewed-by: Oswald Buddenhagen Reviewed-by: Oliver Wolff Reviewed-by: Andrew Knight --- .../manifests/10.0/AppxManifest.xml.in | 49 ++++++++++++++++++++++ mkspecs/winrt-arm-msvc2015/qmake.conf | 32 ++++++++++++++ mkspecs/winrt-arm-msvc2015/qplatformdefs.h | 34 +++++++++++++++ mkspecs/winrt-x64-msvc2015/qmake.conf | 32 ++++++++++++++ mkspecs/winrt-x64-msvc2015/qplatformdefs.h | 34 +++++++++++++++ mkspecs/winrt-x86-msvc2015/qmake.conf | 32 ++++++++++++++ mkspecs/winrt-x86-msvc2015/qplatformdefs.h | 34 +++++++++++++++ qmake/generators/win32/msbuild_objectmodel.cpp | 7 +++- qmake/generators/win32/msvc_nmake.cpp | 28 +++++++++++-- qmake/generators/win32/msvc_objectmodel.h | 3 +- qmake/generators/win32/msvc_vcproj.cpp | 11 +++++ 11 files changed, 290 insertions(+), 6 deletions(-) create mode 100644 mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in create mode 100644 mkspecs/winrt-arm-msvc2015/qmake.conf create mode 100644 mkspecs/winrt-arm-msvc2015/qplatformdefs.h create mode 100644 mkspecs/winrt-x64-msvc2015/qmake.conf create mode 100644 mkspecs/winrt-x64-msvc2015/qplatformdefs.h create mode 100644 mkspecs/winrt-x86-msvc2015/qmake.conf create mode 100644 mkspecs/winrt-x86-msvc2015/qplatformdefs.h diff --git a/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in new file mode 100644 index 0000000000..c6419660c1 --- /dev/null +++ b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in @@ -0,0 +1,49 @@ + + + + + + + + + + $${WINRT_MANIFEST.name} + $${WINRT_MANIFEST.publisher} + $${WINRT_MANIFEST.logo_store} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mkspecs/winrt-arm-msvc2015/qmake.conf b/mkspecs/winrt-arm-msvc2015/qmake.conf new file mode 100644 index 0000000000..fcb6d99aa9 --- /dev/null +++ b/mkspecs/winrt-arm-msvc2015/qmake.conf @@ -0,0 +1,32 @@ +# +# qmake configuration for winrt-arm-msvc2015 +# +# Written for Microsoft Visual C++ 2015 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1900 +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP ARM __ARM__ __arm__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:ARM /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib + +# Note that the order is important, ucrt(d) has to be first +# Otherwise the linker might use malloc from a different library +# but free_dbg() from the runtime, causing assert when deleting +# items from different heaps +CONFIG(debug, debug|release) { + QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS +} else { + QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS +} + +VCPROJ_ARCH = ARM +MSVC_VER = 14.0 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = arm diff --git a/mkspecs/winrt-arm-msvc2015/qplatformdefs.h b/mkspecs/winrt-arm-msvc2015/qplatformdefs.h new file mode 100644 index 0000000000..c8f88524d9 --- /dev/null +++ b/mkspecs/winrt-arm-msvc2015/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x64-msvc2015/qmake.conf b/mkspecs/winrt-x64-msvc2015/qmake.conf new file mode 100644 index 0000000000..e8062f5364 --- /dev/null +++ b/mkspecs/winrt-x64-msvc2015/qmake.conf @@ -0,0 +1,32 @@ +# +# qmake configuration for winrt-x64-msvc2015 +# +# Written for Microsoft Visual C++ 2015 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1900 _WIN32 +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X64 __X64__ __x64__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:X64 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib + +# Note that the order is important, ucrt(d) has to be first +# Otherwise the linker might use malloc from a different library +# but free_dbg() from the runtime, causing assert when deleting +# items from different heaps +CONFIG(debug, debug|release) { + QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS +} else { + QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS +} + +VCPROJ_ARCH = x64 +MSVC_VER = 14.0 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x64 diff --git a/mkspecs/winrt-x64-msvc2015/qplatformdefs.h b/mkspecs/winrt-x64-msvc2015/qplatformdefs.h new file mode 100644 index 0000000000..c8f88524d9 --- /dev/null +++ b/mkspecs/winrt-x64-msvc2015/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x86-msvc2015/qmake.conf b/mkspecs/winrt-x86-msvc2015/qmake.conf new file mode 100644 index 0000000000..5b44a97e8d --- /dev/null +++ b/mkspecs/winrt-x86-msvc2015/qmake.conf @@ -0,0 +1,32 @@ +# +# qmake configuration for winrt-x86-msvc2015 +# +# Written for Microsoft Visual C++ 2015 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1900 _WIN32 +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X86 __X86__ __x86__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib + +# Note that the order is important, ucrt(d) has to be first +# Otherwise the linker might use malloc from a different library +# but free_dbg() from the runtime, causing assert when deleting +# items from different heaps +CONFIG(debug, debug|release) { + QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS +} else { + QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS +} + +VCPROJ_ARCH = Win32 +MSVC_VER = 14.0 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x86 diff --git a/mkspecs/winrt-x86-msvc2015/qplatformdefs.h b/mkspecs/winrt-x86-msvc2015/qplatformdefs.h new file mode 100644 index 0000000000..c8f88524d9 --- /dev/null +++ b/mkspecs/winrt-x86-msvc2015/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 6c2d2c6206..cbf7cf26dc 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -608,10 +608,13 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) xml.setIndentString(" "); + const QString toolsVersion = (tool.SdkVersion == QStringLiteral("10.0")) ? QStringLiteral("14.0") + : QStringLiteral("4.0"); + xml << decl("1.0", "utf-8") << tag("Project") << attrTag("DefaultTargets","Build") - << attrTag("ToolsVersion", "4.0") + << attrTag("ToolsVersion", toolsVersion) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003") << tag("ItemGroup") << attrTag("Label", "ProjectConfigurations"); @@ -640,7 +643,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << tagValue("DefaultLanguage", "en") << tagValue("AppContainerApplication", "true") << tagValue("ApplicationType", isWinPhone ? "Windows Phone" : "Windows Store") - << tagValue("ApplicationTypeRevision", tool.SdkVersion); + << tagValue("ApplicationTypeRevision", tool.SdkVersion == "10.0" ? "8.2" : tool.SdkVersion); } xml << closetag(); diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index eb8ae23384..dfa8f8837b 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -176,11 +176,34 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) const QString vcInstallDir = "/fake/vc_install_dir"; const QString kitDir = "/fake/sdk_install_dir"; #endif // Q_OS_WIN - QStringList incDirs; QStringList libDirs; QStringList binDirs; - if (isPhone) { + if (msvcVer == QStringLiteral("14.0")) { + binDirs << vcInstallDir + QStringLiteral("bin/") + compiler; + binDirs << vcInstallDir + QStringLiteral("bin/"); // Maybe remove for x86 again? + binDirs << kitDir + QStringLiteral("bin/") + (arch == QStringLiteral("arm") ? QStringLiteral("x86") : arch); + binDirs << vcInstallDir + QStringLiteral("../Common7/Tools/bin"); + binDirs << vcInstallDir + QStringLiteral("../Common7/Tools"); + binDirs << vcInstallDir + QStringLiteral("../Common7/ide"); + binDirs << kitDir + QStringLiteral("Windows Performance Toolkit/"); + + incDirs << vcInstallDir + QStringLiteral("include"); + incDirs << vcInstallDir + QStringLiteral("atlmfc/include"); + // ### Investigate why VS uses 10056 first + incDirs << kitDir + QStringLiteral("Include/10.0.10056.0/ucrt"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/ucrt"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/um"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/shared"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/winrt"); + + libDirs << vcInstallDir + QStringLiteral("lib/store/") + compilerArch; + libDirs << vcInstallDir + QStringLiteral("atlmfc/lib") + compilerArch; + // ### Investigate why VS uses 10056 first + libDirs << kitDir + QStringLiteral("lib/10.0.10056.0/ucrt/") + arch; + libDirs << kitDir + QStringLiteral("lib/10.0.10069.0/ucrt/") + arch; + libDirs << kitDir + QStringLiteral("lib/10.0.10069.0/um/") + arch; + } else if (isPhone) { QString sdkDir = vcInstallDir; if (!QDir(sdkDir).exists()) { fprintf(stderr, "Failed to find the Windows Phone SDK in %s.\n" @@ -208,7 +231,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) << kitDir + QStringLiteral("/include/shared") << kitDir + QStringLiteral("/include/winrt"); } - // Inherit PATH binDirs << QString::fromLocal8Bit(qgetenv("PATH")).split(QLatin1Char(';')); diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 59136b16c8..7092da3e59 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -56,7 +56,8 @@ enum DotNET { NET2008 = 0x90, NET2010 = 0xa0, NET2012 = 0xb0, - NET2013 = 0xc0 + NET2013 = 0xc0, + NET2015 = 0xd0 }; /* diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 1fa117afda..fd2fc2eb94 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -71,6 +71,7 @@ struct DotNetCombo { const char *regKey; } dotNetCombo[] = { #ifdef Q_OS_WIN64 + {NET2015, "MSVC.NET 2015 (14.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\14.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 (12.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\12.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 Express Edition (12.0)", "Software\\Wow6432Node\\Microsoft\\VCExpress\\12.0\\Setup\\VC\\ProductDir"}, {NET2012, "MSVC.NET 2012 (11.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir"}, @@ -84,6 +85,7 @@ struct DotNetCombo { {NET2003, "MSVC.NET 2003 (7.1)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir"}, {NET2002, "MSVC.NET 2002 (7.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir"}, #else + {NET2015, "MSVC.NET 2015 (14.0)", "Software\\Microsoft\\VisualStudio\\14.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 (12.0)", "Software\\Microsoft\\VisualStudio\\12.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 Express Edition (12.0)", "Software\\Microsoft\\VCExpress\\12.0\\Setup\\VC\\ProductDir"}, {NET2012, "MSVC.NET 2012 (11.0)", "Software\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir"}, @@ -175,6 +177,8 @@ const char _slnHeader110[] = "Microsoft Visual Studio Solution File, Format "\n# Visual Studio 2012"; const char _slnHeader120[] = "Microsoft Visual Studio Solution File, Format Version 12.00" "\n# Visual Studio 2013"; +const char _slnHeader140[] = "Microsoft Visual Studio Solution File, Format Version 12.00" + "\n# Visual Studio 2015"; // The following UUID _may_ change for later servicepacks... // If so we need to search through the registry at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects @@ -401,6 +405,8 @@ QString VcprojGenerator::retrievePlatformToolSet() const return QStringLiteral("v110") + suffix; case NET2013: return QStringLiteral("v120") + suffix; + case NET2015: + return QStringLiteral("v140") + suffix; default: return QString(); } @@ -647,6 +653,8 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { + case NET2015: + t << _slnHeader140; case NET2013: t << _slnHeader120; break; @@ -972,6 +980,9 @@ void VcprojGenerator::initProject() // Own elements ----------------------------- vcProject.Name = project->first("QMAKE_ORIG_TARGET").toQString(); switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { + case NET2015: + vcProject.Version = "14.00"; + break; case NET2013: vcProject.Version = "12.00"; break; -- cgit v1.2.3 From a8dda3b8b06f86ec3fbf845c5397c746b83e0c11 Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Fri, 10 Apr 2015 14:27:06 +0200 Subject: Tests: Use blacklist for failing tst_qwidget tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the insignificant_tests CONFIG option in favor of a BLACKLIST file. The tests blacklisted have been found using CI builds logs. Change-Id: Iffc9043654a9dcd97d55e262011c8daff6f4e60f Task-number: QTBUG-25300 Task-number: QTBUG-45502 Task-number: QTBUG-46325 Reviewed-by: Morten Johan Sørvig --- tests/auto/widgets/kernel/qwidget/BLACKLIST | 121 ++++++++++++++++++++++++++ tests/auto/widgets/kernel/qwidget/qwidget.pro | 2 - 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index ed40f98051..591aa9e40f 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -1,11 +1,16 @@ +# OSX QTBUG-25300 QTBUG-45502 [normalGeometry] ubuntu-14.04 +osx [saveRestoreGeometry] ubuntu-14.04 +osx [restoreVersion1Geometry] ubuntu-14.04 +osx [updateWhileMinimized] ubuntu-14.04 +osx [focusProxyAndInputMethods] ubuntu-14.04 [touchEventSynthesizedMouseEvent] @@ -14,3 +19,119 @@ ubuntu-14.04 ubuntu-14.04 [largerThanScreen_QTBUG30142] ubuntu-14.04 +[windowState] +osx +[showMaximized] +osx +[setGeometry] +osx +[stackUnder] +osx +[raise] +osx-10.9 +[widgetAt] +osx +[sheetOpacity] +osx +[resizeEvent] +osx +[setWindowGeometry:100,123 200x200, flags 0] +osx-10.10 +[windowMoveResize:100,123 200x200, flags 0] +osx-10.10 +[setWindowGeometry:100,122 200x200, flags 0] +osx-10.9 +[windowMoveResize:100,122 200x200, flags 0] +osx-10.9 +[setWindowGeometry:100,100 824x564, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x564, flags 0] +osx-10.10 +[setWindowGeometry:100,100 824x516, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x516, flags 0] +osx-10.10 +[setWindowGeometry:100,73 200x0, flags 0] +osx-10.10 +[windowMoveResize:100,73 200x0, flags 0] +osx-10.10 +[setWindowGeometry:100,100 824x519, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x519, flags 0] +osx-10.10 +[setWindowGeometry:100,100 824x518, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x518, flags 0] +osx-10.10 +[setWindowGeometry:100,72 200x0, flags 0] +osx-10.9 +[windowMoveResize:100,72 200x0, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x574, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x574, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x578, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x578, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x576, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x576, flags 0] +osx-10.9 +[setWindowGeometry:100,100 824x521, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x521, flags 0] +osx-10.10 +[setWindowGeometry:100,122 952x577, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x577, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x580, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x580, flags 0] +osx-10.9 +[windowMoveResize:130,72 0x0, flags 0] +osx-10.9 +[windowMoveResize:130,122 0x200, flags 0] +osx-10.9 +[childEvents] +osx +[renderInvisible] +osx +[optimizedResizeMove] +osx +[optimizedResize_topLevel] +osx +[render_systemClip] +osx +[update] +osx +[doubleRepaint] +osx +[childAt_unifiedToolBar] +osx +[showMinimizedKeepsFocus] +osx-10.10 +[moveWindowInShowEvent:1] +osx-10.9 +[moveWindowInShowEvent:2] +osx-10.9 +[taskQTBUG_4055_sendSyntheticEnterLeave] +osx +[syntheticEnterLeave] +osx +[maskedUpdate] +osx +[hideWhenFocusWidgetIsChild] +osx-10.10 +[hideOpaqueChildWhileHidden] +osx +[resizeStaticContentsChildWidget_QTBUG35282] +osx-10.9 +[lower] +osx +[setClearAndResizeMask] +osx +[setToolTip] +osx-10.9 diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.pro b/tests/auto/widgets/kernel/qwidget/qwidget.pro index 30e1048247..aae083d45e 100644 --- a/tests/auto/widgets/kernel/qwidget/qwidget.pro +++ b/tests/auto/widgets/kernel/qwidget/qwidget.pro @@ -21,5 +21,3 @@ x11 { } !wince*:win32:!winrt: LIBS += -luser32 -lgdi32 - -mac:CONFIG+=insignificant_test # QTBUG-25300, QTBUG-23695 -- cgit v1.2.3 From fe6eeab5618d9f42929872faff94dacdc0890fd2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 26 May 2015 12:08:17 +0200 Subject: QWindowsVistaStyle: Do not stop animations when falling back to XP. Otherwise, progress bar animations are stopped. Task-number: QTBUG-46308 Change-Id: I7b6a2b26afb885db6bc9aea719a002f0ebe7274d Reviewed-by: J-P Nurmi --- src/widgets/styles/qwindowsvistastyle.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index f715d93298..daa8ab12a9 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -250,8 +250,6 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt int state = option->state; if (!QWindowsVistaStylePrivate::useVista()) { - foreach (const QObject *target, d->animationTargets()) - d->stopAnimation(target); QWindowsStyle::drawPrimitive(element, option, painter, widget); return; } @@ -810,8 +808,6 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QWindowsVistaStylePrivate *d = const_cast(d_func()); if (!QWindowsVistaStylePrivate::useVista()) { - foreach (const QObject *target, d->animationTargets()) - d->stopAnimation(target); QWindowsStyle::drawControl(element, option, painter, widget); return; } @@ -1494,8 +1490,6 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle { QWindowsVistaStylePrivate *d = const_cast(d_func()); if (!QWindowsVistaStylePrivate::useVista()) { - foreach (const QObject *target, d->animationTargets()) - d->stopAnimation(target); QWindowsStyle::drawComplexControl(control, option, painter, widget); return; } -- cgit v1.2.3 From a42330dc12bf7ee920e5c3c5a230e4fccae727bc Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 26 May 2015 14:03:11 +0200 Subject: winrt: Fixed timer handling in case where additional user events occur When timers are used in connection with widgets, it is possible that additional events occur (e.g. deferred deletions). If these happen, the event dispatcher also has to handle timers after handling these events as timer events might not be handled at all otherwise. So instead of returning early, we check whether timer events happened and might return afterwards. Task-number: QTBUG-46299 Change-Id: I3ef0fb23b3ae9a1e13e42497bcfb0976cf4e1b91 Reviewed-by: Andrew Knight --- src/corelib/kernel/qeventdispatcher_winrt.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index b5cfccd649..1509996199 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -203,9 +203,9 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags) } } - // Dispatch accumulated user events - if (sendPostedEvents(flags)) - return true; + // Additional user events have to be handled before timer events, but the function may not + // return yet. + const bool userEventsSent = sendPostedEvents(flags); emit aboutToBlock(); const QVector timerHandles = d->timerIdToHandle.values().toVector(); @@ -228,6 +228,9 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags) return true; } emit awake(); + + if (userEventsSent) + return true; } while (flags & QEventLoop::WaitForMoreEvents); return false; } -- cgit v1.2.3 From d1de6c521ea2114b3bb6dbe4a0bb302f0a3db434 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sat, 16 May 2015 12:52:30 +0200 Subject: QVector: add const first/last getters Convenience to avoid annoying detaching (instead of using at()), especially on temporary vectors (returned by functions or so). [ChangeLog][QtCore][QVector] Added the convenience constFirst and constLast functions. Change-Id: If61b1f0096f6a7a1c9074340e237cc2376ce3d18 Task-number: QTBUG-46026 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qvector.cpp | 22 +++- src/corelib/tools/qvector.h | 2 + tests/auto/corelib/tools/qvector/tst_qvector.cpp | 141 +++++++++++++++++++++++ 3 files changed, 163 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index 4f46764697..b57954dc03 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -951,7 +951,7 @@ Returns a reference to the first item in the vector. This function assumes that the vector isn't empty. - \sa last(), isEmpty() + \sa last(), isEmpty(), constFirst() */ /*! \fn const T& QVector::first() const @@ -959,12 +959,21 @@ \overload */ +/*! \fn const T& QVector::constFirst() const + \since 5.6 + + Returns a const reference to the first item in the vector. This + function assumes that the vector isn't empty. + + \sa constLast(), isEmpty(), first() +*/ + /*! \fn T& QVector::last() Returns a reference to the last item in the vector. This function assumes that the vector isn't empty. - \sa first(), isEmpty() + \sa first(), isEmpty(), constLast() */ /*! \fn const T& QVector::last() const @@ -972,6 +981,15 @@ \overload */ +/*! \fn const T& QVector::constLast() const + \since 5.6 + + Returns a const reference to the last item in the vector. This function + assumes that the vector isn't empty. + + \sa constFirst(), isEmpty(), last() +*/ + /*! \fn T QVector::value(int i) const Returns the value at index position \a i in the vector. diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 2eb2dc4550..2adf2d4522 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -212,8 +212,10 @@ public: inline int count() const { return d->size; } inline T& first() { Q_ASSERT(!isEmpty()); return *begin(); } inline const T &first() const { Q_ASSERT(!isEmpty()); return *begin(); } + inline const T &constFirst() const { Q_ASSERT(!isEmpty()); return *begin(); } inline T& last() { Q_ASSERT(!isEmpty()); return *(end()-1); } inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); } + inline const T &constLast() const { Q_ASSERT(!isEmpty()); return *(end()-1); } inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; } inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; } QVector mid(int pos, int len = -1) const; diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 3f95fa18f6..f9f9ac472a 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -198,6 +198,8 @@ private slots: void clearMovable() const; void clearCustom() const; void constData() const; + void constFirst() const; + void constLast() const; void contains() const; void countInt() const; void countMovable() const; @@ -1222,16 +1224,86 @@ void tst_QVector::first() const // test it starts ok QCOMPARE(myvec.first(), 69); + QCOMPARE(myvec.constFirst(), 69); // test removal changes myvec.remove(0); QCOMPARE(myvec.first(), 42); + QCOMPARE(myvec.constFirst(), 42); // test prepend changes myvec.prepend(23); QCOMPARE(myvec.first(), 23); + QCOMPARE(myvec.constFirst(), 23); } +void tst_QVector::constFirst() const +{ + QVector myvec; + myvec << 69 << 42 << 3; + + // test it starts ok + QCOMPARE(myvec.constFirst(), 69); + QVERIFY(myvec.isDetached()); + + QVector myvecCopy = myvec; + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); + + QCOMPARE(myvec.constFirst(), 69); + QCOMPARE(myvecCopy.constFirst(), 69); + + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); + + // test removal changes + myvec.remove(0); + QVERIFY(myvec.isDetached()); + QVERIFY(!myvec.isSharedWith(myvecCopy)); + QCOMPARE(myvec.constFirst(), 42); + QCOMPARE(myvecCopy.constFirst(), 69); + + myvecCopy = myvec; + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); + + QCOMPARE(myvec.constFirst(), 42); + QCOMPARE(myvecCopy.constFirst(), 42); + + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); + + // test prepend changes + myvec.prepend(23); + QVERIFY(myvec.isDetached()); + QVERIFY(!myvec.isSharedWith(myvecCopy)); + QCOMPARE(myvec.constFirst(), 23); + QCOMPARE(myvecCopy.constFirst(), 42); + + myvecCopy = myvec; + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); + + QCOMPARE(myvec.constFirst(), 23); + QCOMPARE(myvecCopy.constFirst(), 23); + + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); +} + + template void tst_QVector::fromList() const { @@ -1409,14 +1481,83 @@ void tst_QVector::last() const // test starts ok QCOMPARE(myvec.last(), QLatin1String("C")); + QCOMPARE(myvec.constLast(), QLatin1String("C")); // test it changes ok myvec.append(QLatin1String("X")); QCOMPARE(myvec.last(), QLatin1String("X")); + QCOMPARE(myvec.constLast(), QLatin1String("X")); // and remove again myvec.remove(3); QCOMPARE(myvec.last(), QLatin1String("C")); + QCOMPARE(myvec.constLast(), QLatin1String("C")); +} + +void tst_QVector::constLast() const +{ + QVector myvec; + myvec << 69 << 42 << 3; + + // test it starts ok + QCOMPARE(myvec.constLast(), 3); + QVERIFY(myvec.isDetached()); + + QVector myvecCopy = myvec; + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); + + QCOMPARE(myvec.constLast(), 3); + QCOMPARE(myvecCopy.constLast(), 3); + + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); + + // test removal changes + myvec.removeLast(); + QVERIFY(myvec.isDetached()); + QVERIFY(!myvec.isSharedWith(myvecCopy)); + QCOMPARE(myvec.constLast(), 42); + QCOMPARE(myvecCopy.constLast(), 3); + + myvecCopy = myvec; + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); + + QCOMPARE(myvec.constLast(), 42); + QCOMPARE(myvecCopy.constLast(), 42); + + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); + + // test prepend changes + myvec.append(23); + QVERIFY(myvec.isDetached()); + QVERIFY(!myvec.isSharedWith(myvecCopy)); + QCOMPARE(myvec.constLast(), 23); + QCOMPARE(myvecCopy.constLast(), 42); + + myvecCopy = myvec; + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); + + QCOMPARE(myvec.constLast(), 23); + QCOMPARE(myvecCopy.constLast(), 23); + + QVERIFY(!myvec.isDetached()); + QVERIFY(!myvecCopy.isDetached()); + QVERIFY(myvec.isSharedWith(myvecCopy)); + QVERIFY(myvecCopy.isSharedWith(myvec)); } void tst_QVector::lastIndexOf() const -- cgit v1.2.3 From 10d53a3f0e09ec2ef437619bb1bb0dbb40f7ee8b Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 8 Apr 2015 19:44:48 +0200 Subject: Add qHash(QKeySequence) Key sequences can be compared for equality, so qHash should be overloaded, too. [ChangeLog][QtGui][QKeySequence] Added qHash(QKeySequence). Change-Id: I3cf896292459897d66198d96dfcdba1a39bdafce Reviewed-by: Giuseppe D'Angelo --- src/gui/kernel/qkeysequence.cpp | 11 +++++++++++ src/gui/kernel/qkeysequence.h | 6 +++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 23d5f06aa2..ab846b63cb 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -39,6 +39,7 @@ #ifndef QT_NO_SHORTCUT #include "qdebug.h" +#include #ifndef QT_NO_REGEXP # include "qregexp.h" #endif @@ -1409,6 +1410,16 @@ bool QKeySequence::operator==(const QKeySequence &other) const d->key[3] == other.d->key[3]); } +/*! + \since 5.6 + + Calculates the hash value of \a key, using + \a seed to seed the calculation. +*/ +uint qHash(const QKeySequence &key, uint seed) Q_DECL_NOTHROW +{ + return qHashRange(key.d->key, key.d->key + QKeySequencePrivate::MaxKeyCount, seed); +} /*! Provides an arbitrary comparison of this key sequence and diff --git a/src/gui/kernel/qkeysequence.h b/src/gui/kernel/qkeysequence.h index cd7af5718f..e6616dae11 100644 --- a/src/gui/kernel/qkeysequence.h +++ b/src/gui/kernel/qkeysequence.h @@ -43,11 +43,12 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_SHORTCUT +class QKeySequence; + /***************************************************************************** QKeySequence stream functions *****************************************************************************/ #ifndef QT_NO_DATASTREAM -class QKeySequence; Q_GUI_EXPORT QDataStream &operator<<(QDataStream &in, const QKeySequence &ks); Q_GUI_EXPORT QDataStream &operator>>(QDataStream &out, QKeySequence &ks); #endif @@ -59,6 +60,8 @@ void qt_set_sequence_auto_mnemonic(bool b); class QVariant; class QKeySequencePrivate; +Q_GUI_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QKeySequence &key, uint seed = 0) Q_DECL_NOTHROW; + class Q_GUI_EXPORT QKeySequence { Q_GADGET @@ -204,6 +207,7 @@ private: friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &in, const QKeySequence &ks); friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &in, QKeySequence &ks); + friend Q_GUI_EXPORT uint qHash(const QKeySequence &key, uint seed) Q_DECL_NOTHROW; friend class QShortcutMap; friend class QShortcut; -- cgit v1.2.3 From 16b95b65a6fea501dade6e3f5f1ad48f7dfaa173 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 14 Apr 2015 09:37:58 +0200 Subject: Q*GlyphCache: de-inline dtor and export vtable The destructor is the first virtual method. By not defining it out-of-line, we provoke multiple copies of vtables, not all of which can be merged by the linker. If the linker fails, RTTI such as dynamic_cast and catch-blocks involving the type will not work. Additionally, QFontEngineGlyphCache was not exported, and therefore also not its vtable, making it impossible for users outside of QtGui to get a unique RTTI for the class. Change-Id: Ib265945934216bb609629431eb4c71996d4fd39d Reported-by: Volker Krause Task-number: QTBUG-45582 Reviewed-by: Konstantin Ritt Reviewed-by: Friedemann Kleint Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qtextureglyphcache.cpp | 10 ++++++++ src/gui/painting/qtextureglyphcache_p.h | 4 ++- src/gui/text/qfontengineglyphcache.cpp | 43 +++++++++++++++++++++++++++++++++ src/gui/text/qfontengineglyphcache_p.h | 4 +-- src/gui/text/text.pri | 1 + 5 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 src/gui/text/qfontengineglyphcache.cpp diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 4c879cf05d..056fd8b701 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -42,6 +42,11 @@ QT_BEGIN_NAMESPACE // #define CACHE_DEBUG +// out-of-line to avoid vtable duplication, breaking e.g. RTTI +QTextureGlyphCache::~QTextureGlyphCache() +{ +} + int QTextureGlyphCache::calculateSubPixelPositionCount(glyph_t glyph) const { // Test 12 different subpixel positions since it factors into 3*4 so it gives @@ -262,6 +267,11 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition * QImageTextureGlyphCache */ +// out-of-line to avoid vtable duplication, breaking e.g. RTTI +QImageTextureGlyphCache::~QImageTextureGlyphCache() +{ +} + void QImageTextureGlyphCache::resizeTextureData(int width, int height) { m_image = m_image.copy(0, 0, width, height); diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h index c9e7060b0d..7dd8277a45 100644 --- a/src/gui/painting/qtextureglyphcache_p.h +++ b/src/gui/painting/qtextureglyphcache_p.h @@ -72,7 +72,7 @@ public: m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0) { } - virtual ~QTextureGlyphCache() { } + ~QTextureGlyphCache(); struct GlyphAndSubPixelPosition { @@ -158,6 +158,8 @@ class Q_GUI_EXPORT QImageTextureGlyphCache : public QTextureGlyphCache public: QImageTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) : QTextureGlyphCache(format, matrix) { } + ~QImageTextureGlyphCache(); + virtual void createTextureData(int width, int height) Q_DECL_OVERRIDE; virtual void resizeTextureData(int width, int height) Q_DECL_OVERRIDE; virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) Q_DECL_OVERRIDE; diff --git a/src/gui/text/qfontengineglyphcache.cpp b/src/gui/text/qfontengineglyphcache.cpp new file mode 100644 index 0000000000..f6fdfa3ce3 --- /dev/null +++ b/src/gui/text/qfontengineglyphcache.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +QT_BEGIN_NAMESPACE + +// out-of-line to avoid vtable duplication, breaking e.g. RTTI +QFontEngineGlyphCache::~QFontEngineGlyphCache() +{ +} + +QT_END_NAMESPACE diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h index 6cf4d2f1ba..def42c22a3 100644 --- a/src/gui/text/qfontengineglyphcache_p.h +++ b/src/gui/text/qfontengineglyphcache_p.h @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE -class QFontEngineGlyphCache: public QSharedData +class Q_GUI_EXPORT QFontEngineGlyphCache: public QSharedData { public: QFontEngineGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) : m_format(format), m_transform(matrix) @@ -64,7 +64,7 @@ public: Q_ASSERT(m_format != QFontEngine::Format_None); } - virtual ~QFontEngineGlyphCache() { } + virtual ~QFontEngineGlyphCache(); QFontEngine::GlyphFormat glyphFormat() const { return m_format; } const QTransform &transform() const { return m_transform; } diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 61e239f678..087927549f 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -47,6 +47,7 @@ HEADERS += \ SOURCES += \ text/qfont.cpp \ text/qfontengine.cpp \ + text/qfontengineglyphcache.cpp \ text/qfontsubset.cpp \ text/qfontmetrics.cpp \ text/qfontdatabase.cpp \ -- cgit v1.2.3 From 35175b8fa5f8be93b147f57a247b8e52f28ee8cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Fri, 15 May 2015 20:03:18 +0100 Subject: Introduce QDir::listSeparator() Qt should help abstract such platform differences. This ifdef is proliferating in user code (seen a few times in KDE) and even in Qt code (qstandardpaths.cpp). [ChangeLog][QtCore][QDir] Added listSeparator(). Change-Id: Icad082a51c8efd5d63f7af9bbaedbe4bc15b8937 Reviewed-by: Konstantin Ritt Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira --- src/corelib/io/qdir.cpp | 12 ++++++++++++ src/corelib/io/qdir.h | 11 ++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 9b1ec3917a..8b3dd5d82f 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1826,6 +1826,8 @@ QFileInfoList QDir::drives() underlying operating system. If you want to display paths to the user using their operating system's separator use toNativeSeparators(). + + \sa listSeparator() */ QChar QDir::separator() { @@ -1836,6 +1838,16 @@ QChar QDir::separator() #endif } +/*! + \fn QDir::listSeparator() + \since 5.6 + + Returns the native path list separator: ':' under Unix + and ';' under Windows. + + \sa separator() +*/ + /*! Sets the application's current working directory to \a path. Returns \c true if the directory was successfully changed; otherwise diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h index e622011f98..b6946eba65 100644 --- a/src/corelib/io/qdir.h +++ b/src/corelib/io/qdir.h @@ -177,7 +177,16 @@ public: static QFileInfoList drives(); - static QChar separator(); + Q_DECL_CONSTEXPR static inline QChar listSeparator() Q_DECL_NOTHROW + { +#if defined(Q_OS_WIN) + return QLatin1Char(';'); +#else + return QLatin1Char(':'); +#endif + } + + static QChar separator(); // ### Qt6: Make it inline static bool setCurrent(const QString &path); static inline QDir current() { return QDir(currentPath()); } -- cgit v1.2.3 From 6764e1b646d3c6049b24d5ceb7cdecd637cdf8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sun, 24 May 2015 21:25:11 +0100 Subject: QStandardPaths: Use QDir::listSeparator() instead of ifdefs Change-Id: I1783ce7bcbaabb4920166440e2ed0b41d6daa7aa Reviewed-by: Marc Mutz --- src/corelib/io/qstandardpaths.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index 5f764549e0..beb5d29d54 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -494,13 +494,8 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr QStringList searchPaths = paths; if (paths.isEmpty()) { QByteArray pEnv = qgetenv("PATH"); -#if defined(Q_OS_WIN) - const QLatin1Char pathSep(';'); -#else - const QLatin1Char pathSep(':'); -#endif // Remove trailing slashes, which occur on Windows. - const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(pathSep, QString::SkipEmptyParts); + const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(QDir::listSeparator(), QString::SkipEmptyParts); searchPaths.reserve(rawPaths.size()); foreach (const QString &rawPath, rawPaths) { QString cleanPath = QDir::cleanPath(rawPath); -- cgit v1.2.3 From 5f21aa22fbc224cdd4102ae6a7797574a463af3b Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sat, 2 May 2015 12:50:25 +0000 Subject: Haiku: Fix reported geometry of platform window Report the proper window geometry and adapt the geometry parameters of expose events to be relative to the window coordinate system. Change-Id: Ifb32b2663fdf41df0c9783e76e0ebc5e5cf978a3 Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/haiku/qhaikuwindow.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/haiku/qhaikuwindow.cpp b/src/plugins/platforms/haiku/qhaikuwindow.cpp index 140b79af12..9622d12111 100644 --- a/src/plugins/platforms/haiku/qhaikuwindow.cpp +++ b/src/plugins/platforms/haiku/qhaikuwindow.cpp @@ -130,6 +130,7 @@ QHaikuWindow::QHaikuWindow(QWindow *window) if (!m_window) qFatal("QHaikuWindow: failed to create window"); + setGeometry(rect); setWindowFlags(window->flags()); } @@ -164,13 +165,13 @@ void QHaikuWindow::setVisible(bool visible) { if (visible) { m_window->Show(); + + window()->requestActivate(); + + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), window()->geometry().size())); } else { m_window->Hide(); } - - window()->requestActivate(); - - QWindowSystemInterface::handleExposeEvent(window(), window()->geometry()); } bool QHaikuWindow::isExposed() const @@ -307,7 +308,7 @@ void QHaikuWindow::haikuWindowMoved(const QPoint &pos) QPlatformWindow::setGeometry(newGeometry); QWindowSystemInterface::handleGeometryChange(window(), newGeometry); - QWindowSystemInterface::handleExposeEvent(window(), newGeometry); + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size())); } void QHaikuWindow::haikuWindowResized(const QSize &size, bool zoomInProgress) @@ -316,7 +317,7 @@ void QHaikuWindow::haikuWindowResized(const QSize &size, bool zoomInProgress) QPlatformWindow::setGeometry(newGeometry); QWindowSystemInterface::handleGeometryChange(window(), newGeometry); - QWindowSystemInterface::handleExposeEvent(window(), newGeometry); + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), newGeometry.size())); if ((m_windowState == Qt::WindowMaximized) && !zoomInProgress) { // the user has resized the window while maximized -> reset maximized flag -- cgit v1.2.3 From 5d707bff3d2b01532ccfc429096e3fd34988e619 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 21 May 2015 15:45:44 +0200 Subject: Make Qt Edition available to qmake Allow .pro, .prf ... files to check the edition (OpenSource, Evaluation, Preview, Enterprise ...) of the Qt installation. Change-Id: If2a8e3877d066b225b1777916cef1d23c65f8512 Reviewed-by: Oswald Buddenhagen --- configure | 2 ++ tools/configure/configureapp.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/configure b/configure index dddb40f485..19802a367c 100755 --- a/configure +++ b/configure @@ -6763,6 +6763,8 @@ QT_PATCH_VERSION = $QT_PATCH_VERSION QT_LIBINFIX = $QT_LIBINFIX QT_NAMESPACE = $QT_NAMESPACE +QT_EDITION = $Edition + EOF if [ "$CFG_SHARED" = "no" ]; then diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 08ec943563..4d1ce3d113 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3460,6 +3460,9 @@ void Configure::generateQConfigPri() << "QT_MINOR_VERSION = " << dictionary["VERSION_MINOR"] << endl << "QT_PATCH_VERSION = " << dictionary["VERSION_PATCH"] << endl; + configStream << endl + << "QT_EDITION = " << dictionary["EDITION"] << endl; + if (!dictionary["CFG_SYSROOT"].isEmpty() && dictionary["CFG_GCC_SYSROOT"] == "yes") { configStream << endl << "# sysroot" << endl -- cgit v1.2.3 From 40327b6febf268ace25c0d5f372a4811c4867a93 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 22 May 2015 12:45:47 +0200 Subject: Resolve path to right licheck In the unix commercial packages, licheck so far has been a shell script that redirected to the 'right' licheck. To simplify things we now resolve the right executable path in configure itself. Change-Id: I1183d000a11bf42729f3e0405a0bc1d4b618933c Reviewed-by: Oswald Buddenhagen --- configure | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 19802a367c..db4abf977b 100755 --- a/configure +++ b/configure @@ -2962,8 +2962,20 @@ if [ -f "$relpath"/LICENSE.PREVIEW.COMMERCIAL ] && [ $COMMERCIAL_USER = "yes" ]; Edition="Preview" EditionString="Technology Preview" elif [ $COMMERCIAL_USER = "yes" ]; then - if test -x "$relpath/bin/licheck"; then - LicheckOutput=`$relpath/bin/licheck $OPT_CONFIRM_LICENSE $relpath $outpath\ + if [ $UNAME_SYSTEM = "Linux" ]; then + if file -L /bin/sh | grep -q "64-bit" ; then + Licheck=licheck64 + else + Licheck=licheck32 + fi + elif [ $UNAME_SYSTEM = "Darwin" ]; then + Licheck=licheck_mac + else + echo >&2 "Host operating system not supported by this edition of Qt." + exit 1 + fi + if [ -x "$relpath/bin/$Licheck" ]; then + LicheckOutput=`$relpath/bin/$Licheck $OPT_CONFIRM_LICENSE $relpath $outpath\ $PLATFORM $XPLATFORM` if [ $? -ne 0 ]; then exit 1 -- cgit v1.2.3 From 63660402d8d803b97c676395895c25e550c07f94 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 22 May 2015 15:02:23 +0200 Subject: Run license checker in qmake Check for a valid license not only in configure, but also in qmake. To limit the runtime overhead we cache the day of the last run in a .stash file. This allows us to run licheck only for the top-level qmake call, and only once per day. This requires an updated licheck executable that supports the new check mode. [ChangeLog][Tools][qmake] For commercial builds, qmake now checks for a valid Qt license. This requires setting up a Qt Account (or .qt-license file) on the development machine. Change-Id: I2c2a05a4602cc661560568b76ddf520cb8134769 Reviewed-by: Oswald Buddenhagen --- configure | 7 ++++++- mkspecs/features/default_pre.prf | 15 +++++++++++++++ qtbase.pro | 5 +++++ tools/configure/configureapp.cpp | 5 +++++ tools/configure/tools.cpp | 2 ++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/configure b/configure index db4abf977b..234ddc6971 100755 --- a/configure +++ b/configure @@ -6776,9 +6776,14 @@ QT_LIBINFIX = $QT_LIBINFIX QT_NAMESPACE = $QT_NAMESPACE QT_EDITION = $Edition - EOF +if [ "$Edition" != "OpenSource" ] && [ "$Edition" != "Preview" ]; then + echo "QT_LICHECK = $Licheck" >> "$QTCONFIG.tmp" + echo "QT_RELEASE_DATE = $ReleaseDate" >> "$QTCONFIG.tmp" +fi +echo >> "$QTCONFIG.tmp" + if [ "$CFG_SHARED" = "no" ]; then echo "QT_DEFAULT_QPA_PLUGIN = q$QT_QPA_DEFAULT_PLATFORM" >> "$QTCONFIG.tmp" echo >> "$QTCONFIG.tmp" diff --git a/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf index b06b9d6cfc..eb3281ea1d 100644 --- a/mkspecs/features/default_pre.prf +++ b/mkspecs/features/default_pre.prf @@ -7,3 +7,18 @@ CONFIG = \ lex yacc debug exceptions depend_includepath \ testcase_targets import_plugins import_qpa_plugin \ $$CONFIG + +!build_pass:defined(QT_EDITION, var):!equals(QT_EDITION, "OpenSource"):!equals(QT_EDITION, "Preview") { + # + # call license checker (but cache result for one day) + # + today = $$section(_DATE_, " ", 0, 2) + !isEqual(QMAKE_LICHECK_TIMESTAMP, $$today) { + !system("$$system_quote($$system_path($$[QT_HOST_BINS/src]/$$QT_LICHECK)) check" \ + "$$QT_RELEASE_DATE $$[QMAKE_SPEC] $$[QMAKE_XSPEC]"): \ + error("License check failed! Giving up ...") + + cache(QMAKE_LICHECK_TIMESTAMP, set stash, today) + } + unset(today) +} diff --git a/qtbase.pro b/qtbase.pro index bae2641404..51e8fb8760 100644 --- a/qtbase.pro +++ b/qtbase.pro @@ -46,6 +46,11 @@ equals(QMAKE_HOST.os, Windows) { } INSTALLS += qmake +#licheck +licheck.path = $$[QT_HOST_BINS] +licheck.files = $$PWD/bin/$$QT_LICHECK +exists($$licheck.files): INSTALLS += licheck + #syncqt syncqt.path = $$[QT_HOST_BINS] syncqt.files = $$PWD/bin/syncqt.pl diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 4d1ce3d113..6bf0646378 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3463,6 +3463,11 @@ void Configure::generateQConfigPri() configStream << endl << "QT_EDITION = " << dictionary["EDITION"] << endl; + if (dictionary["EDITION"] != "OpenSource" && dictionary["EDITION"] != "Preview") { + configStream << "QT_LICHECK = " << dictionary["LICHECK"] << endl; + configStream << "QT_RELEASE_DATE = " << dictionary["RELEASEDATE"] << endl; + } + if (!dictionary["CFG_SYSROOT"].isEmpty() && dictionary["CFG_GCC_SYSROOT"] == "yes") { configStream << endl << "# sysroot" << endl diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp index 83d969ce16..095e798332 100644 --- a/tools/configure/tools.cpp +++ b/tools/configure/tools.cpp @@ -54,6 +54,8 @@ void Tools::checkLicense(QMap &dictionary, return; } + dictionary["LICHECK"] = "licheck.exe"; + const QString licenseChecker = QDir::toNativeSeparators(sourcePath + "/bin/licheck.exe"); -- cgit v1.2.3 From 18be63de2a5588ea6ac4b9ffe8de176aabe8bd83 Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Mon, 18 May 2015 15:47:51 +0200 Subject: Doc: Added the missing \brief and \image for example docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Qt TestLib examples are just tutorials so updated the qdocconf to use the default thumbnail in the Qt Creator welcome screen. Task-number: QTBUG-41996 Change-Id: Ia04a42a92e414c97a426b6095a62621a348e7de0 Reviewed-by: Topi Reiniö Reviewed-by: Martin Smith --- examples/widgets/doc/images/imagegestures-example.jpg | Bin 0 -> 38962 bytes examples/widgets/doc/src/plugandpaint.qdoc | 9 +++++++-- .../gestures/imagegestures/doc/src/imagegestures.qdoc | 3 +++ src/testlib/doc/qttestlib.qdocconf | 3 +++ src/xml/doc/qtxml.qdocconf | 3 +++ 5 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 examples/widgets/doc/images/imagegestures-example.jpg diff --git a/examples/widgets/doc/images/imagegestures-example.jpg b/examples/widgets/doc/images/imagegestures-example.jpg new file mode 100644 index 0000000000..c8484b4a71 Binary files /dev/null and b/examples/widgets/doc/images/imagegestures-example.jpg differ diff --git a/examples/widgets/doc/src/plugandpaint.qdoc b/examples/widgets/doc/src/plugandpaint.qdoc index 4e48245bd9..caf33feb0a 100644 --- a/examples/widgets/doc/src/plugandpaint.qdoc +++ b/examples/widgets/doc/src/plugandpaint.qdoc @@ -30,8 +30,7 @@ \title Plug & Paint Example \ingroup examples-widgets-tools - \brief The Plug & Paint example demonstrates how to write Qt - applications that can be extended through plugins. + \brief Demonstrates how to extend Qt applications using plugins. \image plugandpaint.png Screenshot of the Plug & Paint example @@ -314,6 +313,9 @@ /*! \example tools/plugandpaintplugins/basictools \title Plug & Paint Basic Tools Example + \brief A plugin providing the basic tools for painting functionality. + + \image plugandpaint.png Screenshot of the Plug & Paint example The Basic Tools example is a static plugin for the \l{tools/plugandpaint}{Plug & Paint} example. It provides a set @@ -499,6 +501,9 @@ /*! \example tools/plugandpaintplugins/extrafilters \title Plug & Paint Extra Filters Example + \brief A plugin providing the extra filters. + + \image plugandpaint.png Screenshot of the Plug & Paint example The Extra Filters example is a plugin for the \l{tools/plugandpaint}{Plug & Paint} example. It provides a set diff --git a/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc b/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc index d6d215d6bd..6a1405b0b1 100644 --- a/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc +++ b/examples/widgets/gestures/imagegestures/doc/src/imagegestures.qdoc @@ -28,10 +28,13 @@ /*! \example gestures/imagegestures \title Image Gestures Example + \brief Demonstrates the use of simple gestures in a widget This example shows how to enable gestures for a widget and use gesture input to perform actions. + \image imagegestures-example.jpg + We use two classes to create the user interface for the application: \c MainWidget and \c ImageWidget. The \c MainWidget class is simply used as a container for the \c ImageWidget class, which we will configure to accept gesture input. Since we diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf index 35b4fbcb7b..0fafc733b1 100644 --- a/src/testlib/doc/qttestlib.qdocconf +++ b/src/testlib/doc/qttestlib.qdocconf @@ -40,5 +40,8 @@ excludedirs += ../../../examples/widgets/doc imagedirs += images +# Add a thumbnail for examples that do not have images +manifestmeta.thumbnail.names = "QtTestLib/Chapter *" + navigation.landingpage = "Qt Test" navigation.cppclassespage = "Qt Test C++ Classes" diff --git a/src/xml/doc/qtxml.qdocconf b/src/xml/doc/qtxml.qdocconf index 8ca421ff4e..419859ac8b 100644 --- a/src/xml/doc/qtxml.qdocconf +++ b/src/xml/doc/qtxml.qdocconf @@ -40,3 +40,6 @@ imagedirs += images \ navigation.landingpage = "Qt XML" navigation.cppclassespage = "Qt XML C++ Classes" + +# Add a thumbnail for examples that do not have images +manifestmeta.thumbnail.names = "QtXml/XML Stream Lint Example" -- cgit v1.2.3 From 02f6b21bbc4f1f7afc30a87227c3a0787a5d2225 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 23 Apr 2015 12:02:40 +0200 Subject: QMetaType: Fix compilation with non default constructible Q_GADGET Do not try to automatically register the meta type for Q_GADGET that are not default constructible. This fixes a source incompatibility in the function pointer syntax of QObject::connect when such types are used as an argument of a signal. Task-number: QTBUG-45721 Change-Id: I3065f6d57bc1f37e16988d2dee99118de250ca56 Reviewed-by: Thiago Macieira --- src/corelib/global/qtypetraits.h | 21 +++++++++++++++++++ src/corelib/kernel/qmetatype.h | 2 +- .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 7 ++++++- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 24 ++++++++++++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qtypetraits.h b/src/corelib/global/qtypetraits.h index 3a305713e6..488e257e0f 100644 --- a/src/corelib/global/qtypetraits.h +++ b/src/corelib/global/qtypetraits.h @@ -506,6 +506,27 @@ Q_STATIC_ASSERT((!is_unsigned::value)); Q_STATIC_ASSERT((!is_signed::value)); Q_STATIC_ASSERT(( is_signed::value)); +template struct is_default_constructible; + +template<> struct is_default_constructible +{ +protected: + template struct test { typedef char type; }; +public: + static bool const value = false; +}; +template<> struct is_default_constructible<>::test { typedef double type; }; + +template struct is_default_constructible : is_default_constructible<> +{ +private: + template static typename test::type sfinae(U*); + template static char sfinae(...); +public: + static bool const value = sizeof(sfinae(0)) > 1; +}; + + } // namespace QtPrivate QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 9ad8702e79..1b214e9f74 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1773,7 +1773,7 @@ template struct QMetaTypeIdQObject { enum { - Defined = 1 + Defined = QtPrivate::is_default_constructible::value }; static int qt_metatype_id() diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 691a4e819d..9cdb1f47f8 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -142,6 +142,11 @@ public: class CustomGadget { Q_GADGET }; +class CustomGadget_NonDefaultConstructible { + Q_GADGET +public: + CustomGadget_NonDefaultConstructible(int) {}; +}; class CustomNonQObject {}; class GadgetDerived : public CustomGadget {}; @@ -159,7 +164,7 @@ void tst_QMetaType::defined() QVERIFY(!QMetaTypeId2::Defined); QVERIFY(!QMetaTypeId2::Defined); QVERIFY(!QMetaTypeId2::Defined); - QVERIFY(!QMetaTypeId2::Defined); + QVERIFY(!QMetaTypeId2::Defined); } struct Bar diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 263cc5a07a..3ec84b5198 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -128,6 +128,7 @@ private slots: void connectWithReference(); void connectManyArguments(); void connectForwardDeclare(); + void connectNoDefaultConstructorArg(); void returnValue_data(); void returnValue(); void returnValue2_data(); @@ -5227,6 +5228,29 @@ void tst_QObject::connectForwardDeclare() QVERIFY(connect(&ob, &ForwardDeclareArguments::mySignal, &ob, &ForwardDeclareArguments::mySlot, Qt::QueuedConnection)); } +class NoDefaultConstructor +{ + Q_GADGET +public: + NoDefaultConstructor(int) {} +}; + +class NoDefaultContructorArguments : public QObject +{ + Q_OBJECT +signals: + void mySignal(const NoDefaultConstructor&); +public slots: + void mySlot(const NoDefaultConstructor&) {} +}; + +void tst_QObject::connectNoDefaultConstructorArg() +{ + NoDefaultContructorArguments ob; + // it should compile + QVERIFY(connect(&ob, &NoDefaultContructorArguments::mySignal, &ob, &NoDefaultContructorArguments::mySlot, Qt::QueuedConnection)); +} + class ReturnValue : public QObject { friend class tst_QObject; Q_OBJECT -- cgit v1.2.3 From 8829ce67d8d0eac90e9fd6fde088b41f157177a5 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 25 May 2015 14:55:38 +0200 Subject: Only add -fPIC flags for compilers known to require it. Commit 083c9269 (Try to ensure that -fPIC is used in CMake builds, 2015-05-11) added a raw -fPIC to the INTERFACE_COMPILE_OPTIONS of Qt5::Core, which affects all consuming compilers. Use the qmake variable $$QMAKE_CXXFLAGS_APP instead, which at least currently contains only the -fPIC variable or harmlessly expands to nothing. If the content of that qmake variable changes in the future, a $$QMAKE_CXXFLAGS_APP_PIC variable should be extracted in qmake and used here. Don't use the POSITION_INDEPENDENT_CODE feature of CMake. That adds the -fPIE flag for executables, which is explicitly what qglobal.h forbids since commit 3eca75de (Make qglobal.h complain if you use -fPIE, 2015-05-11). The current behavior of that CMake feature is tracked here: http://public.kitware.com/Bug/view.php?id=15570 Change-Id: I5c5bcc40fe4b310b55a681a3505f45c50adfa054 Reviewed-by: Oswald Buddenhagen Reviewed-by: Simon Hausmann --- src/corelib/Qt5CoreConfigExtras.cmake.in | 3 +-- src/corelib/Qt5CoreMacros.cmake | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index d4abc5f271..a5cab880ba 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -71,8 +71,7 @@ set(_qt5_corelib_extra_includes) # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") -set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") -set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}) +set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $$QMAKE_CXXFLAGS_APP) !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index 9c81754302..c10880f787 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -281,10 +281,6 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.9) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG) - - if (Qt5_POSITION_INDEPENDENT_CODE) - set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE}) - endif() endforeach() endmacro() endif() -- cgit v1.2.3 From 310b7ef010f524e8d3cde5605cd495a4ffed5862 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Tue, 19 May 2015 10:48:21 +0300 Subject: QIODevice::read(): limit the size of result buffer with a proper value Now its maximum size is QByteArray::MaxSize not INT_MAX. Change-Id: Id548b3cb94f910a3212665182280a3a2948dd93e Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qiodevice.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 872e004d2f..b908ae3145 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -41,7 +41,6 @@ #include "qdir.h" #include -#include #ifdef QIODEVICE_DEBUG # include @@ -942,9 +941,9 @@ QByteArray QIODevice::read(qint64 maxSize) Q_UNUSED(d); #endif - if (maxSize != qint64(int(maxSize))) { + if (quint64(maxSize) >= QByteArray::MaxSize) { checkWarnMessage(this, "read", "maxSize argument exceeds QByteArray size limit"); - maxSize = INT_MAX; + maxSize = QByteArray::MaxSize - 1; } qint64 readBytes = 0; @@ -996,7 +995,7 @@ QByteArray QIODevice::readAll() // flush internal read buffer if (!(d->openMode & Text) && !d->buffer.isEmpty()) { - if (d->buffer.size() >= INT_MAX) + if (quint64(d->buffer.size()) >= QByteArray::MaxSize) return QByteArray(); result = d->buffer.readAll(); readBytes = result.size(); @@ -1179,9 +1178,9 @@ QByteArray QIODevice::readLine(qint64 maxSize) Q_UNUSED(d); #endif - if (maxSize > INT_MAX) { + if (quint64(maxSize) >= QByteArray::MaxSize) { qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit"); - maxSize = INT_MAX; + maxSize = QByteArray::MaxSize - 1; } result.resize(int(maxSize)); @@ -1189,7 +1188,7 @@ QByteArray QIODevice::readLine(qint64 maxSize) if (!result.size()) { // If resize fails or maxSize == 0, read incrementally if (maxSize == 0) - maxSize = INT_MAX; + maxSize = QByteArray::MaxSize - 1; // The first iteration needs to leave an extra byte for the terminating null result.resize(1); -- cgit v1.2.3 From 42b7a7c6097825e9fa4a11abac3ad61db051162d Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 27 May 2015 12:27:19 +0200 Subject: Fix crash due to QTreeView accessing deleted model indexes. QTreeViewPrivate::updateScrollBars depends on a correctly set up viewItems vector. If a delayed layout is pending, we must call QTreeViewPrivate::executePostedLayout before accessing any stored model indices. Task-number: QTBUG-45697 Change-Id: I55fcbaf81f225b26181c2cf739283740b85dd16a Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/itemviews/qtreeview.cpp | 1 + .../widgets/itemviews/qtreeview/tst_qtreeview.cpp | 78 ++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 43db43fcd4..9b3e270fdd 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -3658,6 +3658,7 @@ void QTreeViewPrivate::updateScrollBars() if (!viewportSize.isValid()) viewportSize = QSize(0, 0); + executePostedLayout(); if (viewItems.isEmpty()) { q->doItemsLayout(); } diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 3ead172d82..1324027af6 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -255,6 +255,7 @@ private slots: void taskQTBUG_8176_emitOnExpandAll(); void taskQTBUG_34717_collapseAtBottom(); void taskQTBUG_37813_crash(); + void taskQTBUG_45697_crash(); void testInitialFocus(); }; @@ -4385,5 +4386,82 @@ void tst_QTreeView::taskQTBUG_37813_crash() #endif // QT_BUILD_INTERNAL } +// QTBUG-45697: Using a QTreeView with a multi-column model filtered by QSortFilterProxyModel, +// when sorting the source model while the widget is not yet visible and showing the widget +// later on, corruption occurs in QTreeView. +class Qtbug45697TestWidget : public QWidget +{ + Q_OBJECT +public: + static const int columnCount = 3; + + explicit Qtbug45697TestWidget(); + int timerTick() const { return m_timerTick; } + +public slots: + void slotTimer(); + +private: + QTreeView *m_treeView; + QStandardItemModel *m_model; + QSortFilterProxyModel *m_sortFilterProxyModel; + int m_timerTick; +}; + +Qtbug45697TestWidget::Qtbug45697TestWidget() + : m_treeView(new QTreeView(this)) + , m_model(new QStandardItemModel(0, Qtbug45697TestWidget::columnCount, this)) + , m_sortFilterProxyModel(new QSortFilterProxyModel(this)) + , m_timerTick(0) + { + QVBoxLayout *vBoxLayout = new QVBoxLayout(this); + vBoxLayout->addWidget(m_treeView); + + for (char sortChar = 'z'; sortChar >= 'a' ; --sortChar) { + QList items; + for (int column = 0; column < Qtbug45697TestWidget::columnCount; ++column) { + const QString text = QLatin1Char(sortChar) + QLatin1String(" ") + QString::number(column); + items.append(new QStandardItem(text)); + } + m_model->appendRow(items); + } + + m_sortFilterProxyModel->setSourceModel(m_model); + m_treeView->setModel(m_sortFilterProxyModel); + + QHeaderView *headerView = m_treeView->header(); + for (int s = 1, lastSection = headerView->count() - 1; s < lastSection; ++s ) + headerView->setSectionResizeMode(s, QHeaderView::ResizeToContents); + + QTimer *timer = new QTimer(this); + timer->setInterval(50); + connect(timer, &QTimer::timeout, this, &Qtbug45697TestWidget::slotTimer); + timer->start(); +} + +void Qtbug45697TestWidget::slotTimer() +{ + switch (m_timerTick++) { + case 0: + m_model->sort(0); + break; + case 1: + show(); + break; + default: + close(); + break; + } +} + +void tst_QTreeView::taskQTBUG_45697_crash() +{ + Qtbug45697TestWidget testWidget; + testWidget.setWindowTitle(QTest::currentTestFunction()); + testWidget.resize(400, 400); + testWidget.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(100, 100)); + QTRY_VERIFY(testWidget.timerTick() >= 2); +} + QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" -- cgit v1.2.3 From 9749ddeb4b2eb083413441a9403d7b5ffab1f6c1 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 May 2015 17:02:57 +0200 Subject: Remove test other/baselineexample. baselineexample.pro is missing CONFIG += testcase, so, make check succeeds without doing anything. The test seems to connect to some network server to retrieve baseline images, but that infrastructure apparently no longer exists. Change-Id: I98f4fe5ef8a508fda90e408df2781a944eb99a60 Reviewed-by: Simon Hausmann --- .../auto/other/baselineexample/baselineexample.pro | 19 --- .../other/baselineexample/tst_baselineexample.cpp | 138 --------------------- tests/auto/other/other.pro | 3 - 3 files changed, 160 deletions(-) delete mode 100644 tests/auto/other/baselineexample/baselineexample.pro delete mode 100644 tests/auto/other/baselineexample/tst_baselineexample.cpp diff --git a/tests/auto/other/baselineexample/baselineexample.pro b/tests/auto/other/baselineexample/baselineexample.pro deleted file mode 100644 index c1c4b31bfe..0000000000 --- a/tests/auto/other/baselineexample/baselineexample.pro +++ /dev/null @@ -1,19 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-12-09T14:55:13 -# -#------------------------------------------------- - -QT += testlib widgets - -TARGET = tst_baselineexample -CONFIG += console -CONFIG -= app_bundle - -TEMPLATE = app - -SOURCES += tst_baselineexample.cpp -DEFINES += SRCDIR=\\\"$$PWD/\\\" - -include($$PWD/../../../baselineserver/shared/qbaselinetest.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/other/baselineexample/tst_baselineexample.cpp b/tests/auto/other/baselineexample/tst_baselineexample.cpp deleted file mode 100644 index 9059989015..0000000000 --- a/tests/auto/other/baselineexample/tst_baselineexample.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -class tst_BaselineExample : public QObject -{ - Q_OBJECT - -public: - tst_BaselineExample(); - -private Q_SLOTS: - void testBasicUsage(); - void testMultipleImages(); - void testDataDriven_data(); - void testDataDriven(); - void testDataDrivenChecksum_data(); - void testDataDrivenChecksum(); -}; - - -tst_BaselineExample::tst_BaselineExample() -{ -} - - -void tst_BaselineExample::testBasicUsage() -{ - // Generate an image: - QPushButton b("Press me!"); - b.resize(100, 50); - b.show(); - QVERIFY(QTest::qWaitForWindowExposed(&b)); - QImage img1 = b.grab().toImage(); - QVERIFY(!img1.isNull()); - - // Compare it to baseline on server: - QBASELINE_CHECK(img1, "button"); -} - - -void tst_BaselineExample::testMultipleImages() -{ - QPushButton b("Press me!"); - b.resize(100, 50); - b.show(); - QVERIFY(QTest::qWaitForWindowExposed(&b)); - QBASELINE_CHECK(b.grab().toImage(), "text1"); - - b.setText("Kick me!"); - QTest::qWait(50); - QBASELINE_CHECK(b.grab().toImage(), "text2"); -} - - -void tst_BaselineExample::testDataDriven_data() -{ - QTest::addColumn("label"); - QBaselineTest::newRow("short") << "Ok!"; - QBaselineTest::newRow("long") << "A really long button text that just does not seem to end"; - QBaselineTest::newRow("empty") << ""; - QBaselineTest::newRow("signs") << "!@#$%^&*()_"; - QBaselineTest::newRow("html") << "BOLD"; -} - - -void tst_BaselineExample::testDataDriven() -{ - QFETCH(QString, label); - QPushButton b(label); - b.resize(100, 50); - b.show(); - QVERIFY(QTest::qWaitForWindowExposed(&b)); - QBASELINE_TEST(b.grab().toImage()); -} - - -void tst_BaselineExample::testDataDrivenChecksum_data() -{ - QTest::addColumn("label"); - - const int numItems = 5; - const char *tags[numItems] = {"short", "long", "empty", "signs", "html"}; - const char *labels[numItems] = {"Ok!", "A really long button text that just does not seem to end", "", "!@#$%^&*()_", "BOLD"}; - - for (int i = 0; i Date: Sun, 24 May 2015 09:04:24 -0700 Subject: Fix forkfd on OS X 10.7 and earlier by avoiding waitid altogether On OS X 10.7 and earlier, waitid() never sets si_pid, even when using P_PID. So on OS X, check if waitid() works, and if not, use the same codepath as if HAVE_WAITID were not defined. Change-Id: I64331a090f9358bb01f435954d3dfd3ab430a96c Reviewed-by: Thiago Macieira --- src/3rdparty/forkfd/forkfd.c | 56 +++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index 017ae0741e..8d08f403ec 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -63,7 +63,7 @@ # include # include # if MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 -# define HAVE_BROKEN_WAITID_ALL 1 +# define HAVE_BROKEN_WAITID 1 # endif #endif @@ -109,10 +109,10 @@ static struct sigaction old_sigaction; static pthread_once_t forkfd_initialization = PTHREAD_ONCE_INIT; static ffd_atomic_int forkfd_status = FFD_ATOMIC_INIT(0); -#ifdef HAVE_BROKEN_WAITID_ALL -static int waitid_p_all_works = 0; +#ifdef HAVE_BROKEN_WAITID +static int waitid_works = 0; #else -static const int waitid_p_all_works = 1; +static const int waitid_works = 1; #endif static ProcessInfo *tryAllocateInSection(Header *header, ProcessInfo entries[], int maxCount) @@ -183,10 +183,13 @@ static int tryReaping(pid_t pid, siginfo_t *info) { /* reap the child */ #ifdef HAVE_WAITID - // we have waitid(2), which fills in siginfo_t for us - info->si_pid = 0; - return waitid(P_PID, pid, info, WEXITED | WNOHANG) == 0 && info->si_pid == pid; -#else + if (waitid_works) { + // we have waitid(2), which fills in siginfo_t for us + info->si_pid = 0; + return waitid(P_PID, pid, info, WEXITED | WNOHANG) == 0 && info->si_pid == pid; + } +#endif + int status; if (waitpid(pid, &status, WNOHANG) <= 0) return 0; // child did not change state @@ -206,7 +209,6 @@ static int tryReaping(pid_t pid, siginfo_t *info) } return 1; -#endif } static void freeInfo(Header *header, ProcessInfo *entry) @@ -246,7 +248,7 @@ static void sigchld_handler(int signum) memset(&info, 0, sizeof info); #ifdef HAVE_WAITID - if (!waitid_p_all_works) + if (!waitid_works) goto search_arrays; /* be optimistic: try to see if we can get the child that exited */ @@ -310,12 +312,14 @@ search_arrays: if (pid <= 0) continue; #ifdef HAVE_WAITID - /* The child might have been reaped by the block above in another thread, - * so first check if it's ready and, if it is, lock it */ - if (!isChildReady(pid, &info) || - !ffd_atomic_compare_exchange(&children.entries[i].pid, &pid, -1, - FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) - continue; + if (waitid_works) { + /* The child might have been reaped by the block above in another thread, + * so first check if it's ready and, if it is, lock it */ + if (!isChildReady(pid, &info) || + !ffd_atomic_compare_exchange(&children.entries[i].pid, &pid, -1, + FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) + continue; + } #endif if (tryReaping(pid, &info)) { /* this is our child, send notification and free up this entry */ @@ -331,12 +335,14 @@ search_arrays: if (pid <= 0) continue; #ifdef HAVE_WAITID - /* The child might have been reaped by the block above in another thread, - * so first check if it's ready and, if it is, lock it */ - if (!isChildReady(pid, &info) || - !ffd_atomic_compare_exchange(&array->entries[i].pid, &pid, -1, - FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) - continue; + if (waitid_works) { + /* The child might have been reaped by the block above in another thread, + * so first check if it's ready and, if it is, lock it */ + if (!isChildReady(pid, &info) || + !ffd_atomic_compare_exchange(&array->entries[i].pid, &pid, -1, + FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) + continue; + } #endif if (tryReaping(pid, &info)) { /* this is our child, send notification and free up this entry */ @@ -357,17 +363,19 @@ chain_handler: static void forkfd_initialize() { -#if defined(HAVE_BROKEN_WAITID_ALL) +#if defined(HAVE_BROKEN_WAITID) pid_t pid = fork(); if (pid == 0) { _exit(0); } else if (pid > 0) { siginfo_t info; waitid(P_ALL, 0, &info, WNOWAIT | WEXITED); - waitid_p_all_works = (info.si_pid != 0); + waitid_works = (info.si_pid != 0); + info.si_pid = 0; // now really reap the child waitid(P_PID, pid, &info, WEXITED); + waitid_works = waitid_works && (info.si_pid != 0); } #endif -- cgit v1.2.3 From 5449589b7c45a5ce1374c358bbcb1eba130d390d Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 27 May 2015 14:08:04 +0200 Subject: tst_QApplication - quitOnLastWindowClosed (fix for OS X) Two (?) tests can fail: what they actually try to test is that our application quits on the second single shot timer (2 s. timeout) and not on the first one (timeout 1 s.) - on the first timeout we either ignore event, or we still have another window and should not quit yet, on the second timeout we actually do quit the app. The test checks this in a quite fragile way, counting the number of timeouts for the third 100 ms timer. It looks like on OS X (VM-only) there is some delay (~500-600 ms) before we receive the first timeout so the count is always 14 or less, making the test to fail. Change-Id: I9e8728e6c956025d91528f4195982767a5d3d320 Task-number: QTBUG-46164 Reviewed-by: Simon Hausmann Reviewed-by: Gabriel de Dietrich --- .../kernel/qapplication/tst_qapplication.cpp | 34 +++++++++++++--------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index c9a1a64135..c33fd5a951 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -178,6 +178,12 @@ private slots: void settableStyleHints_data(); void settableStyleHints(); // Needs to run last as it changes style hints. + +protected slots: + void quitApplication(); + +private: + bool quitApplicationTriggered; }; class EventSpy : public QObject @@ -235,6 +241,7 @@ public: static char *argv0; tst_QApplication::tst_QApplication() + : quitApplicationTriggered(false) { #ifdef Q_OS_WINCE // Clean up environment previously to launching test @@ -719,11 +726,8 @@ void tst_QApplication::quitOnLastWindowClosed() { int argc = 0; QApplication app(argc, 0); - QTimer timer; - timer.setInterval(100); QSignalSpy spy(&app, SIGNAL(aboutToQuit())); - QSignalSpy spy2(&timer, SIGNAL(timeout())); CloseEventTestWindow mainWindow; @@ -733,14 +737,14 @@ void tst_QApplication::quitOnLastWindowClosed() mainWindow.show(); QVERIFY(QTest::qWaitForWindowExposed(&mainWindow)); - timer.start(); - QTimer::singleShot(1000, &mainWindow, SLOT(close())); // This should quit the application - QTimer::singleShot(2000, &app, SLOT(quit())); // This makes sure we quit even if it didn't + QTimer::singleShot(1000, &mainWindow, SLOT(close())); // This should NOT quit the application (see CloseEventTestWindow) + quitApplicationTriggered = false; + QTimer::singleShot(2000, this, SLOT(quitApplication())); // This actually quits the application. app.exec(); QCOMPARE(spy.count(), 1); - QVERIFY(spy2.count() > 15); // Should be around 20 if closing did not caused the quit + QVERIFY(quitApplicationTriggered); } { int argc = 0; @@ -768,24 +772,20 @@ void tst_QApplication::quitOnLastWindowClosed() QApplication app(argc, 0); QVERIFY(app.quitOnLastWindowClosed()); - QTimer timer; - timer.setInterval(100); - QSignalSpy timerSpy(&timer, SIGNAL(timeout())); - QWindow w; w.show(); QWidget wid; wid.show(); - timer.start(); QTimer::singleShot(1000, &wid, SLOT(close())); // This should NOT quit the application because the // QWindow is still there. - QTimer::singleShot(2000, &app, SLOT(quit())); // This causes the quit. + quitApplicationTriggered = false; + QTimer::singleShot(2000, this, SLOT(quitApplication())); // This causes the quit. app.exec(); - QVERIFY(timerSpy.count() > 15); // Should be around 20 if closing did not caused the quit + QVERIFY(quitApplicationTriggered); // Should be around 20 if closing did not caused the quit } { // QTBUG-31569: If the last widget with Qt::WA_QuitOnClose set is closed, other // widgets that don't have the attribute set should be closed automatically. @@ -2406,6 +2406,12 @@ void tst_QApplication::globalStaticObjectDestruction() #endif } +void tst_QApplication::quitApplication() +{ + quitApplicationTriggered = true; + qApp->quit(); +} + //QTEST_APPLESS_MAIN(tst_QApplication) int main(int argc, char *argv[]) { -- cgit v1.2.3 From 73d3f1b116a584b97ec0defc9df68bc3507d5cc7 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Tue, 26 May 2015 17:05:35 +0900 Subject: Doc fix typo in QT_MESSAGE_PATTERN Change-Id: I1850c3eb07b06a4174c0e6819074040c4d62c423 Reviewed-by: Kai Koehne --- src/corelib/global/qlogging.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 447a875655..88882bbe8f 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1737,7 +1737,7 @@ void qErrnoWarning(int code, const char *msg, ...) Example: \code - QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D{%endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" + QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" \endcode The default \a pattern is "%{if-category}%{category}: %{endif}%{message}". -- cgit v1.2.3 From 270313d06848e20dffdfae8951838a63e6cb204c Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 26 May 2015 14:33:25 +0200 Subject: Fix wording of error message This broke with commit 83a5694dc21b8 . Change-Id: Ib641cef9639f1c70a5f38ce0e5d9d9e3071373e4 Reviewed-by: Oswald Buddenhagen --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 234ddc6971..de0a1bd5d7 100755 --- a/configure +++ b/configure @@ -2986,7 +2986,7 @@ elif [ $COMMERCIAL_USER = "yes" ]; then echo echo "Error: This is the Open Source version of Qt." echo "If you want to use Enterprise features of Qt," - echo "information use the contact form at http://www.qt.io/contact-us" + echo "use the contact form at http://www.qt.io/contact-us" echo "to purchase a license." echo exit 1 -- cgit v1.2.3 From e63dde49678baf8041e32254a7b6b35d871d201f Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 22 May 2015 15:33:34 +0200 Subject: configure: Remove traces of "Snapshot" edition Change-Id: I7f2511e224d848bb820321be5dd190d8b3b8f1c4 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 6bf0646378..10b33f41e4 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -4389,7 +4389,7 @@ bool Configure::showLicense(QString orgLicenseFile) bool showLgpl2 = true; QString licenseFile = orgLicenseFile; QString theLicense; - if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") { + if (dictionary["EDITION"] == "OpenSource") { if (platform() != ANDROID || dictionary["ANDROID_STYLE_ASSETS"] == "no") { theLicense = "GNU Lesser General Public License (LGPL) version 2.1" "\nor the GNU Lesser General Public License (LGPL) version 3"; @@ -4412,7 +4412,7 @@ bool Configure::showLicense(QString orgLicenseFile) cout << "You are licensed to use this software under the terms of" << endl << "the " << theLicense << "." << endl << endl; - if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") { + if (dictionary["EDITION"] == "OpenSource") { cout << "Type '3' to view the Lesser GNU General Public License version 3 (LGPLv3)." << endl; if (showLgpl2) cout << "Type 'L' to view the Lesser GNU General Public License version 2.1 (LGPLv2.1)." << endl; @@ -4431,7 +4431,7 @@ bool Configure::showLicense(QString orgLicenseFile) } else if (accept == 'n') { return false; } else { - if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") { + if (dictionary["EDITION"] == "OpenSource") { if (accept == '3') licenseFile = orgLicenseFile + "/LICENSE.LGPLv3"; else -- cgit v1.2.3 From d2da14a9e05381eb3dd70071001dce72b2a465f3 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 22 May 2015 15:38:00 +0200 Subject: configure: Remove COMMERCIAL_VERSION define Not used anymore. Change-Id: I7db671008758e79598697e06e12f1b959bf479c6 Reviewed-by: Oswald Buddenhagen --- tools/configure/Makefile.mingw | 2 +- tools/configure/Makefile.win32 | 2 +- tools/configure/configure.pro | 2 -- tools/configure/configureapp.cpp | 14 +------------- 4 files changed, 3 insertions(+), 17 deletions(-) diff --git a/tools/configure/Makefile.mingw b/tools/configure/Makefile.mingw index 40c2112132..9ac99fd678 100644 --- a/tools/configure/Makefile.mingw +++ b/tools/configure/Makefile.mingw @@ -4,7 +4,7 @@ CONFSRC = $(TOOLSRC)/configure RAW_PCH = configure_pch.h PCH = $(RAW_PCH).gch/c++ -DEFINES = -DUNICODE -DQT_NO_DATASTREAM -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DCOMMERCIAL_VERSION +DEFINES = -DUNICODE -DQT_NO_DATASTREAM -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE INCPATH = -I"../../include" -I"../../include/QtCore" -I"../../include/QtCore/$(QTVERSION)" -I"../../include/QtCore/$(QTVERSION)/QtCore" -I"$(TOOLSRC)/shared" -I"$(QTSRC)mkspecs/win32-g++" CXXFLAGS_BARE = -fno-rtti -fno-exceptions -mthreads -Wall -Wextra $(DEFINES) $(INCPATH) CXXFLAGS = -include $(RAW_PCH) $(CXXFLAGS_BARE) diff --git a/tools/configure/Makefile.win32 b/tools/configure/Makefile.win32 index b74b0bc82d..8c6d213e42 100644 --- a/tools/configure/Makefile.win32 +++ b/tools/configure/Makefile.win32 @@ -3,7 +3,7 @@ TOOLSRC = $(QTSRC)tools CONFSRC = $(TOOLSRC)\configure PCH = configure_pch.pch -DEFINES = -DUNICODE -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DCOMMERCIAL_VERSION +DEFINES = -DUNICODE -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE INCPATH = -I"..\..\include" -I"..\..\include\QtCore" -I"..\..\include\QtCore\$(QTVERSION)" -I"..\..\include\QtCore\$(QTVERSION)\QtCore" -I"$(TOOLSRC)\shared" -I"$(QTSRC)mkspecs\win32-msvc2008" CXXFLAGS_BARE = -nologo -Zc:wchar_t -W3 -GR -EHsc -w34100 -w34189 $(CFLAGS_CRT) $(EXTRA_CXXFLAGS) $(DEFINES) $(INCPATH) CXXFLAGS = -FIconfigure_pch.h -Yuconfigure_pch.h -Fp$(PCH) -MP $(CXXFLAGS_BARE) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index d3237d472b..e4901bacde 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -132,5 +132,3 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/plugin/quuid.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qcryptographichash.cpp \ $$QT_SOURCE_TREE/tools/shared/windows/registry.cpp - -DEFINES += COMMERCIAL_VERSION diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 10b33f41e4..faeb45417b 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -34,9 +34,7 @@ #include "configureapp.h" #include "environment.h" -#ifdef COMMERCIAL_VERSION -# include "tools.h" -#endif +#include "tools.h" #include #include @@ -4507,19 +4505,9 @@ void Configure::readLicense() cout << endl << "Cannot find the GPL license files! Please download the Open Source version of the library." << endl; dictionary["DONE"] = "error"; } -#ifdef COMMERCIAL_VERSION else { Tools::checkLicense(dictionary, sourcePath, buildPath); } -#else // !COMMERCIAL_VERSION - else { - cout << endl << "Error: This is the Open Source version of Qt." - << endl << "If you want to use Enterprise features of Qt," - << endl << "information use the contact form at http://www.qt.io/contact-us" - << endl << "to purchase a license." << endl << endl; - dictionary["DONE"] = "error"; - } -#endif } void Configure::reloadCmdLine() -- cgit v1.2.3 From 3311d92d8ed46426e19000d1e3b94029b9058983 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 13 May 2015 13:20:23 +0200 Subject: Fix failing input device notifications on embedded The connection to the deviceListChanged() signal may be queued. To make it work our custom types have to be registered. The problem is only visible with input backends like evdevtouch that live on their own thread. Task-number: QTBUG-46069 Change-Id: I4c03e8031e4337b5e711a3bd2cf405d15d6ce214 Reviewed-by: Gatis Paeglis --- src/gui/kernel/qinputdevicemanager.cpp | 1 + src/gui/kernel/qinputdevicemanager_p.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/gui/kernel/qinputdevicemanager.cpp b/src/gui/kernel/qinputdevicemanager.cpp index d0dd8a4e7c..dbdb03adbb 100644 --- a/src/gui/kernel/qinputdevicemanager.cpp +++ b/src/gui/kernel/qinputdevicemanager.cpp @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE QInputDeviceManager::QInputDeviceManager(QObject *parent) : QObject(*new QInputDeviceManagerPrivate, parent) { + qRegisterMetaType(); } int QInputDeviceManager::deviceCount(DeviceType type) const diff --git a/src/gui/kernel/qinputdevicemanager_p.h b/src/gui/kernel/qinputdevicemanager_p.h index 15c84d1a82..d64793c23c 100644 --- a/src/gui/kernel/qinputdevicemanager_p.h +++ b/src/gui/kernel/qinputdevicemanager_p.h @@ -77,4 +77,6 @@ signals: QT_END_NAMESPACE +Q_DECLARE_METATYPE(QInputDeviceManager::DeviceType) + #endif // QINPUTDEVICEMANAGER_P_H -- cgit v1.2.3 From 43e82a3b094b8894b1cade6a6b871dd57aaa6c83 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 11 May 2015 13:53:37 +0200 Subject: QOpenGLWindow: initializeGL is to be called before resizeGL This involves deinlining some private class stuff to keep things readable and maintainable. Task-number: QTBUG-46002 Change-Id: Ie2888aa6c16a6f5182b61fbaa43288cfcc96cbc4 Reviewed-by: Gunnar Sletta --- src/gui/kernel/qopenglwindow.cpp | 245 +++++++++++++++++++++------------------ 1 file changed, 131 insertions(+), 114 deletions(-) diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index 7113345a75..b2025faaf1 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -175,141 +175,156 @@ public: this->shareContext = qt_gl_global_share_context(); } - ~QOpenGLWindowPrivate() - { - Q_Q(QOpenGLWindow); - if (q->isValid()) { - q->makeCurrent(); // this works even when the platformwindow is destroyed - paintDevice.reset(0); - fbo.reset(0); - blitter.destroy(); - q->doneCurrent(); - } - } + ~QOpenGLWindowPrivate(); static QOpenGLWindowPrivate *get(QOpenGLWindow *w) { return w->d_func(); } - void bindFBO() - { - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->bind(); - else - QOpenGLFramebufferObject::bindDefault(); + void bindFBO(); + void initialize(); + + void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE; + void endPaint() Q_DECL_OVERRIDE; + void flush(const QRegion ®ion) Q_DECL_OVERRIDE; + + QOpenGLWindow::UpdateBehavior updateBehavior; + bool hasFboBlit; + QScopedPointer context; + QOpenGLContext *shareContext; + QScopedPointer fbo; + QScopedPointer paintDevice; + QOpenGLTextureBlitter blitter; + QColor backgroundColor; + QScopedPointer offscreenSurface; +}; + +QOpenGLWindowPrivate::~QOpenGLWindowPrivate() +{ + Q_Q(QOpenGLWindow); + if (q->isValid()) { + q->makeCurrent(); // this works even when the platformwindow is destroyed + paintDevice.reset(0); + fbo.reset(0); + blitter.destroy(); + q->doneCurrent(); } +} - void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE - { - Q_UNUSED(region); - Q_Q(QOpenGLWindow); - - if (!context) { - context.reset(new QOpenGLContext); - context->setShareContext(shareContext); - context->setFormat(q->requestedFormat()); - context->setScreen(q->screen()); - if (!context->create()) - qWarning("QOpenGLWindow::beginPaint: Failed to create context"); - if (!context->makeCurrent(q)) - qWarning("QOpenGLWindow::beginPaint: Failed to make context current"); - - paintDevice.reset(new QOpenGLWindowPaintDevice(q)); - if (updateBehavior == QOpenGLWindow::PartialUpdateBlit) - hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); - - q->initializeGL(); - } else { - context->makeCurrent(q); - } +void QOpenGLWindowPrivate::initialize() +{ + Q_Q(QOpenGLWindow); - const int deviceWidth = q->width() * q->devicePixelRatio(); - const int deviceHeight = q->height() * q->devicePixelRatio(); - const QSize deviceSize(deviceWidth, deviceHeight); - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { - if (!fbo || fbo->size() != deviceSize) { - QOpenGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - if (q->requestedFormat().samples() > 0) { - if (updateBehavior != QOpenGLWindow::PartialUpdateBlend) - fboFormat.setSamples(q->requestedFormat().samples()); - else - qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); - } - fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat)); - markWindowAsDirty(); + if (context) + return; + + context.reset(new QOpenGLContext); + context->setShareContext(shareContext); + context->setFormat(q->requestedFormat()); + if (!context->create()) + qWarning("QOpenGLWindow::beginPaint: Failed to create context"); + if (!context->makeCurrent(q)) + qWarning("QOpenGLWindow::beginPaint: Failed to make context current"); + + paintDevice.reset(new QOpenGLWindowPaintDevice(q)); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlit) + hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); + + q->initializeGL(); +} + +void QOpenGLWindowPrivate::beginPaint(const QRegion ®ion) +{ + Q_UNUSED(region); + Q_Q(QOpenGLWindow); + + initialize(); + context->makeCurrent(q); + + const int deviceWidth = q->width() * q->devicePixelRatio(); + const int deviceHeight = q->height() * q->devicePixelRatio(); + const QSize deviceSize(deviceWidth, deviceHeight); + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { + if (!fbo || fbo->size() != deviceSize) { + QOpenGLFramebufferObjectFormat fboFormat; + fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + if (q->requestedFormat().samples() > 0) { + if (updateBehavior != QOpenGLWindow::PartialUpdateBlend) + fboFormat.setSamples(q->requestedFormat().samples()); + else + qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); } - } else { + fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat)); markWindowAsDirty(); } + } else { + markWindowAsDirty(); + } - paintDevice->setSize(QSize(deviceWidth, deviceHeight)); - paintDevice->setDevicePixelRatio(q->devicePixelRatio()); - context->functions()->glViewport(0, 0, deviceWidth, deviceHeight); + paintDevice->setSize(QSize(deviceWidth, deviceHeight)); + paintDevice->setDevicePixelRatio(q->devicePixelRatio()); + context->functions()->glViewport(0, 0, deviceWidth, deviceHeight); - context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); + context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - q->paintUnderGL(); + q->paintUnderGL(); - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->bind(); - } + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->bind(); +} - void endPaint() Q_DECL_OVERRIDE - { - Q_Q(QOpenGLWindow); - - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->release(); - - context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - - if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) { - const int deviceWidth = q->width() * q->devicePixelRatio(); - const int deviceHeight = q->height() * q->devicePixelRatio(); - QOpenGLExtensions extensions(context.data()); - extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle()); - extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject()); - extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight, - 0, 0, deviceWidth, deviceHeight, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { - if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) { - context->functions()->glEnable(GL_BLEND); - context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - if (!blitter.isCreated()) - blitter.create(); +void QOpenGLWindowPrivate::endPaint() +{ + Q_Q(QOpenGLWindow); + + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->release(); - QRect windowRect(QPoint(0, 0), fbo->size()); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); - blitter.bind(); - blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft); - blitter.release(); + context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) - context->functions()->glDisable(GL_BLEND); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) { + const int deviceWidth = q->width() * q->devicePixelRatio(); + const int deviceHeight = q->height() * q->devicePixelRatio(); + QOpenGLExtensions extensions(context.data()); + extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle()); + extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject()); + extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight, + 0, 0, deviceWidth, deviceHeight, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { + if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) { + context->functions()->glEnable(GL_BLEND); + context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } + if (!blitter.isCreated()) + blitter.create(); - q->paintOverGL(); - } + QRect windowRect(QPoint(0, 0), fbo->size()); + QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); + blitter.bind(); + blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft); + blitter.release(); - void flush(const QRegion ®ion) Q_DECL_OVERRIDE - { - Q_UNUSED(region); - Q_Q(QOpenGLWindow); - context->swapBuffers(q); - emit q->frameSwapped(); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) + context->functions()->glDisable(GL_BLEND); } - QOpenGLWindow::UpdateBehavior updateBehavior; - bool hasFboBlit; - QScopedPointer context; - QOpenGLContext *shareContext; - QScopedPointer fbo; - QScopedPointer paintDevice; - QOpenGLTextureBlitter blitter; - QColor backgroundColor; - QScopedPointer offscreenSurface; -}; + q->paintOverGL(); +} + +void QOpenGLWindowPrivate::bindFBO() +{ + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->bind(); + else + QOpenGLFramebufferObject::bindDefault(); +} + +void QOpenGLWindowPrivate::flush(const QRegion ®ion) +{ + Q_UNUSED(region); + Q_Q(QOpenGLWindow); + context->swapBuffers(q); + emit q->frameSwapped(); +} void QOpenGLWindowPaintDevice::ensureActiveTarget() { @@ -632,6 +647,8 @@ void QOpenGLWindow::paintEvent(QPaintEvent *event) void QOpenGLWindow::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); + Q_D(QOpenGLWindow); + d->initialize(); resizeGL(width(), height()); } -- cgit v1.2.3 From dd02c1eb38c6dfc8367f2c692e11897b6c00b097 Mon Sep 17 00:00:00 2001 From: Marko Kangas Date: Wed, 6 May 2015 13:51:04 +0300 Subject: Add support to disable close button from the tool window in Cocoa. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed regression from Qt4 that close button could't be disabled from the tool window. With this patch buttons are hidden before using button hints like it's on Windows. Change-Id: I00f03ff9528ccae3b1136312404452b9415953b4 Task-number: QTBUG-45971 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index cbe4227b63..86959869cc 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -799,9 +799,22 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) if (flags & Qt::FramelessWindowHint) return styleMask; if ((type & Qt::Popup) == Qt::Popup) { - if (!windowIsPopupType(type)) - styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSTitledWindowMask); + if (!windowIsPopupType(type)) { + styleMask = NSUtilityWindowMask; + if (!(flags & Qt::CustomizeWindowHint)) { + styleMask |= NSResizableWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask | NSTitledWindowMask; + } else { + if (flags & Qt::WindowMaximizeButtonHint) + styleMask |= NSResizableWindowMask; + if (flags & Qt::WindowTitleHint) + styleMask |= NSTitledWindowMask; + if (flags & Qt::WindowCloseButtonHint) + styleMask |= NSClosableWindowMask; + if (flags & Qt::WindowMinimizeButtonHint) + styleMask |= NSMiniaturizableWindowMask; + } + } } else { if (type == Qt::Window && !(flags & Qt::CustomizeWindowHint)) { styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); -- cgit v1.2.3 From 765fea8dad269872a7fbb80a253367ac5e905259 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 27 May 2015 10:49:52 +0200 Subject: QtGui/Windows: Fix static build. qtbase\src\gui\kernel\qgenericpluginfactory.cpp:70: error: C2220: warning treated as error - no 'object' file generated qtbase\src\gui\kernel\qgenericpluginfactory.cpp:70: warning: C4100: 'specification' : unreferenced formal parameter Change-Id: I2dbb114fa9feaf862b4554b128caca0dcb5e291e Reviewed-by: Kai Koehne --- src/gui/kernel/qgenericpluginfactory.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qgenericpluginfactory.cpp b/src/gui/kernel/qgenericpluginfactory.cpp index 7e4727df8c..d7b9bfba06 100644 --- a/src/gui/kernel/qgenericpluginfactory.cpp +++ b/src/gui/kernel/qgenericpluginfactory.cpp @@ -69,13 +69,13 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, */ QObject *QGenericPluginFactory::create(const QString& key, const QString &specification) { +#if (!defined(Q_OS_WIN32) || defined(QT_SHARED)) && !defined(QT_NO_LIBRARY) const QString driver = key.toLower(); - -#if !defined(Q_OS_WIN32) || defined(QT_SHARED) -#ifndef QT_NO_LIBRARY if (QObject *object = qLoadPlugin1(loader(), driver, specification)) return object; -#endif +#else // (!Q_OS_WIN32 || QT_SHARED) && !QT_NO_LIBRARY + Q_UNUSED(key) + Q_UNUSED(specification) #endif return 0; } -- cgit v1.2.3 From 547141352242f7f4eebc6814af7a5ea0f3dff5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 22 May 2015 14:01:59 +0200 Subject: Add shared implementation of a NSAutoreleasePool wrapper to qglobal We have at least 5 different (but equal) implementations of a wrapper in Qt, and some code uses explicit NSAutoreleasePools. Having a shared implementation lets us clean up things a bit and makes it easier to reason about which pools are actually needed. Change-Id: I2fd8eefc3ae7308595ef9899b7820206268362a5 Reviewed-by: Tim Blechmann Reviewed-by: Simon Hausmann --- src/corelib/global/qglobal.h | 64 +++++++++++++--------- src/corelib/io/qfilesystemwatcher_fsevents.mm | 31 ++--------- src/corelib/kernel/qcore_mac_objc.mm | 17 ++++++ src/corelib/tools/qlocale_mac.mm | 14 +---- .../fontdatabases/mac/qcoretextfontdatabase.mm | 14 +---- src/plugins/bearer/corewlan/qcorewlanengine.mm | 30 ++++------ src/plugins/platforms/cocoa/cocoa.pro | 2 - src/plugins/platforms/cocoa/main.mm | 2 +- .../platforms/cocoa/qcocoaautoreleasepool.h | 53 ------------------ .../platforms/cocoa/qcocoaautoreleasepool.mm | 48 ---------------- src/plugins/platforms/cocoa/qcocoacursor.mm | 1 - .../platforms/cocoa/qcocoaeventdispatcher.mm | 11 ++-- .../platforms/cocoa/qcocoafiledialoghelper.mm | 7 +-- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 5 +- src/plugins/platforms/cocoa/qcocoahelpers.mm | 3 +- src/plugins/platforms/cocoa/qcocoainputcontext.mm | 3 +- src/plugins/platforms/cocoa/qcocoaintegration.h | 1 - src/plugins/platforms/cocoa/qcocoaintegration.mm | 7 +-- src/plugins/platforms/cocoa/qcocoamenu.mm | 19 +++---- src/plugins/platforms/cocoa/qcocoamenubar.mm | 9 ++- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 5 +- .../platforms/cocoa/qcocoanativeinterface.mm | 2 +- .../platforms/cocoa/qcocoasystemsettings.mm | 3 +- src/plugins/platforms/cocoa/qcocoatheme.mm | 3 +- src/plugins/platforms/cocoa/qcocoawindow.mm | 19 +++---- src/plugins/platforms/cocoa/qmacclipboard.mm | 3 +- src/plugins/platforms/cocoa/qnsview.mm | 5 +- src/plugins/platforms/cocoa/qprintengine_mac.mm | 3 +- src/plugins/platforms/cocoa/qt_mac_p.h | 11 ---- src/printsupport/dialogs/qpagesetupdialog_mac.mm | 3 +- src/printsupport/dialogs/qprintdialog_mac.mm | 3 +- src/widgets/styles/qmacstyle_mac.mm | 22 ++------ src/widgets/util/qscroller_mac.mm | 3 +- src/widgets/widgets/qmainwindow.cpp | 2 +- .../corelib/tools/qbytearray/tst_qbytearray_mac.mm | 12 ++-- .../corelib/tools/qdatetime/tst_qdatetime_mac.mm | 6 +- .../auto/corelib/tools/qstring/tst_qstring_mac.mm | 8 +-- .../qfontdialog/tst_qfontdialog_mac_helpers.mm | 2 +- 38 files changed, 139 insertions(+), 317 deletions(-) delete mode 100644 src/plugins/platforms/cocoa/qcocoaautoreleasepool.h delete mode 100644 src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index c4e2f7609c..55aa34223e 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -321,6 +321,15 @@ typedef double qreal; # define Q_NETWORK_EXPORT #endif +/* + Some classes do not permit copies to be made of an object. These + classes contains a private copy constructor and assignment + operator to disable copying (the compiler gives an error message). +*/ +#define Q_DISABLE_COPY(Class) \ + Class(const Class &) Q_DECL_EQ_DELETE;\ + Class &operator=(const Class &) Q_DECL_EQ_DELETE; + /* No, this is not an evil backdoor. QT_BUILD_INTERNAL just exports more symbols for Qt's internal unit tests. If you want slower loading times and more @@ -543,7 +552,21 @@ template Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max) { return qMax(min, qMin(max, val)); } -#ifdef Q_OS_DARWIN +#ifndef Q_FORWARD_DECLARE_OBJC_CLASS +# ifdef __OBJC__ +# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname +# else +# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname +# endif +#endif +#ifndef Q_FORWARD_DECLARE_CF_TYPE +# define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref +#endif +#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE +# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref +#endif + +#ifdef Q_OS_MAC # define QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, ios) \ ((defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && osx != __MAC_NA && __MAC_OS_X_VERSION_MAX_ALLOWED >= osx) || \ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios)) @@ -561,7 +584,21 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max QT_MAC_DEPLOYMENT_TARGET_BELOW(__MAC_NA, ios) # define QT_OSX_DEPLOYMENT_TARGET_BELOW(osx) \ QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, __IPHONE_NA) -#endif + +Q_FORWARD_DECLARE_OBJC_CLASS(NSAutoreleasePool); + +// Implemented in qcore_mac_objc.mm +class Q_CORE_EXPORT QMacAutoReleasePool +{ +public: + QMacAutoReleasePool(); + ~QMacAutoReleasePool(); +private: + Q_DISABLE_COPY(QMacAutoReleasePool); + NSAutoreleasePool *pool; +}; + +#endif // Q_OS_MAC /* Data stream functions are provided by many classes (defined in qdatastream.h) @@ -1033,15 +1070,6 @@ Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1); { return T::dynamic_cast_will_always_fail_because_rtti_is_disabled; } #endif -/* - Some classes do not permit copies to be made of an object. These - classes contains a private copy constructor and assignment - operator to disable copying (the compiler gives an error message). -*/ -#define Q_DISABLE_COPY(Class) \ - Class(const Class &) Q_DECL_EQ_DELETE;\ - Class &operator=(const Class &) Q_DECL_EQ_DELETE; - class QByteArray; Q_CORE_EXPORT QByteArray qgetenv(const char *varName); Q_CORE_EXPORT bool qputenv(const char *varName, const QByteArray& value); @@ -1076,20 +1104,6 @@ template struct QConditional { typedef T Type; template struct QConditional { typedef F Type; }; } -#ifndef Q_FORWARD_DECLARE_OBJC_CLASS -# ifdef __OBJC__ -# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname -# else -# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname -# endif -#endif -#ifndef Q_FORWARD_DECLARE_CF_TYPE -# define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref -#endif -#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE -# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref -#endif - QT_END_NAMESPACE // We need to keep QTypeInfo, QSysInfo, QFlags, qDebug & family in qglobal.h for compatibility with Qt 4. diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm index 8a028c91e1..7656530a46 100644 --- a/src/corelib/io/qfilesystemwatcher_fsevents.mm +++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm @@ -56,25 +56,6 @@ QT_BEGIN_NAMESPACE -namespace { -class RaiiAutoreleasePool -{ - Q_DISABLE_COPY(RaiiAutoreleasePool) - -public: - RaiiAutoreleasePool() - : pool([[NSAutoreleasePool alloc] init]) - {} - - ~RaiiAutoreleasePool() - { [pool release]; } - -private: - NSAutoreleasePool *pool; -}; -#define Q_AUTORELEASE_POOL(pool) RaiiAutoreleasePool pool; Q_UNUSED(pool); -} - static void callBackFunction(ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, @@ -82,7 +63,7 @@ static void callBackFunction(ConstFSEventStreamRef streamRef, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]) { - Q_AUTORELEASE_POOL(pool) + QMacAutoReleasePool pool; char **paths = static_cast(eventPaths); QFseventsFileSystemWatcherEngine *engine = static_cast(clientCallBackInfo); @@ -297,7 +278,7 @@ void QFseventsFileSystemWatcherEngine::doEmitDirectoryChanged(const QString &pat void QFseventsFileSystemWatcherEngine::restartStream() { - Q_AUTORELEASE_POOL(pool) + QMacAutoReleasePool pool; QMutexLocker locker(&lock); stopStream(); startStream(); @@ -328,7 +309,7 @@ QFseventsFileSystemWatcherEngine::QFseventsFileSystemWatcherEngine(QObject *pare QFseventsFileSystemWatcherEngine::~QFseventsFileSystemWatcherEngine() { - Q_AUTORELEASE_POOL(pool) + QMacAutoReleasePool pool; if (stream) FSEventStreamStop(stream); @@ -344,7 +325,7 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths, QStringList *files, QStringList *directories) { - Q_AUTORELEASE_POOL(pool) + QMacAutoReleasePool pool; if (stream) { DEBUG("Flushing, last id is %llu", FSEventStreamGetLatestEventId(stream)); @@ -432,7 +413,7 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat QStringList *files, QStringList *directories) { - Q_AUTORELEASE_POOL(pool) + QMacAutoReleasePool pool; QMutexLocker locker(&lock); @@ -489,7 +470,7 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat bool QFseventsFileSystemWatcherEngine::startStream() { Q_ASSERT(stream == 0); - Q_AUTORELEASE_POOL(pool) + QMacAutoReleasePool pool; if (stream) // This shouldn't happen, but let's be nice and handle it. stopStream(); diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index a215557aed..14c0f803b9 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -131,5 +131,22 @@ QAppleOperatingSystemVersion qt_apple_os_version() return v; } +// ------------------------------------------------------------------------- + +QMacAutoReleasePool::QMacAutoReleasePool() + : pool([[NSAutoreleasePool alloc] init]) +{ +} + +QMacAutoReleasePool::~QMacAutoReleasePool() +{ + // Drain behaves the same as release, with the advantage that + // if we're ever used in a garbage-collected environment, the + // drain acts as a hint to the garbage collector to collect. + [pool drain]; +} + +// ------------------------------------------------------------------------- + QT_END_NAMESPACE diff --git a/src/corelib/tools/qlocale_mac.mm b/src/corelib/tools/qlocale_mac.mm index 37a63a2ca4..c0818f07d7 100644 --- a/src/corelib/tools/qlocale_mac.mm +++ b/src/corelib/tools/qlocale_mac.mm @@ -44,18 +44,6 @@ QT_BEGIN_NAMESPACE -namespace { -class AutoReleasePool -{ -public: - AutoReleasePool(): pool([[NSAutoreleasePool alloc] init]) {} - ~AutoReleasePool() { [pool release]; } - -private: - NSAutoreleasePool *pool; -}; -} - /****************************************************************************** ** Wrappers for Mac locale system functions */ @@ -426,7 +414,7 @@ QLocale QSystemLocale::fallbackUiLocale() const QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const { - AutoReleasePool pool; + QMacAutoReleasePool pool; switch(type) { // case Name: // return getMacLocaleName(); diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index be70092010..75c4065d66 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -48,18 +48,6 @@ QT_BEGIN_NAMESPACE -namespace { -class AutoReleasePool -{ -public: - AutoReleasePool(): pool([[NSAutoreleasePool alloc] init]) {} - ~AutoReleasePool() { [pool release]; } - -private: - NSAutoreleasePool *pool; -}; -} - // this could become a list of all languages used for each writing // system, instead of using the single most common language. static const char *languageForWritingSystem[] = { @@ -453,7 +441,7 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo Q_UNUSED(style); Q_UNUSED(script); - AutoReleasePool pool; + QMacAutoReleasePool pool; static QHash fallbackLists; diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 9530dd83d0..db02cfd19d 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -76,12 +76,11 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time - (id) init { [locker lock]; - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; notificationCenter = [NSNotificationCenter defaultCenter]; currentInterface = [CWInterface interfaceWithName:nil]; [notificationCenter addObserver:self selector:@selector(notificationHandler:) name:CWPowerDidChangeNotification object:nil]; [locker unlock]; - [autoreleasepool release]; return self; } @@ -151,7 +150,7 @@ void QScanThread::quit() void QScanThread::run() { - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; QStringList found; mutex.lock(); CWInterface *currentInterface = [CWInterface interfaceWithName: QCFString::toNSString(interfaceName)]; @@ -233,7 +232,6 @@ void QScanThread::run() } } emit networksChanged(); - [autoreleasepool release]; } QStringList QScanThread::foundNetwork(const QString &id, const QString &name, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose) @@ -273,7 +271,7 @@ void QScanThread::getUserConfigurations() { QMutexLocker locker(&mutex); - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; userProfiles.clear(); NSSet *wifiInterfaces = [CWInterface interfaceNames]; @@ -354,7 +352,6 @@ void QScanThread::getUserConfigurations() } } } - [autoreleasepool release]; } QString QScanThread::getSsidFromNetworkName(const QString &name) @@ -433,7 +430,7 @@ QCoreWlanEngine::~QCoreWlanEngine() void QCoreWlanEngine::initialize() { QMutexLocker locker(&mutex); - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; if ([[CWInterface interfaceNames] count] > 0 && !listener) { listener = [[QT_MANGLE_NAMESPACE(QNSListener) alloc] init]; @@ -445,7 +442,6 @@ void QCoreWlanEngine::initialize() storeSession = NULL; startNetworkChangeLoop(); - [autoreleasepool release]; } @@ -466,7 +462,7 @@ bool QCoreWlanEngine::hasIdentifier(const QString &id) void QCoreWlanEngine::connectToId(const QString &id) { QMutexLocker locker(&mutex); - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; QString interfaceString = getInterfaceFromId(id); CWInterface *wifiInterface = @@ -538,7 +534,6 @@ void QCoreWlanEngine::connectToId(const QString &id) locker.unlock(); emit connectionError(id, InterfaceLookupError); - [autoreleasepool release]; } void QCoreWlanEngine::disconnectFromId(const QString &id) @@ -551,7 +546,7 @@ void QCoreWlanEngine::disconnectFromId(const QString &id) emit connectionError(id, DisconnectionError); return; } - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; CWInterface *wifiInterface = [CWInterface interfaceWithName: QCFString::toNSString(interfaceString)]; @@ -560,14 +555,13 @@ void QCoreWlanEngine::disconnectFromId(const QString &id) [wifiInterface disassociate]; QTimer::singleShot(1000, this,SLOT(checkDisconnect())); - [autoreleasepool release]; } void QCoreWlanEngine::checkDisconnect() { QMutexLocker locker(&mutex); if (!disconnectedInterfaceString.isEmpty()) { - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; CWInterface *wifiInterface = [CWInterface interfaceWithName: QCFString::toNSString(disconnectedInterfaceString)]; @@ -579,7 +573,6 @@ void QCoreWlanEngine::checkDisconnect() emit connectionError(id, DisconnectionError); locker.relock(); } - [autoreleasepool release]; disconnectedInterfaceString.clear(); } } @@ -594,7 +587,7 @@ void QCoreWlanEngine::doRequestUpdate() { QMutexLocker locker(&mutex); - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; NSSet *wifiInterfaces = [CWInterface interfaceNames]; for (NSString *ifName in wifiInterfaces) { @@ -604,7 +597,6 @@ void QCoreWlanEngine::doRequestUpdate() locker.unlock(); if ([wifiInterfaces count] == 0) networksChanged(); - [autoreleasepool release]; } bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName) @@ -612,12 +604,11 @@ bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName) QMutexLocker locker(&mutex); bool haswifi = false; if(hasWifi) { - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; CWInterface *defaultInterface = [CWInterface interfaceWithName: QCFString::toNSString(wifiDeviceName)]; if (defaultInterface.powerOn) { haswifi = true; } - [autoreleasepool release]; } return haswifi; } @@ -811,7 +802,7 @@ quint64 QCoreWlanEngine::bytesReceived(const QString &id) quint64 QCoreWlanEngine::startTime(const QString &identifier) { QMutexLocker locker(&mutex); - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; quint64 timestamp = 0; NSString *filePath = @"/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist"; @@ -858,7 +849,6 @@ quint64 QCoreWlanEngine::startTime(const QString &identifier) } } } - [autoreleasepool release]; return timestamp; } diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index ad6cb3a1fc..ba0e6b001a 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -12,7 +12,6 @@ OBJECTIVE_SOURCES += main.mm \ qcocoawindow.mm \ qnsview.mm \ qnsviewaccessibility.mm \ - qcocoaautoreleasepool.mm \ qnswindowdelegate.mm \ qcocoanativeinterface.mm \ qcocoaeventdispatcher.mm \ @@ -48,7 +47,6 @@ HEADERS += qcocoaintegration.h \ qcocoabackingstore.h \ qcocoawindow.h \ qnsview.h \ - qcocoaautoreleasepool.h \ qnswindowdelegate.h \ qcocoanativeinterface.h \ qcocoaeventdispatcher.h \ diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm index eed2ad7dc5..ed139b98b2 100644 --- a/src/plugins/platforms/cocoa/main.mm +++ b/src/plugins/platforms/cocoa/main.mm @@ -52,7 +52,7 @@ QPlatformIntegration * QCocoaIntegrationPlugin::create(const QString& system, co { Q_UNUSED(paramList); - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (system.compare(QLatin1String("cocoa"), Qt::CaseInsensitive) == 0) return new QCocoaIntegration; diff --git a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h deleted file mode 100644 index 8b2a9f3788..0000000000 --- a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QCOCOAAUTORELEASEPOOL_H -#define QCOCOAAUTORELEASEPOOL_H - -#undef slots -#include -#include - -QT_BEGIN_NAMESPACE -class QCocoaAutoReleasePool -{ -public: - QCocoaAutoReleasePool(); - ~QCocoaAutoReleasePool(); - -private: - NSAutoreleasePool *pool; -}; -QT_END_NAMESPACE - -#endif // QCOCOAAUTORELEASEPOOL_H diff --git a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm b/src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm deleted file mode 100644 index 8f30365186..0000000000 --- a/src/plugins/platforms/cocoa/qcocoaautoreleasepool.mm +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qcocoaautoreleasepool.h" - -QT_BEGIN_NAMESPACE - -QCocoaAutoReleasePool::QCocoaAutoReleasePool() -{ - pool = [[NSAutoreleasePool alloc] init]; -} - -QCocoaAutoReleasePool::~QCocoaAutoReleasePool() -{ - [pool release]; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index 06e957cd86..d1d6330249 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -34,7 +34,6 @@ #include "qcocoacursor.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" -#include "qcocoaautoreleasepool.h" #include diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 050fade284..1865624d57 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -66,7 +66,6 @@ ****************************************************************************/ #include "qcocoaeventdispatcher.h" -#include "qcocoaautoreleasepool.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" @@ -364,7 +363,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) if (d->interrupt) break; - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; NSEvent* event = 0; // First, send all previously excluded input events, if any: @@ -622,7 +621,7 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession() continue; if (!info.session) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QCocoaWindow *cocoaWindow = static_cast(info.window->handle()); NSWindow *nswindow = cocoaWindow->nativeWindow(); if (!nswindow) @@ -670,7 +669,7 @@ void QCocoaEventDispatcherPrivate::updateChildrenWorksWhenModal() // Make the dialog children of the window // active. And make the dialog children of // the previous modal dialog unactive again: - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; int size = cocoaModalSessionStack.size(); if (size > 0){ if (QWindow *prevModal = cocoaModalSessionStack[size-1].window) @@ -691,7 +690,7 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions() // point they were marked as stopped), is that ending a session // when no other session runs below it on the stack will make cocoa // drop some events on the floor. - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; int stackSize = cocoaModalSessionStack.size(); for (int i=stackSize-1; i>=0; --i) { @@ -926,7 +925,7 @@ void QCocoaEventDispatcherPrivate::cancelWaitForMoreEvents() { // In case the event dispatcher is waiting for more // events somewhere, we post a dummy event to wake it up: - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint modifierFlags:0 timestamp:0. windowNumber:0 context:0 subtype:QtCocoaEventSubTypeWakeup data1:0 data2:0] atStart:NO]; diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 4ece1b5a22..93ee4e8624 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -53,7 +53,6 @@ #include #include #include -#include "qcocoaautoreleasepool.h" #include #include @@ -557,7 +556,7 @@ QCocoaFileDialogHelper::~QCocoaFileDialogHelper() { if (!mDelegate) return; - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; [mDelegate release]; mDelegate = 0; } @@ -687,7 +686,7 @@ bool QCocoaFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate() { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; const SharedPointerFileDialogOptions &opts = options(); const QList selectedFiles = opts->initiallySelectedFiles(); @@ -737,7 +736,7 @@ void QCocoaFileDialogHelper::exec() // QEventLoop has been interrupted, and the second-most event loop has not // yet been reactivated (regardless if [NSApp run] is still on the stack)), // showing a native modal dialog will fail. - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if ([mDelegate runApplicationModalPanel]) emit accept(); else diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index a3c72c58b9..1d8a1c5e70 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -33,7 +33,6 @@ #include "qcocoaglcontext.h" #include "qcocoawindow.h" -#include "qcocoaautoreleasepool.h" #include "qcocoahelpers.h" #include #include @@ -145,7 +144,7 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo if (m_format.renderableType() != QSurfaceFormat::OpenGL) return; - QCocoaAutoReleasePool pool; // For the SG Canvas render thread + QMacAutoReleasePool pool; // For the SG Canvas render thread NSOpenGLPixelFormat *pixelFormat = static_cast (qcgl_createNSOpenGLPixelFormat(m_format)); m_shareContext = share ? static_cast(share)->nsOpenGLContext() : nil; @@ -218,7 +217,7 @@ bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface) { Q_ASSERT(surface->surface()->supportsOpenGL()); - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QWindow *window = static_cast(surface)->window(); setActiveWindow(window); diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index a84c0c0f2a..c2f0c730fe 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -33,7 +33,6 @@ #include "qcocoahelpers.h" -#include "qcocoaautoreleasepool.h" #include #include @@ -630,7 +629,7 @@ QString qt_mac_applicationName() int qt_mac_mainScreenHeight() { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; // The first screen in the screens array is documented // to have the (0,0) origin. NSRect screenFrame = [[[NSScreen screens] firstObject] frame]; diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm index c22fe8774b..f072991bdd 100644 --- a/src/plugins/platforms/cocoa/qcocoainputcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm @@ -34,7 +34,6 @@ #include "qnsview.h" #include "qcocoainputcontext.h" #include "qcocoanativeinterface.h" -#include "qcocoaautoreleasepool.h" #include "qcocoawindow.h" #include @@ -98,7 +97,7 @@ void QCocoaInputContext::reset() if (!view) return; - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (NSTextInputContext *ctxt = [NSTextInputContext currentInputContext]) { [ctxt discardMarkedText]; [view unmarkText]; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index ee42a83446..cc235135f1 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -36,7 +36,6 @@ #include -#include "qcocoaautoreleasepool.h" #include "qcocoacursor.h" #include "qcocoawindow.h" #include "qcocoanativeinterface.h" diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index c8f6dd05db..04d5769044 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -33,7 +33,6 @@ #include "qcocoaintegration.h" -#include "qcocoaautoreleasepool.h" #include "qcocoawindow.h" #include "qcocoabackingstore.h" #include "qcocoanativeinterface.h" @@ -137,7 +136,7 @@ void QCocoaScreen::updateGeometry() qreal QCocoaScreen::devicePixelRatio() const { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; NSScreen * screen = osScreen(); return qreal(screen ? [screen backingScaleFactor] : 1.0); } @@ -263,7 +262,7 @@ QCocoaIntegration::QCocoaIntegration() mInstance = this; initResources(); - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; qApp->setAttribute(Qt::AA_DontUseNativeMenuBar, false); @@ -314,7 +313,7 @@ QCocoaIntegration::~QCocoaIntegration() qt_resetNSApplicationSendEvent(); - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) { // remove the apple event handlers installed by QCocoaApplicationDelegate QCocoaApplicationDelegate *delegate = [QCocoaApplicationDelegate sharedDelegate]; diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 09a4c95469..b9ffecd3b0 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -34,7 +34,6 @@ #include "qcocoamenu.h" #include "qcocoahelpers.h" -#include "qcocoaautoreleasepool.h" #include #include @@ -223,7 +222,7 @@ QCocoaMenu::QCocoaMenu() : m_menuBar(0), m_containingMenuItem(0) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this]; m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; @@ -243,7 +242,7 @@ QCocoaMenu::~QCocoaMenu() if (m_containingMenuItem) m_containingMenuItem->clearMenu(this); - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; [m_nativeItem setSubmenu:nil]; [m_nativeMenu release]; [m_delegate release]; @@ -252,7 +251,7 @@ QCocoaMenu::~QCocoaMenu() void QCocoaMenu::setText(const QString &text) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QString stripped = qt_mac_removeAmpersandEscapes(text); [m_nativeMenu setTitle:QCFString::toNSString(stripped)]; [m_nativeItem setTitle:QCFString::toNSString(stripped)]; @@ -274,7 +273,7 @@ void QCocoaMenu::setFont(const QFont &font) void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QCocoaMenuItem *cocoaItem = static_cast(menuItem); QCocoaMenuItem *beforeItem = static_cast(before); @@ -328,7 +327,7 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QCocoaMenuItem *cocoaItem = static_cast(menuItem); if (!m_menuItems.contains(cocoaItem)) { qWarning() << Q_FUNC_INFO << "Menu does not contain the item to be removed"; @@ -358,7 +357,7 @@ QCocoaMenuItem *QCocoaMenu::itemOrNull(int index) const void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QCocoaMenuItem *cocoaItem = static_cast(menuItem); if (!m_menuItems.contains(cocoaItem)) { qWarning() << Q_FUNC_INFO << "Item does not belong to this menu"; @@ -387,7 +386,7 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) void QCocoaMenu::syncSeparatorsCollapsible(bool enable) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (enable) { bool previousIsSeparator = true; // setting to true kills all the separators placed at the top. NSMenuItem *previousItem = nil; @@ -445,7 +444,7 @@ void QCocoaMenu::setVisible(bool visible) void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QPoint pos = QPoint(targetRect.left(), targetRect.top() + targetRect.height()); QCocoaWindow *cocoaWindow = parentWindow ? static_cast(parentWindow->handle()) : 0; @@ -550,7 +549,7 @@ QList QCocoaMenu::merged() const void QCocoaMenu::syncModalState(bool modal) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (!m_enabled) modal = true; diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 7c902a0e53..7775cdbde6 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -37,7 +37,6 @@ #include "qcocoawindow.h" #include "qcocoamenuloader.h" #include "qcocoaapplication.h" // for custom application category -#include "qcocoaautoreleasepool.h" #include "qcocoaapplicationdelegate.h" #include @@ -84,7 +83,7 @@ QCocoaMenuBar::~QCocoaMenuBar() void QCocoaMenuBar::insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (beforeMenu) { NSUInteger nativeIndex = [m_nativeMenu indexOfItem:beforeMenu->nsMenuItem()]; @@ -127,7 +126,7 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor void QCocoaMenuBar::removeNativeMenu(QCocoaMenu *menu) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (menu->menuBar() == this) menu->setMenuBar(0); @@ -148,7 +147,7 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu) void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QCocoaMenu *cocoaMenu = static_cast(menu); Q_FOREACH (QCocoaMenuItem *item, cocoaMenu->items()) @@ -261,7 +260,7 @@ void QCocoaMenuBar::resetKnownMenuItemsToQt() void QCocoaMenuBar::updateMenuBarImmediately() { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QCocoaMenuBar *mb = findGlobalMenubar(); QCocoaWindow *cw = findWindowForMenubar(); diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index f288ab85c0..942fc8db21 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -37,7 +37,6 @@ #include "qcocoamenubar.h" #include "messages.h" #include "qcocoahelpers.h" -#include "qcocoaautoreleasepool.h" #include "qt_mac_p.h" #include "qcocoaapplication.h" // for custom application category #include "qcocoamenuloader.h" @@ -104,7 +103,7 @@ QCocoaMenuItem::QCocoaMenuItem() : QCocoaMenuItem::~QCocoaMenuItem() { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (m_menu && COCOA_MENU_ANCESTOR(m_menu) == this) SET_COCOA_MENU_ANCESTOR(m_menu, 0); @@ -139,7 +138,7 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu) m_menu->setContainingMenuItem(0); } - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; m_menu = static_cast(menu); if (m_menu) { SET_COCOA_MENU_ANCESTOR(m_menu, this); diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index 205a49d25a..c8b54c9224 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -234,7 +234,7 @@ void QCocoaNativeInterface::registerDraggedTypes(const QStringList &types) void QCocoaNativeInterface::setDockMenu(QPlatformMenu *platformMenu) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QCocoaMenu *cocoaPlatformMenu = static_cast(platformMenu); NSMenu *menu = cocoaPlatformMenu->nsMenu(); [NSApp QT_MANGLE_NAMESPACE(qt_setDockMenu): menu]; diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index 65cc9bc38b..93f8b2ba6f 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -33,7 +33,6 @@ #include "qcocoasystemsettings.h" -#include "qcocoaautoreleasepool.h" #include "qcocoahelpers.h" #include @@ -45,7 +44,7 @@ QT_BEGIN_NAMESPACE QColor qt_mac_colorForTheme(ThemeBrush brush) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QCFType cgClr = 0; HIThemeBrushCreateCGColor(brush, &cgClr); diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 11749e14de..4b73d0af08 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -47,7 +47,6 @@ #include "qcocoamenu.h" #include "qcocoamenubar.h" #include "qcocoahelpers.h" -#include "qcocoaautoreleasepool.h" #include #include @@ -253,7 +252,7 @@ QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &siz QPlatformTheme::IconOptions iconOptions) const { Q_UNUSED(iconOptions); - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; NSImage *iconImage = [[NSWorkspace sharedWorkspace] iconForFile:QCFString::toNSString(fileInfo.canonicalFilePath())]; if (!iconImage) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index f6389a2096..8af0a71bc1 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -33,7 +33,6 @@ #include "qcocoawindow.h" #include "qcocoaintegration.h" #include "qnswindowdelegate.h" -#include "qcocoaautoreleasepool.h" #include "qcocoaeventdispatcher.h" #ifndef QT_NO_OPENGL #include "qcocoaglcontext.h" @@ -374,7 +373,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) #ifdef QT_COCOA_ENABLE_WINDOW_DEBUG qDebug() << "QCocoaWindow::QCocoaWindow" << this; #endif - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (tlw->type() == Qt::ForeignWindow) { NSView *foreignView = (NSView *)WId(tlw->property("_q_foreignWinId").value()); @@ -410,7 +409,7 @@ QCocoaWindow::~QCocoaWindow() qDebug() << "QCocoaWindow::~QCocoaWindow" << this; #endif - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; [m_nsWindow setContentView:nil]; [m_nsWindow.helper detachFromPlatformWindow]; if (m_isNSWindowChild) { @@ -492,7 +491,7 @@ QRect QCocoaWindow::geometry() const void QCocoaWindow::setCocoaGeometry(const QRect &rect) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (m_contentViewIsEmbedded) { QPlatformWindow::setGeometry(rect); @@ -616,7 +615,7 @@ void QCocoaWindow::setVisible(bool visible) m_inSetVisible = true; - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QCocoaWindow *parentCocoaWindow = 0; if (window()->transientParent()) parentCocoaWindow = static_cast(window()->transientParent()->handle()); @@ -887,7 +886,7 @@ void QCocoaWindow::setWindowState(Qt::WindowState state) void QCocoaWindow::setWindowTitle(const QString &title) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (!m_nsWindow) return; @@ -898,7 +897,7 @@ void QCocoaWindow::setWindowTitle(const QString &title) void QCocoaWindow::setWindowFilePath(const QString &filePath) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (!m_nsWindow) return; @@ -908,7 +907,7 @@ void QCocoaWindow::setWindowFilePath(const QString &filePath) void QCocoaWindow::setWindowIcon(const QIcon &icon) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; NSButton *iconButton = [m_nsWindow standardWindowButton:NSWindowDocumentIconButton]; if (iconButton == nil) { @@ -1026,7 +1025,7 @@ bool QCocoaWindow::isOpaque() const void QCocoaWindow::propagateSizeHints() { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; if (!m_nsWindow) return; @@ -1367,7 +1366,7 @@ bool QCocoaWindow::shouldUseNSPanel() QCocoaNSWindow * QCocoaWindow::createNSWindow() { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QRect rect = initialGeometry(window(), window()->geometry(), defaultWindowWidth, defaultWindowHeight); NSRect frame = qt_mac_flipRect(rect); diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index 3d88a8d5df..f4fd32ffd1 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -43,7 +43,6 @@ #include #include #include "qcocoahelpers.h" -#include "qcocoaautoreleasepool.h" QT_BEGIN_NAMESPACE @@ -555,7 +554,7 @@ QMacPasteboard::sync() const QString qt_mac_get_pasteboardString(PasteboardRef paste) { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; NSPasteboard *pb = nil; CFStringRef pbname; if (PasteboardCopyName(paste, &pbname) == noErr) { diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 3c12228ef6..df4ebec88b 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -39,7 +39,6 @@ #include "qnsview.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" -#include "qcocoaautoreleasepool.h" #include "qmultitouch_mac_p.h" #include "qcocoadrag.h" #include @@ -849,7 +848,7 @@ QT_WARNING_POP { [super updateTrackingAreas]; - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; // NSTrackingInVisibleRect keeps care of updating once the tracking is set up, so bail out early if (m_trackingArea && [[self trackingAreas] containsObject:m_trackingArea]) @@ -1786,7 +1785,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) -(void)registerDragTypes { - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; QStringList customTypes = qt_mac_enabledDraggedTypes(); if (currentCustomDragTypes == 0 || *currentCustomDragTypes != customTypes) { if (currentCustomDragTypes == 0) diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index 348b537691..a2285d8a4f 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -38,7 +38,6 @@ #include #include -#include "qcocoaautoreleasepool.h" #ifndef QT_NO_PRINTER @@ -230,7 +229,7 @@ void QMacPrintEnginePrivate::initialize() q->gccaps = paintEngine->gccaps; - QCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; printInfo = [[NSPrintInfo alloc] initWithDictionary:[NSDictionary dictionary]]; QList resolutions = m_printDevice->supportedResolutions(); diff --git a/src/plugins/platforms/cocoa/qt_mac_p.h b/src/plugins/platforms/cocoa/qt_mac_p.h index e210f0221f..576e0f9729 100644 --- a/src/plugins/platforms/cocoa/qt_mac_p.h +++ b/src/plugins/platforms/cocoa/qt_mac_p.h @@ -103,17 +103,6 @@ public: } }; -class Q_WIDGETS_EXPORT QMacCocoaAutoReleasePool -{ -private: - void *pool; -public: - QMacCocoaAutoReleasePool(); - ~QMacCocoaAutoReleasePool(); - - inline void *handle() const { return pool; } -}; - QString qt_mac_removeMnemonics(const QString &original); //implemented in qmacstyle_mac.cpp class Q_WIDGETS_EXPORT QMacWindowChangeEvent diff --git a/src/printsupport/dialogs/qpagesetupdialog_mac.mm b/src/printsupport/dialogs/qpagesetupdialog_mac.mm index 886cbc0152..b86de31883 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_mac.mm +++ b/src/printsupport/dialogs/qpagesetupdialog_mac.mm @@ -201,10 +201,9 @@ int QPageSetupDialog::exec() QDialog::setVisible(true); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; static_cast (d)->openCocoaPageLayout(Qt::ApplicationModal); static_cast (d)->closeCocoaPageLayout(); - [pool release]; QDialog::setVisible(false); diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm index 1655131de4..030526954d 100644 --- a/src/printsupport/dialogs/qprintdialog_mac.mm +++ b/src/printsupport/dialogs/qprintdialog_mac.mm @@ -301,10 +301,9 @@ int QPrintDialog::exec() QDialog::setVisible(true); - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; d->openCocoaPrintPanel(Qt::ApplicationModal); d->closeCocoaPrintPanel(); - [pool release]; QDialog::setVisible(false); diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 67970ba33d..50c8fd7ed8 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -93,18 +93,6 @@ QT_USE_NAMESPACE -namespace { -class AutoReleasePool -{ -public: - AutoReleasePool(): pool([[NSAutoreleasePool alloc] init]) {} - ~AutoReleasePool() { [pool release]; } - -private: - NSAutoreleasePool *pool; -}; -} - @interface QT_MANGLE_NAMESPACE(NotificationReceiver) : NSObject { QMacStylePrivate *mPrivate; } @@ -1753,7 +1741,7 @@ QMacStylePrivate::QMacStylePrivate() QMacStylePrivate::~QMacStylePrivate() { - AutoReleasePool pool; + QMacAutoReleasePool pool; Q_FOREACH (NSView *b, cocoaControls) [b release]; } @@ -2135,7 +2123,7 @@ QMacStyle::QMacStyle() : QCommonStyle(*new QMacStylePrivate) { Q_D(QMacStyle); - AutoReleasePool pool; + QMacAutoReleasePool pool; d->receiver = [[NotificationReceiver alloc] initWithPrivate:d]; NotificationReceiver *receiver = static_cast(d->receiver); @@ -2152,7 +2140,7 @@ QMacStyle::QMacStyle() QMacStyle::~QMacStyle() { Q_D(QMacStyle); - AutoReleasePool pool; + QMacAutoReleasePool pool; [reinterpret_cast(d->nsscroller) release]; @@ -2169,7 +2157,7 @@ QMacStyle::~QMacStyle() */ QPixmap QMacStylePrivate::generateBackgroundPattern() const { - AutoReleasePool pool; + QMacAutoReleasePool pool; QPixmap px(4, 4); QMacCGContext cg(&px); HIThemeSetFill(kThemeBrushDialogBackgroundActive, 0, cg, kHIThemeOrientationNormal); @@ -2767,7 +2755,7 @@ QPalette QMacStyle::standardPalette() const int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w, QStyleHintReturn *hret) const { - AutoReleasePool pool; + QMacAutoReleasePool pool; SInt32 ret = 0; switch (sh) { diff --git a/src/widgets/util/qscroller_mac.mm b/src/widgets/util/qscroller_mac.mm index 9120c43075..07de07de52 100644 --- a/src/widgets/util/qscroller_mac.mm +++ b/src/widgets/util/qscroller_mac.mm @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE QPointF QScrollerPrivate::realDpi(int screen) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; NSArray *nsscreens = [NSScreen screens]; if (screen < 0 || screen >= int([nsscreens count])) @@ -59,7 +59,6 @@ QPointF QScrollerPrivate::realDpi(int screen) } else { return QPointF(); } - [pool release]; } QT_END_NAMESPACE diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index 8eb9050528..f365ff7d17 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -1087,7 +1087,7 @@ void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget addDockWidget(area, dockwidget, orientation); #ifdef Q_DEAD_CODE_FROM_QT4_MAC //drawer support - QMacCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp if (qt_mac_is_macdrawer(dockwidget)) { extern bool qt_mac_set_drawer_preferred_edge(QWidget *, Qt::DockWidgetArea); //qwidget_mac.cpp diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray_mac.mm b/tests/auto/corelib/tools/qbytearray/tst_qbytearray_mac.mm index c2b76cc41a..95d05904a2 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray_mac.mm +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray_mac.mm @@ -72,35 +72,31 @@ void tst_QByteArray_macTypes() } // QByteArray <-> NSData { - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; QByteArray qtByteArray("test bytearray"); const NSData *nsData = qtByteArray.toNSData(); QCOMPARE(QByteArray::fromNSData(nsData), qtByteArray); - [autoreleasepool release]; } { - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; QByteArray qtByteArray("test bytearray"); const NSData *nsData = qtByteArray.toNSData(); QByteArray qtByteArrayCopy(qtByteArray); qtByteArray = qtByteArray.toUpper(); // modify QCOMPARE(QByteArray::fromNSData(nsData), qtByteArrayCopy); - [autoreleasepool release]; } // QByteArray <-> NSData Raw { - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; QByteArray qtByteArray("test bytearray"); const NSData *nsData = qtByteArray.toRawNSData(); QCOMPARE([nsData bytes], qtByteArray.constData()); - [autoreleasepool release]; } { - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; const char data[] = "nsdata test"; const NSData *nsData = [NSData dataWithBytes:data length:sizeof(data)]; QByteArray qtByteArray = QByteArray::fromRawNSData(nsData); QCOMPARE(qtByteArray.constData(), [nsData bytes]); - [autoreleasepool release]; } } diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm b/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm index 6bdaa94e49..0ad9a8253b 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime_mac.mm @@ -56,19 +56,17 @@ void tst_QDateTime_macTypes() } // QDateTime <-> NSDate { - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0); const NSDate *nsDate = qtDateTime.toNSDate(); QCOMPARE(QDateTime::fromNSDate(nsDate), qtDateTime); - [autoreleasepool release]; } { - NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; QDateTime qtDateTime = QDateTime::fromMSecsSinceEpoch(0); const NSDate *nsDate = qtDateTime.toNSDate(); QDateTime qtDateTimeCopy(qtDateTime); qtDateTime.setTime_t(10000); // modify QCOMPARE(QDateTime::fromNSDate(nsDate), qtDateTimeCopy); - [autoreleasepool release]; } } diff --git a/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm b/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm index f4b748e62a..550f835bea 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm +++ b/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm @@ -55,23 +55,19 @@ void tst_QString_macTypes() } // QString <-> NSString { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; QString qtString("test string"); const NSString *nsString = qtString.toNSString(); QCOMPARE(QString::fromNSString(nsString), qtString); - - [pool release]; } { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + QMacAutoReleasePool pool; QString qtString("test string"); const NSString *nsString = qtString.toNSString(); QString qtStringCopy(qtString); qtString = qtString.toUpper(); // modify QCOMPARE(QString::fromNSString(nsString), qtStringCopy); - - [pool release]; } } diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm index 6e4ad29190..0d29f5b7a2 100644 --- a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm +++ b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm @@ -36,7 +36,7 @@ void click_cocoa_button() { - QMacCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; NSArray *windows = [NSApp windows]; for (NSWindow *window in windows) { // This is NOT how one should do RTTI, but since I don't want to leak the class too much... -- cgit v1.2.3 From 6255859ebf19b38c864cd6dbaf2878e0116535a4 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 27 May 2015 16:17:19 +0200 Subject: Fix cmake auto tests failing with cmake 2.8.11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit 3eca75de67b3fd2c890715b30c7899cebc096fe9 the use of _EXECUTABLE_COMPILE_FLAGS becomes mandatory for 2.8.11 or older. Therefore use it in test_use_modules - that's supposed to work with all cmake versions it seems - and bump test_interface to require 2.8.12. Change-Id: I7cfb6c6f1e8a97be916d372b9d9148490926693c Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Stephen Kelly --- tests/auto/cmake/CMakeLists.txt | 5 +---- tests/auto/cmake/test_interface/CMakeLists.txt | 2 +- tests/auto/cmake/test_use_modules_function/CMakeLists.txt | 2 ++ 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index 87d8a802f3..b68aafe956 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -126,11 +126,8 @@ if (QT_WITH_ANGLE OR (NOT WIN32 AND NOT APPLE AND NOT NO_EGL)) endif() expect_pass(test_opengl_lib) -if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) - expect_pass(test_interface) -endif() - if (NOT CMAKE_VERSION VERSION_LESS 2.8.12) + expect_pass(test_interface) expect_pass(test_interface_link_libraries) expect_pass(test_moc_macro_target) endif() diff --git a/tests/auto/cmake/test_interface/CMakeLists.txt b/tests/auto/cmake/test_interface/CMakeLists.txt index a8af92da63..bd3217a497 100644 --- a/tests/auto/cmake/test_interface/CMakeLists.txt +++ b/tests/auto/cmake/test_interface/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8.11) +cmake_minimum_required(VERSION 2.8.12) project(test_interface) diff --git a/tests/auto/cmake/test_use_modules_function/CMakeLists.txt b/tests/auto/cmake/test_use_modules_function/CMakeLists.txt index bfcdd9d1d7..be05c75054 100644 --- a/tests/auto/cmake/test_use_modules_function/CMakeLists.txt +++ b/tests/auto/cmake/test_use_modules_function/CMakeLists.txt @@ -12,5 +12,7 @@ add_executable(three three.cpp) find_package(Qt5Core) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") + qt5_use_modules(two Test) qt5_use_modules(three Gui Test) -- cgit v1.2.3 From e22d75d0b139fe9e4b11f32ebc5fb1024f493fbe Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 2 Jan 2015 10:09:21 +0100 Subject: Translate AM/PM under the QDateTimeParser context so it is consistent In order to ensure that the same text will be used in both QDateTimeParser and QDateTimeEdit, use the QDateTimeParser context for the AM and PM strings. Task-number: QTBUG-251 Change-Id: I89b0809825251181440bf19cbe5828024a43acfb Reviewed-by: Oswald Buddenhagen --- src/corelib/tools/qdatetimeparser.cpp | 14 +++++++------- src/corelib/tools/qdatetimeparser_p.h | 3 ++- src/widgets/widgets/qdatetimeedit.cpp | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 255e9557e2..eaa695ef27 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1362,11 +1362,11 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex \internal returns - 0 if str == QDateTimeEdit::tr("AM") - 1 if str == QDateTimeEdit::tr("PM") - 2 if str can become QDateTimeEdit::tr("AM") - 3 if str can become QDateTimeEdit::tr("PM") - 4 if str can become QDateTimeEdit::tr("PM") and can become QDateTimeEdit::tr("AM") + 0 if str == tr("AM") + 1 if str == tr("PM") + 2 if str can become tr("AM") + 3 if str can become tr("PM") + 4 if str can become tr("PM") and can become tr("AM") -1 can't become anything sensible */ @@ -1737,9 +1737,9 @@ QDateTime QDateTimeParser::getMaximum() const QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const { if (ap == AmText) { - return (cs == UpperCase ? QLatin1String("AM") : QLatin1String("am")); + return (cs == UpperCase ? tr("AM") : tr("am")); } else { - return (cs == UpperCase ? QLatin1String("PM") : QLatin1String("pm")); + return (cs == UpperCase ? tr("PM") : tr("pm")); } } diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h index 55dc3bf7a0..9457e35ad5 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -54,7 +54,7 @@ # include "QtCore/qvariant.h" #endif #include "QtCore/qvector.h" - +#include "QtCore/qcoreapplication.h" #define QDATETIMEEDIT_TIME_MIN QTime(0, 0, 0, 0) #define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999) @@ -72,6 +72,7 @@ QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QDateTimeParser { + Q_DECLARE_TR_FUNCTIONS(QDateTimeParser) public: enum Context { FromString, diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index b1749fa5d3..a8da78a025 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -2316,9 +2316,9 @@ void QDateTimeEdit::paintEvent(QPaintEvent *event) QString QDateTimeEditPrivate::getAmPmText(AmPm ap, Case cs) const { if (ap == AmText) { - return (cs == UpperCase ? QDateTimeEdit::tr("AM") : QDateTimeEdit::tr("am")); + return (cs == UpperCase ? QDateTimeParser::tr("AM") : QDateTimeParser::tr("am")); } else { - return (cs == UpperCase ? QDateTimeEdit::tr("PM") : QDateTimeEdit::tr("pm")); + return (cs == UpperCase ? QDateTimeParser::tr("PM") : QDateTimeParser::tr("pm")); } } -- cgit v1.2.3 From 347cc69cb2caa5f2f682bd213429394f4d668f4b Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 27 May 2015 12:57:58 +0300 Subject: ANGLE: fix DllMain collision in static builds The symbol is simply renamed in static builds, allowing wrappers of the library to still call the function if needed. Task-number: QTBUG-46209 Change-Id: I5d4ad2df59f206a3794b99364d122f9d0f12f8c6 Reviewed-by: Friedemann Kleint Reviewed-by: Tim Blechmann Reviewed-by: Kai Koehne --- src/angle/src/libGLESv2/libGLESv2.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro index 1bf9af0436..5979b68098 100644 --- a/src/angle/src/libGLESv2/libGLESv2.pro +++ b/src/angle/src/libGLESv2/libGLESv2.pro @@ -329,6 +329,8 @@ angle_d3d11 { !static { DEF_FILE = $$ANGLE_DIR/src/libGLESv2/$${TARGET}.def mingw:equals(QT_ARCH, i386): DEF_FILE = $$ANGLE_DIR/src/libGLESv2/$${TARGET}_mingw32.def +} else { + DEFINES += DllMain=DllMain_ANGLE # prevent symbol from conflicting with the user's DllMain } float_converter.target = float_converter -- cgit v1.2.3 From 584576aeeefd9c0b53de6fd5fc83b3316dce7fd7 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 11 May 2015 15:17:12 +0200 Subject: ANGLE: Fix compilation without d3d11 Change-Id: I0b772698cf521083e5ecf35a395af57100a50131 Reviewed-by: Friedemann Kleint Reviewed-by: Andrew Knight --- .../src/libANGLE/renderer/d3d/d3d11/NativeWindow.h | 4 +- .../renderer/d3d/d3d11/win32/NativeWindow.cpp | 2 + .../0007-ANGLE-Fix-compilation-without-d3d11.patch | 57 ++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h index 81b9ea748d..0f70fe4615 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h @@ -38,7 +38,7 @@ class InspectableNativeWindow; using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; -#else +#elif defined(ANGLE_ENABLE_D3D11) typedef IDXGISwapChain DXGISwapChain; typedef IDXGIFactory DXGIFactory; #endif @@ -60,9 +60,11 @@ class NativeWindow #endif static bool isValidNativeWindow(EGLNativeWindowType window); +#if defined(ANGLE_ENABLE_D3D11) HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, DXGI_FORMAT format, UINT width, UINT height, DXGISwapChain** swapChain); +#endif inline EGLNativeWindowType getNativeWindow() const { return mWindow; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp index 9d8f0bb96c..0a4f45b5b7 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp @@ -37,6 +37,7 @@ bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window) return IsWindow(window) == TRUE; } +#if defined(ANGLE_ENABLE_D3D11) HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain** swapChain) @@ -65,4 +66,5 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory return factory->CreateSwapChain(device, &swapChainDesc, swapChain); } +#endif } diff --git a/src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch b/src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch new file mode 100644 index 0000000000..eca7d0e162 --- /dev/null +++ b/src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch @@ -0,0 +1,57 @@ +From 1f993a2492a618becd4bf89ef0d6cb5d2c9aa67a Mon Sep 17 00:00:00 2001 +From: Kai Koehne +Date: Mon, 11 May 2015 15:17:12 +0200 +Subject: [PATCH] ANGLE: Fix compilation without d3d11 + +Change-Id: I0b772698cf521083e5ecf35a395af57100a50131 +--- + src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h | 4 +++- + .../angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp | 2 ++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +index 81b9ea7..0f70fe4 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +@@ -38,7 +38,7 @@ class InspectableNativeWindow; + using namespace Microsoft::WRL; + using namespace Microsoft::WRL::Wrappers; + +-#else ++#elif defined(ANGLE_ENABLE_D3D11) + typedef IDXGISwapChain DXGISwapChain; + typedef IDXGIFactory DXGIFactory; + #endif +@@ -60,9 +60,11 @@ class NativeWindow + #endif + static bool isValidNativeWindow(EGLNativeWindowType window); + ++#if defined(ANGLE_ENABLE_D3D11) + HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, + DXGI_FORMAT format, UINT width, UINT height, + DXGISwapChain** swapChain); ++#endif + + inline EGLNativeWindowType getNativeWindow() const { return mWindow; } + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +index 9d8f0bb..0a4f45b 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +@@ -37,6 +37,7 @@ bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window) + return IsWindow(window) == TRUE; + } + ++#if defined(ANGLE_ENABLE_D3D11) + HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, + DXGI_FORMAT format, unsigned int width, unsigned int height, + DXGISwapChain** swapChain) +@@ -65,4 +66,5 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory + + return factory->CreateSwapChain(device, &swapChainDesc, swapChain); + } ++#endif + } +-- +1.9.5.msysgit.0 + -- cgit v1.2.3 From 5f2e4d3116593a566c03707d35c8a18b1e461855 Mon Sep 17 00:00:00 2001 From: Caner Altinbasak Date: Fri, 15 May 2015 22:06:02 +0100 Subject: Fix for eglfs context sharing problem in qtwebengine widget EGLFS backend does not use global sharing context. WebEngineWidgets was failing to access textures created by WebEngineChromium and textures were ending up as black rectangles. This fix initialises window surface context with shared context and fixes the bug. Change-Id: I97189c06ee593ba55f353f44c23233175ebd3cba Reviewed-by: Laszlo Agocs --- src/plugins/platforms/eglfs/qeglfswindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index 30fdce9fd3..c0d51c94a5 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,7 @@ void QEglFSWindow::create() if (isRaster()) { QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance()); + context->setShareContext(qt_gl_global_share_context()); context->setFormat(m_format); context->setScreen(window()->screen()); if (!context->create()) -- cgit v1.2.3 From 22ecebcc72e418b6bf22562bd8a247261a7a4a37 Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Mon, 18 May 2015 11:26:32 +0300 Subject: Add QMAKE_LIBDIR_EGL only if it exists Must not add -L without a directory path, so check that QMAKE_LIBDIR_EGL actually has a directory to add. Change-Id: I81920e3427f348739ced045a83f53265d72b261a Reviewed-by: Laszlo Agocs --- config.tests/qpa/eglfs-brcm/eglfs-brcm.pro | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro b/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro index b63c75c070..ce16a3a391 100644 --- a/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro +++ b/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro @@ -4,4 +4,8 @@ CONFIG -= qt INCLUDEPATH += $$QMAKE_INCDIR_EGL -LIBS += -L$$QMAKE_LIBDIR_EGL -lEGL -lGLESv2 -lbcm_host +for(p, QMAKE_LIBDIR_EGL) { + exists($$p):LIBS += -L$$p +} + +LIBS += -lEGL -lGLESv2 -lbcm_host -- cgit v1.2.3 From 9d662d9d2f33d75d3fbf682ee9fadc291ecae5cb Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 27 May 2015 12:47:12 +0200 Subject: Mention cmake changes in ChangeLog for -fPIE -> -fPIC changes This is a follow-up change to commit 3eca75de67b3fd2c890715b30c7899cebc096fe9 to mention changes required to CMakeLists.txt for users of Qt. Change-Id: I1c9ed162427cdc620f998ccf266d59886901c28d Reviewed-by: Lars Knoll --- dist/changes-5.4.2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dist/changes-5.4.2 b/dist/changes-5.4.2 index 5827187e9e..29d3c6346d 100644 --- a/dist/changes-5.4.2 +++ b/dist/changes-5.4.2 @@ -41,6 +41,10 @@ information about a particular change. Qt's option "reduce relocations" is active. Note that Clang is known to generate incompatible code even with -fPIC if the -flto option is active. + Applications using qmake or cmake >= 2.8.12 as their build system will + adapt automatically. Applications using an older release of cmake need to + change their CMakeLists.txt to add Qt5Core_EXECUTABLE_COMPILE_FLAGS to + CMAKE_CXX_FLAGS. **************************************************************************** * Library * -- cgit v1.2.3 From bccdb62340659cfdf4e0f8b53180fb73fda6ea39 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Wed, 27 May 2015 15:12:54 +0300 Subject: Improve QHeaderView::sectionsInserted performance Old implementation had complexity O(oldSectionCount); replace it with O(hiddenSectionCount) algorithm. This boosts performance in case of the vertical headers for models with big row count. Change-Id: I7bb02f5579ce83fbdecf5f8c3aa7dcc0ac60dd40 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/itemviews/qheaderview.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 66ff472724..bca315f80b 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -1879,13 +1879,13 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent, // insert sections into hiddenSectionSize QHash newHiddenSectionSize; // from logical index to section size - for (int i = 0; i < logicalFirst; ++i) - if (isSectionHidden(i)) - newHiddenSectionSize[i] = d->hiddenSectionSize[i]; - for (int j = logicalLast + 1; j < d->sectionCount(); ++j) - if (isSectionHidden(j)) - newHiddenSectionSize[j] = d->hiddenSectionSize[j - insertCount]; - d->hiddenSectionSize = newHiddenSectionSize; + for (QHash::const_iterator it = d->hiddenSectionSize.cbegin(), + end = d->hiddenSectionSize.cend(); it != end; ++it) { + const int oldIndex = it.key(); + const int newIndex = (oldIndex < logicalFirst) ? oldIndex : oldIndex + insertCount; + newHiddenSectionSize[newIndex] = it.value(); + } + d->hiddenSectionSize.swap(newHiddenSectionSize); d->doDelayedResizeSections(); emit sectionCountChanged(oldCount, count()); -- cgit v1.2.3 From ac4b28ce4d0793d7f36d4d2325070daa0dbcae0b Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Wed, 27 May 2015 18:25:55 +0300 Subject: QRingBuffer: merge indexOf() overloads Change-Id: Icfed4a29bc2ac95b3e0300eb4579751fe7e57e77 Reviewed-by: Oswald Buddenhagen --- src/corelib/tools/qringbuffer.cpp | 18 ------------------ src/corelib/tools/qringbuffer_p.h | 2 +- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp index d8becbe07d..bcf6d2646e 100644 --- a/src/corelib/tools/qringbuffer.cpp +++ b/src/corelib/tools/qringbuffer.cpp @@ -188,24 +188,6 @@ void QRingBuffer::clear() bufferSize = 0; } -qint64 QRingBuffer::indexOf(char c) const -{ - qint64 index = 0; - qint64 j = head; - for (int i = 0; i < buffers.size(); ++i) { - const char *ptr = buffers[i].constData() + j; - j = index + (i == tailBuffer ? tail : buffers[i].size()) - j; - - while (index < j) { - if (*ptr++ == c) - return index; - ++index; - } - j = 0; - } - return -1; -} - qint64 QRingBuffer::indexOf(char c, qint64 maxLength) const { qint64 index = 0; diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index 3a8cca46d8..68509a6a80 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -113,7 +113,7 @@ public: } Q_CORE_EXPORT void clear(); - Q_CORE_EXPORT qint64 indexOf(char c) const; + inline qint64 indexOf(char c) const { return indexOf(c, size()); } Q_CORE_EXPORT qint64 indexOf(char c, qint64 maxLength) const; Q_CORE_EXPORT qint64 read(char *data, qint64 maxLength); Q_CORE_EXPORT QByteArray read(); -- cgit v1.2.3 From a47dbb010f2bf423a6f0a63bae6676a2788cdfdb Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 May 2015 16:12:57 +0200 Subject: windows: Use EGL extensions as they ought to be used We take some shortcuts still because we know that with ANGLE the header with the extension constants is always available. A proper implementation would not rely on the constants being available and would dynamically check for the extension and would take care of defining the constants if not available. However, just getting the extension list to check if the functions needed to get the display are available is already a chicken-egg problem so we won't go there. Using eglGetProcAddress properly solves the issues with static builds too since this always works. Task-number: QTBUG-46284 Change-Id: Iff23669ebacaffa0c5f76fd2c928af689307874f Reviewed-by: Friedemann Kleint Reviewed-by: Gunnar Roth Reviewed-by: Andrew Knight --- src/plugins/platforms/windows/qwindowseglcontext.cpp | 16 +++++++++++----- src/plugins/platforms/windows/qwindowseglcontext.h | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 0184877fdd..06c9985cac 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -39,7 +39,6 @@ #include #if defined(QT_OPENGL_ES_2_ANGLE) || defined(QT_OPENGL_DYNAMIC) -# define EGL_EGLEXT_PROTOTYPES # include #endif @@ -137,7 +136,6 @@ bool QWindowsLibEGL::init() eglGetError = RESOLVE((EGLint (EGLAPIENTRY *)(void)), eglGetError); eglGetDisplay = RESOLVE((EGLDisplay (EGLAPIENTRY *)(EGLNativeDisplayType)), eglGetDisplay); - eglGetPlatformDisplayEXT = RESOLVE((EGLDisplay (EGLAPIENTRY *)(EGLenum platform, void *native_display, const EGLint *attrib_list)), eglGetPlatformDisplayEXT); eglInitialize = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLint *, EGLint *)), eglInitialize); eglTerminate = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay)), eglTerminate); eglChooseConfig = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)), eglChooseConfig); @@ -156,7 +154,15 @@ bool QWindowsLibEGL::init() eglSwapBuffers = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface)), eglSwapBuffers); eglGetProcAddress = RESOLVE((__eglMustCastToProperFunctionPointerType (EGLAPIENTRY * )(const char *)), eglGetProcAddress); - return eglGetError && eglGetDisplay && eglInitialize; + if (!eglGetError || !eglGetDisplay || !eglInitialize || !eglGetProcAddress) + return false; + + eglGetPlatformDisplayEXT = 0; +#ifdef EGL_ANGLE_platform_angle + eglGetPlatformDisplayEXT = reinterpret_cast(eglGetProcAddress("eglGetPlatformDisplayEXT")); +#endif + + return true; } #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) @@ -360,7 +366,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: EGLDisplay display = EGL_NO_DISPLAY; EGLint major = 0; EGLint minor = 0; -#ifdef EGL_ANGLE_platform_angle_opengl +#ifdef EGL_ANGLE_platform_angle if (libEGL.eglGetPlatformDisplayEXT && (preferredType & QWindowsOpenGLTester::AngleBackendMask)) { const EGLint anglePlatformAttributes[][5] = { @@ -384,7 +390,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: } } } -#else // EGL_ANGLE_platform_angle_opengl +#else // EGL_ANGLE_platform_angle Q_UNUSED(preferredType) #endif if (display == EGL_NO_DISPLAY) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 2b249348c3..d8302c97a7 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -46,7 +46,6 @@ struct QWindowsLibEGL EGLint (EGLAPIENTRY * eglGetError)(void); EGLDisplay (EGLAPIENTRY * eglGetDisplay)(EGLNativeDisplayType display_id); - EGLDisplay (EGLAPIENTRY * eglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list); EGLBoolean (EGLAPIENTRY * eglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor); EGLBoolean (EGLAPIENTRY * eglTerminate)(EGLDisplay dpy); EGLBoolean (EGLAPIENTRY * eglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, @@ -74,6 +73,8 @@ struct QWindowsLibEGL EGLBoolean (EGLAPIENTRY * eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface); __eglMustCastToProperFunctionPointerType (EGLAPIENTRY * eglGetProcAddress)(const char *procname); + EGLDisplay (EGLAPIENTRY * eglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list); + private: #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) void *resolve(const char *name); -- cgit v1.2.3 From 95b6c4fed6521aa2212cab67cb8a6e5553e86117 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 28 May 2015 11:21:35 -0700 Subject: Make qglobal.h only complain for GCC >= 5 about -fPIE Commit 3eca75de67b3fd2c890715b30c7899cebc096fe9 introduced the #error nagging about use of -fPIE, but it makes the transition quite difficult for people using other buildsystems. So let's give people a grace period and enforce only for GCC >= 5. Clang is affected, but differently. The problem only happens with -flto -- that is, it happens when the linker detects that it's creating a final executable. Maybe -Wl,-pie would fix it. Change-Id: If4d5ac8db0ed4a84a3eaffff13e275edc29a72b7 Reviewed-by: Simon Hausmann Reviewed-by: Dmitry Shachnev --- src/corelib/global/qglobal.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 4547877da6..d9742408a3 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1047,7 +1047,8 @@ Q_CORE_EXPORT int qrand(); # define QT_NO_SHAREDMEMORY #endif -#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && (!defined(__PIC__) || defined(__PIE__)) +#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && \ + (!defined(__PIC__) || (defined(__PIE__) && defined(Q_CC_GNU) && Q_CC_GNU >= 500)) # error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ "Compile your code with -fPIC (-fPIE is not enough)." #endif -- cgit v1.2.3 From e3983c87280ade48b243d9c60bed639713851be9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 28 May 2015 21:20:55 +0200 Subject: Revert some changes in light of GCC 4 -fPIE reversal The -fPIE option is now accepted when using GCC 4, which means it is available for backward compatibility for clients using CMake 2.8.11 or older which makes use of the POSITION_INDEPENDENT_CODE feature. Conditionally use that feature for old versions of cmake with GCC 4. Restore the tests for those versions, and clarify the situation in the ChangeLog. Change-Id: I5a06b155dda7db559d86841a2b34fd8ed95acbd0 Reviewed-by: Thiago Macieira --- dist/changes-5.4.2 | 20 +++++++++++++------- src/corelib/Qt5CoreConfigExtras.cmake.in | 8 +++++++- src/corelib/Qt5CoreMacros.cmake | 6 ++++++ tests/auto/cmake/CMakeLists.txt | 5 ++++- tests/auto/cmake/test_interface/CMakeLists.txt | 2 +- .../cmake/test_use_modules_function/CMakeLists.txt | 2 -- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/dist/changes-5.4.2 b/dist/changes-5.4.2 index 29d3c6346d..1a34898011 100644 --- a/dist/changes-5.4.2 +++ b/dist/changes-5.4.2 @@ -37,14 +37,20 @@ information about a particular change. - On x86 and x86-64 systems with ELF binaries (especially Linux), due to a new optimization in GCC 5.x in combination with a recent version of GNU binutils, compiling Qt applications with -fPIE is no longer - enough. Applications now need to be compiled with the -fPIC option if - Qt's option "reduce relocations" is active. Note that Clang is known - to generate incompatible code even with -fPIC if the -flto option is - active. + enough with GCC 5.x. Applications now need to be compiled with + the -fPIC option if Qt's option "reduce relocations" is active. For + backward compatibility only, Qt accepts the use of -fPIE for GCC 4.x + versions. + Note that Clang is known to generate incompatible code even with -fPIC if + the -flto option is active. Applications using qmake or cmake >= 2.8.12 as their build system will - adapt automatically. Applications using an older release of cmake need to - change their CMakeLists.txt to add Qt5Core_EXECUTABLE_COMPILE_FLAGS to - CMAKE_CXX_FLAGS. + adapt automatically. Applications using an older release of cmake in + combination with GCC 5.x need to change their CMakeLists.txt to add + Qt5Core_EXECUTABLE_COMPILE_FLAGS to CMAKE_CXX_FLAGS. In particular, + applications using cmake >= 2.8.9 and < 2.8.11 will continue to build + with the -fPIE option and invoke the special compatibility mode if using + GCC 4.x. + **************************************************************************** * Library * diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index a5cab880ba..65fd1f9383 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -71,7 +71,13 @@ set(_qt5_corelib_extra_includes) # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") -set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $$QMAKE_CXXFLAGS_APP) +if (CMAKE_VERSION VERSION_LESS 2.8.12 + AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" + OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)) + set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") +else() + set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $$QMAKE_CXXFLAGS_APP) +endif() !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index c10880f787..cfbb381df5 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -281,6 +281,12 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.9) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG) + if (Qt5_POSITION_INDEPENDENT_CODE + AND (CMAKE_VERSION VERSION_LESS 2.8.12 + AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" + OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))) + set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE}) + endif() endforeach() endmacro() endif() diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index b68aafe956..87d8a802f3 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -126,8 +126,11 @@ if (QT_WITH_ANGLE OR (NOT WIN32 AND NOT APPLE AND NOT NO_EGL)) endif() expect_pass(test_opengl_lib) -if (NOT CMAKE_VERSION VERSION_LESS 2.8.12) +if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) expect_pass(test_interface) +endif() + +if (NOT CMAKE_VERSION VERSION_LESS 2.8.12) expect_pass(test_interface_link_libraries) expect_pass(test_moc_macro_target) endif() diff --git a/tests/auto/cmake/test_interface/CMakeLists.txt b/tests/auto/cmake/test_interface/CMakeLists.txt index bd3217a497..a8af92da63 100644 --- a/tests/auto/cmake/test_interface/CMakeLists.txt +++ b/tests/auto/cmake/test_interface/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 2.8.11) project(test_interface) diff --git a/tests/auto/cmake/test_use_modules_function/CMakeLists.txt b/tests/auto/cmake/test_use_modules_function/CMakeLists.txt index be05c75054..bfcdd9d1d7 100644 --- a/tests/auto/cmake/test_use_modules_function/CMakeLists.txt +++ b/tests/auto/cmake/test_use_modules_function/CMakeLists.txt @@ -12,7 +12,5 @@ add_executable(three three.cpp) find_package(Qt5Core) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") - qt5_use_modules(two Test) qt5_use_modules(three Gui Test) -- cgit v1.2.3 From 0a7fcfd61263bc156b780c5e48656c00c64721ed Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 28 May 2015 10:00:45 +0200 Subject: Windows: Fix font metrics of Vista style wizards. QVistaHelper::drawTitleBar() used the font returned by QApplication::font("QMdiSubWindowTitleBar") (typically "MS Shell Dlg 2",16) to calculate the bounding rectangle of the title text. However, if the window is a toplevel QVistaHelper::drawTitleText() uses the theme font obtained for WIZ_TMT_CAPTIONFONT (typically "Segoe UI",11.25) to draw the title (since it is a window title). This causes the font to be cropped when changing the application font or spurious black rectangles to occur. Fix this by exposing QWindowsFontDatabase::LOGFONT_to_QFont() via QWindowsNativeInterface, and creating a QFont from the LOGFONT obtained for WIZ_TMT_CAPTIONFONT and using that for the bounding rectangle in the case of toplevel windows. Split up the HFONT QVistaHelper::getCaptionFont(HANDLE hTheme) into static LOGFONT getCaptionLogFont(HANDLE hTheme) and use that to obtain the HFONT in drawTitleText() or QFont in static QFont getCaptionQFont(), respectively. Task-number: QTBUG-46360 Change-Id: I9069b403f7f948b6738eec452cb7584be45b8a29 Reviewed-by: Oliver Wolff --- .../platforms/windows/qwindowsnativeinterface.cpp | 6 +++ .../platforms/windows/qwindowsnativeinterface.h | 2 + src/widgets/dialogs/qwizard_win.cpp | 50 +++++++++++++++------- src/widgets/dialogs/qwizard_win_p.h | 1 - 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 9691156403..6e58c55bbe 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -34,6 +34,7 @@ #include "qwindowsnativeinterface.h" #include "qwindowswindow.h" #include "qwindowscontext.h" +#include "qwindowsfontdatabase.h" #include "qwindowsopenglcontext.h" #include "qwindowsopengltester.h" #include "qwindowsintegration.h" @@ -222,6 +223,11 @@ int QWindowsNativeInterface::registerMimeType(const QString &mimeType) return QWindowsMime::registerMimeType(mimeType); } +QFont QWindowsNativeInterface::logFontToQFont(const void *logFont, int verticalDpi) +{ + return QWindowsFontDatabase::LOGFONT_to_QFont(*reinterpret_cast(logFont), verticalDpi); +} + QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &function) const { if (function == QWindowsWindowFunctions::setTouchWindowTouchTypeIdentifier()) diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h index be8418b769..97839ae1ae 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h @@ -34,6 +34,7 @@ #ifndef QWINDOWSNATIVEINTERFACE_H #define QWINDOWSNATIVEINTERFACE_H +#include #include QT_BEGIN_NAMESPACE @@ -77,6 +78,7 @@ public: Q_INVOKABLE void registerWindowsMime(void *mimeIn); Q_INVOKABLE void unregisterWindowsMime(void *mime); Q_INVOKABLE int registerMimeType(const QString &mimeType); + Q_INVOKABLE QFont logFontToQFont(const void *logFont, int verticalDpi); bool asyncExpose() const; void setAsyncExpose(bool value); diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 701fea1c03..a4b37f360b 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -361,6 +361,36 @@ bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type) Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &); +static LOGFONT getCaptionLogFont(HANDLE hTheme) +{ + LOGFONT result = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } }; + + if (!hTheme || FAILED(pGetThemeSysFont(hTheme, WIZ_TMT_CAPTIONFONT, &result))) { + NONCLIENTMETRICS ncm; + ncm.cbSize = sizeof(NONCLIENTMETRICS); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false); + result = ncm.lfMessageFont; + } + return result; +} + +static bool getCaptionQFont(int dpi, QFont *result) +{ + if (!pOpenThemeData) + return false; + const HANDLE hTheme = + pOpenThemeData(QApplicationPrivate::getHWNDForWidget(QApplication::desktop()), L"WINDOW"); + if (!hTheme) + return false; + // Call into QWindowsNativeInterface to convert the LOGFONT into a QFont. + const LOGFONT logFont = getCaptionLogFont(hTheme); + QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface(); + return ni && QMetaObject::invokeMethod(ni, "logFontToQFont", Qt::DirectConnection, + Q_RETURN_ARG(QFont, *result), + Q_ARG(const void *, &logFont), + Q_ARG(int, dpi)); +} + void QVistaHelper::drawTitleBar(QPainter *painter) { Q_ASSERT(backButton_); @@ -378,7 +408,9 @@ void QVistaHelper::drawTitleBar(QPainter *painter) const int verticalCenter = (btnTop + btnHeight / 2) - 1; const QString text = wizard->window()->windowTitle(); - const QFont font = QApplication::font("QMdiSubWindowTitleBar"); + QFont font; + if (!isWindow || !getCaptionQFont(wizard->logicalDpiY() * wizard->devicePixelRatio(), &font)) + font = QApplication::font("QMdiSubWindowTitleBar"); const QFontMetrics fontMetrics(font); const QRect brect = fontMetrics.boundingRect(text); int textHeight = brect.height(); @@ -649,19 +681,6 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event) return false; } -HFONT QVistaHelper::getCaptionFont(HANDLE hTheme) -{ - LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } }; - - if (!hTheme || FAILED(pGetThemeSysFont(hTheme, WIZ_TMT_CAPTIONFONT, &lf))) { - NONCLIENTMETRICS ncm; - ncm.cbSize = sizeof(NONCLIENTMETRICS); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false); - lf = ncm.lfMessageFont; - } - return CreateFontIndirect(&lf); -} - // Return a HDC for the wizard along with the transformation if the // wizard is a child window. HDC QVistaHelper::backingStoreDC(const QWidget *wizard, QPoint *offset) @@ -713,7 +732,8 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0); // Set up the DC - HFONT hCaptionFont = getCaptionFont(hTheme); + const LOGFONT captionLogFont = getCaptionLogFont(hTheme); + const HFONT hCaptionFont = CreateFontIndirect(&captionLogFont); HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp); HFONT hOldFont = (HFONT)SelectObject(dcMem, (HGDIOBJ) hCaptionFont); diff --git a/src/widgets/dialogs/qwizard_win_p.h b/src/widgets/dialogs/qwizard_win_p.h index 8c36472bee..84b795d506 100644 --- a/src/widgets/dialogs/qwizard_win_p.h +++ b/src/widgets/dialogs/qwizard_win_p.h @@ -105,7 +105,6 @@ public: static HDC backingStoreDC(const QWidget *wizard, QPoint *offset); private: - static HFONT getCaptionFont(HANDLE hTheme); HWND wizardHWND() const; bool drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc); static bool drawBlackRect(const QRect &rect, HDC hdc); -- cgit v1.2.3 From f5d1c329ce9c2c81e3bf59017fb2cdd4261b5336 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 27 May 2015 15:00:00 +0200 Subject: Emphasize the need for calling setDefaultFormat early on OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-46067 Change-Id: I0fe6e7ba309306a8fc471424b30eed4491bd39e7 Reviewed-by: Topi Reiniö --- src/widgets/kernel/qopenglwidget.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index b8df25b38f..9bfdc62e60 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -104,6 +104,12 @@ QT_BEGIN_NAMESPACE non-sharable. To overcome this issue, prefer using QSurfaceFormat::setDefaultFormat() instead of setFormat(). + \note Calling QSurfaceFormat::setDefaultFormat() before constructing + the QApplication instance is mandatory on some platforms (for example, + OS X) when an OpenGL core profile context is requested. This is to + ensure that resource sharing between contexts stays functional as all + internal contexts are created using the correct version and profile. + \section1 Painting Techniques As described above, subclass QOpenGLWidget to render pure 3D content in the -- cgit v1.2.3 From 386aca1ba4da3383cd6b6253a7240417ff2d91a0 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Fri, 22 May 2015 09:13:51 +1000 Subject: Fix no bearermanagement build As pointed out in the bug, it also fixes API use when configured with no bearermanagement. Task-number: QTBUG-46239 Change-Id: Ief8df85ad6acf61e8d5bb3eed54e7d6ecb84c1a0 Reviewed-by: Alex Blasche --- src/network/access/qnetworkaccessmanager.cpp | 41 +++++++++++++------------- src/plugins/bearer/corewlan/qcorewlanengine.mm | 3 ++ 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 52d56fb071..14db4554bb 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -961,6 +961,27 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess } } +/*! + \internal + + Returns the network session currently in use. + This can be changed at any time, ownership remains with the QNetworkAccessManager +*/ +const QWeakPointer QNetworkAccessManagerPrivate::getNetworkSession(const QNetworkAccessManager *q) +{ + return q->d_func()->networkSessionWeakRef; +} + +QSharedPointer QNetworkAccessManagerPrivate::getNetworkSession() const +{ + if (networkSessionStrongRef) + return networkSessionStrongRef; + return networkSessionWeakRef.toStrongRef(); +} + +#endif // QT_NO_BEARERMANAGEMENT + + #ifndef QT_NO_SSL /*! \since 5.2 @@ -1021,26 +1042,6 @@ void QNetworkAccessManager::connectToHost(const QString &hostName, quint16 port) get(request); } -/*! - \internal - - Returns the network session currently in use. - This can be changed at any time, ownership remains with the QNetworkAccessManager -*/ -const QWeakPointer QNetworkAccessManagerPrivate::getNetworkSession(const QNetworkAccessManager *q) -{ - return q->d_func()->networkSessionWeakRef; -} - -QSharedPointer QNetworkAccessManagerPrivate::getNetworkSession() const -{ - if (networkSessionStrongRef) - return networkSessionStrongRef; - return networkSessionWeakRef.toStrongRef(); -} - -#endif // QT_NO_BEARERMANAGEMENT - /*! \since 4.7 diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 2b38409723..3cee70044f 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -52,6 +52,7 @@ #include #include +#ifndef QT_NO_BEARERMANAGEMENT extern "C" { // Otherwise it won't find CWKeychain* symbols at link time #import @@ -896,3 +897,5 @@ quint64 QCoreWlanEngine::getBytes(const QString &interfaceName, bool b) } QT_END_NAMESPACE + +#endif -- cgit v1.2.3 From db54498fd124edc69313f64d2af8070afc104d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Thu, 28 May 2015 20:24:42 +0100 Subject: Mark two member functions const Change-Id: I42266689ccac2d0234eb0b047d2dc949e6f59196 Reviewed-by: Marc Mutz --- src/corelib/io/qtemporaryfile.cpp | 4 ++-- src/corelib/io/qtemporaryfile_p.h | 2 +- src/network/access/qnetworkaccessauthenticationmanager_p.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 556bc6e760..bdf4392275 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -236,9 +236,9 @@ QTemporaryFileEngine::~QTemporaryFileEngine() QFSFileEngine::close(); } -bool QTemporaryFileEngine::isReallyOpen() +bool QTemporaryFileEngine::isReallyOpen() const { - Q_D(QFSFileEngine); + Q_D(const QFSFileEngine); if (!((0 == d->fh) && (-1 == d->fd) #if defined Q_OS_WIN diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h index 475298f264..341ae9bd3f 100644 --- a/src/corelib/io/qtemporaryfile_p.h +++ b/src/corelib/io/qtemporaryfile_p.h @@ -95,7 +95,7 @@ public: ~QTemporaryFileEngine(); - bool isReallyOpen(); + bool isReallyOpen() const; void setFileName(const QString &file); void setFileTemplate(const QString &fileTemplate); diff --git a/src/network/access/qnetworkaccessauthenticationmanager_p.h b/src/network/access/qnetworkaccessauthenticationmanager_p.h index 8f06ecb6b7..462827d7fc 100644 --- a/src/network/access/qnetworkaccessauthenticationmanager_p.h +++ b/src/network/access/qnetworkaccessauthenticationmanager_p.h @@ -64,7 +64,7 @@ public: QString domain; QString user; QString password; - bool isNull() { + bool isNull() const { return domain.isNull() && user.isNull() && password.isNull(); } }; -- cgit v1.2.3 From c0ddd5fa12f696838cb1d1de3f721f19a87c8509 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 20 Feb 2014 17:16:29 +0100 Subject: QTextLayout: replace a use of an inefficient QList with QVector The QTextLayout::FormatRange is larger than void* and thus should not be held in QList. Use a QVector instead. Other parts of Qt already hold FormatRanges in QVectors, so this also makes handling FormatRanges more consistent. To avoid ugly names for the getter which doesn't overload on return type alone), rename the set of function to format (from additionalFormats). [ChangeLog][QtGui][QTextLayout] Added QVector-based alternatives setFormat(), format(), and clearFormat() to setAdditionalFormats(), additionalFormats(), and clearAdditionalFormats(), resp. Change-Id: Ie04a561b43c91c3b2befb3cac2981821f84d5f77 Reviewed-by: Konstantin Ritt Reviewed-by: Simon Hausmann --- src/gui/text/qtextengine.cpp | 10 +++++----- src/gui/text/qtextengine_p.h | 8 ++++---- src/gui/text/qtextlayout.cpp | 40 ++++++++++++++++++++++++++++++++++++++-- src/gui/text/qtextlayout.h | 3 +++ 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 67a19804a3..187ffa5be7 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2571,7 +2571,7 @@ void QTextEngine::setPreeditArea(int position, const QString &preeditText) clearLineData(); } -void QTextEngine::setFormats(const QList &formats) +void QTextEngine::setFormats(const QVector &formats) { if (formats.isEmpty()) { if (!specialData) @@ -2946,17 +2946,17 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const namespace { class FormatRangeComparatorByStart { - const QList &list; + const QVector &list; public: - FormatRangeComparatorByStart(const QList &list) : list(list) { } + FormatRangeComparatorByStart(const QVector &list) : list(list) { } bool operator()(int a, int b) { return list.at(a).start < list.at(b).start; } }; class FormatRangeComparatorByEnd { - const QList &list; + const QVector &list; public: - FormatRangeComparatorByEnd(const QList &list) : list(list) { } + FormatRangeComparatorByEnd(const QVector &list) : list(list) { } bool operator()(int a, int b) { return list.at(a).start + list.at(a).length < list.at(b).start + list.at(b).length; } diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 39b9e0cb5a..3590c6da07 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -570,9 +570,9 @@ public: inline bool hasFormats() const { return block.docHandle() || (specialData && !specialData->formats.isEmpty()); } - inline QList formats() const - { return specialData ? specialData->formats : QList(); } - void setFormats(const QList &formats); + inline QVector formats() const + { return specialData ? specialData->formats : QVector(); } + void setFormats(const QVector &formats); private: static void init(QTextEngine *e); @@ -580,7 +580,7 @@ private: struct SpecialData { int preeditPosition; QString preeditText; - QList formats; + QVector formats; QVector resolvedFormats; // only used when no docHandle is available QScopedPointer formatCollection; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 7da3e84041..dabe06fa88 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -485,7 +485,6 @@ QString QTextLayout::preeditAreaText() const return d->preeditAreaText(); } - /*! Sets the additional formats supported by the text layout to \a formatList. The formats are applied with preedit area text in place. @@ -494,7 +493,20 @@ QString QTextLayout::preeditAreaText() const */ void QTextLayout::setAdditionalFormats(const QList &formatList) { - d->setFormats(formatList); + setFormats(formatList.toVector()); +} + +/*! + \since 5.6 + + Sets the additional formats supported by the text layout to \a formats. + The formats are applied with preedit area text in place. + + \sa formats(), clearFormats() +*/ +void QTextLayout::setFormats(const QVector &formats) +{ + d->setFormats(formats); if (d->block.docHandle()) d->block.docHandle()->documentChange(d->block.position(), d->block.length()); @@ -506,6 +518,18 @@ void QTextLayout::setAdditionalFormats(const QList &formatList) \sa setAdditionalFormats(), clearAdditionalFormats() */ QList QTextLayout::additionalFormats() const +{ + return formats().toList(); +} + +/*! + \since 5.6 + + Returns the list of additional formats supported by the text layout. + + \sa setFormats(), clearFormats() +*/ +QVector QTextLayout::formats() const { return d->formats(); } @@ -520,6 +544,18 @@ void QTextLayout::clearAdditionalFormats() setAdditionalFormats(QList()); } +/*! + \since 5.6 + + Clears the list of additional formats supported by the text layout. + + \sa formats(), setFormats() +*/ +void QTextLayout::clearFormats() +{ + setFormats(QVector()); +} + /*! Enables caching of the complete layout information if \a enable is true; otherwise disables layout caching. Usually diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index 47dcd388e2..ce092e0928 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -129,6 +129,9 @@ public: void setAdditionalFormats(const QList &overrides); QList additionalFormats() const; void clearAdditionalFormats(); + void setFormats(const QVector &overrides); + QVector formats() const; + void clearFormats(); void setCacheEnabled(bool enable); bool cacheEnabled() const; -- cgit v1.2.3 From aff3f7f767617c9f569ed5101a12d677233be901 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 29 May 2015 12:29:55 +0200 Subject: Fix QIODevice::errorString() and other places where we expose errno Commit e486d69133178ccce7c75cf48201ab28efb20e44 changed the behavior of QString::fromLocal8Bit(const QByteArray &) to preserve embedded null characters. The embedded null character from qt_error_string()'s buffer is not something we want to preserve, it is merely a safe guard. Therefore let's strip it away. Change-Id: Iceac91551f51a1036a942ff30d246baea7a6fd7c Reviewed-by: Marc Mutz --- src/corelib/global/qglobal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 2176a148b0..4f611bddbc 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2955,7 +2955,7 @@ namespace { // depending on the return type static inline Q_DECL_UNUSED QString fromstrerror_helper(int, const QByteArray &buf) { - return QString::fromLocal8Bit(buf); + return QString::fromLocal8Bit(buf.constData()); } static inline Q_DECL_UNUSED QString fromstrerror_helper(const char *str, const QByteArray &) { -- cgit v1.2.3 From 4964c895406b8316d15668affd32cc5eb7b6c7ea Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 29 May 2015 15:53:02 +0200 Subject: tst_QDockWidget::restoreDockWidget: Add QSKIP for XCB. The positioning test has been observed to fail on X11. Change-Id: I58727126a8742de93ec203e9992a9ae1b454f731 Reviewed-by: Simon Hausmann --- tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp index ade9f72543..2bbc2e05b7 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -764,6 +764,8 @@ void tst_QDockWidget::restoreDockWidget() restoreWindow.show(); QVERIFY(QTest::qWaitForWindowExposed(&restoreWindow)); QTRY_VERIFY(dock->isFloating()); + if (!QGuiApplication::platformName().compare("xcb", Qt::CaseInsensitive)) + QSKIP("Skip due to Window manager positioning issues", Abort); QTRY_COMPARE(dock->pos(), dockPos); } } -- cgit v1.2.3 From 0c5befa129ad913c5934e72f19abbff553aee6da Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 May 2015 16:45:37 +0200 Subject: Reanimate test gui/kernel/qtouchevent/tst_qtouchevent. Add CONFIG += testcase to the .pro file which was missing. The test thus was never executed by make check and left to rot. Fix up code: - Remove module includes. - Introduce explicit constructors taking parent object for helper classes, removing calls to setParent(). - Ensure test does not leak objects by converting pointers to stack variables or introducing QScopedPointer, verify by checking for an empty window list in cleanup(). - Simplify code by removing unneeded variables. - Split up conditions in QVERIFY(). Fix tests: - Show windows were required when events are sent to QWidget::windowHandle(). - Invert the conditions checking whether touch events are accepted by widgets since widgets no longer accept them by defaults in Qt 5 after e50416066cab4be7df8382bd224d9e4ddd7a903a. - XFAIL multiPointRawEventTranslationOnTouchPad() which started to fail at some point in Qt 5. - Mark as insignificant on OS X due to crash. Task-number: QTBUG-46266 Change-Id: I6676d021afb015411a24d97d9b8f7c327d4d3c3f Reviewed-by: Simon Hausmann --- tests/auto/gui/kernel/qtouchevent/qtouchevent.pro | 2 + .../gui/kernel/qtouchevent/tst_qtouchevent.cpp | 314 ++++++++++----------- 2 files changed, 152 insertions(+), 164 deletions(-) diff --git a/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro b/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro index 7136611165..b1e3c10724 100644 --- a/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro +++ b/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro @@ -1,3 +1,5 @@ +CONFIG += testcase +osx: CONFIG += insignificant_test # QTBUG-46266, crashes SOURCES=tst_qtouchevent.cpp TARGET=tst_qtouchevent QT += testlib widgets gui-private diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index fe11f39242..dc35058f66 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -31,11 +31,16 @@ ** ****************************************************************************/ -#include -#include +#include +#include +#include +#include +#include +#include #include #include +// FIXME: Use static functions of QWindowSystemInterface introduced with HighDPI scaling in 5.6 instead. static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt) { QWindowSystemInterface::TouchPoint p; @@ -72,8 +77,7 @@ public: ulong timestamp; QTouchDevice *deviceFromEvent; - tst_QTouchEventWidget() - : QWidget() + explicit tst_QTouchEventWidget(QWidget *parent = Q_NULLPTR) : QWidget(parent) { reset(); } @@ -88,7 +92,7 @@ public: deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false; } - bool event(QEvent *event) + bool event(QEvent *event) Q_DECL_OVERRIDE { switch (event->type()) { case QEvent::TouchBegin: @@ -142,8 +146,8 @@ public: bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd; tst_QTouchEventGraphicsItem **weakpointer; - tst_QTouchEventGraphicsItem() - : QGraphicsItem(), weakpointer(0) + explicit tst_QTouchEventGraphicsItem(QGraphicsItem *parent = Q_NULLPTR) + : QGraphicsItem(parent), weakpointer(0) { reset(); } @@ -165,10 +169,10 @@ public: deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false; } - QRectF boundingRect() const { return QRectF(0, 0, 10, 10); } - void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) { } + QRectF boundingRect() const Q_DECL_OVERRIDE { return QRectF(0, 0, 10, 10); } + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) Q_DECL_OVERRIDE { } - bool sceneEvent(QEvent *event) + bool sceneEvent(QEvent *event) Q_DECL_OVERRIDE { switch (event->type()) { case QEvent::TouchBegin: @@ -214,9 +218,9 @@ class tst_QTouchEvent : public QObject Q_OBJECT public: tst_QTouchEvent(); - ~tst_QTouchEvent() { } private slots: + void cleanup(); void touchDisabledByDefault(); void touchEventAcceptedByDefault(); void touchBeginPropagatesWhenIgnored(); @@ -236,15 +240,18 @@ private: QTouchDevice *touchPadDevice; }; -tst_QTouchEvent::tst_QTouchEvent() +tst_QTouchEvent::tst_QTouchEvent() : touchScreenDevice(new QTouchDevice), touchPadDevice(new QTouchDevice) { - touchScreenDevice = new QTouchDevice; - touchPadDevice = new QTouchDevice; touchPadDevice->setType(QTouchDevice::TouchPad); QWindowSystemInterface::registerTouchDevice(touchScreenDevice); QWindowSystemInterface::registerTouchDevice(touchPadDevice); } +void tst_QTouchEvent::cleanup() +{ + QVERIFY(QGuiApplication::topLevelWindows().isEmpty()); +} + void tst_QTouchEvent::touchDisabledByDefault() { // QWidget @@ -261,8 +268,7 @@ void tst_QTouchEvent::touchDisabledByDefault() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&widget, &touchEvent); - QVERIFY(!res); + QVERIFY(!QApplication::sendEvent(&widget, &touchEvent)); QVERIFY(!touchEvent.isAccepted()); } @@ -290,8 +296,7 @@ void tst_QTouchEvent::touchDisabledByDefault() Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(!res); + QVERIFY(!QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(!touchEvent.isAccepted()); QVERIFY(!item.seenTouchBegin); } @@ -299,7 +304,7 @@ void tst_QTouchEvent::touchDisabledByDefault() void tst_QTouchEvent::touchEventAcceptedByDefault() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); // QWidget @@ -317,16 +322,14 @@ void tst_QTouchEvent::touchEventAcceptedByDefault() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&widget, &touchEvent); - QVERIFY(res); - QVERIFY(touchEvent.isAccepted()); + QVERIFY(QApplication::sendEvent(&widget, &touchEvent)); + QVERIFY(!touchEvent.isAccepted()); // Qt 5.X ignores touch events. // tst_QTouchEventWidget does handle, sending succeeds tst_QTouchEventWidget touchWidget; touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchEvent.ignore(); - res = QApplication::sendEvent(&touchWidget, &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&touchWidget, &touchEvent)); QVERIFY(touchEvent.isAccepted()); } @@ -355,8 +358,7 @@ void tst_QTouchEvent::touchEventAcceptedByDefault() Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(item.seenTouchBegin); } @@ -383,8 +385,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&grandchild, &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -398,8 +399,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() grandchild.setAttribute(Qt::WA_AcceptTouchEvents, false); touchEvent.ignore(); - res = QApplication::sendEvent(&grandchild, &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(!grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -435,8 +435,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -471,8 +470,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(!grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -499,8 +497,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&child, &touchBeginEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&child, &touchBeginEvent)); QVERIFY(touchBeginEvent.isAccepted()); QVERIFY(child.seenTouchBegin); QVERIFY(!window.seenTouchBegin); @@ -511,8 +508,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointMoved, touchPoints); - res = QApplication::sendEvent(&child, &touchUpdateEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&child, &touchUpdateEvent)); QVERIFY(!touchUpdateEvent.isAccepted()); QVERIFY(child.seenTouchUpdate); QVERIFY(!window.seenTouchUpdate); @@ -523,8 +519,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - res = QApplication::sendEvent(&child, &touchEndEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&child, &touchEndEvent)); QVERIFY(!touchEndEvent.isAccepted()); QVERIFY(child.seenTouchEnd); QVERIFY(!window.seenTouchEnd); @@ -558,8 +553,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); QVERIFY(touchBeginEvent.isAccepted()); QVERIFY(child.seenTouchBegin); QVERIFY(!root.seenTouchBegin); @@ -571,8 +565,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointMoved, (QList() << touchPoint)); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); // the scene accepts the event, since it found an item to send the event to QVERIFY(!touchUpdateEvent.isAccepted()); QVERIFY(child.seenTouchUpdate); @@ -585,8 +578,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointReleased, (QList() << touchPoint)); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); // the scene accepts the event, since it found an item to send the event to QVERIFY(!touchEndEvent.isAccepted()); QVERIFY(child.seenTouchEnd); @@ -601,17 +593,20 @@ QPointF normalized(const QPointF &pos, const QRectF &rect) void tst_QTouchEvent::basicRawEventTranslation() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); QPointF pos = touchWidget.rect().center(); QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint()); QPointF delta(10, 10); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QTouchEvent::TouchPoint rawTouchPoint; rawTouchPoint.setId(0); @@ -726,24 +721,24 @@ void tst_QTouchEvent::basicRawEventTranslation() void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); - tst_QTouchEventWidget leftWidget; - leftWidget.setParent(&touchWidget); + tst_QTouchEventWidget leftWidget(&touchWidget); leftWidget.setAttribute(Qt::WA_AcceptTouchEvents); leftWidget.setGeometry(0, 100, 100, 100); - leftWidget.show(); - tst_QTouchEventWidget rightWidget; - rightWidget.setParent(&touchWidget); + tst_QTouchEventWidget rightWidget(&touchWidget); rightWidget.setAttribute(Qt::WA_AcceptTouchEvents); rightWidget.setGeometry(300, 100, 100, 100); - rightWidget.show(); + + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); QPointF leftPos = leftWidget.rect().center(); QPointF rightPos = rightWidget.rect().center(); @@ -751,8 +746,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint()); QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint()); QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint()); - QPointF delta(10, 10); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QList rawTouchPoints; rawTouchPoints.append(QTouchEvent::TouchPoint(0)); @@ -956,24 +950,25 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); - tst_QTouchEventWidget leftWidget; - leftWidget.setParent(&touchWidget); + tst_QTouchEventWidget leftWidget(&touchWidget); leftWidget.setAttribute(Qt::WA_AcceptTouchEvents); leftWidget.setGeometry(0, 100, 100, 100); - leftWidget.show(); + leftWidget.acceptTouchBegin =true; - tst_QTouchEventWidget rightWidget; - rightWidget.setParent(&touchWidget); + tst_QTouchEventWidget rightWidget(&touchWidget); rightWidget.setAttribute(Qt::WA_AcceptTouchEvents); rightWidget.setGeometry(300, 100, 100, 100); - rightWidget.show(); + + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); QPointF leftPos = leftWidget.rect().center(); QPointF rightPos = rightWidget.rect().center(); @@ -981,8 +976,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint()); QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint()); QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint()); - QPointF delta(10, 10); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QList rawTouchPoints; rawTouchPoints.append(QTouchEvent::TouchPoint(0)); @@ -1003,7 +997,8 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); QVERIFY(!touchWidget.seenTouchEnd); - QVERIFY(leftWidget.seenTouchBegin); + QEXPECT_FAIL("", "QTBUG-46266, fails in Qt 5", Abort); + QVERIFY(!leftWidget.seenTouchBegin); QVERIFY(!leftWidget.seenTouchUpdate); QVERIFY(!leftWidget.seenTouchEnd); QVERIFY(!rightWidget.seenTouchBegin); @@ -1186,19 +1181,15 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() void tst_QTouchEvent::deleteInEventHandler() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); // QWidget { QWidget window; - tst_QTouchEventWidget *child1, *child2, *child3; - child1 = new tst_QTouchEventWidget; - child2 = new tst_QTouchEventWidget; - child3 = new tst_QTouchEventWidget; - child1->setParent(&window); - child2->setParent(&window); - child3->setParent(&window); + QPointer child1 = new tst_QTouchEventWidget(&window); + QPointer child2 = new tst_QTouchEventWidget(&window); + QPointer child3 = new tst_QTouchEventWidget(&window); child1->setAttribute(Qt::WA_AcceptTouchEvents); child2->setAttribute(Qt::WA_AcceptTouchEvents); child3->setAttribute(Qt::WA_AcceptTouchEvents); @@ -1223,47 +1214,43 @@ void tst_QTouchEvent::deleteInEventHandler() Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - QPointer p; - bool res; - touchBeginEvent.ignore(); - p = child1; - res = QApplication::sendEvent(child1, &touchBeginEvent); + QVERIFY(QApplication::sendEvent(child1, &touchBeginEvent)); // event is handled, but widget should be deleted - QVERIFY(res && touchBeginEvent.isAccepted() && p.isNull()); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(child1.isNull()); touchBeginEvent.ignore(); - p = child2; - res = QApplication::sendEvent(child2, &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && !p.isNull()); + QVERIFY(QApplication::sendEvent(child2, &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(!child2.isNull()); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(child2, &touchUpdateEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && p.isNull()); + QVERIFY(QApplication::sendEvent(child2, &touchUpdateEvent)); + QVERIFY(touchUpdateEvent.isAccepted()); + QVERIFY(child2.isNull()); touchBeginEvent.ignore(); - p = child3; - res = QApplication::sendEvent(child3, &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && !p.isNull()); + QVERIFY(QApplication::sendEvent(child3, &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(!child3.isNull()); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(child3, &touchUpdateEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && !p.isNull()); + QVERIFY(QApplication::sendEvent(child3, &touchUpdateEvent)); + QVERIFY(touchUpdateEvent.isAccepted()); + QVERIFY(!child3.isNull()); touchEndEvent.ignore(); - res = QApplication::sendEvent(child3, &touchEndEvent); - QVERIFY(res && touchEndEvent.isAccepted() && p.isNull()); + QVERIFY(QApplication::sendEvent(child3, &touchEndEvent)); + QVERIFY(touchEndEvent.isAccepted()); + QVERIFY(child3.isNull()); } // QGraphicsView { QGraphicsScene scene; QGraphicsView view(&scene); - tst_QTouchEventGraphicsItem *root, *child1, *child2, *child3; - root = new tst_QTouchEventGraphicsItem; - child1 = new tst_QTouchEventGraphicsItem; - child2 = new tst_QTouchEventGraphicsItem; - child3 = new tst_QTouchEventGraphicsItem; - child1->setParentItem(root); - child2->setParentItem(root); - child3->setParentItem(root); + QScopedPointer root(new tst_QTouchEventGraphicsItem); + tst_QTouchEventGraphicsItem *child1 = new tst_QTouchEventGraphicsItem(root.data()); + tst_QTouchEventGraphicsItem *child2 = new tst_QTouchEventGraphicsItem(root.data()); + tst_QTouchEventGraphicsItem *child3 = new tst_QTouchEventGraphicsItem(root.data()); child1->setZValue(1.); child2->setZValue(0.); child3->setZValue(-1.); @@ -1274,7 +1261,7 @@ void tst_QTouchEvent::deleteInEventHandler() child2->deleteInTouchUpdate = true; child3->deleteInTouchEnd = true; - scene.addItem(root); + scene.addItem(root.data()); view.resize(200, 200); view.fitInView(scene.sceneRect()); @@ -1302,71 +1289,75 @@ void tst_QTouchEvent::deleteInEventHandler() Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - bool res; child1->weakpointer = &child1; touchBeginEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && !child1); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(!child1); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && !child1); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); // Qt 5.X ignores touch events. + QVERIFY(!child1); touchEndEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && !child1); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(!child1); child2->weakpointer = &child2; touchBeginEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && child2); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(child2); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res && !touchUpdateEvent.isAccepted() && !child2); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(!child2); touchEndEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res && !touchUpdateEvent.isAccepted() && !child2); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(!child2); child3->weakpointer = &child3; - res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && child3); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res && !touchUpdateEvent.isAccepted() && child3); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res && !touchEndEvent.isAccepted() && !child3); - - delete root; + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(child3); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(child3); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); + QVERIFY(!touchEndEvent.isAccepted()); + QVERIFY(!child3); } } void tst_QTouchEvent::deleteInRawEventTranslation() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 300, 300); - tst_QTouchEventWidget *leftWidget = new tst_QTouchEventWidget; - leftWidget->setParent(&touchWidget); + QPointer leftWidget = new tst_QTouchEventWidget(&touchWidget); leftWidget->setAttribute(Qt::WA_AcceptTouchEvents); leftWidget->setGeometry(0, 100, 100, 100); leftWidget->deleteInTouchBegin = true; - leftWidget->show(); - tst_QTouchEventWidget *centerWidget = new tst_QTouchEventWidget; - centerWidget->setParent(&touchWidget); + QPointer centerWidget = new tst_QTouchEventWidget(&touchWidget); centerWidget->setAttribute(Qt::WA_AcceptTouchEvents); centerWidget->setGeometry(100, 100, 100, 100); centerWidget->deleteInTouchUpdate = true; - centerWidget->show(); - tst_QTouchEventWidget *rightWidget = new tst_QTouchEventWidget; - rightWidget->setParent(&touchWidget); + QPointer rightWidget = new tst_QTouchEventWidget(&touchWidget); rightWidget->setAttribute(Qt::WA_AcceptTouchEvents); rightWidget->setGeometry(200, 100, 100, 100); rightWidget->deleteInTouchEnd = true; - rightWidget->show(); + + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); QPointF leftPos = leftWidget->rect().center(); QPointF centerPos = centerWidget->rect().center(); @@ -1374,9 +1365,7 @@ void tst_QTouchEvent::deleteInRawEventTranslation() QPointF leftScreenPos = leftWidget->mapToGlobal(leftPos.toPoint()); QPointF centerScreenPos = centerWidget->mapToGlobal(centerPos.toPoint()); QPointF rightScreenPos = rightWidget->mapToGlobal(rightPos.toPoint()); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); - - QPointer pl = leftWidget, pc = centerWidget, pr = rightWidget; + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QList rawTouchPoints; rawTouchPoints.append(QTouchEvent::TouchPoint(0)); @@ -1398,7 +1387,9 @@ void tst_QTouchEvent::deleteInRawEventTranslation() touchScreenDevice, touchPointList(rawTouchPoints)); QCoreApplication::processEvents(); - QVERIFY(pl.isNull() && !pc.isNull() && !pr.isNull()); + QVERIFY(leftWidget.isNull()); + QVERIFY(!centerWidget.isNull()); + QVERIFY(!rightWidget.isNull()); // generate update events on all widget, the center widget should die rawTouchPoints[0].setState(Qt::TouchPointMoved); @@ -1455,14 +1446,13 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() { QGraphicsScene scene; QGraphicsView view(&scene); - tst_QTouchEventGraphicsItem *root; - root = new tst_QTouchEventGraphicsItem; + QScopedPointer root(new tst_QTouchEventGraphicsItem); root->setAcceptTouchEvents(true); - scene.addItem(root); + scene.addItem(root.data()); - QGraphicsWidget *glassWidget = new QGraphicsWidget; + QScopedPointer glassWidget(new QGraphicsWidget); glassWidget->setMinimumSize(100, 100); - scene.addItem(glassWidget); + scene.addItem(glassWidget.data()); view.resize(200, 200); view.show(); @@ -1498,17 +1488,13 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() QCOMPARE(root->touchBeginCounter, 0); QCOMPARE(root->touchUpdateCounter, 0); QCOMPARE(root->touchEndCounter, 0); - - - delete root; - delete glassWidget; } class WindowTouchEventFilter : public QObject { Q_OBJECT public: - bool eventFilter(QObject *obj, QEvent *event); + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; struct TouchInfo { QList points; QEvent::Type lastSeenType; @@ -1537,18 +1523,18 @@ void tst_QTouchEvent::testQGuiAppDelivery() device->setType(QTouchDevice::TouchScreen); QWindowSystemInterface::registerTouchDevice(device); - QWindow *w = new QWindow; - w->setGeometry(100, 100, 100, 100); - w->show(); - QVERIFY(QTest::qWaitForWindowExposed(w)); + QWindow w; + w.setGeometry(100, 100, 100, 100); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); WindowTouchEventFilter filter; - w->installEventFilter(&filter); + w.installEventFilter(&filter); QList points; // Pass empty list, should be ignored. - QWindowSystemInterface::handleTouchEvent(w, 0, points); + QWindowSystemInterface::handleTouchEvent(&w, 0, points); QCoreApplication::processEvents(); QCOMPARE(filter.d.isEmpty(), true); @@ -1559,12 +1545,12 @@ void tst_QTouchEvent::testQGuiAppDelivery() points.append(tp); // Pass 0 as device, should be ignored. - QWindowSystemInterface::handleTouchEvent(w, 0, points); + QWindowSystemInterface::handleTouchEvent(&w, 0, points); QCoreApplication::processEvents(); QCOMPARE(filter.d.isEmpty(), true); // Now the real thing. - QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchBegin + QWindowSystemInterface::handleTouchEvent(&w, device, points); // TouchBegin QCoreApplication::processEvents(); QCOMPARE(filter.d.count(), 1); QCOMPARE(filter.d.contains(device), true); @@ -1572,7 +1558,7 @@ void tst_QTouchEvent::testQGuiAppDelivery() QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchBegin); points[0].state = Qt::TouchPointMoved; - QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchUpdate + QWindowSystemInterface::handleTouchEvent(&w, device, points); // TouchUpdate QCoreApplication::processEvents(); QCOMPARE(filter.d.count(), 1); QCOMPARE(filter.d.contains(device), true); @@ -1580,7 +1566,7 @@ void tst_QTouchEvent::testQGuiAppDelivery() QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchUpdate); points[0].state = Qt::TouchPointReleased; - QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchEnd + QWindowSystemInterface::handleTouchEvent(&w, device, points); // TouchEnd QCoreApplication::processEvents(); QCOMPARE(filter.d.count(), 1); QCOMPARE(filter.d.contains(device), true); @@ -1597,13 +1583,13 @@ void tst_QTouchEvent::testMultiDevice() deviceTwo->setType(QTouchDevice::TouchScreen); QWindowSystemInterface::registerTouchDevice(deviceTwo); - QWindow *w = new QWindow; - w->setGeometry(100, 100, 100, 100); - w->show(); - QVERIFY(QTest::qWaitForWindowExposed(w)); + QWindow w; + w.setGeometry(100, 100, 100, 100); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); WindowTouchEventFilter filter; - w->installEventFilter(&filter); + w.installEventFilter(&filter); QList pointsOne, pointsTwo; @@ -1620,8 +1606,8 @@ void tst_QTouchEvent::testMultiDevice() tp.area = QRectF(140, 140, 20, 20); pointsTwo.append(tp); - QWindowSystemInterface::handleTouchEvent(w, deviceOne, pointsOne); - QWindowSystemInterface::handleTouchEvent(w, deviceTwo, pointsTwo); + QWindowSystemInterface::handleTouchEvent(&w, deviceOne, pointsOne); + QWindowSystemInterface::handleTouchEvent(&w, deviceTwo, pointsTwo); QCoreApplication::processEvents(); QCOMPARE(filter.d.contains(deviceOne), true); -- cgit v1.2.3 From 21ec751cdcf2f5aa4c14a040edbe26b0cb3b2540 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Tue, 26 May 2015 10:45:57 +0100 Subject: Remove unsafe random seeding fallback path. OpenSSL should automatically seed the random number generator, and the current fallback code does not offer strong guarantees. It should never actually be used, so let's remove it entirely. Change-Id: I9a0a70345fe8df5913871bcac644623b687aea01 Reviewed-by: Peter Hartmann --- src/network/ssl/qsslsocket_openssl.cpp | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 00e13e449b..0bb153516c 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -494,30 +494,8 @@ bool QSslSocketPrivate::ensureLibraryLoaded() // Initialize OpenSSL's random seed. if (!q_RAND_status()) { - struct { - int msec; - int sec; - void *stack; - } randomish; - - int attempts = 500; - do { - if (attempts < 500) { -#ifdef Q_OS_UNIX - struct timespec ts = {0, 33333333}; - nanosleep(&ts, 0); -#else - Sleep(3); -#endif - randomish.msec = attempts; - } - randomish.stack = (void *)&randomish; - randomish.msec = QTime::currentTime().msec(); - randomish.sec = QTime::currentTime().second(); - q_RAND_seed((const char *)&randomish, sizeof(randomish)); - } while (!q_RAND_status() && --attempts); - if (!attempts) - return false; + qWarning("Random number generator not seeded, disabling SSL support"); + return false; } } return true; -- cgit v1.2.3 From a7a0b741c57e0990373f18b7862799e5f6f032b7 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 12 May 2015 17:01:22 +0200 Subject: Remove unused call indirection The global variable is a left over from when there was an MMX assembler implementation, and is now just making the compiler's job harder. Change-Id: I686704b64a2f8c68ec8ca83f2ac3e465ded773e0 Reviewed-by: Konstantin Ritt Reviewed-by: Gunnar Sletta Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/gui/painting/qimagescale.cpp | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 5f1b25e189..84b574dd34 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -38,22 +38,6 @@ QT_BEGIN_NAMESPACE -typedef void (*qt_qimageScaleFunc)(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -static void qt_qimageScaleAARGB(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -static void qt_qimageScaleAARGBA(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -qt_qimageScaleFunc qt_qimageScaleArgb = qt_qimageScaleAARGBA; -qt_qimageScaleFunc qt_qimageScaleRgb = qt_qimageScaleAARGB; - - /* * Copyright (C) 2004, 2005 Daniel M. Duley * @@ -794,11 +778,11 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh) } if (src.hasAlphaChannel()) - qt_qimageScaleArgb(scaleinfo, (unsigned int *)buffer.scanLine(0), - 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); + qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0), + 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); else - qt_qimageScaleRgb(scaleinfo, (unsigned int *)buffer.scanLine(0), - 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); + qt_qimageScaleAARGB(scaleinfo, (unsigned int *)buffer.scanLine(0), + 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); qimageFreeScaleInfo(scaleinfo); return buffer; -- cgit v1.2.3 From 455653d77f274ffd16e7fa3198ef719162a26a71 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 12 May 2015 17:07:25 +0200 Subject: Combine x and y oriented sample helpers The range sampling operates the same in both directions just with different step-sizes, so the code can be unduplicated, Change-Id: I47805a7e925d4058f62c558ef08e79485915e937 Reviewed-by: Gunnar Sletta --- src/gui/painting/qimagescale.cpp | 136 +++++++++++----------------------- src/gui/painting/qimagescale_sse4.cpp | 42 ++++------- 2 files changed, 58 insertions(+), 120 deletions(-) diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 84b574dd34..9b4eabc552 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -99,13 +99,6 @@ using namespace QImageScale; // Code ported from Imlib... // -// FIXME: replace with qRed, etc... These work on pointers to pixels, not -// pixel values -#define A_VAL(p) (qAlpha(*p)) -#define R_VAL(p) (qRed(*p)) -#define G_VAL(p) (qGreen(*p)) -#define B_VAL(p) (qBlue(*p)) - const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh) { @@ -365,46 +358,25 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, } } -inline static void qt_qimageScaleAARGBA_helper_x(const unsigned int *pix, int xap, int Cx, int &r, int &g, int &b, int &a) +inline static void qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, int &r, int &g, int &b, int &a) { - r = R_VAL(pix) * xap; - g = G_VAL(pix) * xap; - b = B_VAL(pix) * xap; - a = A_VAL(pix) * xap; + r = qRed(*pix) * xyap; + g = qGreen(*pix) * xyap; + b = qBlue(*pix) * xyap; + a = qAlpha(*pix) * xyap; int j; - for (j = (1 << 14) - xap; j > Cx; j -= Cx ){ - pix++; - r += R_VAL(pix) * Cx; - g += G_VAL(pix) * Cx; - b += B_VAL(pix) * Cx; - a += A_VAL(pix) * Cx; - } - pix++; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - a += A_VAL(pix) * j; -} - -inline static void qt_qimageScaleAARGBA_helper_y(const unsigned int *pix, int yap, int Cy, int sow, int &r, int &g, int &b, int &a) -{ - r = R_VAL(pix) * yap; - g = G_VAL(pix) * yap; - b = B_VAL(pix) * yap; - a = A_VAL(pix) * yap; - int j; - for (j = (1 << 14) - yap; j > Cy; j -= Cy ){ - pix += sow; - r += R_VAL(pix) * Cy; - g += G_VAL(pix) * Cy; - b += B_VAL(pix) * Cy; - a += A_VAL(pix) * Cy; - } - pix += sow; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - a += A_VAL(pix) * j; + for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) { + pix += step; + r += qRed(*pix) * Cxy; + g += qGreen(*pix) * Cxy; + b += qBlue(*pix) * Cxy; + a += qAlpha(*pix) * Cxy; + } + pix += step; + r += qRed(*pix) * j; + g += qGreen(*pix) * j; + b += qBlue(*pix) * j; + a += qAlpha(*pix) * j; } static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, @@ -427,12 +399,12 @@ static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b, a; - qt_qimageScaleAARGBA_helper_y(sptr, yap, Cy, sow, r, g, b, a); + qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, r, g, b, a); int xap = xapoints[x]; if (xap > 0) { int rr, gg, bb, aa; - qt_qimageScaleAARGBA_helper_y(sptr + 1, yap, Cy, sow, rr, gg, bb, aa); + qt_qimageScaleAARGBA_helper(sptr + 1, yap, Cy, sow, rr, gg, bb, aa); r = r * (256 - xap); g = g * (256 - xap); @@ -468,12 +440,12 @@ static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b, a; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, r, g, b, a); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, r, g, b, a); int yap = yapoints[dyy + y]; if (yap > 0) { int rr, gg, bb, aa; - qt_qimageScaleAARGBA_helper_x(sptr + sow, xap, Cx, rr, gg, bb, aa); + qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa); r = r * (256 - yap); g = g * (256 - yap); @@ -512,7 +484,7 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int rx, gx, bx, ax; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); int r = ((rx>>4) * yap); int g = ((gx>>4) * yap); @@ -522,14 +494,14 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); r += ((rx>>4) * Cy); g += ((gx>>4) * Cy); b += ((bx>>4) * Cy); a += ((ax>>4) * Cy); } sptr += sow; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); r += ((rx>>4) * j); g += ((gx>>4) * j); @@ -593,40 +565,22 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, } -inline static void qt_qimageScaleAARGB_helper_x(const unsigned int *pix, int xap, int Cx, int &r, int &g, int &b) +inline static void qt_qimageScaleAARGB_helper(const unsigned int *pix, int xyap, int Cxy, int step, int &r, int &g, int &b) { - r = R_VAL(pix) * xap; - g = G_VAL(pix) * xap; - b = B_VAL(pix) * xap; + r = qRed(*pix) * xyap; + g = qGreen(*pix) * xyap; + b = qBlue(*pix) * xyap; int j; - for (j = (1 << 14) - xap; j > Cx; j -= Cx ){ - pix++; - r += R_VAL(pix) * Cx; - g += G_VAL(pix) * Cx; - b += B_VAL(pix) * Cx; - } - pix++; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; -} - -inline static void qt_qimageScaleAARGB_helper_y(const unsigned int *pix, int yap, int Cy, int sow, int &r, int &g, int &b) -{ - r = R_VAL(pix) * yap; - g = G_VAL(pix) * yap; - b = B_VAL(pix) * yap; - int j; - for (j = (1 << 14) - yap; j > Cy; j -= Cy ){ - pix += sow; - r += R_VAL(pix) * Cy; - g += G_VAL(pix) * Cy; - b += B_VAL(pix) * Cy; - } - pix += sow; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; + for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) { + pix += step; + r += qRed(*pix) * Cxy; + g += qGreen(*pix) * Cxy; + b += qBlue(*pix) * Cxy; + } + pix += step; + r += qRed(*pix) * j; + g += qGreen(*pix) * j; + b += qBlue(*pix) * j; } static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, @@ -649,12 +603,12 @@ static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int * for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b; - qt_qimageScaleAARGB_helper_y(sptr, yap, Cy, sow, r, g, b); + qt_qimageScaleAARGB_helper(sptr, yap, Cy, sow, r, g, b); int xap = xapoints[x]; if (xap > 0) { int rr, bb, gg; - qt_qimageScaleAARGB_helper_y(sptr + 1, yap, Cy, sow, rr, gg, bb); + qt_qimageScaleAARGB_helper(sptr + 1, yap, Cy, sow, rr, gg, bb); r = r * (256 - xap); g = g * (256 - xap); @@ -688,12 +642,12 @@ static void qt_qimageScaleAARGB_down_x_up_y(QImageScaleInfo *isi, unsigned int * const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, r, g, b); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, r, g, b); int yap = yapoints[dyy + y]; if (yap > 0) { int rr, bb, gg; - qt_qimageScaleAARGB_helper_x(sptr + sow, xap, Cx, rr, gg, bb); + qt_qimageScaleAARGB_helper(sptr + sow, xap, Cx, 1, rr, gg, bb); r = r * (256 - yap); g = g * (256 - yap); @@ -729,7 +683,7 @@ static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int rx, gx, bx; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); int r = (rx >> 4) * yap; int g = (gx >> 4) * yap; @@ -738,14 +692,14 @@ static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); r += (rx >> 4) * Cy; g += (gx >> 4) * Cy; b += (bx >> 4) * Cy; } sptr += sow; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); r += (rx >> 4) * j; g += (gx >> 4) * j; diff --git a/src/gui/painting/qimagescale_sse4.cpp b/src/gui/painting/qimagescale_sse4.cpp index 565ea4daa1..303e0fd980 100644 --- a/src/gui/painting/qimagescale_sse4.cpp +++ b/src/gui/painting/qimagescale_sse4.cpp @@ -41,33 +41,17 @@ QT_BEGIN_NAMESPACE using namespace QImageScale; -inline static __m128i qt_qimageScaleAARGBA_helper_x(const unsigned int *pix, int xap, int Cx, const __m128i vxap, const __m128i vCx) +inline static __m128i qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, const __m128i vxyap, const __m128i vCxy) { __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - __m128i vx = _mm_mullo_epi32(vpix, vxap); + __m128i vx = _mm_mullo_epi32(vpix, vxyap); int i; - for (i = (1 << 14) - xap; i > Cx; i -= Cx) { - pix++; + for (i = (1 << 14) - xyap; i > Cxy; i -= Cxy) { + pix += step; vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCx)); + vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCxy)); } - pix++; - vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i))); - return vx; -} - -inline static __m128i qt_qimageScaleAARGBA_helper_y(const unsigned int *pix, int yap, int Cy, int sow, const __m128i vyap, const __m128i vCy) -{ - __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - __m128i vx = _mm_mullo_epi32(vpix, vyap); - int i; - for (i = (1 << 14) - yap; i > Cy; i -= Cy) { - pix += sow; - vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCy)); - } - pix += sow; + pix += step; vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i))); return vx; @@ -97,13 +81,13 @@ void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *d unsigned int *dptr = dest + dx + ((y + dy) * dow); for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_y(sptr, yap, Cy, sow, vyap, vCy); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, vyap, vCy); int xap = xapoints[x]; if (xap > 0) { const __m128i vxap = _mm_set1_epi32(xap); const __m128i vinvxap = _mm_sub_epi32(v256, vxap); - __m128i vr = qt_qimageScaleAARGBA_helper_y(sptr + 1, yap, Cy, sow, vyap, vCy); + __m128i vr = qt_qimageScaleAARGBA_helper(sptr + 1, yap, Cy, sow, vyap, vCy); vx = _mm_mullo_epi32(vx, vinvxap); vr = _mm_mullo_epi32(vr, vxap); @@ -145,13 +129,13 @@ void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *d const __m128i vxap = _mm_set1_epi32(xap); const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); int yap = yapoints[dyy + y]; if (yap > 0) { const __m128i vyap = _mm_set1_epi32(yap); const __m128i vinvyap = _mm_sub_epi32(v256, vyap); - __m128i vr = qt_qimageScaleAARGBA_helper_x(sptr + sow, xap, Cx, vxap, vCx); + __m128i vr = qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1, vxap, vCx); vx = _mm_mullo_epi32(vx, vinvyap); vr = _mm_mullo_epi32(vr, vyap); @@ -194,17 +178,17 @@ void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest, const __m128i vxap = _mm_set1_epi32(xap); const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); __m128i vr = _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vyap); int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vCy)); } sptr += sow; - vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), _mm_set1_epi32(j))); vr = _mm_srli_epi32(vr, 24); -- cgit v1.2.3 From 5b739a5b8cfbbedd9265b192d08b346d9b265590 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 29 May 2015 12:21:21 +0200 Subject: Revert "Android: Don't show translucent system UI on top of Qt" This reverts commit c9aaa3e2cde5ffe5edaa4f17f84020d82609b7e9. This fix broke fullscreen mode on Android. A better solution is in the works, but we'll probably push that to Qt 5.5.1 instead since it comes with a risk and we don't want to delay the release any further. Change-Id: I3aae6d52ebb8425089cdb6f7fc4c8ce9ad4911df Task-number: QTBUG-38700 Task-number: QTBUG-46234 Reviewed-by: BogDan Vatra --- .../qtproject/qt5/android/QtActivityDelegate.java | 25 +--------------------- src/android/templates/AndroidManifest.xml | 4 ---- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 73140839cc..d6cd49f44c 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -65,7 +65,6 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; -import android.widget.LinearLayout; import java.io.BufferedReader; import java.io.DataOutputStream; @@ -789,29 +788,7 @@ public class QtActivityDelegate 0, 0, metrics.xdpi, metrics.ydpi, metrics.scaledDensity); } - - ViewGroup layout = null; m_layout = new QtLayout(m_activity); - if (Build.VERSION.SDK_INT >= 14) { - try { - ActivityInfo activityInfo = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), - PackageManager.GET_META_DATA); - if (activityInfo.metaData == null - || !activityInfo.metaData.containsKey("android.app.allow_overlapping_system_ui") - || !activityInfo.metaData.getBoolean("android.app.allow_overlapping_system_ui")) { - layout = new LinearLayout(m_activity); - layout.setFitsSystemWindows(true); - layout.addView(m_layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (layout == null) - layout = m_layout; - m_editText = new QtEditText(m_activity, this); m_imm = (InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE); m_surfaces = new HashMap(); @@ -834,7 +811,7 @@ public class QtActivityDelegate Log.w("Qt A11y", "Unknown exception: " + e.toString()); } - m_activity.setContentView(layout, + m_activity.setContentView(m_layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index 779612cdaf..60c612976f 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -44,10 +44,6 @@ signal is sent! --> - - - - -- cgit v1.2.3 From fda08f3971e854ad1623fb99212746143c27e412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Wed, 27 May 2015 11:20:57 +0100 Subject: QHash: Add a findNode() overload that doesn't calculate hash Needed for QSet::intersects() for optimization purposes. No need to calculate the hash when we already have it. Change-Id: I247602bb0558ca8d1fb8333de9d5f339146c576d Reviewed-by: Marc Mutz Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qhash.h | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index c4c8c8f3cc..3d713146fe 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -451,6 +451,7 @@ private: void detach_helper(); void freeData(QHashData *d); Node **findNode(const Key &key, uint *hp = 0) const; + Node **findNode(const Key &key, uint h) const; Node *createNode(uint h, const Key &key, const T &value, Node **nextNode); void deleteNode(Node *node); static void deleteNode2(QHashData::Node *node); @@ -846,17 +847,10 @@ Q_INLINE_TEMPLATE bool QHash::contains(const Key &akey) const } template -Q_OUTOFLINE_TEMPLATE typename QHash::Node **QHash::findNode(const Key &akey, - uint *ahp) const +Q_OUTOFLINE_TEMPLATE typename QHash::Node **QHash::findNode(const Key &akey, uint h) const { Node **node; - uint h = 0; - if (d->numBuckets || ahp) { - h = qHash(akey, d->seed); - if (ahp) - *ahp = h; - } if (d->numBuckets) { node = reinterpret_cast(&d->buckets[h % d->numBuckets]); Q_ASSERT(*node == e || (*node)->next); @@ -868,6 +862,20 @@ Q_OUTOFLINE_TEMPLATE typename QHash::Node **QHash::findNode(cons return node; } +template +Q_OUTOFLINE_TEMPLATE typename QHash::Node **QHash::findNode(const Key &akey, + uint *ahp) const +{ + uint h = 0; + + if (d->numBuckets || ahp) { + h = qHash(akey, d->seed); + if (ahp) + *ahp = h; + } + return findNode(akey, h); +} + template Q_OUTOFLINE_TEMPLATE bool QHash::operator==(const QHash &other) const { -- cgit v1.2.3 From 9eff0dd19d6507ec400f036dd27efe960e4e5f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Mon, 25 May 2015 18:32:35 +0100 Subject: QSet: Introduce intersects(). The pattern "mySet.intersect(other).isEmpty()" has been spotted in the wild and in Qt codebase. intersects() is much cheaper because it bails out as soon as we find one common item and doesn't do any allocations. [ChangeLog][QtCore][QSet] Added intersects(). Change-Id: I44a350dc4cdb9deb835a23eee99fc99d6ca24c82 Reviewed-by: Marc Mutz --- src/corelib/tools/qhash.h | 1 + src/corelib/tools/qset.h | 30 ++++++++++++++++++++++++++++++ src/corelib/tools/qset.qdoc | 12 +++++++++++- tests/auto/corelib/tools/qset/tst_qset.cpp | 27 +++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 3d713146fe..2080a22e23 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -353,6 +353,7 @@ public: class const_iterator { friend class iterator; + friend class QSet; QHashData::Node *i; public: diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index e4688711d6..5a9c75fe07 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -137,6 +137,7 @@ public: typedef QHash Hash; typename Hash::const_iterator i; friend class iterator; + friend class QSet; public: typedef std::bidirectional_iterator_tag iterator_category; @@ -191,6 +192,7 @@ public: inline const_iterator constFind(const T &value) const { return find(value); } QSet &unite(const QSet &other); QSet &intersect(const QSet &other); + bool intersects(const QSet &other) const; QSet &subtract(const QSet &other); // STL compatibility @@ -283,6 +285,34 @@ Q_INLINE_TEMPLATE QSet &QSet::intersect(const QSet &other) return *this; } +template +Q_INLINE_TEMPLATE bool QSet::intersects(const QSet &other) const +{ + const bool otherIsBigger = other.size() > size(); + const QSet &smallestSet = otherIsBigger ? *this : other; + const QSet &biggestSet = otherIsBigger ? other : *this; + const bool equalSeeds = q_hash.d->seed == other.q_hash.d->seed; + typename QSet::const_iterator i = smallestSet.cbegin(); + typename QSet::const_iterator e = smallestSet.cend(); + + if (Q_LIKELY(equalSeeds)) { + // If seeds are equal we take the fast path so no hash is recalculated. + while (i != e) { + if (*biggestSet.q_hash.findNode(*i, i.i.i->h) != biggestSet.q_hash.e) + return true; + ++i; + } + } else { + while (i != e) { + if (biggestSet.contains(*i)) + return true; + ++i; + } + } + + return false; +} + template Q_INLINE_TEMPLATE QSet &QSet::subtract(const QSet &other) { diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc index 94cfa729f5..c4f33deed6 100644 --- a/src/corelib/tools/qset.qdoc +++ b/src/corelib/tools/qset.qdoc @@ -490,7 +490,17 @@ Removes all items from this set that are not contained in the \a other set. A reference to this set is returned. - \sa operator&=(), unite(), subtract() + \sa intersects(), operator&=(), unite(), subtract() +*/ + +/*! + \fn bool QSet::intersects(const QSet &other) const + \since 5.6 + + Returns \c true if this set has at least one item in common with + \a other. + + \sa contains(), intersect() */ /*! diff --git a/tests/auto/corelib/tools/qset/tst_qset.cpp b/tests/auto/corelib/tools/qset/tst_qset.cpp index f13d69514a..ef0ebabd66 100644 --- a/tests/auto/corelib/tools/qset/tst_qset.cpp +++ b/tests/auto/corelib/tools/qset/tst_qset.cpp @@ -73,6 +73,7 @@ private slots: void makeSureTheComfortFunctionsCompile(); void initializerList(); void qhash(); + void intersects(); }; struct IdentityTracker { @@ -1030,6 +1031,32 @@ void tst_QSet::qhash() } } +void tst_QSet::intersects() +{ + QSet s1; + QSet s2; + + QVERIFY(!s1.intersects(s1)); + QVERIFY(!s1.intersects(s2)); + + s1 << 100; + QVERIFY(s1.intersects(s1)); + QVERIFY(!s1.intersects(s2)); + + s2 << 200; + QVERIFY(!s1.intersects(s2)); + + s1 << 200; + QVERIFY(s1.intersects(s2)); + + const QtQHashSeedSaver seedSaver(0x10101010); + QSet s3; + s3 << 500; + QVERIFY(!s1.intersects(s3)); + s3 << 200; + QVERIFY(s1.intersects(s3)); +} + QTEST_APPLESS_MAIN(tst_QSet) #include "tst_qset.moc" -- cgit v1.2.3 From 71c85c554a49ed3a17167e436630ddaff2b9fcb1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 29 May 2015 12:39:24 +0200 Subject: moc: Fix crash parsing invalid macro invocation When invoking a macro with less argument than it expect, we would crash trying to access the vector of arguments from the invocation as we are trying to substitute an argument. (Note that we do not show an error in case of argument mismatch because ithat might happen parsing valid code as moc's c++ parser is not 100% accurate (that was QTBUG-29331)) Task-number: QTBUG-46210 Change-Id: I3f08d7f5049e593a5bdc02a594ea63cadf66e7a4 Reviewed-by: Gabriel de Dietrich --- src/tools/moc/preprocessor.cpp | 8 +++++--- tests/auto/tools/moc/tst_moc.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 51873033c7..f253c49995 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -661,8 +661,10 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym expansion += s; } } else if (mode == Hash) { - if (index < 0) + if (index < 0 || index >= arguments.size()) { that->error("'#' is not followed by a macro parameter"); + continue; + } const Symbols &arg = arguments.at(index); QByteArray stringified; @@ -681,7 +683,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym expansion.pop_back(); Symbol next = s; - if (index >= 0) { + if (index >= 0 && index < arguments.size()) { const Symbols &arg = arguments.at(index); if (arg.size() == 0) { mode = Normal; @@ -703,7 +705,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym expansion += next; } - if (index >= 0) { + if (index >= 0 && index < arguments.size()) { const Symbols &arg = arguments.at(index); for (int i = 1; i < arg.size(); ++i) expansion += arg.at(i); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 8bef678af9..350c6142d2 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1882,6 +1882,13 @@ void tst_Moc::warnings_data() << 1 << QString() << QString("standard input:5: Error: Class declaration lacks Q_OBJECT macro."); + + QTest::newRow("QTBUG-46210: crash on invalid macro") + << QByteArray("#define Foo(a, b, c) a b c #a #b #c a##b##c #d\n Foo(45);") + << QStringList() + << 1 + << QString("IGNORE_ALL_STDOUT") + << QString(":2: Error: '#' is not followed by a macro parameter"); } void tst_Moc::warnings() -- cgit v1.2.3 From 45751d0ea3c4325f8f8c33969015763b5b897e77 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 18 May 2015 10:52:06 +0200 Subject: Fix combobox regression 5.4 -> 5.5 To avoid a touch release outside the combobox triggering the popup, a check was added that the combobox was hit. This fails if the combox itself is only used for the popup and associated behavior, but does not exist as widget. This patch changes the check so that only touch release checks for a hit, but a generic click still behaves as in 5.4 to avoid regressions. This fixes comboboxes no longer working in QtWebKit, since QtWebKit renders its own comboxes in webpages, and only uses the popup of the QComboBox. Task-number: QTBUG-46152 Change-Id: I74fd57b2e42e77aa4a269d812ca4a6689f254889 Reviewed-by: Florian Bruhin Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qcombobox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 76f923904d..ef80e359df 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -3034,7 +3034,7 @@ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e) QStyle::SubControl sc = q->style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, e->pos(), q); if (e->button() == Qt::LeftButton - && sc != QStyle::SC_None + && !(sc == QStyle::SC_None && e->type() == QEvent::MouseButtonRelease) && (sc == QStyle::SC_ComboBoxArrow || !q->isEditable()) && !viewContainer()->isVisible()) { if (sc == QStyle::SC_ComboBoxArrow) -- cgit v1.2.3 From 87d57d19941fba4a921020480ca5761f23536c93 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 21 Feb 2014 15:15:29 +0100 Subject: Fix users of QTextLayout::additionalFormats to use the new API QTextLayout::additionalFormats setters and getters using QList have been deprecated; port to the QVector versions. Moved op== definition for FormatRange needed in tst_qsyntaxhighlighter.cpp to a friend declaration in FormatRange itself, because MSVC 2008 doesn't find it otherwise. Change-Id: Ibab6589df057f02377d895079b56395859e3401e Reviewed-by: Konstantin Ritt --- src/gui/painting/qpainter.cpp | 4 +-- src/gui/text/qsyntaxhighlighter.cpp | 8 +++--- src/gui/text/qtextdocument.cpp | 2 +- src/gui/text/qtextlayout.cpp | 4 +-- src/gui/text/qtextlayout.h | 5 ++++ src/widgets/graphicsview/qgraphicsitem.cpp | 4 +-- src/widgets/widgets/qwidgetlinecontrol.cpp | 6 ++--- src/widgets/widgets/qwidgettextcontrol.cpp | 6 ++--- .../qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp | 31 ++++++++-------------- tests/benchmarks/gui/text/qtext/main.cpp | 14 +++++----- 10 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 973c9da96c..c17ea9c878 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7441,7 +7441,7 @@ start_lengthVariant: } } - QList underlineFormats; + QVector underlineFormats; int length = offset - old_offset; if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) { QChar *cout = text.data() + old_offset; @@ -7515,7 +7515,7 @@ start_lengthVariant: engine.forceJustification = true; QTextLayout textLayout(&engine); textLayout.setCacheEnabled(true); - textLayout.setAdditionalFormats(underlineFormats); + textLayout.setFormats(underlineFormats); if (finalText.isEmpty()) { height = fm.height(); diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp index 162c646a98..f180a839b7 100644 --- a/src/gui/text/qsyntaxhighlighter.cpp +++ b/src/gui/text/qsyntaxhighlighter.cpp @@ -90,13 +90,13 @@ void QSyntaxHighlighterPrivate::applyFormatChanges() QTextLayout *layout = currentBlock.layout(); - QList ranges = layout->additionalFormats(); + QVector ranges = layout->formats(); const int preeditAreaStart = layout->preeditAreaPosition(); const int preeditAreaLength = layout->preeditAreaText().length(); if (preeditAreaLength != 0) { - QList::Iterator it = ranges.begin(); + QVector::Iterator it = ranges.begin(); while (it != ranges.end()) { if (it->start >= preeditAreaStart && it->start + it->length <= preeditAreaStart + preeditAreaLength) { @@ -142,7 +142,7 @@ void QSyntaxHighlighterPrivate::applyFormatChanges() } if (formatsChanged) { - layout->setAdditionalFormats(ranges); + layout->setFormats(ranges); doc->markContentsDirty(currentBlock.position(), currentBlock.length()); } } @@ -329,7 +329,7 @@ void QSyntaxHighlighter::setDocument(QTextDocument *doc) QTextCursor cursor(d->doc); cursor.beginEditBlock(); for (QTextBlock blk = d->doc->begin(); blk.isValid(); blk = blk.next()) - blk.layout()->clearAdditionalFormats(); + blk.layout()->clearFormats(); cursor.endEditBlock(); } d->doc = doc; diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index d3b70aaf26..3d248f4afc 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1949,7 +1949,7 @@ void QTextDocument::print(QPagedPaintDevice *printer) const for (QTextBlock srcBlock = firstBlock(), dstBlock = clonedDoc->firstBlock(); srcBlock.isValid() && dstBlock.isValid(); srcBlock = srcBlock.next(), dstBlock = dstBlock.next()) { - dstBlock.layout()->setAdditionalFormats(srcBlock.layout()->additionalFormats()); + dstBlock.layout()->setFormats(srcBlock.layout()->formats()); } QAbstractTextDocumentLayout *layout = doc->documentLayout(); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index dabe06fa88..c42054c07c 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -69,7 +69,7 @@ QT_BEGIN_NAMESPACE for a specified area in the text layout's content. \inmodule QtGui - \sa QTextLayout::setAdditionalFormats(), QTextLayout::draw() + \sa QTextLayout::setFormats(), QTextLayout::draw() */ /*! @@ -541,7 +541,7 @@ QVector QTextLayout::formats() const */ void QTextLayout::clearAdditionalFormats() { - setAdditionalFormats(QList()); + clearFormats(); } /*! diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index ce092e0928..9709af4fd1 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -125,6 +125,11 @@ public: int start; int length; QTextCharFormat format; + + friend bool operator==(const FormatRange &lhs, const FormatRange &rhs) + { return lhs.start == rhs.start && lhs.length == rhs.length && lhs.format == rhs.format; } + friend bool operator!=(const FormatRange &lhs, const FormatRange &rhs) + { return !operator==(lhs, rhs); } }; void setAdditionalFormats(const QList &overrides); QList additionalFormats() const; diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index cd30410097..d0a16690e6 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -10829,9 +10829,9 @@ void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphic range.start = 0; range.length = layout.text().length(); range.format.setTextOutline(d->pen); - QList formats; + QVector formats; formats.append(range); - layout.setAdditionalFormats(formats); + layout.setFormats(formats); } setupTextLayout(&layout); diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index 759e41a5fa..3cd0277f77 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -189,7 +189,7 @@ void QWidgetLineControl::commitPreedit() m_preeditCursor = 0; setPreeditArea(-1, QString()); - m_textLayout.clearAdditionalFormats(); + m_textLayout.clearFormats(); updateDisplayText(/*force*/ true); #endif } @@ -557,7 +557,7 @@ void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event) const int oldPreeditCursor = m_preeditCursor; m_preeditCursor = event->preeditString().length(); m_hideCursor = false; - QList formats; + QVector formats; for (int i = 0; i < event->attributes().size(); ++i) { const QInputMethodEvent::Attribute &a = event->attributes().at(i); if (a.type == QInputMethodEvent::Cursor) { @@ -574,7 +574,7 @@ void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event) } } } - m_textLayout.setAdditionalFormats(formats); + m_textLayout.setFormats(formats); updateDisplayText(/*force*/ true); if (cursorPositionChanged) emitCursorPositionChanged(); diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 53b2406fc1..a46abf374d 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -2029,7 +2029,7 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) QTextLayout *layout = block.layout(); if (isGettingInput) layout->setPreeditArea(cursor.position() - block.position(), e->preeditString()); - QList overrides; + QVector overrides; const int oldPreeditCursor = preeditCursor; preeditCursor = e->preeditString().length(); hideCursor = false; @@ -2049,7 +2049,7 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) } } } - layout->setAdditionalFormats(overrides); + layout->setFormats(overrides); cursor.endEditBlock(); @@ -2878,7 +2878,7 @@ void QWidgetTextControlPrivate::commitPreedit() QTextBlock block = cursor.block(); QTextLayout *layout = block.layout(); layout->setPreeditArea(-1, QString()); - layout->clearAdditionalFormats(); + layout->clearFormats(); cursor.endEditBlock(); } diff --git a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp index 014ed4c7c8..c0b0738e2a 100644 --- a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp +++ b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp @@ -120,7 +120,7 @@ void tst_QSyntaxHighlighter::cleanup() class TestHighlighter : public QSyntaxHighlighter { public: - inline TestHighlighter(const QList &fmts, QTextDocument *parent) + inline TestHighlighter(const QVector &fmts, QTextDocument *parent) : QSyntaxHighlighter(parent), formats(fmts), highlighted(false), callCount(0) {} inline TestHighlighter(QObject *parent) : QSyntaxHighlighter(parent) {} @@ -138,24 +138,15 @@ public: ++callCount; } - QList formats; + QVector formats; bool highlighted; int callCount; QString highlightedText; }; -QT_BEGIN_NAMESPACE -bool operator==(const QTextLayout::FormatRange &lhs, const QTextLayout::FormatRange &rhs) -{ - return lhs.start == rhs.start - && lhs.length == rhs.length - && lhs.format == rhs.format; -} -QT_END_NAMESPACE - void tst_QSyntaxHighlighter::basic() { - QList formats; + QVector formats; QTextLayout::FormatRange range; range.start = 0; range.length = 2; @@ -179,7 +170,7 @@ void tst_QSyntaxHighlighter::basic() QVERIFY(hl->highlighted); QVERIFY(lout->documentChangedCalled); - QVERIFY(doc->begin().layout()->additionalFormats() == formats); + QVERIFY(doc->begin().layout()->formats() == formats); } class CommentTestHighlighter : public QSyntaxHighlighter @@ -222,7 +213,7 @@ void tst_QSyntaxHighlighter::basicTwo() void tst_QSyntaxHighlighter::removeFormatsOnDelete() { - QList formats; + QVector formats; QTextLayout::FormatRange range; range.start = 0; range.length = 9; @@ -237,9 +228,9 @@ void tst_QSyntaxHighlighter::removeFormatsOnDelete() QVERIFY(lout->documentChangedCalled); lout->documentChangedCalled = false; - QVERIFY(!doc->begin().layout()->additionalFormats().isEmpty()); + QVERIFY(!doc->begin().layout()->formats().isEmpty()); delete hl; - QVERIFY(doc->begin().layout()->additionalFormats().isEmpty()); + QVERIFY(doc->begin().layout()->formats().isEmpty()); QVERIFY(lout->documentChangedCalled); } @@ -405,7 +396,7 @@ void tst_QSyntaxHighlighter::highlightToEndOfDocument2() void tst_QSyntaxHighlighter::preservePreeditArea() { - QList formats; + QVector formats; QTextLayout::FormatRange range; range.start = 0; range.length = 8; @@ -432,12 +423,12 @@ void tst_QSyntaxHighlighter::preservePreeditArea() hl->callCount = 0; cursor.beginEditBlock(); - layout->setAdditionalFormats(formats); + layout->setFormats(formats); cursor.endEditBlock(); QCOMPARE(hl->callCount, 1); - formats = layout->additionalFormats(); + formats = layout->formats(); QCOMPARE(formats.count(), 3); range = formats.at(0); @@ -483,7 +474,7 @@ void tst_QSyntaxHighlighter::avoidUnnecessaryRehighlight() void tst_QSyntaxHighlighter::noContentsChangedDuringHighlight() { - QList formats; + QVector formats; QTextLayout::FormatRange range; range.start = 0; range.length = 10; diff --git a/tests/benchmarks/gui/text/qtext/main.cpp b/tests/benchmarks/gui/text/qtext/main.cpp index 224d9619ec..f20b3f6cce 100644 --- a/tests/benchmarks/gui/text/qtext/main.cpp +++ b/tests/benchmarks/gui/text/qtext/main.cpp @@ -42,7 +42,7 @@ #include #include -Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QVector) class tst_QText: public QObject { @@ -324,13 +324,13 @@ void tst_QText::layout() void tst_QText::formattedLayout_data() { QTest::addColumn("text"); - QTest::addColumn >("ranges"); + QTest::addColumn >("ranges"); QTextCharFormat format; format.setForeground(QColor("steelblue")); { - QList ranges; + QVector ranges; QTextLayout::FormatRange formatRange; formatRange.format = format; @@ -341,7 +341,7 @@ void tst_QText::formattedLayout_data() QTest::newRow("short-single") << m_shortLorem << ranges; } { - QList ranges; + QVector ranges; QString text = m_lorem.repeated(100); const int width = 1; @@ -360,15 +360,15 @@ void tst_QText::formattedLayout_data() void tst_QText::formattedLayout() { QFETCH(QString, text); - QFETCH(QList, ranges); + QFETCH(QVector, ranges); QTextLayout layout(text); - layout.setAdditionalFormats(ranges); + layout.setFormats(ranges); setupTextLayout(&layout); QBENCHMARK { QTextLayout layout(text); - layout.setAdditionalFormats(ranges); + layout.setFormats(ranges); setupTextLayout(&layout); } } -- cgit v1.2.3 From 88875becb78a06f9192f15fd0aaef1ac80f810c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sat, 30 May 2015 10:28:10 +0100 Subject: QStateMachine: Use QSet::intersects() instead of QSet::intersect() It's much faster. Change-Id: I2b5024259cfa993775aafea56a898d5d15eed347 Reviewed-by: Marc Mutz --- src/corelib/statemachine/qstatemachine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 3d2da77390..a8d07602b6 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -506,7 +506,7 @@ void QStateMachinePrivate::removeConflictingTransitions(QList exitSetT2 = computeExitSet_Unordered(QList() << t2); - if (exitSetT1.intersect(exitSetT2).isEmpty()) { + if (!exitSetT1.intersects(exitSetT2)) { // No conflict, no cry. Next patient please. ++t2It; } else { -- cgit v1.2.3 From 5335e6a558a0aa8b86b9c564f91c6ec10380c7af Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 21 Feb 2014 15:18:55 +0100 Subject: QWidget{Text,Line}Control: reserve() a vector Reduces reallocation overhead. Change-Id: Ibbb5d6257f78e7f9668b8c7f17aa498f6d4994d3 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Lars Knoll Reviewed-by: Gunnar Sletta Reviewed-by: Konstantin Ritt --- src/widgets/widgets/qwidgetlinecontrol.cpp | 1 + src/widgets/widgets/qwidgettextcontrol.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index 3cd0277f77..436937be72 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -558,6 +558,7 @@ void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event) m_preeditCursor = event->preeditString().length(); m_hideCursor = false; QVector formats; + formats.reserve(event->attributes().size()); for (int i = 0; i < event->attributes().size(); ++i) { const QInputMethodEvent::Attribute &a = event->attributes().at(i); if (a.type == QInputMethodEvent::Cursor) { diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index a46abf374d..22d199fc74 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -2030,6 +2030,7 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) if (isGettingInput) layout->setPreeditArea(cursor.position() - block.position(), e->preeditString()); QVector overrides; + overrides.reserve(e->attributes().size()); const int oldPreeditCursor = preeditCursor; preeditCursor = e->preeditString().length(); hideCursor = false; -- cgit v1.2.3 From 1d8b6597a36f266c3384553365326cf7ec9f8641 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 21 Feb 2014 15:18:00 +0100 Subject: QGraphicsWidget: micro-optimization Pass a temporary QVector instead of a named variable. Apart from less function calls, it also makes the code C++11-ready (enables move semantics). Change-Id: Ia7d3bed8aeae48453f96dc3c979f7ae394a5a26d Reviewed-by: Konstantin Ritt Reviewed-by: Simon Hausmann --- src/widgets/graphicsview/qgraphicsitem.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index d0a16690e6..1fdbe0fc18 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -10829,9 +10829,7 @@ void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphic range.start = 0; range.length = layout.text().length(); range.format.setTextOutline(d->pen); - QVector formats; - formats.append(range); - layout.setFormats(formats); + layout.setFormats(QVector(1, range)); } setupTextLayout(&layout); -- cgit v1.2.3 From 218e6cc6c9b4d4c54dce74ee5a65bb44c9f93b11 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 29 May 2015 12:48:33 +0200 Subject: Fix subpixel rendered text in QGLWidget Subpixel rendered text doesn't work in the old OpenGL paint engine because it assumes the glyphs are returned in RGB32 format, when they may be in ARGB32. This patch changes the test of the returned format to just check for 32bit matching the logic in the new OpenGL paint engine. Change-Id: Ib5b784dedba51cf22f216e2f035361518610b96b Reviewed-by: Laszlo Agocs --- src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 637c375311..9a1ae6e008 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -304,19 +304,23 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub for (int x = 0; x < maskWidth; ++x) src[x] = -src[x]; // convert 0 and 1 into 0 and 255 } - } else if (mask.format() == QImage::Format_RGB32) { + } else if (mask.depth() == 32) { // Make the alpha component equal to the average of the RGB values. // This is needed when drawing sub-pixel antialiased text on translucent targets. for (int y = 0; y < maskHeight; ++y) { quint32 *src = (quint32 *) mask.scanLine(y); for (int x = 0; x < maskWidth; ++x) { - uchar r = src[x] >> 16; - uchar g = src[x] >> 8; - uchar b = src[x]; - quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding. + int r = qRed(src[x]); + int g = qGreen(src[x]); + int b = qBlue(src[x]); + int avg; + if (mask.format() == QImage::Format_RGB32) + avg = (r + g + b + 1) / 3; // "+1" for rounding. + else // Format_ARGB_Premultiplied + avg = qAlpha(src[x]); if (ctx->contextHandle()->isOpenGLES()) { // swizzle the bits to accommodate for the GL_RGBA upload. - src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16); + src[x] = (avg << 24) | (r << 0) | (g << 8) | (b << 16); } else { src[x] = (src[x] & 0x00ffffff) | (avg << 24); } @@ -325,7 +329,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub } funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); - if (mask.format() == QImage::Format_RGB32) { + if (mask.depth() == 32) { GLenum format = GL_RGBA; #if !defined(QT_OPENGL_ES_2) if (!ctx->contextHandle()->isOpenGLES()) -- cgit v1.2.3 From 60f4d5165a6533e48deedd9f2a7d021ce0f5bc11 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 1 Jun 2015 00:39:08 +0200 Subject: src/gui/text/text.pri: add missing header qabstracttextdocumentlayout_p.h Change-Id: Ia825ef6d932fbd45ceaf8c54a3207f207fa40994 Reviewed-by: Konstantin Ritt Reviewed-by: Simon Hausmann --- src/gui/text/text.pri | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 087927549f..be60ba72cc 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -21,6 +21,7 @@ HEADERS += \ text/qtextdocument_p.h \ text/qtexthtmlparser_p.h \ text/qabstracttextdocumentlayout.h \ + text/qabstracttextdocumentlayout_p.h \ text/qtextdocumentlayout_p.h \ text/qtextcursor.h \ text/qtextcursor_p.h \ -- cgit v1.2.3 From 4ca16e99e7163802d85d6deb42ecac72413e7b1f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 26 May 2015 22:16:25 +0200 Subject: QAbstractTextDocumentLayoutPrivate: declare dtor out-of-line and export class De-duplicates vtables and enables RTTI on this class hierarchy. Export, as QPlainTextDocumentLayoutPrivate (QtWidgets) inherits it. Change-Id: I8aee43b43898a72430d8bc1247ea76c7d4e9031d Reported-by: Volker Krause Task-number: QTBUG-45582 Reviewed-by: Konstantin Ritt Reviewed-by: Simon Hausmann --- src/gui/text/qabstracttextdocumentlayout.cpp | 4 ++++ src/gui/text/qabstracttextdocumentlayout_p.h | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp index 70be92535d..8d2da46ab3 100644 --- a/src/gui/text/qabstracttextdocumentlayout.cpp +++ b/src/gui/text/qabstracttextdocumentlayout.cpp @@ -40,6 +40,10 @@ QT_BEGIN_NAMESPACE +QAbstractTextDocumentLayoutPrivate::~QAbstractTextDocumentLayoutPrivate() +{ +} + /*! \class QAbstractTextDocumentLayout \reentrant diff --git a/src/gui/text/qabstracttextdocumentlayout_p.h b/src/gui/text/qabstracttextdocumentlayout_p.h index 505135fa4b..a7f28ebf96 100644 --- a/src/gui/text/qabstracttextdocumentlayout_p.h +++ b/src/gui/text/qabstracttextdocumentlayout_p.h @@ -58,13 +58,14 @@ struct QTextObjectHandler }; typedef QHash HandlerHash; -class QAbstractTextDocumentLayoutPrivate : public QObjectPrivate +class Q_GUI_EXPORT QAbstractTextDocumentLayoutPrivate : public QObjectPrivate { public: Q_DECLARE_PUBLIC(QAbstractTextDocumentLayout) inline QAbstractTextDocumentLayoutPrivate() : paintDevice(0) {} + ~QAbstractTextDocumentLayoutPrivate(); inline void setDocument(QTextDocument *doc) { document = doc; -- cgit v1.2.3 From 2d7004c58752eda813496fcf8a7d2582e956ba5e Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 29 May 2015 10:26:03 +0200 Subject: configure: Show only LGPLv3 for WinRT & WinCE With Qt 5.5 we are changing the license of the Qt for the WinRT & WinCE ports to LGPLv3 / GPLv2+ / commercial. Change-Id: I221559c5c42b1dcda172eb85e6bfa53c91976b23 Reviewed-by: Oswald Buddenhagen --- tools/configure/configureapp.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index faeb45417b..3bf0546ac1 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -4388,7 +4388,9 @@ bool Configure::showLicense(QString orgLicenseFile) QString licenseFile = orgLicenseFile; QString theLicense; if (dictionary["EDITION"] == "OpenSource") { - if (platform() != ANDROID || dictionary["ANDROID_STYLE_ASSETS"] == "no") { + if (platform() != WINDOWS_RT + && platform() != WINDOWS_CE + && (platform() != ANDROID || dictionary["ANDROID_STYLE_ASSETS"] == "no")) { theLicense = "GNU Lesser General Public License (LGPL) version 2.1" "\nor the GNU Lesser General Public License (LGPL) version 3"; } else { -- cgit v1.2.3 From 53d289ec4c0f512a3475da4bbf1f940cd6838ace Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 27 Mar 2015 11:51:02 +0100 Subject: xcb: Use XIGrabDevice instead of xcb_grab_pointer with XI 2.2 Switch to using the pointer events from XI2 when touch is available (i.e. version is >= 2.2). This allows us to select and grab the button and motion events together with the touch ones. This prevents the issue of not getting touch events when grabbing via the plain xcb functions. To prevent touch sequences from being replayed after ungrabbing (for example after dismissing a popup that caused a grab), we try to accept touches via XIAllowTouchEvents. Unfortunately this leads to a deadlock and therefore we can only do it when we know we have a new enough libXi. This is a configure time check which is not ideal since the system on which apps run can have a newer libXi than the machine that did the Qt build, but seems like the best we can do. The environment variable QT_XCB_NO_XI2_MOUSE can be set to 1 in order to prevent processing mouse events through XInput. This restores the old behavior with broken grabbing. [ChangeLog][QtGui] Pointer event delivery on X11 is now done via XInput 2.2+ when available. Done-with: Michal Klocek Done-with: Alexander Volkov Task-number: QTBUG-43525 Task-number: QTBUG-45054 Task-number: QTBUG-30417 Change-Id: I7cb2002b31bef4cd527aa427549dcf2d5467968e Reviewed-by: Laszlo Agocs Reviewed-by: Shawn Rutledge --- configure | 8 + src/plugins/platforms/xcb/qxcbconnection.cpp | 79 ++--- src/plugins/platforms/xcb/qxcbconnection.h | 35 +- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 433 +++++++++++++++-------- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 31 ++ src/plugins/platforms/xcb/qxcbkeyboard.h | 1 + src/plugins/platforms/xcb/qxcbwindow.cpp | 126 +++++-- src/plugins/platforms/xcb/qxcbwindow.h | 10 + src/plugins/platforms/xcb/xcb_qpa_lib.pro | 5 + 9 files changed, 501 insertions(+), 227 deletions(-) diff --git a/configure b/configure index de0a1bd5d7..7251e8e673 100755 --- a/configure +++ b/configure @@ -5358,6 +5358,14 @@ fi # auto-detect XInput2 support if [ "$CFG_XINPUT2" != "no" ]; then if compileTest x11/xinput2 "XInput2"; then + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists xi 2>/dev/null; then + QMAKE_LIBXI_VERSION_MAJOR=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 1` + QMAKE_LIBXI_VERSION_MINOR=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 2` + QMAKE_LIBXI_VERSION_PATCH=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 3` + QMakeVar set QMAKE_LIBXI_VERSION_MAJOR "$QMAKE_LIBXI_VERSION_MAJOR" + QMakeVar set QMAKE_LIBXI_VERSION_MINOR "$QMAKE_LIBXI_VERSION_MINOR" + QMakeVar set QMAKE_LIBXI_VERSION_PATCH "$QMAKE_LIBXI_VERSION_PATCH" + fi CFG_XINPUT2=yes CFG_XINPUT=no else diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 92d064df9b..80c844e658 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -70,7 +70,6 @@ #endif #if defined(XCB_USE_XINPUT2) -#include #include #endif @@ -457,6 +456,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra , m_focusWindow(0) , m_systemTrayTracker(0) , m_glIntegration(Q_NULLPTR) + , m_xiGrab(false) { #ifdef XCB_USE_XLIB Display *dpy = XOpenDisplay(m_displayName.constData()); @@ -909,7 +909,7 @@ static Qt::MouseButtons translateMouseButtons(int s) return ret; } -static Qt::MouseButton translateMouseButton(xcb_button_t s) +Qt::MouseButton QXcbConnection::translateMouseButton(xcb_button_t s) { switch (s) { case 1: return Qt::LeftButton; @@ -944,39 +944,6 @@ static Qt::MouseButton translateMouseButton(xcb_button_t s) } } -void QXcbConnection::handleButtonPress(xcb_generic_event_t *ev) -{ - xcb_button_press_event_t *event = (xcb_button_press_event_t *)ev; - - // the event explicitly contains the state of the three first buttons, - // the rest we need to manage ourselves - m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); - m_buttons |= translateMouseButton(event->detail); - qCDebug(lcQpaXInput, "xcb: pressed mouse button %d, button state %X", event->detail, static_cast(m_buttons)); -} - -void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev) -{ - xcb_button_release_event_t *event = (xcb_button_release_event_t *)ev; - - // the event explicitly contains the state of the three first buttons, - // the rest we need to manage ourselves - m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); - m_buttons &= ~translateMouseButton(event->detail); - qCDebug(lcQpaXInput, "xcb: released mouse button %d, button state %X", event->detail, static_cast(m_buttons)); -} - -void QXcbConnection::handleMotionNotify(xcb_generic_event_t *ev) -{ - xcb_motion_notify_event_t *event = (xcb_motion_notify_event_t *)ev; - - m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); -#ifdef Q_XCB_DEBUG - qCDebug(lcQpaXInput, "xcb: moved mouse to %4d, %4d; button state %X", - event->event_x, event->event_y, static_cast(m_buttons)); -#endif -} - #ifndef QT_NO_XKB namespace { typedef union { @@ -1018,18 +985,35 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) switch (response_type) { case XCB_EXPOSE: HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent); - case XCB_BUTTON_PRESS: - m_keyboard->updateXKBStateFromCore(((xcb_button_press_event_t *)event)->state); - handleButtonPress(event); + + // press/release/motion is only delivered here when XI 2.2+ is _not_ in use + case XCB_BUTTON_PRESS: { + xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; + m_keyboard->updateXKBStateFromCore(ev->state); + // the event explicitly contains the state of the three first buttons, + // the rest we need to manage ourselves + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); + m_buttons |= translateMouseButton(ev->detail); + qCDebug(lcQpaXInput, "legacy mouse press, button %d state %X", ev->detail, static_cast(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent); - case XCB_BUTTON_RELEASE: - m_keyboard->updateXKBStateFromCore(((xcb_button_release_event_t *)event)->state); - handleButtonRelease(event); + } + case XCB_BUTTON_RELEASE: { + xcb_button_release_event_t *ev = (xcb_button_release_event_t *)event; + m_keyboard->updateXKBStateFromCore(ev->state); + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); + m_buttons &= ~translateMouseButton(ev->detail); + qCDebug(lcQpaXInput, "legacy mouse release, button %d state %X", ev->detail, static_cast(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); - case XCB_MOTION_NOTIFY: - m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state); - handleMotionNotify(event); + } + case XCB_MOTION_NOTIFY: { + xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event; + m_keyboard->updateXKBStateFromCore(ev->state); + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); + qCDebug(lcQpaXInput, "legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y, + ev->detail, static_cast(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent); + } + case XCB_CONFIGURE_NOTIFY: HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent); case XCB_MAP_NOTIFY: @@ -1090,6 +1074,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) break; #if defined(XCB_USE_XINPUT2) case XCB_GE_GENERIC: + // Here the windowEventListener is invoked from xi2HandleEvent() if (m_xi2Enabled) xi2HandleEvent(reinterpret_cast(event)); break; @@ -1931,6 +1916,12 @@ void QXcbConnection::initializeXKB() #endif } +bool QXcbConnection::xi2MouseEvents() const +{ + static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE"); + return mouseViaXI2; +} + #if defined(XCB_USE_XINPUT2) static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index e4274eca4d..2005ae0701 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -69,7 +69,8 @@ #endif #endif struct XInput2TouchDeviceData; -#endif +#endif // XCB_USE_XINPUT2 + struct xcb_randr_get_output_info_reply_t; //#define Q_XCB_DEBUG @@ -347,6 +348,7 @@ public: virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {} virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {} virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {} + virtual void handleXIMouseEvent(xcb_ge_event_t *) {} virtual QXcbWindow *toWindow() { return 0; } }; @@ -413,14 +415,14 @@ public: void xi2Select(xcb_window_t window); #endif #ifdef XCB_USE_XINPUT21 - bool isUsingXInput21() const { return m_xi2Enabled && m_xi2Minor >= 1; } + bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; } #else - bool isUsingXInput21() const { return false; } + bool isAtLeastXI21() const { return false; } #endif #ifdef XCB_USE_XINPUT22 - bool isUsingXInput22() const { return m_xi2Enabled && m_xi2Minor >= 2; } + bool isAtLeastXI22() const { return m_xi2Enabled && m_xi2Minor >= 2; } #else - bool isUsingXInput22() const { return false; } + bool isAtLeastXI22() const { return false; } #endif void sync(); @@ -457,7 +459,9 @@ public: xcb_timestamp_t getTimestamp(); + void setButton(Qt::MouseButton button, bool down) { if (down) m_buttons |= button; else m_buttons &= ~button; } Qt::MouseButtons buttons() const { return m_buttons; } + Qt::MouseButton translateMouseButton(xcb_button_t s); QXcbWindow *focusWindow() const { return m_focusWindow; } void setFocusWindow(QXcbWindow *); @@ -477,11 +481,19 @@ public: void handleEnterEvent(const xcb_enter_notify_event_t *); #endif +#ifdef XCB_USE_XINPUT22 + bool xi2SetMouseGrabEnabled(xcb_window_t w, bool grab); +#endif + Qt::MouseButton xiToQtMouseButton(uint32_t b); + QXcbEventReader *eventReader() const { return m_reader; } bool canGrab() const { return m_canGrabServer; } QXcbGlIntegration *glIntegration() const { return m_glIntegration; } + + bool xi2MouseEvents() const; + protected: bool event(QEvent *e) Q_DECL_OVERRIDE; @@ -509,9 +521,6 @@ private: bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output); void initializeScreens(); void updateScreens(const xcb_randr_notify_event_t *event); - void handleButtonPress(xcb_generic_event_t *event); - void handleButtonRelease(xcb_generic_event_t *event); - void handleMotionNotify(xcb_generic_event_t *event); bool m_xi2Enabled; int m_xi2Minor; @@ -524,6 +533,9 @@ private: void xi2HandleHierachyEvent(void *event); void xi2HandleDeviceChangedEvent(void *event); int m_xiOpCode, m_xiEventBase, m_xiErrorBase; +#ifdef XCB_USE_XINPUT22 + void xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow); +#endif // XCB_USE_XINPUT22 #ifndef QT_NO_TABLETEVENT struct TabletData { TabletData() : deviceId(0), pointerType(QTabletEvent::UnknownPointer), @@ -543,10 +555,10 @@ private: }; QHash valuatorInfo; }; - bool xi2HandleTabletEvent(void *event, TabletData *tabletData); + bool xi2HandleTabletEvent(void *event, TabletData *tabletData, QXcbWindowEventListener *eventListener); void xi2ReportTabletEvent(TabletData &tabletData, void *event); QVector m_tabletData; -#endif +#endif // !QT_NO_TABLETEVENT struct ScrollingDevice { ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { } int deviceId; @@ -559,9 +571,7 @@ private: void updateScrollingDevice(ScrollingDevice& scrollingDevice, int num_classes, void *classes); void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice); QHash m_scrollingDevices; -#endif // XCB_USE_XINPUT2 -#if defined(XCB_USE_XINPUT2) static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value); static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode); #endif @@ -633,6 +643,7 @@ private: QByteArray m_startupId; QXcbSystemTrayTracker *m_systemTrayTracker; QXcbGlIntegration *m_glIntegration; + bool m_xiGrab; friend class QXcbEventReader; }; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 1848fc14f0..0e8a162a7d 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -275,34 +275,37 @@ void QXcbConnection::xi2Select(xcb_window_t window) unsigned char *xiBitMask = reinterpret_cast(&bitMask); #ifdef XCB_USE_XINPUT22 - if (isUsingXInput22()) { + if (isAtLeastXI22()) { bitMask |= XI_TouchBeginMask; bitMask |= XI_TouchUpdateMask; bitMask |= XI_TouchEndMask; + bitMask |= XI_PropertyEventMask; // for tablets + if (xi2MouseEvents()) { + // We want both mouse and touch through XI2 if touch is supported (>= 2.2). + // The plain xcb press and motion events will not be delivered after this. + bitMask |= XI_ButtonPressMask; + bitMask |= XI_ButtonReleaseMask; + bitMask |= XI_MotionMask; + qCDebug(lcQpaXInput, "XInput 2.2: Selecting press/release/motion events in addition to touch"); + } XIEventMask mask; mask.mask_len = sizeof(bitMask); mask.mask = xiBitMask; - if (!m_touchDevices.isEmpty()) { - // If we select for touch events on the master pointer, XInput2 - // will not synthesize mouse events. This means Qt must do it, - // which is also preferable, since Qt can control better when - // to do so. - mask.deviceid = XIAllMasterDevices; - Status result = XISelectEvents(xDisplay, window, &mask, 1); - if (result != Success) - qCDebug(lcQpaXInput, "XInput 2.2: failed to select touch events, window %x, result %d", window, result); - } + // When xi2MouseEvents() is true (the default), pointer emulation for touch and tablet + // events will get disabled. This is preferable for touch, as Qt Quick handles touch events + // directly while for others QtGui synthesizes mouse events, not so much for tablets. For + // the latter we will synthesize the events ourselves. + mask.deviceid = XIAllMasterDevices; + Status result = XISelectEvents(xDisplay, window, &mask, 1); + if (result != Success) + qCDebug(lcQpaXInput, "XInput 2.2: failed to select pointer/touch events, window %x, result %d", window, result); } #endif // XCB_USE_XINPUT22 + const bool pointerSelected = isAtLeastXI22() && xi2MouseEvents(); QSet tabletDevices; #ifndef QT_NO_TABLETEVENT - // For each tablet, select some additional event types. - // Press, motion, etc. events must never be selected for _all_ devices - // as that would render the standard XCB_MOTION_NOTIFY and - // similar handlers useless and we have no intention to infect - // all the pure xcb code with Xlib-based XI2. - if (!m_tabletData.isEmpty()) { + if (!m_tabletData.isEmpty() && !pointerSelected) { unsigned int tabletBitMask; unsigned char *xiTabletBitMask = reinterpret_cast(&tabletBitMask); QVector xiEventMask(m_tabletData.count()); @@ -323,7 +326,8 @@ void QXcbConnection::xi2Select(xcb_window_t window) #ifdef XCB_USE_XINPUT21 // Enable each scroll device - if (!m_scrollingDevices.isEmpty()) { + if (!m_scrollingDevices.isEmpty() && !pointerSelected) { + // Only when XI2 mouse events are not enabled, otherwise motion and release are selected already. QVector xiEventMask(m_scrollingDevices.size()); unsigned int scrollBitMask; unsigned char *xiScrollBitMask = reinterpret_cast(&scrollBitMask); @@ -425,7 +429,7 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) dev->size.width() > 10000 || dev->size.height() > 10000) dev->size = QSizeF(130, 110); } - if (!isUsingXInput22() || type == QTouchDevice::TouchPad) + if (!isAtLeastXI22() || type == QTouchDevice::TouchPad) caps |= QTouchDevice::MouseEmulation; if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) { @@ -447,7 +451,7 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) } #if defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT) -static qreal fixed1616ToReal(FP1616 val) +static inline qreal fixed1616ToReal(FP1616 val) { return qreal(val) / 0x10000; } @@ -468,155 +472,280 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) { if (xi2PrepareXIGenericDeviceEvent(event, m_xiOpCode)) { xXIGenericDeviceEvent *xiEvent = reinterpret_cast(event); + int sourceDeviceId = xiEvent->deviceid; // may be the master id + xXIDeviceEvent *xiDeviceEvent = 0; + QXcbWindowEventListener *eventListener = 0; - if (xiEvent->evtype == XI_HierarchyChanged) { + switch (xiEvent->evtype) { + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_Motion: + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: + { + xiDeviceEvent = reinterpret_cast(event); + eventListener = windowEventListenerFromId(xiDeviceEvent->event); + if (eventListener) { + long result = 0; + if (eventListener->handleGenericEvent(reinterpret_cast(event), &result)) + return; + } + sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master + break; + } + case XI_HierarchyChanged: xi2HandleHierachyEvent(xiEvent); return; - } - if (xiEvent->evtype == XI_DeviceChanged) { + case XI_DeviceChanged: xi2HandleDeviceChangedEvent(xiEvent); return; + default: + break; } #ifndef QT_NO_TABLETEVENT for (int i = 0; i < m_tabletData.count(); ++i) { - if (m_tabletData.at(i).deviceId == xiEvent->deviceid) { - if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i])) + if (m_tabletData.at(i).deviceId == sourceDeviceId) { + if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) return; } } #endif // QT_NO_TABLETEVENT #ifdef XCB_USE_XINPUT21 - QHash::iterator device = m_scrollingDevices.find(xiEvent->deviceid); + QHash::iterator device = m_scrollingDevices.find(sourceDeviceId); if (device != m_scrollingDevices.end()) xi2HandleScrollEvent(xiEvent, device.value()); #endif // XCB_USE_XINPUT21 #ifdef XCB_USE_XINPUT22 - if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) { - xXIDeviceEvent* xiDeviceEvent = reinterpret_cast(event); - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f", - event->event_type, xiEvent->sequenceNumber, xiDeviceEvent->detail, - fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y), - fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y) ); - - if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) { - XInput2TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid); - Q_ASSERT(dev); - const bool firstTouch = m_touchPoints.isEmpty(); - if (xiEvent->evtype == XI_TouchBegin) { - QWindowSystemInterface::TouchPoint tp; - tp.id = xiDeviceEvent->detail % INT_MAX; - tp.state = Qt::TouchPointPressed; - tp.pressure = -1.0; - m_touchPoints[tp.id] = tp; - } - QWindowSystemInterface::TouchPoint &touchPoint = m_touchPoints[xiDeviceEvent->detail]; - qreal x = fixed1616ToReal(xiDeviceEvent->root_x); - qreal y = fixed1616ToReal(xiDeviceEvent->root_y); - qreal nx = -1.0, ny = -1.0, d = 0.0; - QXcbScreen* screen = m_screens.at(0); - for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { - XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; - if (classinfo->type == XIValuatorClass) { - XIValuatorClassInfo *vci = reinterpret_cast(classinfo); - int n = vci->number; - double value; - if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value)) - continue; - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput, " valuator %20s value %lf from range %lf -> %lf", - atomName(vci->label).constData(), value, vci->min, vci->max ); - if (vci->label == atom(QXcbAtom::RelX)) { - nx = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::RelY)) { - ny = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsX)) { - nx = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsY)) { - ny = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsMTPositionX)) { - nx = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) { - ny = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) { - d = valuatorNormalized(value, vci) * screen->geometry().width(); - } else if (vci->label == atom(QXcbAtom::AbsMTPressure) || - vci->label == atom(QXcbAtom::AbsPressure)) { - touchPoint.pressure = valuatorNormalized(value, vci); - } - } - } - // If any value was not updated, use the last-known value. - if (nx == -1.0) { - x = touchPoint.area.center().x(); - nx = x / screen->geometry().width(); - } - if (ny == -1.0) { - y = touchPoint.area.center().y(); - ny = y / screen->geometry().height(); - } - if (xiEvent->evtype != XI_TouchEnd) { - if (d == 0.0) - d = touchPoint.area.width(); - } - - switch (xiEvent->evtype) { - case XI_TouchBegin: - if (firstTouch) { - dev->firstPressedPosition = QPointF(x, y); - dev->firstPressedNormalPosition = QPointF(nx, ny); - } - dev->pointPressedPosition.insert(touchPoint.id, QPointF(x, y)); - break; - case XI_TouchUpdate: - if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { - qreal dx = (nx - dev->firstPressedNormalPosition.x()) * - dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); - qreal dy = (ny - dev->firstPressedNormalPosition.y()) * - dev->size.height() * screen->geometry().height() / screen->physicalSize().height(); - x = dev->firstPressedPosition.x() + dx; - y = dev->firstPressedPosition.y() + dy; - touchPoint.state = Qt::TouchPointMoved; - } else if (touchPoint.area.center() != QPoint(x, y)) { - touchPoint.state = Qt::TouchPointMoved; - dev->pointPressedPosition[touchPoint.id] = QPointF(x, y); - } - break; - case XI_TouchEnd: - touchPoint.state = Qt::TouchPointReleased; - if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { - qreal dx = (nx - dev->firstPressedNormalPosition.x()) * - dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); - qreal dy = (ny - dev->firstPressedNormalPosition.y()) * - dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); - x = dev->firstPressedPosition.x() + dx; - y = dev->firstPressedPosition.y() + dy; - } - dev->pointPressedPosition.remove(touchPoint.id); - } - touchPoint.area = QRectF(x - d/2, y - d/2, d, d); - touchPoint.normalPosition = QPointF(nx, ny); + if (xiDeviceEvent) { + switch (xiDeviceEvent->evtype) { + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_Motion: + if (xi2MouseEvents() && eventListener) + eventListener->handleXIMouseEvent(event); + break; + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << - " area " << touchPoint.area << " pressure " << touchPoint.pressure; - QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiEvent->time, dev->qtTouchDevice, m_touchPoints.values()); - if (touchPoint.state == Qt::TouchPointReleased) - // If a touchpoint was released, we can forget it, because the ID won't be reused. - m_touchPoints.remove(touchPoint.id); - else - // Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent - // with this touch point if the next XI2 event is about a different touch point. - touchPoint.state = Qt::TouchPointStationary; + qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f on window %x", + event->event_type, xiDeviceEvent->sequenceNumber, xiDeviceEvent->detail, + fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y), + fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event); + if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) + xi2ProcessTouch(xiDeviceEvent, platformWindow); + break; } } #endif // XCB_USE_XINPUT22 } } +#ifdef XCB_USE_XINPUT22 +void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow) +{ + xXIDeviceEvent *xiDeviceEvent = static_cast(xiDevEvent); + XInput2TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid); + Q_ASSERT(dev); + const bool firstTouch = m_touchPoints.isEmpty(); + if (xiDeviceEvent->evtype == XI_TouchBegin) { + QWindowSystemInterface::TouchPoint tp; + tp.id = xiDeviceEvent->detail % INT_MAX; + tp.state = Qt::TouchPointPressed; + tp.pressure = -1.0; + m_touchPoints[tp.id] = tp; + } + QWindowSystemInterface::TouchPoint &touchPoint = m_touchPoints[xiDeviceEvent->detail]; + qreal x = fixed1616ToReal(xiDeviceEvent->root_x); + qreal y = fixed1616ToReal(xiDeviceEvent->root_y); + qreal nx = -1.0, ny = -1.0, d = 0.0; + QXcbScreen* screen = m_screens.at(0); + for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { + XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; + if (classinfo->type == XIValuatorClass) { + XIValuatorClassInfo *vci = reinterpret_cast(classinfo); + int n = vci->number; + double value; + if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value)) + continue; + if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) + qCDebug(lcQpaXInput, " valuator %20s value %lf from range %lf -> %lf", + atomName(vci->label).constData(), value, vci->min, vci->max ); + if (vci->label == atom(QXcbAtom::RelX)) { + nx = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::RelY)) { + ny = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsX)) { + nx = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsY)) { + ny = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsMTPositionX)) { + nx = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) { + ny = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) { + d = valuatorNormalized(value, vci) * screen->geometry().width(); + } else if (vci->label == atom(QXcbAtom::AbsMTPressure) || + vci->label == atom(QXcbAtom::AbsPressure)) { + touchPoint.pressure = valuatorNormalized(value, vci); + } + } + } + // If any value was not updated, use the last-known value. + if (nx == -1.0) { + x = touchPoint.area.center().x(); + nx = x / screen->geometry().width(); + } + if (ny == -1.0) { + y = touchPoint.area.center().y(); + ny = y / screen->geometry().height(); + } + if (xiDeviceEvent->evtype != XI_TouchEnd) { + if (d == 0.0) + d = touchPoint.area.width(); + } + + switch (xiDeviceEvent->evtype) { + case XI_TouchBegin: + if (firstTouch) { + dev->firstPressedPosition = QPointF(x, y); + dev->firstPressedNormalPosition = QPointF(nx, ny); + } + dev->pointPressedPosition.insert(touchPoint.id, QPointF(x, y)); + + // Touches must be accepted when we are grabbing touch events. Otherwise the entire sequence + // will get replayed when the grab ends. + if (m_xiGrab) { + // XIAllowTouchEvents deadlocks with libXi < 1.7.4 (this has nothing to do with the XI2 versions like 2.2) + // http://lists.x.org/archives/xorg-devel/2014-July/043059.html +#ifndef LIBXI_MAJOR + static bool allowTouchWarningShown = false; + if (!allowTouchWarningShown) { + allowTouchWarningShown = true; + qWarning("Skipping XIAllowTouchEvents() because it was not possible to detect libXi version at build time." + " Minimum libXi version required is 1.7.4." + " Expect issues with touch behavior."); + } +#elif LIBXI_MAJOR == 1 && (LIBXI_MINOR < 7 || (LIBXI_MINOR == 7 && LIBXI_PATCH < 4)) + static bool allowTouchWarningShown = false; + if (!allowTouchWarningShown) { + allowTouchWarningShown = true; + qWarning("Skipping XIAllowTouchEvents() due to not having libXi >= 1.7.4." + " libXi version at build time was %d.%d.%d." + " Expect issues with touch behavior.", LIBXI_MAJOR, LIBXI_MINOR, LIBXI_PATCH); + } +#else + XIAllowTouchEvents(static_cast(m_xlib_display), xiDeviceEvent->deviceid, + xiDeviceEvent->detail, xiDeviceEvent->event, XIAcceptTouch); +#endif + } + break; + case XI_TouchUpdate: + if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { + qreal dx = (nx - dev->firstPressedNormalPosition.x()) * + dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); + qreal dy = (ny - dev->firstPressedNormalPosition.y()) * + dev->size.height() * screen->geometry().height() / screen->physicalSize().height(); + x = dev->firstPressedPosition.x() + dx; + y = dev->firstPressedPosition.y() + dy; + touchPoint.state = Qt::TouchPointMoved; + } else if (touchPoint.area.center() != QPoint(x, y)) { + touchPoint.state = Qt::TouchPointMoved; + dev->pointPressedPosition[touchPoint.id] = QPointF(x, y); + } + break; + case XI_TouchEnd: + touchPoint.state = Qt::TouchPointReleased; + if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { + qreal dx = (nx - dev->firstPressedNormalPosition.x()) * + dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); + qreal dy = (ny - dev->firstPressedNormalPosition.y()) * + dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); + x = dev->firstPressedPosition.x() + dx; + y = dev->firstPressedPosition.y() + dy; + } + dev->pointPressedPosition.remove(touchPoint.id); + } + touchPoint.area = QRectF(x - d/2, y - d/2, d, d); + touchPoint.normalPosition = QPointF(nx, ny); + + if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) + qCDebug(lcQpaXInput) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << + " area " << touchPoint.area << " pressure " << touchPoint.pressure; + QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiDeviceEvent->time, dev->qtTouchDevice, m_touchPoints.values()); + if (touchPoint.state == Qt::TouchPointReleased) + // If a touchpoint was released, we can forget it, because the ID won't be reused. + m_touchPoints.remove(touchPoint.id); + else + // Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent + // with this touch point if the next XI2 event is about a different touch point. + touchPoint.state = Qt::TouchPointStationary; +} + +bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) +{ + if (grab && !canGrab()) + return false; + + int num_devices = 0; + Display *xDisplay = static_cast(xlib_display()); + XIDeviceInfo *info = XIQueryDevice(xDisplay, XIAllMasterDevices, &num_devices); + if (!info) + return false; + + XIEventMask evmask; + unsigned char mask[XIMaskLen(XI_LASTEVENT)]; + evmask.mask = mask; + evmask.mask_len = sizeof(mask); + memset(mask, 0, sizeof(mask)); + evmask.deviceid = XIAllMasterDevices; + + XISetMask(mask, XI_ButtonPress); + XISetMask(mask, XI_ButtonRelease); + XISetMask(mask, XI_Motion); + XISetMask(mask, XI_TouchBegin); + XISetMask(mask, XI_TouchUpdate); + XISetMask(mask, XI_TouchEnd); + + bool grabbed = true; + for (int i = 0; i < num_devices; i++) { + int id = info[i].deviceid, n = 0; + XIDeviceInfo *deviceInfo = XIQueryDevice(xDisplay, id, &n); + if (deviceInfo) { + const bool grabbable = deviceInfo->use != XIMasterKeyboard; + XIFreeDeviceInfo(deviceInfo); + if (!grabbable) + continue; + } + if (!grab) { + Status result = XIUngrabDevice(xDisplay, id, CurrentTime); + if (result != Success) { + grabbed = false; + qCDebug(lcQpaXInput, "XInput 2.2: failed to ungrab events for device %d (result %d)", id, result); + } + } else { + Status result = XIGrabDevice(xDisplay, id, w, CurrentTime, None, XIGrabModeAsync, + XIGrabModeAsync, False, &evmask); + if (result != Success) { + grabbed = false; + qCDebug(lcQpaXInput, "XInput 2.2: failed to grab events for device %d on window %x (result %d)", id, w, result); + } + } + } + + XIFreeDeviceInfo(info); + + m_xiGrab = grabbed; + + return grabbed; +} +#endif // XCB_USE_XINPUT22 + void QXcbConnection::xi2HandleHierachyEvent(void *event) { xXIHierarchyEvent *xiEvent = reinterpret_cast(event); @@ -785,7 +914,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin #endif // XCB_USE_XINPUT21 } -static Qt::MouseButton xiToQtMouseButton(uint32_t b) { +Qt::MouseButton QXcbConnection::xiToQtMouseButton(uint32_t b) +{ switch (b) { case 1: return Qt::LeftButton; case 2: return Qt::MiddleButton; @@ -832,20 +962,29 @@ static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) { } #ifndef QT_NO_TABLETEVENT -bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData) +bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, QXcbWindowEventListener *eventListener) { bool handled = true; Display *xDisplay = static_cast(m_xlib_display); xXIGenericDeviceEvent *xiEvent = static_cast(event); + xXIDeviceEvent *xiDeviceEvent = reinterpret_cast(xiEvent); + +#ifdef XCB_USE_XINPUT22 + // Synthesize mouse events since otherwise there are no mouse events from + // the pen on the XI 2.2+ path. + if (xi2MouseEvents() && eventListener) + eventListener->handleXIMouseEvent(reinterpret_cast(event)); +#endif + switch (xiEvent->evtype) { case XI_ButtonPress: { - Qt::MouseButton b = xiToQtMouseButton(reinterpret_cast(event)->detail); + Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail); tabletData->buttons |= b; xi2ReportTabletEvent(*tabletData, xiEvent); break; } case XI_ButtonRelease: { - Qt::MouseButton b = xiToQtMouseButton(reinterpret_cast(event)->detail); + Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail); tabletData->buttons ^= b; xi2ReportTabletEvent(*tabletData, xiEvent); break; @@ -908,7 +1047,7 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData) // TODO maybe have a hash of tabletData->deviceId to device data so we can // look up the tablet name here, and distinguish multiple tablets qCDebug(lcQpaXInput, "XI2 proximity change on tablet %d (USB %x): last tool: %x id %x current tool: %x id %x TabletDevice %d", - ev->deviceid, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID], + tabletData->deviceId, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID], ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], tabletData->tool); } XFree(data); @@ -972,7 +1111,7 @@ void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event) if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) qCDebug(lcQpaXInput, "XI2 event on tablet %d with tool %d type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf", - ev->deviceid, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail, + tabletData.deviceId, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail, fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y), fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y), (int)tabletData.buttons, pressure, xTilt, yTilt, rotation); diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 6a9ef5869e..2d96ed1c21 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -47,6 +47,12 @@ #include #include +#ifdef XCB_USE_XINPUT22 +#include +#undef KeyPress +#undef KeyRelease +#endif + #ifndef XK_ISO_Left_Tab #define XK_ISO_Left_Tab 0xFE20 #endif @@ -791,6 +797,31 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state) } } +void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo) +{ +#ifdef XCB_USE_XINPUT22 + if (m_config && !connection()->hasXKB()) { + xXIModifierInfo *mods = static_cast(modInfo); + xXIGroupInfo *group = static_cast(groupInfo); + const xkb_state_component newState = xkb_state_update_mask(xkb_state, + mods->base_mods, + mods->latched_mods, + mods->locked_mods, + group->base_group, + group->latched_group, + group->locked_group); + + if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { + //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); + } + } +#else + Q_UNUSED(modInfo); + Q_UNUSED(groupInfo); + Q_ASSERT(false); // this can't be +#endif +} + quint32 QXcbKeyboard::xkbModMask(quint16 state) { quint32 xkb_mask = 0; diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 2281674e2f..d2e37d624c 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -68,6 +68,7 @@ public: void updateXKBMods(); quint32 xkbModMask(quint16 state); void updateXKBStateFromCore(quint16 state); + void updateXKBStateFromXI(void *modInfo, void *groupInfo); #ifndef QT_NO_XKB // when XKEYBOARD is present on the X server int coreDeviceId() const { return core_device_id; } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 3188a7f19d..d1b688857d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -96,6 +96,7 @@ #if defined(XCB_USE_XINPUT2) #include +#include #endif #define XCOORD_MAX 16383 @@ -2106,16 +2107,17 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) } } -void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) +void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { - const bool isWheel = event->detail >= 4 && event->detail <= 7; + const bool isWheel = detail >= 4 && detail <= 7; if (!isWheel && window() != QGuiApplication::focusWindow()) { QWindow *w = static_cast(QObjectPrivate::get(window()))->eventReceiver(); if (!(w->flags() & Qt::WindowDoesNotAcceptFocus)) w->requestActivate(); } - updateNetWmUserTime(event->time); + updateNetWmUserTime(timestamp); if (m_embedded) { if (window() != QGuiApplication::focusWindow()) { @@ -2126,53 +2128,125 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) } } const int dpr = int(devicePixelRatio()); - QPoint local(event->event_x/dpr, event->event_y/dpr); - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); - - Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + QPoint local(event_x / dpr, event_y / dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); if (isWheel) { - if (!connection()->isUsingXInput21()) { + if (!connection()->isAtLeastXI21()) { // Logic borrowed from qapplication_x11.cpp - int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1); - bool hor = (((event->detail == 4 || event->detail == 5) + int delta = 120 * ((detail == 4 || detail == 6) ? 1 : -1); + bool hor = (((detail == 4 || detail == 5) && (modifiers & Qt::AltModifier)) - || (event->detail == 6 || event->detail == 7)); + || (detail == 6 || detail == 7)); - QWindowSystemInterface::handleWheelEvent(window(), event->time, + QWindowSystemInterface::handleWheelEvent(window(), timestamp, local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers); } return; } - handleMouseEvent(event->time, local, global, modifiers); + handleMouseEvent(timestamp, local, global, modifiers); } -void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event) +void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { const int dpr = int(devicePixelRatio()); - QPoint local(event->event_x/dpr, event->event_y/dpr); - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); - Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + QPoint local(event_x / dpr, event_y / dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); - if (event->detail >= 4 && event->detail <= 7) { + if (detail >= 4 && detail <= 7) { // mouse wheel, handled in handleButtonPressEvent() return; } - handleMouseEvent(event->time, local, global, modifiers); + handleMouseEvent(timestamp, local, global, modifiers); } -void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) +void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { - const int dpr = int(devicePixelRatio()); - QPoint local(event->event_x/dpr, event->event_y/dpr); if (!xcbScreen()) return; - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); + const int dpr = int(devicePixelRatio()); + QPoint local(event_x / dpr, event_y / dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); + handleMouseEvent(timestamp, local, global, modifiers); +} + +// Handlers for plain xcb events. Used only when XI 2.2 or newer is not available. +void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) +{ Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + handleButtonPressEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail, + modifiers, event->time); +} - handleMouseEvent(event->time, local, global, modifiers); +void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event) +{ + Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + handleButtonReleaseEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail, + modifiers, event->time); +} + +void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) +{ + Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers, event->time); +} + +#ifdef XCB_USE_XINPUT22 +static inline int fixed1616ToInt(FP1616 val) +{ + return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); +} +#endif + +// With XI 2.2+ press/release/motion comes here instead of the above handlers. +void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) +{ +#ifdef XCB_USE_XINPUT22 + QXcbConnection *conn = connection(); + xXIDeviceEvent *ev = reinterpret_cast(event); + const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods); + const int event_x = fixed1616ToInt(ev->event_x); + const int event_y = fixed1616ToInt(ev->event_y); + const int root_x = fixed1616ToInt(ev->root_x); + const int root_y = fixed1616ToInt(ev->root_y); + + conn->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group); + + const Qt::MouseButton button = conn->xiToQtMouseButton(ev->detail); + + if (ev->buttons_len > 0) { + unsigned char *buttonMask = (unsigned char *) &ev[1]; + for (int i = 1; i <= 15; ++i) + conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i)); + } + + switch (ev->evtype) { + case XI_ButtonPress: + qCDebug(lcQpaXInput, "XI2 mouse press, button %d", button); + conn->setButton(button, true); + handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time); + break; + case XI_ButtonRelease: + qCDebug(lcQpaXInput, "XI2 mouse release, button %d", button); + conn->setButton(button, false); + handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time); + break; + case XI_Motion: + qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d", event_x, event_y); + handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time); + break; + default: + qWarning() << "Unrecognized XI2 mouse event" << ev->evtype; + break; + } +#else + Q_UNUSED(event); + Q_ASSERT(false); // this can't be +#endif } QXcbWindow *QXcbWindow::toWindow() { return this; } @@ -2356,6 +2430,10 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab) bool QXcbWindow::setMouseGrabEnabled(bool grab) { +#ifdef XCB_USE_XINPUT22 + if (connection()->xi2MouseEvents()) + return connection()->xi2SetMouseGrabEnabled(m_window, grab); +#endif if (grab && !connection()->canGrab()) return false; diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 512bc54255..e62bfcba64 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -131,6 +131,7 @@ public: void handleFocusInEvent(const xcb_focus_in_event_t *event) Q_DECL_OVERRIDE; void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE; void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE; + void handleXIMouseEvent(xcb_ge_event_t *) Q_DECL_OVERRIDE; QXcbWindow *toWindow() Q_DECL_OVERRIDE; @@ -199,6 +200,15 @@ protected: void doFocusIn(); void doFocusOut(); + void handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + + void handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + + void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + xcb_window_t m_window; QXcbScreen *m_xcbScreen; diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index fd704dd904..12987567ff 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -59,6 +59,11 @@ contains(QT_CONFIG, xcb-xlib) { DEFINES += XCB_USE_XINPUT2 SOURCES += qxcbconnection_xi2.cpp LIBS += -lXi + !isEmpty(QMAKE_LIBXI_VERSION_MAJOR) { + DEFINES += LIBXI_MAJOR=$$QMAKE_LIBXI_VERSION_MAJOR \ + LIBXI_MINOR=$$QMAKE_LIBXI_VERSION_MINOR \ + LIBXI_PATCH=$$QMAKE_LIBXI_VERSION_PATCH + } } } -- cgit v1.2.3 From 34b57dc767268ba315ac54fd3f2c8e9c1104c66f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 26 May 2015 22:16:25 +0200 Subject: QGraphicsTransformPrivate: declare dtor out-of-line and export class De-duplicates vtables and enables RTTI on this class hierarchy. Export, as QDeclarativeTranslatePrivate (QtQuick1) inherits it. Change-Id: I32439c59f7d4bff466ecae969bb761a42c3837f1 Reported-by: Volker Krause Task-number: QTBUG-45582 Reviewed-by: Lars Knoll --- src/widgets/graphicsview/qgraphicstransform.cpp | 5 +++++ src/widgets/graphicsview/qgraphicstransform_p.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/widgets/graphicsview/qgraphicstransform.cpp b/src/widgets/graphicsview/qgraphicstransform.cpp index 67564b5a8b..fe963fbf3c 100644 --- a/src/widgets/graphicsview/qgraphicstransform.cpp +++ b/src/widgets/graphicsview/qgraphicstransform.cpp @@ -89,6 +89,11 @@ #ifndef QT_NO_GRAPHICSVIEW QT_BEGIN_NAMESPACE + +QGraphicsTransformPrivate::~QGraphicsTransformPrivate() +{ +} + void QGraphicsTransformPrivate::setItem(QGraphicsItem *i) { if (item == i) diff --git a/src/widgets/graphicsview/qgraphicstransform_p.h b/src/widgets/graphicsview/qgraphicstransform_p.h index dde085935f..c81a95fd3d 100644 --- a/src/widgets/graphicsview/qgraphicstransform_p.h +++ b/src/widgets/graphicsview/qgraphicstransform_p.h @@ -51,12 +51,14 @@ QT_BEGIN_NAMESPACE class QGraphicsItem; -class QGraphicsTransformPrivate : public QObjectPrivate { +// ### Qt 6: unexport again, if QtQuick1's QDeclarativeTranslatePrivate is gone by then +class Q_WIDGETS_EXPORT QGraphicsTransformPrivate : public QObjectPrivate { public: Q_DECLARE_PUBLIC(QGraphicsTransform) QGraphicsTransformPrivate() : QObjectPrivate(), item(0) {} + ~QGraphicsTransformPrivate(); QGraphicsItem *item; -- cgit v1.2.3 From ecb25dac6894cf3e9169528d56adbe92eb1182b9 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 28 May 2015 18:13:18 +0200 Subject: QCocoaMenu: return YES if we have a shortcut for a pseudo-first responder When running a modal session with NSOpenPanel (QFileDialog), our menu delegate should not touch qApp->focusObject, since it's not what actually has focus inside NSOpenPanel (will be some native view). Return YES instead. Task-number: QTBUG-17291 Change-Id: I94f3281237fb25495d317b02310bf9d77b21d2ba Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoamenu.mm | 34 ++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 09a4c95469..dd2c37d914 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -81,7 +81,7 @@ QT_END_NAMESPACE } - (id) initWithMenu:(QCocoaMenu*) m; -- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier; +- (NSMenuItem *)findItem:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier; @end @@ -152,11 +152,20 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); // Change the private unicode keys to the ones used in setting the "Key Equivalents" NSString *characters = qt_mac_removePrivateUnicode([event characters]); - if ([self hasShortcut:menu - forKey:characters - // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ... - forModifiers:([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask)) - ]) { + // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ... + const NSUInteger mask = NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask; + if (NSMenuItem *menuItem = [self findItem:menu forKey:characters forModifiers:([event modifierFlags] & mask)]) { + if (!menuItem.target) { + // This item was modified by QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder + // and it looks like we're running a modal session for NSOpenPanel/NSSavePanel. + // QCocoaFileDialogHelper is actually the only place we use this and we run NSOpenPanel modal + // (modal sheet, window modal, application modal). + // Whatever the current first responder is, let's give it a chance + // and do not touch the Qt's focusObject (which is different from some native view + // having a focus inside NSSave/OpenPanel. + return YES; + } + QObject *object = qApp->focusObject(); if (object) { QChar ch; @@ -194,22 +203,23 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); return NO; } -- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier +- (NSMenuItem *)findItem:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier { for (NSMenuItem *item in [menu itemArray]) { if (![item isEnabled] || [item isHidden] || [item isSeparatorItem]) continue; - if ([item hasSubmenu] - && [self hasShortcut:[item submenu] forKey:key forModifiers:modifier]) - return YES; + if ([item hasSubmenu]) { + if (NSMenuItem *nested = [self findItem:[item submenu] forKey:key forModifiers:modifier]) + return nested; + } NSString *menuKey = [item keyEquivalent]; if (menuKey && NSOrderedSame == [menuKey compare:key] && modifier == [item keyEquivalentModifierMask]) - return YES; + return item; } - return NO; + return nil; } @end -- cgit v1.2.3 From 55f3e6bc342ba52304febbc1159c566daa894993 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 25 May 2015 23:31:05 +0300 Subject: WinRT: Fix argument handling on Windows 10 The Windows 10 CRT does not export __getmainargs(), so we need to move to GetCommandLine like on WinCE and desktop Windows. As CommandLineToArgv is not available, the command line is split according by spaces, allowing for quotes (and quote escaping) around arguments. Change-Id: Ibc969df94ca5423a3a71d8190bbacd201189ea19 Reviewed-by: Andrew Knight Reviewed-by: Maurice Kalinowski --- src/winmain/qtmain_winrt.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 5a44df622a..e68da520e7 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -222,11 +222,49 @@ private: // Main entry point for Appx containers int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { +#if _MSC_VER < 1900 int argc = 0; char **argv, **env; _startupinfo info = { _query_new_mode() }; if (int init = __getmainargs(&argc, &argv, &env, false, &info)) return init; +#else + QByteArray commandLine = QString::fromWCharArray(GetCommandLine()).toUtf8(); + QVarLengthArray args; + args.append(commandLine.data()); + bool quote = false; + bool escape = false; + for (int i = 0; i < commandLine.size(); ++i) { + switch (commandLine.at(i)) { + case '\\': + escape = true; + break; + case '"': + if (escape) { + escape = false; + break; + } + quote = !quote; + commandLine[i] = '\0'; + break; + case ' ': + if (quote) + break; + commandLine[i] = '\0'; + if (args.last()[0] != '\0') + args.append(commandLine.data() + i + 1); + // fall through + default: + if (args.last()[0] == '\0') + args.last() = commandLine.data() + i; + escape = false; // only quotes are escaped + break; + } + } + int argc = args.size(); + char **argv = args.data(); + char **env = Q_NULLPTR; +#endif // _MSC_VER >= 1900 for (int i = 0; env && env[i]; ++i) { QByteArray var(env[i]); -- cgit v1.2.3 From 069be1654359ab93f89d339775795508d106153a Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Tue, 21 Oct 2014 22:44:12 +0400 Subject: Fix statfs usage for BSD4 systems in QStorageInfo According to NETBSD manual pages, there's no statfs structure; statvfs should be used instead, change introduces defines for the stat(v)fs struct/function. Task-number: QTBUG-40785 Change-Id: I98599e4635e46f90ffcc99c768f4c250f09f914f Reviewed-by: Thiago Macieira --- src/corelib/io/qstorageinfo_unix.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 7b8f608050..d170e7c0c0 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -67,8 +67,20 @@ #endif #if defined(Q_OS_BSD4) -# define QT_STATFSBUF struct statvfs -# define QT_STATFS ::statvfs +# if defined(Q_OS_NETBSD) + define QT_STATFSBUF struct statvfs + define QT_STATFS ::statvfs +# else +# define QT_STATFSBUF struct statfs +# define QT_STATFS ::statfs +# endif + +# if !defined(ST_RDONLY) +# define ST_RDONLY MNT_RDONLY +# endif +# if !defined(_STATFS_F_FLAGS) +# define _STATFS_F_FLAGS 1 +# endif #elif defined(Q_OS_ANDROID) # define QT_STATFS ::statfs # define QT_STATFSBUF struct statfs @@ -122,11 +134,7 @@ public: inline QByteArray device() const; private: #if defined(Q_OS_BSD4) -# if defined(Q_OS_NETBSD) - struct statvfs *stat_buf; -# else - struct statfs *stat_buf; -# endif + QT_STATFSBUF *stat_buf; int entryCount; int currentIndex; #elif defined(Q_OS_SOLARIS) @@ -501,7 +509,7 @@ void QStorageInfoPrivate::retrieveVolumeInfo() bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize; bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize; bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize; -#if defined(Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined (Q_OS_BSD4) #if defined(_STATFS_F_FLAGS) readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0; #endif -- cgit v1.2.3 From e1b366a89c719c833bfd78d432988e3c14557e00 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 26 May 2015 22:27:36 +0200 Subject: QFramePrivate: use direct instead of copy initialization Probably not performance-relevant here, but easier to read and safer, too (consider what happens if frect becomes QRectF). Change-Id: Ia5e4369b550b3a5b899b41ac4cbbda91229f2eb4 Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qframe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qframe.cpp b/src/widgets/widgets/qframe.cpp index 0861ea70b5..d5cedc4607 100644 --- a/src/widgets/widgets/qframe.cpp +++ b/src/widgets/widgets/qframe.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE QFramePrivate::QFramePrivate() - : frect(QRect(0, 0, 0, 0)), + : frect(0, 0, 0, 0), frameStyle(QFrame::NoFrame | QFrame::Plain), lineWidth(1), midLineWidth(0), -- cgit v1.2.3 From 26f72237692afc66088d55baa76f4ac0228a5e4e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 28 May 2015 18:19:51 +0200 Subject: fix installing unix dll symlinks on windows hosts ... by implementing a fake ln in qmake. symlinks are supported only since vista (we officially still support xp), and even there are permission-restricted (MS being (rightfully) afraid of symlink attacks). so we fake the links by copying the files instead. the previous hack was a bit naive, simply using cp/copy instead of ln. this didn't work with relative paths, as real symlinks are resolved against their parent directory, not the working directory of the "ln" command. the new fake does this correctly. Change-Id: Ia2f5d68a39d6ffcc8a4383f9d0fc63a9da0a05c3 Reviewed-by: Joerg Bornemann --- mkspecs/features/spec_post.prf | 5 ++- qmake/main.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/spec_post.prf b/mkspecs/features/spec_post.prf index c9578773fe..4d398059b2 100644 --- a/mkspecs/features/spec_post.prf +++ b/mkspecs/features/spec_post.prf @@ -109,9 +109,8 @@ equals(MAKEFILE_GENERATOR, MSBUILD) \ } QMAKE_INSTALL_DIR = $$QMAKE_COPY_DIR equals(QMAKE_HOST.os, Windows) { - # Ugly (and broken for relative paths) hack to support cross-building for Unix. - QMAKE_SYMBOLIC_LINK = $$QMAKE_COPY - QMAKE_LN_SHLIB = $$QMAKE_SYMBOLIC_LINK + QMAKE_SYMBOLIC_LINK = $(QMAKE) -install ln -f -s + QMAKE_LN_SHLIB = $(QMAKE) -install ln -s } else { QMAKE_SYMBOLIC_LINK = ln -f -s QMAKE_LN_SHLIB = ln -s diff --git a/qmake/main.cpp b/qmake/main.cpp index 27969932bc..bde537dcca 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -163,6 +163,75 @@ static int doSed(int argc, char **argv) return 0; } +static int doLink(int argc, char **argv) +{ + bool isSymlink = false; + bool force = false; + QList inFiles; + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-s")) { + isSymlink = true; + } else if (!strcmp(argv[i], "-f")) { + force = true; + } else if (argv[i][0] == '-') { + fprintf(stderr, "Error: unrecognized ln option '%s'\n", argv[i]); + return 3; + } else { + inFiles << argv[i]; + } + } + if (inFiles.size() != 2) { + fprintf(stderr, "Error: this ln requires exactly two file arguments\n"); + return 3; + } + if (!isSymlink) { + fprintf(stderr, "Error: this ln supports faking symlinks only\n"); + return 3; + } + QString target = QString::fromLocal8Bit(inFiles[0]); + QString linkname = QString::fromLocal8Bit(inFiles[1]); + + QDir destdir; + QFileInfo tfi(target); + QFileInfo lfi(linkname); + if (lfi.isDir()) { + destdir.setPath(linkname); + lfi.setFile(destdir, tfi.fileName()); + } else { + destdir.setPath(lfi.path()); + } + if (!destdir.exists()) { + fprintf(stderr, "Error: destination directory %s does not exist\n", qPrintable(destdir.path())); + return 1; + } + tfi.setFile(destdir.absoluteFilePath(tfi.filePath())); + if (!tfi.exists()) { + fprintf(stderr, "Error: this ln does not support symlinking non-existing targets\n"); + return 3; + } + if (tfi.isDir()) { + fprintf(stderr, "Error: this ln does not support symlinking directories\n"); + return 3; + } + if (lfi.exists()) { + if (!force) { + fprintf(stderr, "Error: %s exists\n", qPrintable(lfi.filePath())); + return 1; + } + if (!QFile::remove(lfi.filePath())) { + fprintf(stderr, "Error: cannot overwrite %s\n", qPrintable(lfi.filePath())); + return 1; + } + } + if (!QFile::copy(tfi.filePath(), lfi.filePath())) { + fprintf(stderr, "Error: cannot copy %s to %s\n", + qPrintable(tfi.filePath()), qPrintable(lfi.filePath())); + return 1; + } + + return 0; +} + static int doInstall(int argc, char **argv) { if (!argc) { @@ -171,6 +240,8 @@ static int doInstall(int argc, char **argv) } if (!strcmp(argv[0], "sed")) return doSed(argc - 1, argv + 1); + if (!strcmp(argv[0], "ln")) + return doLink(argc - 1, argv + 1); fprintf(stderr, "Error: unrecognized -install subcommand '%s'\n", argv[0]); return 3; } -- cgit v1.2.3 From 85c12d57456d1d793c62ac9125f7d16e96e2bf3c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 27 May 2015 20:42:56 +0200 Subject: fix incorrect path separators coming from installed .prl files we use qmake properties in the installed .prl files, so the paths need to be converted to native separators before emission. Task-number: QTBUG-46217 Change-Id: If3fb0a84488795478fc2a701271c931c62eba6aa Reviewed-by: Joerg Bornemann --- qmake/generators/win32/winmakefile.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 8a60c44032..46a05c52b2 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -100,10 +100,13 @@ ProString Win32MakefileGenerator::fixLibFlag(const ProString &lib) { if (lib.startsWith('/')) { if (lib.startsWith("/LIBPATH:")) - return QStringLiteral("/LIBPATH:") + escapeFilePath(lib.mid(9)); + return QLatin1String("/LIBPATH:") + + escapeFilePath(Option::fixPathToTargetOS(lib.mid(9).toQString(), false)); + // This appears to be a user-supplied flag. Assume sufficient quoting. return lib; } - return escapeFilePath(lib); + // This must be a fully resolved library path. + return escapeFilePath(Option::fixPathToTargetOS(lib.toQString(), false)); } bool -- cgit v1.2.3 From 275709fb43c154ccb1d95391f4829bd1aecebb12 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 27 May 2015 20:58:44 +0200 Subject: don't process .prl files recursively they are self-contained, as they are the result of another project's full resolution. consequently, recursing them just burns cycles, and additionally introduces the risk of an endless loop if the file is botched. Task-number: QTBUG-12711 Change-Id: I401ee691c170092cc61fe05538cec4272ed8f922 Reviewed-by: Joerg Bornemann --- qmake/generators/unix/unixmake.cpp | 2 +- qmake/generators/win32/winmakefile.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 723eea80d3..c4750cb8a4 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -612,7 +612,7 @@ UnixMakefileGenerator::processPrlFiles() ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); if(!prl_libs.isEmpty()) { for(int prl = 0; prl < prl_libs.size(); ++prl) - l.insert(lit+prl+1, prl_libs.at(prl).toQString()); + l.insert(++lit, prl_libs.at(prl)); prl_libs.clear(); } } diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 46a05c52b2..386e2865fa 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -234,7 +234,7 @@ Win32MakefileGenerator::processPrlFiles() } ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); for (int prl = 0; prl < prl_libs.size(); ++prl) - l.insert(lit + prl + 1, prl_libs.at(prl)); + l.insert(++lit, prl_libs.at(prl)); prl_libs.clear(); } -- cgit v1.2.3 From 78e335408303380310dd59fab421e495cf517ead Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 1 Jun 2015 11:44:37 +0200 Subject: Clip QOpenGLWidget and QQuickWidget correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce support for the widgets' clipRect(). Right now render-to-texture widgets in scroll areas placed close to each other result in broken (non-existent) clipping. Similarly, stack-on-top widgets fail to clip when placed inside a scroll area. This is now corrected and the qopenglwidget example is enhanced to utilize a scroll area. Task-number: QTBUG-45860 Change-Id: I859a63d61a50d64ba9e87244f83c5969dce12337 Reviewed-by: Jørgen Lind --- examples/opengl/qopenglwidget/glwidget.cpp | 6 +-- examples/opengl/qopenglwidget/mainwindow.cpp | 20 ++++++-- examples/opengl/qopenglwidget/mainwindow.h | 2 + src/gui/painting/qplatformbackingstore.cpp | 59 ++++++++++++++++------ src/gui/painting/qplatformbackingstore.h | 4 +- .../platformcompositor/qopenglcompositor.cpp | 31 ++++++++++-- .../qopenglcompositorbackingstore.cpp | 3 +- src/widgets/kernel/qwidgetbackingstore.cpp | 3 +- 8 files changed, 99 insertions(+), 29 deletions(-) diff --git a/examples/opengl/qopenglwidget/glwidget.cpp b/examples/opengl/qopenglwidget/glwidget.cpp index f93e667615..df52e3efbf 100644 --- a/examples/opengl/qopenglwidget/glwidget.cpp +++ b/examples/opengl/qopenglwidget/glwidget.cpp @@ -537,14 +537,14 @@ void GLWidget::setTransparent(bool transparent) window()->update(); } -void GLWidget::resizeGL(int w, int h) +void GLWidget::resizeGL(int, int) { if (m_hasButton) { if (!m_btn) { - m_btn = new QPushButton("A widget on top.\nPress me!", this); + m_btn = new QPushButton("A widget on top.\nPress for more widgets.", this); connect(m_btn, &QPushButton::clicked, this, &GLWidget::handleButtonPress); } - m_btn->move(w / 2, h / 2); + m_btn->move(20, 80); } } diff --git a/examples/opengl/qopenglwidget/mainwindow.cpp b/examples/opengl/qopenglwidget/mainwindow.cpp index 6cf1d5d6e2..22111afdcb 100644 --- a/examples/opengl/qopenglwidget/mainwindow.cpp +++ b/examples/opengl/qopenglwidget/mainwindow.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include "glwidget.h" @@ -69,7 +70,7 @@ MainWindow::MainWindow() "and therefore an interval < 16 ms will likely lead to a 60 FPS update rate."); QGroupBox *updateGroupBox = new QGroupBox(this); QCheckBox *timerBased = new QCheckBox("Use timer", this); - timerBased->setChecked(true); + timerBased->setChecked(false); timerBased->setToolTip("Toggles using a timer to trigger update().\n" "When not set, each paintGL() schedules the next update immediately,\n" "expecting the blocking swap to throttle the thread.\n" @@ -87,7 +88,7 @@ MainWindow::MainWindow() slider->setRange(0, 50); slider->setSliderPosition(30); m_timer->setInterval(10); - label->setText("A QOpenGLWidget"); + label->setText("A scrollable QOpenGLWidget"); label->setAlignment(Qt::AlignHCenter); QGroupBox * groupBox = new QGroupBox(this); @@ -96,7 +97,10 @@ MainWindow::MainWindow() m_layout = new QGridLayout(groupBox); - m_layout->addWidget(glwidget,1,0,8,1); + QScrollArea *scrollArea = new QScrollArea; + scrollArea->setWidget(glwidget); + + m_layout->addWidget(scrollArea,1,0,8,1); m_layout->addWidget(label,9,0,1,1); m_layout->addWidget(updateGroupBox, 10, 0, 1, 1); m_layout->addWidget(slider, 11,0,1,1); @@ -134,7 +138,10 @@ MainWindow::MainWindow() connect(timerBased, &QCheckBox::toggled, this, &MainWindow::timerUsageChanged); connect(timerBased, &QCheckBox::toggled, updateInterval, &QWidget::setEnabled); - m_timer->start(); + if (timerBased->isChecked()) + m_timer->start(); + else + updateInterval->setEnabled(false); } void MainWindow::updateIntervalChanged(int value) @@ -170,3 +177,8 @@ void MainWindow::timerUsageChanged(bool enabled) w->update(); } } + +void MainWindow::resizeEvent(QResizeEvent *) +{ + m_glWidgets[0]->setMinimumSize(size() + QSize(128, 128)); +} diff --git a/examples/opengl/qopenglwidget/mainwindow.h b/examples/opengl/qopenglwidget/mainwindow.h index f1b2c51e53..9ad8a01339 100644 --- a/examples/opengl/qopenglwidget/mainwindow.h +++ b/examples/opengl/qopenglwidget/mainwindow.h @@ -56,6 +56,8 @@ public: void addNew(); bool timerEnabled() const { return m_timer->isActive(); } + void resizeEvent(QResizeEvent *); + private slots: void updateIntervalChanged(int value); void timerUsageChanged(bool enabled); diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 14a9429c71..83077f38ca 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -86,6 +86,7 @@ struct QBackingstoreTextureInfo QWidget *widget; // may be null GLuint textureId; QRect rect; + QRect clipRect; QPlatformTextureList::Flags flags; }; @@ -142,6 +143,12 @@ QRect QPlatformTextureList::geometry(int index) const return d->textures.at(index).rect; } +QRect QPlatformTextureList::clipRect(int index) const +{ + Q_D(const QPlatformTextureList); + return d->textures.at(index).clipRect; +} + void QPlatformTextureList::lock(bool on) { Q_D(QPlatformTextureList); @@ -157,13 +164,15 @@ bool QPlatformTextureList::isLocked() const return d->locked; } -void QPlatformTextureList::appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags) +void QPlatformTextureList::appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, + const QRect &clipRect, Flags flags) { Q_D(QPlatformTextureList); QBackingstoreTextureInfo bi; bi.widget = widget; bi.textureId = textureId; bi.rect = geometry; + bi.clipRect = clipRect; bi.flags = flags; d->textures.append(bi); } @@ -198,7 +207,7 @@ void QPlatformTextureList::clear() #ifndef QT_NO_OPENGL -static QRect deviceRect(const QRect &rect, QWindow *window) +static inline QRect deviceRect(const QRect &rect, QWindow *window) { QRect deviceRect(rect.topLeft() * window->devicePixelRatio(), rect.size() * window->devicePixelRatio()); @@ -219,6 +228,32 @@ static QRegion deviceRegion(const QRegion ®ion, QWindow *window) return deviceRegion; } +static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) +{ + return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1, + topLeftRect.width(), topLeftRect.height()); +} + +static void blit(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect, + QOpenGLTextureBlitter *blitter) +{ + const QRect rectInWindow = textures->geometry(idx); + QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); + const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); + + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(deviceRect(clippedRectInWindow, window), + deviceWindowRect); + + const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window), + deviceRect(rectInWindow, window).size(), + QOpenGLTextureBlitter::OriginBottomLeft); + + blitter->blit(textures->textureId(idx), target, source); +} + /*! Flushes the given \a region from the specified \a window onto the screen, and composes it with the specified \a textures. @@ -254,15 +289,12 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i d_ptr->blitter->bind(); - QRect windowRect(QPoint(), window->size() * window->devicePixelRatio()); + const QRect deviceWindowRect = deviceRect(QRect(QPoint(), window->size()), window); // Textures for renderToTexture widgets. for (int i = 0; i < textures->count(); ++i) { - if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QRect targetRect = deviceRect(textures->geometry(i), window); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect); - d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); - } + if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) + blit(textures, i, window, deviceWindowRect, d_ptr->blitter); } funcs->glEnable(GL_BLEND); @@ -272,6 +304,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i // semi-transparency even when it is not wanted. funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + // Backingstore texture with the normal widgets. GLuint textureId = 0; QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft; if (QPlatformGraphicsBuffer *graphicsBuffer = this->graphicsBuffer()) { @@ -307,7 +340,6 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i origin = QOpenGLTextureBlitter::OriginBottomLeft; textureId = d_ptr->textureId; } else { - // Backingstore texture with the normal widgets. TextureFlags flags = 0; textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &flags); d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0; @@ -316,7 +348,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i } if (textureId) { - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), windowRect); + QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), deviceWindowRect); if (d_ptr->needsSwizzle) d_ptr->blitter->setSwizzleRB(true); d_ptr->blitter->blit(textureId, target, origin); @@ -326,11 +358,8 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i // Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set. for (int i = 0; i < textures->count(); ++i) { - if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QRect targetRect = deviceRect(textures->geometry(i), window); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect); - d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); - } + if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) + blit(textures, i, window, deviceWindowRect, d_ptr->blitter); } funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index ae7314b6d0..5fa7e6dac0 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -82,12 +82,14 @@ public: bool isEmpty() const { return count() == 0; } GLuint textureId(int index) const; QRect geometry(int index) const; + QRect clipRect(int index) const; QWidget *widget(int index); Flags flags(int index) const; void lock(bool on); bool isLocked() const; - void appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags = 0); + void appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, + const QRect &clipRect = QRect(), Flags flags = 0); void clear(); Q_SIGNALS: diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp index 3fd6c999a2..2e386532e2 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp @@ -169,6 +169,29 @@ struct BlendStateBinder bool m_blend; }; +static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) +{ + return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1, + topLeftRect.width(), topLeftRect.height()); +} + +static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter) +{ + const QRect rectInWindow = textures->geometry(idx); + QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); + const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); + + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(clippedRectInWindow, targetWindowRect); + const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect, rectInWindow.size(), + QOpenGLTextureBlitter::OriginBottomLeft); + + blitter->blit(textures->textureId(idx), target, source); +} + void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) { const QPlatformTextureList *textures = window->textures(); @@ -181,7 +204,6 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) for (int i = 0; i < textures->count(); ++i) { uint textureId = textures->textureId(i); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); const float opacity = window->sourceWindow()->opacity(); if (opacity != currentOpacity) { currentOpacity = opacity; @@ -191,24 +213,25 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) if (textures->count() > 1 && i == textures->count() - 1) { // Backingstore for a widget with QOpenGLWidget subwidgets blend.set(true); + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); } else if (textures->count() == 1) { // A regular QWidget window const bool translucent = window->sourceWindow()->requestedFormat().alphaBufferSize() > 0; blend.set(translucent); + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); } else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { // Texture from an FBO belonging to a QOpenGLWidget blend.set(false); - m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft); + clippedBlit(textures, i, targetWindowRect, &m_blitter); } } for (int i = 0; i < textures->count(); ++i) { if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); blend.set(true); - m_blitter.blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); + clippedBlit(textures, i, targetWindowRect, &m_blitter); } } diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 3caec468a6..4cf64e61da 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -175,7 +175,8 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi m_textures->clear(); for (int i = 0; i < textures->count(); ++i) - m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), textures->flags(i)); + m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), + textures->clipRect(i), textures->flags(i)); updateTexture(); m_textures->appendTexture(Q_NULLPTR, m_bsTexture, window->geometry()); diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 485cf82078..5752317924 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -962,7 +962,8 @@ static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatfo QPlatformTextureList::Flags flags = 0; if (widget->testAttribute(Qt::WA_AlwaysStackOnTop)) flags |= QPlatformTextureList::StacksOnTop; - widgetTextures->appendTexture(widget, wd->textureId(), QRect(widget->mapTo(tlw, QPoint()), widget->size()), flags); + const QRect rect(widget->mapTo(tlw, QPoint()), widget->size()); + widgetTextures->appendTexture(widget, wd->textureId(), rect, wd->clipRect(), flags); } for (int i = 0; i < wd->children.size(); ++i) { -- cgit v1.2.3 From 0e1b4e896fba50ce6603bc323b2940e6859e7421 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 1 Jun 2015 15:23:19 +0200 Subject: Avoid QWidget dependency in QtGui MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not a real dependency as all we need is to store a pointer, but better not to use the name QWidget at all. Change-Id: I30ef1dd44ac7e42c1b9c84675f94088b8c516076 Reviewed-by: Jørgen Lind --- src/gui/painting/qplatformbackingstore.cpp | 10 +++++----- src/gui/painting/qplatformbackingstore.h | 4 ++-- .../platformcompositor/qopenglcompositorbackingstore.cpp | 2 +- src/widgets/kernel/qwidgetbackingstore.cpp | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 83077f38ca..62492980de 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -83,7 +83,7 @@ public: struct QBackingstoreTextureInfo { - QWidget *widget; // may be null + void *source; // may be null GLuint textureId; QRect rect; QRect clipRect; @@ -125,10 +125,10 @@ GLuint QPlatformTextureList::textureId(int index) const return d->textures.at(index).textureId; } -QWidget *QPlatformTextureList::widget(int index) +void *QPlatformTextureList::source(int index) { Q_D(const QPlatformTextureList); - return d->textures.at(index).widget; + return d->textures.at(index).source; } QPlatformTextureList::Flags QPlatformTextureList::flags(int index) const @@ -164,12 +164,12 @@ bool QPlatformTextureList::isLocked() const return d->locked; } -void QPlatformTextureList::appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, +void QPlatformTextureList::appendTexture(void *source, GLuint textureId, const QRect &geometry, const QRect &clipRect, Flags flags) { Q_D(QPlatformTextureList); QBackingstoreTextureInfo bi; - bi.widget = widget; + bi.source = source; bi.textureId = textureId; bi.rect = geometry; bi.clipRect = clipRect; diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index 5fa7e6dac0..eac97e9cf6 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -83,12 +83,12 @@ public: GLuint textureId(int index) const; QRect geometry(int index) const; QRect clipRect(int index) const; - QWidget *widget(int index); + void *source(int index); Flags flags(int index) const; void lock(bool on); bool isLocked() const; - void appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, + void appendTexture(void *source, GLuint textureId, const QRect &geometry, const QRect &clipRect = QRect(), Flags flags = 0); void clear(); diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 4cf64e61da..8ce1ed2d2b 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -175,7 +175,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi m_textures->clear(); for (int i = 0; i < textures->count(); ++i) - m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), + m_textures->appendTexture(textures->source(i), textures->textureId(i), textures->geometry(i), textures->clipRect(i), textures->flags(i)); updateTexture(); diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 5752317924..d1070839fa 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1157,7 +1157,7 @@ void QWidgetBackingStore::doSync() #ifndef QT_NO_OPENGL if (widgetTextures && widgetTextures->count()) { for (int i = 0; i < widgetTextures->count(); ++i) { - QWidget *w = widgetTextures->widget(i); + QWidget *w = static_cast(widgetTextures->source(i)); if (dirtyRenderToTextureWidgets.contains(w)) { const QRect rect = widgetTextures->geometry(i); // mapped to the tlw already dirty += rect; -- cgit v1.2.3 From 6fba3c1904aa7601722a70099d88126191cf60cf Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 1 Jun 2015 09:58:59 +0200 Subject: Stabilize tst_qtouchevent. - Use QTRY_COMPARE() in touchBeginWithGraphicsWidget. - Change raw event translation tests to wait for the window to become active to avoid WM positioning issues. - Blacklist the raw event translation tests on Linux. Task-number: QTBUG-46266 Change-Id: I73aae375ee279a518a2a083d0ce8919cce474cb3 Reviewed-by: Simon Hausmann --- tests/auto/gui/kernel/qtouchevent/BLACKLIST | 6 ++++++ tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 tests/auto/gui/kernel/qtouchevent/BLACKLIST diff --git a/tests/auto/gui/kernel/qtouchevent/BLACKLIST b/tests/auto/gui/kernel/qtouchevent/BLACKLIST new file mode 100644 index 0000000000..8e78d7e41f --- /dev/null +++ b/tests/auto/gui/kernel/qtouchevent/BLACKLIST @@ -0,0 +1,6 @@ +[basicRawEventTranslation] +linux +[multiPointRawEventTranslationOnTouchScreen] +linux +[multiPointRawEventTranslationOnTouchPad] +linux diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index dc35058f66..aa1f573aa9 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -601,7 +601,7 @@ void tst_QTouchEvent::basicRawEventTranslation() touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); touchWidget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); + QVERIFY(QTest::qWaitForWindowActive(&touchWidget)); QPointF pos = touchWidget.rect().center(); QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint()); @@ -738,7 +738,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() rightWidget.setGeometry(300, 100, 100, 100); touchWidget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); + QVERIFY(QTest::qWaitForWindowActive(&touchWidget)); QPointF leftPos = leftWidget.rect().center(); QPointF rightPos = rightWidget.rect().center(); @@ -968,7 +968,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() rightWidget.setGeometry(300, 100, 100, 100); touchWidget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); + QVERIFY(QTest::qWaitForWindowActive(&touchWidget)); QPointF leftPos = leftWidget.rect().center(); QPointF rightPos = rightWidget.rect().center(); @@ -1468,7 +1468,7 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()) .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); - QCOMPARE(root->touchBeginCounter, 1); + QTRY_COMPARE(root->touchBeginCounter, 1); QCOMPARE(root->touchUpdateCounter, 1); QCOMPARE(root->touchEndCounter, 1); QCOMPARE(root->touchUpdatePoints.size(), 2); -- cgit v1.2.3 From 6b4c1ad58cfc3a67e4f4474c1faa89359b8b636c Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 1 Jun 2015 15:20:46 +0200 Subject: Fix wrong method name in QColor documentation The methods are called hslHue and hslSaturation. This was leading to dead links. Change-Id: I0997c415958aae9a66fb037d98f8ad3d43b38231 Reviewed-by: Oswald Buddenhagen --- src/gui/painting/qcolor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index a6b44cde15..d50c42f1ee 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -717,8 +717,8 @@ void QColor::setHsv(int h, int s, int v, int a) saturation, lightness, and alpha-channel (transparency) components of the color's HSL value. - These components can be retrieved individually using the hueHslF(), - saturationHslF(), lightnessF() and alphaF() functions. + These components can be retrieved individually using the hslHueF(), + hslSaturationF(), lightnessF() and alphaF() functions. \sa setHsl() */ @@ -747,8 +747,8 @@ void QColor::getHslF(qreal *h, qreal *s, qreal *l, qreal *a) const saturation, lightness, and alpha-channel (transparency) components of the color's HSL value. - These components can be retrieved individually using the hueHsl(), - saturationHsl(), lightness() and alpha() functions. + These components can be retrieved individually using the hslHue(), + hslSaturation(), lightness() and alpha() functions. \sa setHsl() */ -- cgit v1.2.3 From d83bd9c6f5abd936b853029bf7030ebb4792f9fb Mon Sep 17 00:00:00 2001 From: "M. Moellney" Date: Wed, 27 May 2015 22:31:21 +0200 Subject: Introduce qmake RC_DEFINES for RC preprocessor defines qmake win32 generators by default used values of DEFINES for RC preprocessor defines, too. For simple defines this works. For string literals this failed for the .vcxproj files: DEFINES += "FOO=\"BAR BAR\"" works for CL but fails for RC. DEFINES += "FOO=\\\"BAR BAR\\\"" works for RC but fails for CL. This patch introduces the qmake variable RC_DEFINES. The variable contains the preprocessor defines, that are used for RC. If the varible is not set, the DEFINES values are used for RC. Task-number: QTBUG-44184 Change-Id: I4202271759d29de8c1829347ae3ef117eda54b38 Reviewed-by: Oswald Buddenhagen --- qmake/doc/snippets/code/doc_src_qmake-manual.pro | 5 +++++ qmake/doc/src/qmake-manual.qdoc | 8 ++++++++ qmake/generators/win32/mingw_make.cpp | 7 ++++++- qmake/generators/win32/msvc_vcproj.cpp | 7 ++++++- qmake/generators/win32/winmakefile.cpp | 17 ++++++++++++----- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/qmake/doc/snippets/code/doc_src_qmake-manual.pro b/qmake/doc/snippets/code/doc_src_qmake-manual.pro index 335fa6f97e..748b6bb646 100644 --- a/qmake/doc/snippets/code/doc_src_qmake-manual.pro +++ b/qmake/doc/snippets/code/doc_src_qmake-manual.pro @@ -987,3 +987,8 @@ QMAKE_SONAME_PREFIX = /Library/Frameworks #! [185] VERSION_PE_HEADER = 1.2 #! [185] + +#! [186] +RC_DEFINES += USE_MY_STUFF +#! [186] + diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 56d9dd35ae..bda658689c 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -2314,6 +2314,14 @@ .rc file. This is only utilized if the \l{VERSION} or \l{RC_ICONS} variable is set and the \l{RC_FILE} and \l{RES_FILE} variables are not set. + \target RC_DEFINES + \section1 RC_DEFINES + + Windows only. qmake adds the values of this variable as RC preprocessor macros + (/d option). If this variable is not set, the \l{DEFINES} variable is used instead. + + \snippet code/doc_src_qmake-manual.pro 186 + \target RC_ICONS \section1 RC_ICONS diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index c19e17bc0e..57955dc456 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -405,9 +405,14 @@ void MingwMakefileGenerator::writeRcFilePart(QTextStream &t) } if (!rc_file.isEmpty()) { + + ProString defines = varGlue("RC_DEFINES", " -D", " -D", ""); + if (defines.isEmpty()) + defines = ProString(" $(DEFINES)"); + t << escapeDependencyPath(var("RES_FILE")) << ": " << escapeDependencyPath(rc_file) << "\n\t" << var("QMAKE_RC") << " -i " << escapeFilePath(rc_file) << " -o " << fileVar("RES_FILE") - << incPathStr << " $(DEFINES)\n\n"; + << incPathStr << defines << "\n\n"; } } diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 1fa117afda..0ece5786bd 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1213,7 +1213,12 @@ void VcprojGenerator::initLinkerTool() void VcprojGenerator::initResourceTool() { VCConfiguration &conf = vcProject.Configuration; - conf.resource.PreprocessorDefinitions = conf.compiler.PreprocessorDefinitions; + + ProStringList rcDefines = project->values("RC_DEFINES"); + if (rcDefines.size() > 0) + conf.resource.PreprocessorDefinitions = rcDefines.toQStringList(); + else + conf.resource.PreprocessorDefinitions = conf.compiler.PreprocessorDefinitions; foreach (const ProString &path, project->values("RC_INCLUDEPATH")) { QString fixedPath = fileFixify(path.toQString()); diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 6ea129f82c..ab4f48685b 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -752,10 +752,6 @@ void Win32MakefileGenerator::writeRcFilePart(QTextStream &t) if(!project->values("RC_FILE").isEmpty()) { const ProString res_file = project->first("RES_FILE"); const QString rc_file = fileFixify(project->first("RC_FILE").toQString()); - // The resource tool needs to have the same defines passed in as the compiler, since you may - // use these defines in the .rc file itself. Also, we need to add the _DEBUG define manually - // since the compiler defines this symbol by itself, and we use it in the automatically - // created rc file when VERSION is define the .pro file. const ProStringList rcIncPaths = project->values("RC_INCLUDEPATH"); QString incPathStr; @@ -767,9 +763,20 @@ void Win32MakefileGenerator::writeRcFilePart(QTextStream &t) incPathStr += escapeFilePath(path); } + // The resource tool may use defines. This might be the same defines passed in as the + // compiler, since you may use these defines in the .rc file itself. + // As the escape syntax for the command line defines for RC is different from that for CL, + // we might have to set specific defines for RC. + ProString defines = varGlue("RC_DEFINES", " -D", " -D", ""); + if (defines.isEmpty()) + defines = ProString(" $(DEFINES)"); + + // Also, we need to add the _DEBUG define manually since the compiler defines this symbol + // by itself, and we use it in the automatically created rc file when VERSION is defined + // in the .pro file. t << escapeDependencyPath(res_file) << ": " << escapeDependencyPath(rc_file) << "\n\t" << var("QMAKE_RC") << (project->isActiveConfig("debug") ? " -D_DEBUG" : "") - << " $(DEFINES)" << incPathStr << " -fo " << escapeFilePath(res_file) + << defines << incPathStr << " -fo " << escapeFilePath(res_file) << ' ' << escapeFilePath(rc_file); t << endl << endl; } -- cgit v1.2.3 From f7047d52da47a8426189d0aff8c5104b23cbfd89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 13 May 2015 21:04:27 +0200 Subject: Cocoa: add QT_MAC_USE_NSWINDOW env. variable When enabled, all QWindows will be backed by a NSWindow. This is unlike the default where only top-level QWindows get a NSWindow. The QWindow still has (Q)NSView as the NSWindow content view. The return value of the winId functions are still the NSView and is not affected by this switch. Change-Id: I131b89af04c09451a6e7515d1da3f7498f53979a Reviewed-by: Gabriel de Dietrich Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoawindow.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 86959869cc..495d5831f7 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1254,7 +1254,9 @@ QCocoaGLContext *QCocoaWindow::currentContext() const void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) { bool wasNSWindowChild = m_isNSWindowChild; - m_isNSWindowChild = parentWindow && (window()->property("_q_platform_MacUseNSWindow").toBool()); + BOOL requestNSWindowChild = qt_mac_resolveOption(NO, window(), "_q_platform_MacUseNSWindow", + "QT_MAC_USE_NSWINDOW"); + m_isNSWindowChild = parentWindow && requestNSWindowChild; bool needsNSWindow = m_isNSWindowChild || !parentWindow; QCocoaWindow *oldParentCocoaWindow = m_parentCocoaWindow; -- cgit v1.2.3 From 11512d6a2cd6d816a13db7ee0c48627d6534b377 Mon Sep 17 00:00:00 2001 From: Pier Luigi Fiorini Date: Fri, 22 May 2015 20:30:59 +0200 Subject: eglfs_kms: Virtual desktop Now we can choose to use separate screens or virtual desktop. With virtual desktop the geometry of all screens is taken into account so that the input plugin do not clamp global pointer coordinates to the first screen anymore, we also create only one hardware cursor that can now freely move on all the screens. Virtual desktop is enabled by default, but the old default behavior can be restored by setting separateScreens to true. Change-Id: I78dbf9e8d3dd44f68d33350dc8fc3727bf8a26fe Reviewed-by: Laszlo Agocs --- .../eglfs_kms/qeglfskmscursor.cpp | 45 +++++++++++++++------- .../eglfs_kms/qeglfskmsdevice.cpp | 25 ++++++++++++ .../deviceintegration/eglfs_kms/qeglfskmsdevice.h | 6 +++ .../eglfs_kms/qeglfskmsintegration.cpp | 9 +++++ .../eglfs_kms/qeglfskmsintegration.h | 3 ++ .../eglfs_kms/qeglfskmsscreen.cpp | 5 +++ .../deviceintegration/eglfs_kms/qeglfskmsscreen.h | 7 ++++ 7 files changed, 86 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp index cd92c49ff1..fe47c947b4 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -87,8 +88,11 @@ QEglFSKmsCursor::QEglFSKmsCursor(QEglFSKmsScreen *screen) QEglFSKmsCursor::~QEglFSKmsCursor() { - drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0, 0); - drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0); + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast(screen); + drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); + drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); + } gbm_bo_destroy(m_bo); m_bo = Q_NULLPTR; @@ -143,10 +147,15 @@ void QEglFSKmsCursor::changeCursor(QCursor *windowCursor, QWindow *window) gbm_bo_write(m_bo, cursorImage.constBits(), cursorImage.byteCount()); uint32_t handle = gbm_bo_get_handle(m_bo).u32; - int status = drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, handle, - m_cursorSize.width(), m_cursorSize.height()); - if (status != 0) - qWarning("Could not set cursor: %d", status); + + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast(screen); + + int status = drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, handle, + m_cursorSize.width(), m_cursorSize.height()); + if (status != 0) + qWarning("Could not set cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), status); + } } #endif // QT_NO_CURSOR @@ -157,12 +166,17 @@ QPoint QEglFSKmsCursor::pos() const void QEglFSKmsCursor::setPos(const QPoint &pos) { - QPoint adjustedPos = pos - m_cursorImage.hotspot(); - int ret = drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, adjustedPos.x(), adjustedPos.y()); - if (ret == 0) { - m_pos = pos; - } else { - qWarning("Failed to move cursor: %d", ret); + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast(screen); + QPoint origin = kmsScreen->geometry().topLeft(); + QPoint localPos = pos - origin; + QPoint adjustedPos = localPos - m_cursorImage.hotspot(); + + int ret = drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, adjustedPos.x(), adjustedPos.y()); + if (ret == 0) + m_pos = pos; + else + qWarning("Failed to move cursor on screen %s: %d", kmsScreen->name().toLatin1().constData(), ret); } } @@ -176,8 +190,11 @@ void QEglFSKmsCursor::initCursorAtlas() QFile file(QString::fromUtf8(json)); if (!file.open(QFile::ReadOnly)) { - drmModeSetCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0, 0); - drmModeMoveCursor(m_screen->device()->fd(), m_screen->output().crtc_id, 0, 0); + Q_FOREACH (QPlatformScreen *screen, m_screen->virtualSiblings()) { + QEglFSKmsScreen *kmsScreen = static_cast(screen); + drmModeSetCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0, 0); + drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); + } m_visible = false; return; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp index bafe1e3324..18a66e34f5 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -308,6 +309,7 @@ QEglFSKmsDevice::QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QStrin , m_gbm_device(Q_NULLPTR) , m_crtc_allocator(0) , m_connector_allocator(0) + , m_globalCursor(Q_NULLPTR) { } @@ -347,6 +349,10 @@ void QEglFSKmsDevice::close() qt_safe_close(m_dri_fd); m_dri_fd = -1; } + + if (m_globalCursor) + m_globalCursor->deleteLater(); + m_globalCursor = Q_NULLPTR; } void QEglFSKmsDevice::createScreens() @@ -357,6 +363,8 @@ void QEglFSKmsDevice::createScreens() return; } + QEglFSKmsScreen *primaryScreen = Q_NULLPTR; + QList siblings; QPoint pos(0, 0); QEglFSIntegration *integration = static_cast(QGuiApplicationPrivate::platformIntegration()); @@ -369,12 +377,24 @@ void QEglFSKmsDevice::createScreens() if (screen) { integration->addScreen(screen); pos.rx() += screen->geometry().width(); + siblings << screen; + + if (!primaryScreen) + primaryScreen = screen; } drmModeFreeConnector(connector); } drmModeFreeResources(resources); + + if (!m_integration->separateScreens()) { + Q_FOREACH (QPlatformScreen *screen, siblings) + static_cast(screen)->setVirtualSiblings(siblings); + + if (primaryScreen) + m_globalCursor = new QEglFSKmsCursor(primaryScreen); + } } gbm_device *QEglFSKmsDevice::device() const @@ -387,6 +407,11 @@ int QEglFSKmsDevice::fd() const return m_dri_fd; } +QPlatformCursor *QEglFSKmsDevice::globalCursor() const +{ + return m_globalCursor; +} + void QEglFSKmsDevice::handleDrmEvent() { drmEventContext drmEvent = { diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h index 29a1332c9a..23fca934e5 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.h @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -34,6 +35,7 @@ #ifndef QEGLFSKMSDEVICE_H #define QEGLFSKMSDEVICE_H +#include "qeglfskmscursor.h" #include "qeglfskmsintegration.h" #include @@ -57,6 +59,8 @@ public: gbm_device *device() const; int fd() const; + QPlatformCursor *globalCursor() const; + void handleDrmEvent(); private: @@ -70,6 +74,8 @@ private: quint32 m_crtc_allocator; quint32 m_connector_allocator; + QEglFSKmsCursor *m_globalCursor; + int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp index 7bb932cf00..45224ccb87 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -60,6 +61,7 @@ QEglFSKmsIntegration::QEglFSKmsIntegration() : m_device(Q_NULLPTR) , m_hwCursor(true) , m_pbuffers(false) + , m_separateScreens(false) {} void QEglFSKmsIntegration::platformInit() @@ -203,6 +205,11 @@ bool QEglFSKmsIntegration::hwCursor() const return m_hwCursor; } +bool QEglFSKmsIntegration::separateScreens() const +{ + return m_separateScreens; +} + QMap QEglFSKmsIntegration::outputSettings() const { return m_outputSettings; @@ -235,6 +242,7 @@ void QEglFSKmsIntegration::loadConfig() m_hwCursor = object.value(QStringLiteral("hwcursor")).toBool(m_hwCursor); m_pbuffers = object.value(QStringLiteral("pbuffers")).toBool(m_pbuffers); m_devicePath = object.value(QStringLiteral("device")).toString(); + m_separateScreens = object.value(QStringLiteral("separateScreens")).toBool(m_separateScreens); const QJsonArray outputs = object.value(QStringLiteral("outputs")).toArray(); for (int i = 0; i < outputs.size(); i++) { @@ -254,6 +262,7 @@ void QEglFSKmsIntegration::loadConfig() qCDebug(qLcEglfsKmsDebug) << "Configuration:\n" << "\thwcursor:" << m_hwCursor << "\n" << "\tpbuffers:" << m_pbuffers << "\n" + << "\tseparateScreens:" << m_separateScreens << "\n" << "\toutputs:" << m_outputSettings; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h index 9a160d2570..edb6906a4b 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.h @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -65,6 +66,7 @@ public: bool supportsPBuffers() const Q_DECL_OVERRIDE; bool hwCursor() const; + bool separateScreens() const; QMap outputSettings() const; private: @@ -73,6 +75,7 @@ private: QEglFSKmsDevice *m_device; bool m_hwCursor; bool m_pbuffers; + bool m_separateScreens; QString m_devicePath; QMap m_outputSettings; }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp index a27819d1dd..5e49c224a0 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -120,6 +121,7 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, , m_cursor(Q_NULLPTR) , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) { + m_siblings << this; } QEglFSKmsScreen::~QEglFSKmsScreen() @@ -185,6 +187,9 @@ QString QEglFSKmsScreen::name() const QPlatformCursor *QEglFSKmsScreen::cursor() const { if (m_integration->hwCursor()) { + if (!m_integration->separateScreens()) + return m_device->globalCursor(); + if (m_cursor.isNull()) { QEglFSKmsScreen *that = const_cast(this); that->m_cursor.reset(new QEglFSKmsCursor(that)); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h index 16521c7fe0..4c1b0d02ad 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2015 Pier Luigi Fiorini ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** @@ -85,6 +86,10 @@ public: qreal refreshRate() const Q_DECL_OVERRIDE; + QList virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; } + void setVirtualSiblings(QList sl) { m_siblings = sl; } + + QEglFSKmsIntegration *integration() const { return m_integration; } QEglFSKmsDevice *device() const { return m_device; } gbm_surface *surface() const { return m_gbm_surface; } @@ -110,6 +115,8 @@ private: QPoint m_pos; QScopedPointer m_cursor; + QList m_siblings; + struct FrameBuffer { FrameBuffer() : fb(0) {} uint32_t fb; -- cgit v1.2.3 From e5d85ff44ee6a3125d928597583de7a7ebe8a644 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 1 Jun 2015 09:55:12 +0200 Subject: imageviewer example: support loading images on iOS Use the last path from QSP to hint that we want to load photos from the global photo library. This should currently only make a difference on iOS. Change-Id: I7a6217dbbbc2e247b69bf406c02001458c757211 Reviewed-by: Shawn Rutledge --- examples/widgets/widgets/imageviewer/imageviewer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/widgets/widgets/imageviewer/imageviewer.cpp b/examples/widgets/widgets/imageviewer/imageviewer.cpp index c32f21e7f3..0b8513f090 100644 --- a/examples/widgets/widgets/imageviewer/imageviewer.cpp +++ b/examples/widgets/widgets/imageviewer/imageviewer.cpp @@ -107,7 +107,7 @@ void ImageViewer::open() mimeTypeFilters.sort(); const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); QFileDialog dialog(this, tr("Open File"), - picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.first()); + picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.last()); dialog.setAcceptMode(QFileDialog::AcceptOpen); dialog.setMimeTypeFilters(mimeTypeFilters); dialog.selectMimeTypeFilter("image/jpeg"); -- cgit v1.2.3 From 71fe2df77304342fd125c5607e0979c6f84b4ef8 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 7 May 2015 14:00:54 +0200 Subject: Syntax clean up in qimagescale Corrects a few white-spaces, return statements and else statements to fit Qt coding style. Comment updated to indicate how far the code is getting from its original roots. No semantic changes. Change-Id: Ia2288c501788a291bfc4e8b70e8eb1efb7a90128 Reviewed-by: Oswald Buddenhagen --- src/gui/painting/qimagescale.cpp | 53 ++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 9b4eabc552..867c64c5e0 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -77,6 +77,8 @@ QT_BEGIN_NAMESPACE * * Changes include formatting, namespaces and other C++'ings, removal of old * #ifdef'ed code, and removal of unneeded border calculation code. + * Later the code has been refactored and an SSE4.1 optimizated path have been + * added instead of the removed MMX assembler. * * Imlib2 is (C) Carsten Haitzler and various contributors. The MMX code * is by Willem Monsuwe . All other modifications are @@ -100,13 +102,13 @@ using namespace QImageScale; // const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src, - int sw, int sh, int dh) + int sw, int sh, int dh) { const unsigned int **p; int j = 0, rv = 0; qint64 val, inc; - if(dh < 0){ + if (dh < 0) { dh = -dh; rv = 1; } @@ -134,7 +136,7 @@ int* QImageScale::qimageCalcXPoints(int sw, int dw) int *p, j = 0, rv = 0; qint64 val, inc; - if(dw < 0){ + if (dw < 0) { dw = -dw; rv = 1; } @@ -155,25 +157,23 @@ int* QImageScale::qimageCalcXPoints(int sw, int dw) p[dw - i - 1] = tmp; } } - return(p); + return p; } int* QImageScale::qimageCalcApoints(int s, int d, int up) { int *p, j = 0, rv = 0; - if(d < 0){ + if (d < 0) { rv = 1; d = -d; } p = new int[d]; - /* scaling up */ - if(up){ - qint64 val, inc; - - val = 0x8000 * s / d - 0x8000; - inc = (((qint64)s) << 16) / d; + if (up) { + /* scaling up */ + qint64 val = 0x8000 * s / d - 0x8000; + qint64 inc = (((qint64)s) << 16) / d; for (int i = 0; i < d; i++) { int pos = val >> 16; if (pos < 0) @@ -184,9 +184,8 @@ int* QImageScale::qimageCalcApoints(int s, int d, int up) p[j++] = (val >> 8) - ((val >> 8) & 0xffffff00); val += inc; } - } - /* scaling down */ - else { + } else { + /* scaling down */ qint64 val = 0; qint64 inc = (((qint64)s) << 16) / d; int Cp = (((d << 14) + s - 1) / s); @@ -197,7 +196,7 @@ int* QImageScale::qimageCalcApoints(int s, int d, int up) val += inc; } } - if(rv){ + if (rv) { int tmp; for (int i = d / 2; --i >= 0; ) { tmp = p[i]; @@ -210,7 +209,7 @@ int* QImageScale::qimageCalcApoints(int s, int d, int up) QImageScaleInfo* QImageScale::qimageFreeScaleInfo(QImageScaleInfo *isi) { - if(isi){ + if (isi) { delete[] isi->xpoints; delete[] isi->ypoints; delete[] isi->xapoints; @@ -231,28 +230,28 @@ QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img, sch = dh * qlonglong(img.height()) / sh; isi = new QImageScaleInfo; - if(!isi) + if (!isi) return 0; memset(isi, 0, sizeof(QImageScaleInfo)); isi->xup_yup = (qAbs(dw) >= sw) + ((qAbs(dh) >= sh) << 1); isi->xpoints = qimageCalcXPoints(img.width(), scw); - if(!isi->xpoints) - return(qimageFreeScaleInfo(isi)); + if (!isi->xpoints) + return qimageFreeScaleInfo(isi); isi->ypoints = qimageCalcYPoints((const unsigned int *)img.scanLine(0), img.bytesPerLine() / 4, img.height(), sch); if (!isi->ypoints) - return(qimageFreeScaleInfo(isi)); - if(aa) { + return qimageFreeScaleInfo(isi); + if (aa) { isi->xapoints = qimageCalcApoints(img.width(), scw, isi->xup_yup & 1); - if(!isi->xapoints) - return(qimageFreeScaleInfo(isi)); + if (!isi->xapoints) + return qimageFreeScaleInfo(isi); isi->yapoints = qimageCalcApoints(img.height(), sch, isi->xup_yup & 2); - if(!isi->yapoints) - return(qimageFreeScaleInfo(isi)); + if (!isi->yapoints) + return qimageFreeScaleInfo(isi); } - return(isi); + return isi; } @@ -326,7 +325,7 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, int dh, int dow, int sow) { /* scaling up both ways */ - if (isi->xup_yup == 3){ + if (isi->xup_yup == 3) { qt_qimageScaleAARGBA_up_xy(isi, dest, dxx, dyy, dx, dy, dw, dh, dow, sow); } /* if we're scaling down vertically */ -- cgit v1.2.3 From beef975f92e42143c464d68afa6b8cd4f7ef7389 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 2 Jun 2015 08:43:17 +0200 Subject: Cleanup the mouse event handling in testlib Calling QCursor::setPos() to emulate mouse move events is a rather bad idea, as it creates round trips through the server, leading to timing issues etc. In addition, we should not call qapp->notify(), but rather route the events through the proper QPA interface. This is required to properly generate all other events such as enter/leave etc. As this breaks existing tests, put the new behavior behind an #ifdef for now. Like this, we can fix tests one by one, and then turn on the define by default for 5.6 (with a changelog message). We emulate timestamps to avoid creating double clicks by mistake. In addition, fix QGuiApplication::processMouseEvent to not push events back into the QPA event queue (as this is a bad hack and breaks the new testing system). Change-Id: I71774cb56674d7fb66b9a7cf1e1ada1629536408 Reviewed-by: Simon Hausmann --- src/gui/kernel/qguiapplication.cpp | 10 +++-- src/gui/kernel/qwindowsysteminterface.cpp | 4 +- src/testlib/qtestmouse.h | 72 ++++++++++++++++--------------- 3 files changed, 46 insertions(+), 40 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 4146ddd8ba..024578ccdd 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1695,12 +1695,14 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo // A mouse event should not change both position and buttons at the same time. Instead we // should first send a move event followed by a button changed event. Since this is not the case // with the current event, we split it in two. - QWindowSystemInterfacePrivate::MouseEvent *mouseButtonEvent = new QWindowSystemInterfacePrivate::MouseEvent( + QWindowSystemInterfacePrivate::MouseEvent mouseButtonEvent( e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers); if (e->flags & QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic) - mouseButtonEvent->flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; - QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(mouseButtonEvent); - stateChange = Qt::NoButton; + mouseButtonEvent.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic; + e->buttons = buttons; + processMouseEvent(e); + processMouseEvent(&mouseButtonEvent); + return; } QWindow *window = e->window.data(); diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index de8e5fbe64..823387b702 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -810,8 +810,8 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPo } #endif -Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier) { - unsigned long timestamp = QWindowSystemInterfacePrivate::eventTime.elapsed(); +Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, int timestamp) +{ QWindowSystemInterfacePrivate::MouseEvent e(w, timestamp, local, global, b, mods, Qt::MouseEventNotSynthesized); QGuiApplicationPrivate::processWindowSystemEvent(&e); } diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h index 2cf84a7ea0..5f69463867 100644 --- a/src/testlib/qtestmouse.h +++ b/src/testlib/qtestmouse.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -57,7 +58,7 @@ QT_BEGIN_NAMESPACE -Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier); +Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, int timestamp); namespace QTest { @@ -83,7 +84,8 @@ namespace QTest QTest::qWarn("Mouse event occurs outside of target window."); } - static Qt::MouseButton lastButton = Qt::NoButton; + static Qt::MouseButton lastButton = Qt::NoButton; + static int timestamp = 0; if (delay == -1 || delay < defaultMouseDelay()) delay = defaultMouseDelay(); @@ -93,42 +95,38 @@ namespace QTest if (pos.isNull()) pos = window->geometry().center(); - if (action == MouseClick) { - mouseEvent(MousePress, window, button, stateKey, pos); - mouseEvent(MouseRelease, window, button, stateKey, pos); - return; - } QTEST_ASSERT(uint(stateKey) == 0 || stateKey & Qt::KeyboardModifierMask); stateKey &= static_cast(Qt::KeyboardModifierMask); + QPointF global = window->mapToGlobal(pos); + QPointer w(window); switch (action) { - case MousePress: - qt_handleMouseEvent(window,pos,window->mapToGlobal(pos),button,stateKey); - lastButton = button; - break; - case MouseRelease: - qt_handleMouseEvent(window,pos,window->mapToGlobal(pos),Qt::NoButton,stateKey); - lastButton = Qt::NoButton; + case MouseDClick: + qt_handleMouseEvent(w, pos, global, button, stateKey, timestamp); + qt_handleMouseEvent(w, pos, global, Qt::NoButton, stateKey, ++timestamp); + // fall through + case MousePress: + case MouseClick: + qt_handleMouseEvent(w, pos, global, button, stateKey, ++timestamp); + lastButton = button; + if (action == MousePress) break; - case MouseDClick: - qt_handleMouseEvent(window,pos,window->mapToGlobal(pos),button,stateKey); - qWait(10); - qt_handleMouseEvent(window,pos,window->mapToGlobal(pos),Qt::NoButton,stateKey); - qWait(20); - qt_handleMouseEvent(window,pos,window->mapToGlobal(pos),button,stateKey); - qWait(10); - qt_handleMouseEvent(window,pos,window->mapToGlobal(pos),Qt::NoButton,stateKey); - break; - case MouseMove: - qt_handleMouseEvent(window,pos,window->mapToGlobal(pos),lastButton,stateKey); - // No QCursor::setPos() call here. That could potentially result in mouse events sent by the windowing system - // which is highly undesired here. Tests must avoid relying on QCursor. - break; - default: - QTEST_ASSERT(false); + // fall through + case MouseRelease: + qt_handleMouseEvent(w, pos, global, Qt::NoButton, stateKey, ++timestamp); + timestamp += 500; // avoid double clicks being generated + lastButton = Qt::NoButton; + break; + case MouseMove: + qt_handleMouseEvent(w, pos, global, lastButton, stateKey, ++timestamp); + // No QCursor::setPos() call here. That could potentially result in mouse events sent by the windowing system + // which is highly undesired here. Tests must avoid relying on QCursor. + break; + default: + QTEST_ASSERT(false); } waitForEvents(); } @@ -153,6 +151,15 @@ namespace QTest Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1) { QTEST_ASSERT(widget); + + if (pos.isNull()) + pos = widget->rect().center(); + +#ifdef QTEST_QPA_MOUSE_HANDLING + QWindow *w = widget->window()->windowHandle(); + QTEST_ASSERT(w); + mouseEvent(action, w, button, stateKey, w->mapFromGlobal(widget->mapToGlobal(pos)), delay); +#else extern int Q_TESTLIB_EXPORT defaultMouseDelay(); if (delay == -1 || delay < defaultMouseDelay()) @@ -160,9 +167,6 @@ namespace QTest if (delay > 0) QTest::qWait(delay); - if (pos.isNull()) - pos = widget->rect().center(); - if (action == MouseClick) { mouseEvent(MousePress, widget, button, stateKey, pos); mouseEvent(MouseRelease, widget, button, stateKey, pos); @@ -203,7 +207,7 @@ namespace QTest QString warning = QString::fromLatin1("Mouse event \"%1\" not accepted by receiving widget"); QTest::qWarn(warning.arg(QString::fromLatin1(mouseActionNames[static_cast(action)])).toLatin1().data()); } - +#endif } inline void mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, -- cgit v1.2.3 From 9b0809d50a50ae7c5eb3d58d0bfbca5b7f8de4ec Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 1 Jun 2015 11:52:45 +0200 Subject: Fix crash during autotest execution on Mac OS X Change-Id: Ib9cd6791a7b48a0cde9e6d991b2d7f6fb4020819 Reviewed-by: Simon Hausmann --- src/widgets/accessible/itemviews.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp index 4f6cb56060..c7625c2827 100644 --- a/src/widgets/accessible/itemviews.cpp +++ b/src/widgets/accessible/itemviews.cpp @@ -1010,6 +1010,9 @@ QAccessible::Role QAccessibleTableCell::role() const QAccessible::State QAccessibleTableCell::state() const { QAccessible::State st; + if (!view) + return st; + QRect globalRect = view->rect(); globalRect.translate(view->mapToGlobal(QPoint(0,0))); if (!globalRect.intersects(rect())) -- cgit v1.2.3 From a1c0a59ce6488134a38552fd12c831d2aa0f2693 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 26 May 2015 17:32:47 +0200 Subject: deprecate DEPLOYMENT variable Deprecate the qmake variable DEPLOYMENT that was used for installing files on remote devices for Windows RT and Windows CE Visual Studio projects. Use INSTALLS for both nmake and Visual Studio projects. [ChangeLog][core][qmake] Deprecated the qmake variable DEPLOYMENT in favor of INSTALLS. Task-number: QTBUG-21854 Change-Id: Ia9d2c69feb7d87b0b9dc69ff7c0a68be35a57acd Reviewed-by: Oliver Wolff Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt.prf | 2 +- qmake/doc/snippets/code/doc_src_qmake-manual.pro | 15 --------- qmake/doc/src/qmake-manual.qdoc | 39 +++++------------------- qmake/generators/win32/msvc_vcproj.cpp | 3 +- qmake/library/qmakeevaluator.cpp | 3 +- 5 files changed, 11 insertions(+), 51 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 264641b5b3..464aca4d71 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -260,7 +260,7 @@ for(QT_CURRENT_VERIFY, $$list($$QT_PLUGIN_VERIFY)) { eval(qt_additional_plugin_$${QTPLUG}.files = $$[QT_INSTALL_PLUGINS/get]/$${QT_PLUGINPATH}/$${QT_ITEM}) eval(qt_additional_plugin_$${QTPLUG}.path = $${QT_PLUGINPATH}) - DEPLOYMENT *= qt_additional_plugin_$${QTPLUG} + INSTALLS *= qt_additional_plugin_$${QTPLUG} } } } diff --git a/qmake/doc/snippets/code/doc_src_qmake-manual.pro b/qmake/doc/snippets/code/doc_src_qmake-manual.pro index 748b6bb646..7609a98111 100644 --- a/qmake/doc/snippets/code/doc_src_qmake-manual.pro +++ b/qmake/doc/snippets/code/doc_src_qmake-manual.pro @@ -186,21 +186,6 @@ DEFINES += USE_MY_STUFF #! [27] -#! [28] -myFiles.files = path\*.png -DEPLOYMENT += myFiles -#! [28] - - -#! [29] -myFiles.files = path\file1.ext1 path2\file2.ext1 path3\* -myFiles.path = \some\path\on\device -someother.files = C:\additional\files\* -someother.path = \myFiles\path2 -DEPLOYMENT += myFiles someother -#! [29] - - #! [30] DESTDIR = ../../lib #! [30] diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index bda658689c..6f855ba9ca 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -1120,38 +1120,6 @@ Specifies a list of all directories to look in to resolve dependencies. This variable is used when crawling through \c included files. - \target DEPLOYMENT - \section1 DEPLOYMENT - - \note This variable is used only on the Windows CE platform. - - Specifies which additional files will be deployed. Deployment means the - transfer of files from the development system to the target device or - emulator. - - Files can be deployed by either creating a Visual Studio project or using - the \l {Using Qt Test remotely on Windows CE}{cetest} executable. - - For example, the following definition uploads all PNG images in \c path to - the directory where the build target is deployed: - - \snippet code/doc_src_qmake-manual.pro 28 - - The default deployment target path for Windows CE is - \c{%CSIDL_PROGRAM_FILES%\target}, which usually gets expanded to - \c{\Program Files\target}. - - It is also possible to specify multiple \c sources to be deployed on - target \c paths. In addition, different variables can be used for - deployment to different directories. - - For example: - - \snippet code/doc_src_qmake-manual.pro 29 - - \note In Windows CE all linked Qt libraries will be deployed to the path - specified by \c{myFiles.path}. - \target DEPLOYMENT_PLUGIN \section1 DEPLOYMENT_PLUGIN @@ -1276,6 +1244,13 @@ For more information, see \l{Installing Files}. + This variable is also used to specify which additional files will be + deployed to embedded devices. + + For Windows CE, the default deployment target path is + \c{%CSIDL_PROGRAM_FILES%\target}, which usually gets expanded to + \c{\Program Files\target}. + \target LEXIMPLS \section1 LEXIMPLS diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 0ece5786bd..20113e5746 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1374,8 +1374,7 @@ void VcprojGenerator::initDeploymentTool() } } - // foreach item in DEPLOYMENT - foreach (const ProString &item, project->values("DEPLOYMENT")) { + foreach (const ProString &item, project->values("INSTALLS")) { // get item.path QString devicePath = project->first(ProKey(item + ".path")).toQString(); if (!conf.WinRT) { diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 5c9dc45f3a..723d5c7271 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -188,7 +188,8 @@ void QMakeEvaluator::initStatics() { "QMAKE_RPATH", "QMAKE_LFLAGS_RPATH" }, { "QMAKE_FRAMEWORKDIR", "QMAKE_FRAMEWORKPATH" }, { "QMAKE_FRAMEWORKDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS" }, - { "IN_PWD", "PWD" } + { "IN_PWD", "PWD" }, + { "DEPLOYMENT", "INSTALLS" } }; for (unsigned i = 0; i < sizeof(mapInits)/sizeof(mapInits[0]); ++i) statics.varMap.insert(ProKey(mapInits[i].oldname), ProKey(mapInits[i].newname)); -- cgit v1.2.3 From cd0bed6d7189fe338043e5dbdf5e8b110da7b06f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 2 Jun 2015 10:17:38 +0200 Subject: Polish and stabilize tst_qtooltip. - Implement init() and cleanup() to verify that no top level widgets are leaked. - Position widget in tst_QToolTip::task183679() and set window title. - Remove hardcoded wait in tst_QToolTip::whatsThis() and use a find function within QTRY_VERIFY(). - Rearrange and clean code a bit. Change-Id: I0b1ad88444fc9441c1071a2527f75de1f68ea9e5 Reviewed-by: Simon Hausmann --- .../auto/widgets/kernel/qtooltip/tst_qtooltip.cpp | 62 +++++++++++++--------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp index ebd99be786..0de9e188a0 100644 --- a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp +++ b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp @@ -34,30 +34,32 @@ #include #include +#include +#include class tst_QToolTip : public QObject { Q_OBJECT -public: - tst_QToolTip() {} - virtual ~tst_QToolTip() {} - -public slots: - void initTestCase() {} - void cleanupTestCase() {} - void init() {} - void cleanup() {} - private slots: - - // task-specific tests below me + void init(); + void cleanup(); void task183679_data(); void task183679(); void whatsThis(); void setPalette(); }; +void tst_QToolTip::init() +{ + QVERIFY(!QToolTip::isVisible()); +} + +void tst_QToolTip::cleanup() +{ + QTRY_VERIFY(QApplication::topLevelWidgets().isEmpty()); +} + class Widget_task183679 : public QWidget { Q_OBJECT @@ -100,12 +102,14 @@ void tst_QToolTip::task183679() #endif Widget_task183679 widget; + widget.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(50, 50)); + widget.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + + QLatin1Char(' ') + QLatin1String(QTest::currentDataTag())); widget.show(); QApplication::setActiveWindow(&widget); QVERIFY(QTest::qWaitForWindowActive(&widget)); widget.showDelayedToolTip(100); - QTest::qWait(300); QTRY_VERIFY(QToolTip::isVisible()); QTest::keyPress(&widget, key); @@ -116,26 +120,31 @@ void tst_QToolTip::task183679() QTest::qWait(1500); QCOMPARE(QToolTip::isVisible(), visible); + if (visible) + QToolTip::hideText(); } -#include +static QWidget *findWhatsThat() +{ + foreach (QWidget *widget, QApplication::topLevelWidgets()) { + if (widget->inherits("QWhatsThat")) + return widget; + } + return Q_NULLPTR; +} void tst_QToolTip::whatsThis() { qApp->setStyleSheet( "QWidget { font-size: 72px; }" ); - QWhatsThis::showText(QPoint(0,0), "THis is text"); - QTest::qWait(400); - QWidget *whatsthis = 0; - foreach (QWidget *widget, QApplication::topLevelWidgets()) { - if (widget->inherits("QWhatsThat")) { - whatsthis = widget; - break; - } - } - QVERIFY(whatsthis); + QWhatsThis::showText(QPoint(0, 0), "This is text"); + + QWidget *whatsthis = Q_NULLPTR; + QTRY_VERIFY( (whatsthis = findWhatsThat()) ); QVERIFY(whatsthis->isVisible()); - QVERIFY(whatsthis->height() > 100); // Test QTBUG-2416 - qApp->setStyleSheet(""); + const int whatsThisHeight = whatsthis->height(); + qApp->setStyleSheet(QString()); + QWhatsThis::hideText(); + QVERIFY2(whatsThisHeight > 100, QByteArray::number(whatsThisHeight)); // Test QTBUG-2416 } @@ -167,6 +176,7 @@ void tst_QToolTip::setPalette() newPalette.setColor(QPalette::ToolTipText, Qt::blue); QToolTip::setPalette(newPalette); QCOMPARE(toolTip->palette(), newPalette); + QToolTip::hideText(); } QTEST_MAIN(tst_QToolTip) -- cgit v1.2.3 From f44a59f390be9b67365db8796aa6a54fe9241028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Sun, 10 May 2015 12:26:47 +0100 Subject: Don't assign iterator to const_iterator It should also be possible to use QT_STRICT_ITERATORS in Qt's own code base Change-Id: I0914db480d4d2b06e71e3a2588163efdd3ff6d27 Reviewed-by: Marc Mutz Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qcommandlineparser.cpp | 8 ++-- src/gui/text/qfontengine_ft.cpp | 2 +- src/network/ssl/qasn1element.cpp | 52 ++++++++++++------------ src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 4 +- src/tools/qdoc/htmlgenerator.cpp | 4 +- src/tools/qdoc/node.cpp | 12 +++--- src/tools/qdoc/puredocparser.cpp | 4 +- src/tools/qdoc/qdocdatabase.cpp | 4 +- src/tools/qdoc/tree.cpp | 8 ++-- 9 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index 21bc14a272..0814921a58 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -115,8 +115,8 @@ public: QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const { - const NameHash_t::const_iterator it = nameHash.find(optionName); - if (it == nameHash.end()) { + const NameHash_t::const_iterator it = nameHash.constFind(optionName); + if (it == nameHash.cend()) { qWarning("QCommandLineParser: option not defined: \"%s\"", qPrintable(optionName)); return QStringList(); } @@ -806,8 +806,8 @@ QString QCommandLineParser::value(const QString &optionName) const QStringList QCommandLineParser::values(const QString &optionName) const { d->checkParsed("values"); - const NameHash_t::const_iterator it = d->nameHash.find(optionName); - if (it != d->nameHash.end()) { + const NameHash_t::const_iterator it = d->nameHash.constFind(optionName); + if (it != d->nameHash.cend()) { const int optionOffset = *it; QStringList values = d->optionValuesHash.value(optionOffset); if (values.isEmpty()) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 931c71dc63..37be0afccf 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -115,7 +115,7 @@ public: QtFreetypeData::~QtFreetypeData() { - for (QHash::ConstIterator iter = faces.begin(); iter != faces.end(); ++iter) + for (QHash::ConstIterator iter = faces.cbegin(); iter != faces.cend(); ++iter) iter.value()->cleanup(); faces.clear(); FT_Done_FreeType(library); diff --git a/src/network/ssl/qasn1element.cpp b/src/network/ssl/qasn1element.cpp index 95c360e7af..82807aec6e 100644 --- a/src/network/ssl/qasn1element.cpp +++ b/src/network/ssl/qasn1element.cpp @@ -46,32 +46,32 @@ static OidNameMap createOidMap() { OidNameMap oids; // used by unit tests - oids.insert(oids.end(), QByteArrayLiteral("0.9.2342.19200300.100.1.5"), QByteArrayLiteral("favouriteDrink")); - oids.insert(oids.end(), QByteArrayLiteral("1.2.840.113549.1.9.1"), QByteArrayLiteral("emailAddress")); - oids.insert(oids.end(), QByteArrayLiteral("1.3.6.1.5.5.7.1.1"), QByteArrayLiteral("authorityInfoAccess")); - oids.insert(oids.end(), QByteArrayLiteral("1.3.6.1.5.5.7.48.1"), QByteArrayLiteral("OCSP")); - oids.insert(oids.end(), QByteArrayLiteral("1.3.6.1.5.5.7.48.2"), QByteArrayLiteral("caIssuers")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.29.14"), QByteArrayLiteral("subjectKeyIdentifier")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.29.15"), QByteArrayLiteral("keyUsage")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.29.17"), QByteArrayLiteral("subjectAltName")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.29.19"), QByteArrayLiteral("basicConstraints")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.29.35"), QByteArrayLiteral("authorityKeyIdentifier")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.10"), QByteArrayLiteral("O")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.11"), QByteArrayLiteral("OU")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.12"), QByteArrayLiteral("title")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.13"), QByteArrayLiteral("description")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.17"), QByteArrayLiteral("postalCode")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.3"), QByteArrayLiteral("CN")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.4"), QByteArrayLiteral("SN")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.41"), QByteArrayLiteral("name")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.42"), QByteArrayLiteral("GN")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.43"), QByteArrayLiteral("initials")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.46"), QByteArrayLiteral("dnQualifier")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.5"), QByteArrayLiteral("serialNumber")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.6"), QByteArrayLiteral("C")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.7"), QByteArrayLiteral("L")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.8"), QByteArrayLiteral("ST")); - oids.insert(oids.end(), QByteArrayLiteral("2.5.4.9"), QByteArrayLiteral("street")); + oids.insert(oids.cend(), QByteArrayLiteral("0.9.2342.19200300.100.1.5"), QByteArrayLiteral("favouriteDrink")); + oids.insert(oids.cend(), QByteArrayLiteral("1.2.840.113549.1.9.1"), QByteArrayLiteral("emailAddress")); + oids.insert(oids.cend(), QByteArrayLiteral("1.3.6.1.5.5.7.1.1"), QByteArrayLiteral("authorityInfoAccess")); + oids.insert(oids.cend(), QByteArrayLiteral("1.3.6.1.5.5.7.48.1"), QByteArrayLiteral("OCSP")); + oids.insert(oids.cend(), QByteArrayLiteral("1.3.6.1.5.5.7.48.2"), QByteArrayLiteral("caIssuers")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.29.14"), QByteArrayLiteral("subjectKeyIdentifier")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.29.15"), QByteArrayLiteral("keyUsage")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.29.17"), QByteArrayLiteral("subjectAltName")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.29.19"), QByteArrayLiteral("basicConstraints")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.29.35"), QByteArrayLiteral("authorityKeyIdentifier")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.10"), QByteArrayLiteral("O")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.11"), QByteArrayLiteral("OU")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.12"), QByteArrayLiteral("title")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.13"), QByteArrayLiteral("description")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.17"), QByteArrayLiteral("postalCode")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.3"), QByteArrayLiteral("CN")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.4"), QByteArrayLiteral("SN")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.41"), QByteArrayLiteral("name")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.42"), QByteArrayLiteral("GN")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.43"), QByteArrayLiteral("initials")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.46"), QByteArrayLiteral("dnQualifier")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.5"), QByteArrayLiteral("serialNumber")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.6"), QByteArrayLiteral("C")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.7"), QByteArrayLiteral("L")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.8"), QByteArrayLiteral("ST")); + oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.9"), QByteArrayLiteral("street")); return oids; } Q_GLOBAL_STATIC_WITH_ARGS(OidNameMap, oidNameMap, (createOidMap())) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 0e8a162a7d..c7784ddb48 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -364,8 +364,8 @@ void QXcbConnection::xi2Select(xcb_window_t window) XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) { XInput2TouchDeviceData *dev = Q_NULLPTR; - QHash::const_iterator devIt = m_touchDevices.find(id); - if ( devIt != m_touchDevices.end() ) { + QHash::const_iterator devIt = m_touchDevices.constFind(id); + if (devIt != m_touchDevices.cend()) { dev = devIt.value(); } else { int nrDevices = 0; diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 8d84019ab5..b340883c12 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -2199,7 +2199,7 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker) out() << "
\n"; QStringList::ConstIterator i; - for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) { + for (i = requisiteorder.constBegin(); i != requisiteorder.constEnd(); ++i) { if (requisites.contains(*i)) { out() << "" @@ -2319,7 +2319,7 @@ void HtmlGenerator::generateQmlRequisites(QmlTypeNode *qcn, CodeMarker *marker) out() << "
\n"; QStringList::ConstIterator i; - for (i = requisiteorder.begin(); i != requisiteorder.constEnd(); ++i) { + for (i = requisiteorder.constBegin(); i != requisiteorder.constEnd(); ++i) { if (requisites.contains(*i)) { out() << "" diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index 230ce50df8..37bc0c5fef 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -2763,8 +2763,8 @@ bool CollectionNode::hasNamespaces() const bool CollectionNode::hasClasses() const { if (!members_.isEmpty()) { - NodeList::const_iterator i = members_.begin(); - while (i != members_.end()) { + NodeList::const_iterator i = members_.cbegin(); + while (i != members_.cend()) { if ((*i)->isClass()) return true; ++i; @@ -2780,8 +2780,8 @@ bool CollectionNode::hasClasses() const void CollectionNode::getMemberNamespaces(NodeMap& out) { out.clear(); - NodeList::const_iterator i = members_.begin(); - while (i != members_.end()) { + NodeList::const_iterator i = members_.cbegin(); + while (i != members_.cend()) { if ((*i)->isNamespace()) out.insert((*i)->name(),(*i)); ++i; @@ -2795,8 +2795,8 @@ void CollectionNode::getMemberNamespaces(NodeMap& out) void CollectionNode::getMemberClasses(NodeMap& out) { out.clear(); - NodeList::const_iterator i = members_.begin(); - while (i != members_.end()) { + NodeList::const_iterator i = members_.cbegin(); + while (i != members_.cend()) { if ((*i)->isClass()) out.insert((*i)->name(),(*i)); ++i; diff --git a/src/tools/qdoc/puredocparser.cpp b/src/tools/qdoc/puredocparser.cpp index 7029431460..e47460efb2 100644 --- a/src/tools/qdoc/puredocparser.cpp +++ b/src/tools/qdoc/puredocparser.cpp @@ -188,8 +188,8 @@ bool PureDocParser::processQdocComments() topics.insert(i+1,"and"); doc.location().warning(tr("Multiple topic commands found in comment: %1").arg(topics)); } - ArgList::ConstIterator a = args.begin(); - while (a != args.end()) { + ArgList::ConstIterator a = args.cbegin(); + while (a != args.cend()) { Doc nodeDoc = doc; Node* node = processTopicCommand(nodeDoc,topic,*a); if (node != 0) { diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp index f1afb92eff..bf84fa8335 100644 --- a/src/tools/qdoc/qdocdatabase.cpp +++ b/src/tools/qdoc/qdocdatabase.cpp @@ -1549,8 +1549,8 @@ void QDocDatabase::mergeCollections(Node::Genus genus, CNMap& cnm, const Node* r foreach (Tree* t, searchOrder()) { CNMap* m = t->getCollectionMap(genus); if (m && !m->isEmpty()) { - CNMap::const_iterator i = m->begin(); - while (i != m->end()) { + CNMap::const_iterator i = m->cbegin(); + while (i != m->cend()) { if (!i.value()->isInternal()) cnmm.insert(i.key(), i.value()); ++i; diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp index 420396e51c..1b0aba1a0c 100644 --- a/src/tools/qdoc/tree.cpp +++ b/src/tools/qdoc/tree.cpp @@ -1222,8 +1222,8 @@ CollectionNode* Tree::getCollection(const QString& name, Node::Genus genus) { CNMap* m = getCollectionMap(genus); if (m) { - CNMap::const_iterator i = m->find(name); - if (i != m->end()) + CNMap::const_iterator i = m->constFind(name); + if (i != m->cend()) return i.value(); } return 0; @@ -1249,8 +1249,8 @@ CollectionNode* Tree::findCollection(const QString& name, Node::Genus genus) CNMap* m = getCollectionMap(genus); if (!m) // error return 0; - CNMap::const_iterator i = m->find(name); - if (i != m->end()) + CNMap::const_iterator i = m->constFind(name); + if (i != m->cend()) return i.value(); Node::Type t = Node::NoType; switch (genus) { -- cgit v1.2.3 From b1a0cf72f84803196539c4b0b03bfaeea9000d94 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 26 May 2015 22:16:25 +0200 Subject: QRunnable: declare dtor out-of-line and export class De-duplicates vtables and enables RTTI on this hierarchy. Change-Id: Ia60f4aa446f93ab91ea8780a3acc1118210ba7d5 Reported-by: Volker Krause Task-number: QTBUG-45582 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/corelib/thread/qrunnable.cpp | 11 +++++++++++ src/corelib/thread/qrunnable.h | 5 ++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/corelib/thread/qrunnable.cpp b/src/corelib/thread/qrunnable.cpp index 64a2613d27..04aa39a81e 100644 --- a/src/corelib/thread/qrunnable.cpp +++ b/src/corelib/thread/qrunnable.cpp @@ -31,6 +31,15 @@ ** ****************************************************************************/ +#include "qrunnable.h" + +QT_BEGIN_NAMESPACE + +QRunnable::~QRunnable() +{ + // Must be empty until ### Qt 6 +} + /*! \class QRunnable \inmodule QtCore @@ -98,3 +107,5 @@ \sa autoDelete(), QThreadPool */ + +QT_END_NAMESPACE diff --git a/src/corelib/thread/qrunnable.h b/src/corelib/thread/qrunnable.h index f00c58d51d..7233f33621 100644 --- a/src/corelib/thread/qrunnable.h +++ b/src/corelib/thread/qrunnable.h @@ -38,8 +38,7 @@ QT_BEGIN_NAMESPACE - -class QRunnable +class Q_CORE_EXPORT QRunnable { int ref; @@ -51,7 +50,7 @@ public: virtual void run() = 0; QRunnable() : ref(0) { } - virtual ~QRunnable() { } + virtual ~QRunnable(); bool autoDelete() const { return ref != -1; } void setAutoDelete(bool _autoDelete) { ref = _autoDelete ? 0 : -1; } -- cgit v1.2.3 From 2fa7b3b317fa941064ec4ba62163e3244becf55a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 26 May 2015 22:16:25 +0200 Subject: Q(Unhandled)Exception: declare dtor out-of-line De-duplicates vtables and enables RTTI on this hierarchy. This is esp. important for exception classes, as RTTI is used to select the catch clause to handle the exception in-flight. The issue is made a bit complicated by the fact that the exception specification changed from C++98 to 11 and that C++98 clients require the empty throw() specification while we don't want to introduce warnings for C++11 users. Let's hope no compiler includes throw specs into the mangled names. Task-number: QTBUG-45582 Change-Id: If086c8c38fccdc2c9c7e2aa7a492192cc1f86a6c Reviewed-by: Thiago Macieira --- src/corelib/thread/qexception.cpp | 10 ++++++++++ src/corelib/thread/qexception.h | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/corelib/thread/qexception.cpp b/src/corelib/thread/qexception.cpp index acc3663936..550bdc8fe4 100644 --- a/src/corelib/thread/qexception.cpp +++ b/src/corelib/thread/qexception.cpp @@ -107,6 +107,11 @@ QT_BEGIN_NAMESPACE \internal */ +QException::~QException() +{ + // must stay empty until ### Qt 6 +} + void QException::raise() const { QException e = *this; @@ -118,6 +123,11 @@ QException *QException::clone() const return new QException(*this); } +QUnhandledException::~QUnhandledException() +{ + // must stay empty until ### Qt 6 +} + void QUnhandledException::raise() const { QUnhandledException e = *this; diff --git a/src/corelib/thread/qexception.h b/src/corelib/thread/qexception.h index 55fc441020..edf361ebd3 100644 --- a/src/corelib/thread/qexception.h +++ b/src/corelib/thread/qexception.h @@ -53,6 +53,11 @@ QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QException : public std::exception { public: + ~QException() +#ifndef Q_COMPILER_NOEXCEPT + throw() +#endif + ; virtual void raise() const; virtual QException *clone() const; }; @@ -60,6 +65,11 @@ public: class Q_CORE_EXPORT QUnhandledException : public QException { public: + ~QUnhandledException() +#ifndef Q_COMPILER_NOEXCEPT + throw() +#endif +; void raise() const Q_DECL_OVERRIDE; QUnhandledException *clone() const Q_DECL_OVERRIDE; }; -- cgit v1.2.3 From f0a4d6463e5260a4fa46744b8c65877c9b5fae85 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 1 Jun 2015 15:57:22 +0200 Subject: QRunnable: add Q_DISABLE_COPY ...but only for Qt 6. It's a source-incompatible change, e.g. in a user hierarchy of clone()able runnables. Change-Id: I8610308dea46da19bda5c96985d35f31c43484be Reviewed-by: Thiago Macieira --- src/corelib/thread/qrunnable.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/thread/qrunnable.h b/src/corelib/thread/qrunnable.h index 7233f33621..28d14a46c0 100644 --- a/src/corelib/thread/qrunnable.h +++ b/src/corelib/thread/qrunnable.h @@ -45,7 +45,9 @@ class Q_CORE_EXPORT QRunnable friend class QThreadPool; friend class QThreadPoolPrivate; friend class QThreadPoolThread; - +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + Q_DISABLE_COPY(QRunnable) +#endif public: virtual void run() = 0; -- cgit v1.2.3 From 6a86b8fa7802b49296e12a846524e0918a59b997 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 1 Jun 2015 14:42:21 +0200 Subject: QTestLib: Move lastButton member into implementation Keeping a static variable in an inline function is a bad idea because each definition of that function will have its own version of the variable. As qtestmouse.h can be included multiple times in the same test (via some utility classes as with tst_qquickflickable), this leads to confusion. Change-Id: I80f198817c34c3a7e07bf6944189927817efb8a6 Reviewed-by: Lars Knoll Reviewed-by: Simon Hausmann Reviewed-by: Marc Mutz --- src/testlib/qtestmouse.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++ src/testlib/qtestmouse.h | 22 +++++++++++----------- src/testlib/testlib.pro | 1 + 3 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 src/testlib/qtestmouse.cpp diff --git a/src/testlib/qtestmouse.cpp b/src/testlib/qtestmouse.cpp new file mode 100644 index 0000000000..99a75744fa --- /dev/null +++ b/src/testlib/qtestmouse.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtTest module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +namespace QTest { + +Q_TESTLIB_EXPORT Qt::MouseButton lastMouseButton = Qt::NoButton; +Q_TESTLIB_EXPORT int lastMouseTimestamp = 0; + +} // namespace QTest + +QT_END_NAMESPACE diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h index 5f69463867..fa6bb29d3a 100644 --- a/src/testlib/qtestmouse.h +++ b/src/testlib/qtestmouse.h @@ -64,6 +64,9 @@ namespace QTest { enum MouseAction { MousePress, MouseRelease, MouseClick, MouseDClick, MouseMove }; + extern Q_TESTLIB_EXPORT Qt::MouseButton lastMouseButton; + extern Q_TESTLIB_EXPORT int lastMouseTimestamp; + static void waitForEvents() { #ifdef Q_OS_MAC @@ -84,9 +87,6 @@ namespace QTest QTest::qWarn("Mouse event occurs outside of target window."); } - static Qt::MouseButton lastButton = Qt::NoButton; - static int timestamp = 0; - if (delay == -1 || delay < defaultMouseDelay()) delay = defaultMouseDelay(); if (delay > 0) @@ -105,23 +105,23 @@ namespace QTest switch (action) { case MouseDClick: - qt_handleMouseEvent(w, pos, global, button, stateKey, timestamp); - qt_handleMouseEvent(w, pos, global, Qt::NoButton, stateKey, ++timestamp); + qt_handleMouseEvent(w, pos, global, button, stateKey, lastMouseTimestamp); + qt_handleMouseEvent(w, pos, global, Qt::NoButton, stateKey, ++lastMouseTimestamp); // fall through case MousePress: case MouseClick: - qt_handleMouseEvent(w, pos, global, button, stateKey, ++timestamp); - lastButton = button; + qt_handleMouseEvent(w, pos, global, button, stateKey, ++lastMouseTimestamp); + lastMouseButton = button; if (action == MousePress) break; // fall through case MouseRelease: - qt_handleMouseEvent(w, pos, global, Qt::NoButton, stateKey, ++timestamp); - timestamp += 500; // avoid double clicks being generated - lastButton = Qt::NoButton; + qt_handleMouseEvent(w, pos, global, Qt::NoButton, stateKey, ++lastMouseTimestamp); + lastMouseTimestamp += 500; // avoid double clicks being generated + lastMouseButton = Qt::NoButton; break; case MouseMove: - qt_handleMouseEvent(w, pos, global, lastButton, stateKey, ++timestamp); + qt_handleMouseEvent(w, pos, global, lastMouseButton, stateKey, ++lastMouseTimestamp); // No QCursor::setPos() call here. That could potentially result in mouse events sent by the windowing system // which is highly undesired here. Tests must avoid relying on QCursor. break; diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro index 52bcdd097b..2d9bae5f31 100644 --- a/src/testlib/testlib.pro +++ b/src/testlib/testlib.pro @@ -56,6 +56,7 @@ SOURCES = qtestcase.cpp \ qcsvbenchmarklogger.cpp \ qtestelement.cpp \ qtestelementattribute.cpp \ + qtestmouse.cpp \ qtestxunitstreamer.cpp \ qxunittestlogger.cpp \ qtestblacklist.cpp -- cgit v1.2.3 From 933bf178aab88ab5df8a68cbf02611d6d8744b1b Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 26 May 2015 22:16:25 +0200 Subject: QFramePrivate & subclasses: declare dtor out-of-line De-duplicates vtables and enables RTTI on this class hierarchy. Export QFramePrivate, as QAbstractScrollAreaPrivate (a subclass) is exported, too. Change-Id: I541886373435dc49c4267190a7191e2436f4c95e Reported-by: Volker Krause Task-number: QTBUG-45582 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/widgets/widgets/qabstractscrollarea.cpp | 4 ++++ src/widgets/widgets/qabstractscrollarea_p.h | 3 +++ src/widgets/widgets/qframe.cpp | 4 ++++ src/widgets/widgets/qframe_p.h | 4 +++- src/widgets/widgets/qlabel.cpp | 4 ++++ src/widgets/widgets/qlabel_p.h | 1 + src/widgets/widgets/qsplitter.cpp | 4 ++++ src/widgets/widgets/qsplitter_p.h | 1 + 8 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 2e1caedde7..5e45c66f3b 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -168,6 +168,10 @@ QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate() { } +QAbstractScrollAreaPrivate::~QAbstractScrollAreaPrivate() +{ +} + QAbstractScrollAreaScrollBarContainer::QAbstractScrollAreaScrollBarContainer(Qt::Orientation orientation, QWidget *parent) :QWidget(parent), scrollBar(new QScrollBar(orientation, this)), layout(new QBoxLayout(orientation == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom)), diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h index f770bb69f8..33222573f4 100644 --- a/src/widgets/widgets/qabstractscrollarea_p.h +++ b/src/widgets/widgets/qabstractscrollarea_p.h @@ -54,12 +54,15 @@ QT_BEGIN_NAMESPACE class QScrollBar; class QAbstractScrollAreaScrollBarContainer; + +// ### Qt 6: is the export still needed? If not, unexport QFramePrivate, too. class Q_WIDGETS_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate { Q_DECLARE_PUBLIC(QAbstractScrollArea) public: QAbstractScrollAreaPrivate(); + ~QAbstractScrollAreaPrivate(); void replaceScrollBar(QScrollBar *scrollBar, Qt::Orientation orientation); diff --git a/src/widgets/widgets/qframe.cpp b/src/widgets/widgets/qframe.cpp index d5cedc4607..755b03a4ca 100644 --- a/src/widgets/widgets/qframe.cpp +++ b/src/widgets/widgets/qframe.cpp @@ -55,6 +55,10 @@ QFramePrivate::QFramePrivate() { } +QFramePrivate::~QFramePrivate() +{ +} + inline void QFramePrivate::init() { setLayoutItemMargins(QStyle::SE_FrameLayoutItem); diff --git a/src/widgets/widgets/qframe_p.h b/src/widgets/widgets/qframe_p.h index 2b80e9abbe..eb04bbed4a 100644 --- a/src/widgets/widgets/qframe_p.h +++ b/src/widgets/widgets/qframe_p.h @@ -50,11 +50,13 @@ QT_BEGIN_NAMESPACE -class QFramePrivate : public QWidgetPrivate +// ### unexport this class when and if QAbstractScrollAreaPrivate is unexported +class Q_WIDGETS_EXPORT QFramePrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QFrame) public: QFramePrivate(); + ~QFramePrivate(); void updateFrameWidth(); void updateStyledFrameWidths(); diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index 83e94c4128..409e4a34f9 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -53,6 +53,10 @@ QT_BEGIN_NAMESPACE +QLabelPrivate::~QLabelPrivate() +{ +} + /*! \class QLabel \brief The QLabel widget provides a text or image display. diff --git a/src/widgets/widgets/qlabel_p.h b/src/widgets/widgets/qlabel_p.h index 3778cb9d47..2eb4ff9fc6 100644 --- a/src/widgets/widgets/qlabel_p.h +++ b/src/widgets/widgets/qlabel_p.h @@ -65,6 +65,7 @@ class QLabelPrivate : public QFramePrivate Q_DECLARE_PUBLIC(QLabel) public: QLabelPrivate() {} + ~QLabelPrivate(); void init(); void clearContents(); diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index de6e45234c..38773a4fbf 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -58,6 +58,10 @@ QT_BEGIN_NAMESPACE //#define QSPLITTER_DEBUG +QSplitterPrivate::~QSplitterPrivate() +{ +} + /*! \class QSplitterHandle \brief The QSplitterHandle class provides handle functionality for the splitter. diff --git a/src/widgets/widgets/qsplitter_p.h b/src/widgets/widgets/qsplitter_p.h index a45f776da1..890bd535ec 100644 --- a/src/widgets/widgets/qsplitter_p.h +++ b/src/widgets/widgets/qsplitter_p.h @@ -76,6 +76,7 @@ class QSplitterPrivate : public QFramePrivate public: QSplitterPrivate() : rubberBand(0), opaque(true), firstShow(true), childrenCollapsible(true), compatMode(false), handleWidth(-1), blockChildAdd(false), opaqueResizeSet(false) {} + ~QSplitterPrivate(); QPointer rubberBand; mutable QList list; -- cgit v1.2.3 From dd274a5455296fcfe8631c2c2c7271546e9547bc Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik Date: Mon, 1 Jun 2015 11:14:04 +0200 Subject: Rename ReturnKey to EnterKey This makes the terminology consistent with Sailfish OS and the QNX QPA. The kImePlatformDataReturnKeyType in the iOS QPA is not changed to not break compatibility. Also, improve documentation. Change-Id: I2780de5b1e9277185ae1d4d9bbc67e36682fbfba Reviewed-by: J-P Nurmi Reviewed-by: Richard Moe Gustavsen --- src/corelib/global/qnamespace.h | 22 ++++++------ src/corelib/global/qnamespace.qdoc | 47 +++++++++++++------------- src/plugins/platforms/ios/qiosinputcontext.mm | 2 +- src/plugins/platforms/ios/qiostextresponder.mm | 18 +++++----- 4 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 123e2edf0e..c6465ed087 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1323,7 +1323,7 @@ public: ImAbsolutePosition = 0x400, ImTextBeforeCursor = 0x800, ImTextAfterCursor = 0x1000, - ImReturnKeyType = 0x2000, + ImEnterKeyType = 0x2000, ImPlatformData = 0x80000000, ImQueryInput = ImCursorRectangle | ImCursorPosition | ImSurroundingText | @@ -1363,15 +1363,15 @@ public: }; Q_DECLARE_FLAGS(InputMethodHints, InputMethodHint) - enum ReturnKeyType { - ReturnKeyDefault, - ReturnKeyEnter, - ReturnKeyDone, - ReturnKeyGo, - ReturnKeySend, - ReturnKeySearch, - ReturnKeyNext, - ReturnKeyPrevious + enum EnterKeyType { + EnterKeyDefault, + EnterKeyReturn, + EnterKeyDone, + EnterKeyGo, + EnterKeySend, + EnterKeySearch, + EnterKeyNext, + EnterKeyPrevious }; enum ToolButtonStyle { @@ -1697,7 +1697,7 @@ public: QT_Q_ENUM(InputMethodHint) QT_Q_ENUM(InputMethodQuery) QT_Q_FLAG(InputMethodHints) - QT_Q_ENUM(ReturnKeyType) + QT_Q_ENUM(EnterKeyType) QT_Q_FLAG(InputMethodQueries) QT_Q_FLAG(TouchPointStates) QT_Q_ENUM(ScreenOrientation) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index d4d7b631ad..b981fed500 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2527,7 +2527,7 @@ but \b{must} not return an empty string unless the cursor is at the start of the document. \value ImTextAfterCursor The plain text after the cursor. The widget can decide how much text to return, but \b{must} not return an empty string unless the cursor is at the end of the document. - \value ImReturnKeyType The return key type. + \value ImEnterKeyType The Enter key type. Masks: @@ -2538,31 +2538,32 @@ */ /*! - \enum Qt::ReturnKeyType + \enum Qt::EnterKeyType This can be used to alter the appearance of the Return key on an on screen keyboard. - Note that not all of these values are supported on all platforms. - - \value ReturnKeyDefault The default return key. - This can either be a button closing the keyboard, or a Return button - causing a new line in case of a multi-line input field. - \value ReturnKeyEnter Show a Return button that inserts a new line. - The keyboard will not close when this button is pressed. - \value ReturnKeyDone Show a "Done" button. - The keyboard will close when this button is pressed. - \value ReturnKeyGo Show a "Go" button. - Typically used in an address bar when entering an URL; the keyboard - will close when this button is pressed. - \value ReturnKeySend Show a "Send" button. - The keyboard will close when this button is pressed. - \value ReturnKeySearch Show a "Search" button. - The keyboard will close when this button is pressed. - \value ReturnKeyNext Show a "Next" button. - Typically used in a form to allow navigating to the next input field; - the keyboard will not close when this button is pressed. - \value ReturnKeyPrevious Show a "Previous" button. - The keyboard will not close when this button is pressed. + \note Not all of these values are supported on all platforms. + For unsuppoted values the default key will be used instead. + + \value EnterKeyDefault The default Enter key. + This can either be a button closing the keyboard, or a Return button + causing a new line in case of a multi-line input field. + \value EnterKeyReturn Show a Return button that inserts a new line. + The keyboard will not close when this button is pressed. + \value EnterKeyDone Show a "Done" button. + The keyboard will close when this button is pressed. + \value EnterKeyGo Show a "Go" button. + Typically used in an address bar when entering a URL; the keyboard + will close when this button is pressed. + \value EnterKeySend Show a "Send" button. + The keyboard will close when this button is pressed. + \value EnterKeySearch Show a "Search" button. + The keyboard will close when this button is pressed. + \value EnterKeyNext Show a "Next" button. + Typically used in a form to allow navigating to the next input field; + the keyboard will not close when this button is pressed. + \value EnterKeyPrevious Show a "Previous" button. + The keyboard will not close when this button is pressed. \since 5.6 */ diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 037b28e91d..d03c589b2a 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -579,7 +579,7 @@ void QIOSInputContext::focusWindowChanged(QWindow *focusWindow) void QIOSInputContext::update(Qt::InputMethodQueries updatedProperties) { // Mask for properties that we are interested in and see if any of them changed - updatedProperties &= (Qt::ImEnabled | Qt::ImHints | Qt::ImQueryInput | Qt::ImReturnKeyType | Qt::ImPlatformData); + updatedProperties &= (Qt::ImEnabled | Qt::ImHints | Qt::ImQueryInput | Qt::ImEnterKeyType | Qt::ImPlatformData); qImDebug() << "fw =" << qApp->focusWindow() << "fo =" << qApp->focusObject(); diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index c7356d7abd..d86f545154 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -170,25 +170,25 @@ QVariantMap platformData = m_configuredImeState->value(Qt::ImPlatformData).toMap(); Qt::InputMethodHints hints = Qt::InputMethodHints(m_configuredImeState->value(Qt::ImHints).toUInt()); - Qt::ReturnKeyType returnKeyType = Qt::ReturnKeyType(m_configuredImeState->value(Qt::ImReturnKeyType).toUInt()); + Qt::EnterKeyType enterKeyType = Qt::EnterKeyType(m_configuredImeState->value(Qt::ImEnterKeyType).toUInt()); - switch (returnKeyType) { - case Qt::ReturnKeyEnter: + switch (enterKeyType) { + case Qt::EnterKeyReturn: self.returnKeyType = UIReturnKeyDefault; break; - case Qt::ReturnKeyDone: + case Qt::EnterKeyDone: self.returnKeyType = UIReturnKeyDone; break; - case Qt::ReturnKeyGo: + case Qt::EnterKeyGo: self.returnKeyType = UIReturnKeyGo; break; - case Qt::ReturnKeySend: + case Qt::EnterKeySend: self.returnKeyType = UIReturnKeySend; break; - case Qt::ReturnKeySearch: + case Qt::EnterKeySearch: self.returnKeyType = UIReturnKeySearch; break; - case Qt::ReturnKeyNext: + case Qt::EnterKeyNext: self.returnKeyType = UIReturnKeyNext; break; default: @@ -255,7 +255,7 @@ } // Based on what we set up in initWithInputContext above - updatedProperties &= (Qt::ImHints | Qt::ImReturnKeyType | Qt::ImPlatformData); + updatedProperties &= (Qt::ImHints | Qt::ImEnterKeyType | Qt::ImPlatformData); if (!updatedProperties) return NO; -- cgit v1.2.3 From 3ce99adfa48b09cf5dc73cc0922855fc066938fa Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 1 Jun 2015 21:28:59 +0200 Subject: use INSTALLS instead of DEPLOYMENT The DEPLOYMENT variable has been deprecated. Change-Id: I1c7c07b36a2e665ae302e4f43f7f2dc752f3c1f4 Reviewed-by: Oswald Buddenhagen --- examples/sql/books/books.pro | 2 +- examples/widgets/draganddrop/puzzle/puzzle.pro | 2 +- examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro | 2 +- examples/widgets/widgets/icons/icons.pro | 2 +- examples/widgets/widgets/movie/movie.pro | 2 +- examples/xml/dombookmarks/dombookmarks.pro | 2 +- examples/xml/htmlinfo/htmlinfo.pro | 2 +- examples/xml/saxbookmarks/saxbookmarks.pro | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/sql/books/books.pro b/examples/sql/books/books.pro index 31c47ba04f..1cdcaff870 100644 --- a/examples/sql/books/books.pro +++ b/examples/sql/books/books.pro @@ -16,5 +16,5 @@ wince*: { CONFIG(debug, debug|release):sqlPlugins.files = $$QT_BUILD_TREE/plugins/sqldrivers/*d4.dll CONFIG(release, debug|release):sqlPlugins.files = $$QT_BUILD_TREE/plugins/sqldrivers/*[^d]4.dll sqlPlugins.path = sqldrivers - DEPLOYMENT += sqlPlugins + INSTALLS += sqlPlugins } diff --git a/examples/widgets/draganddrop/puzzle/puzzle.pro b/examples/widgets/draganddrop/puzzle/puzzle.pro index 95008fc29b..b310f1f776 100644 --- a/examples/widgets/draganddrop/puzzle/puzzle.pro +++ b/examples/widgets/draganddrop/puzzle/puzzle.pro @@ -18,5 +18,5 @@ INSTALLS += target wince*: { addFile.files = example.jpg addFile.path = . - DEPLOYMENT += addFile + INSTALLS += addFile } diff --git a/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro index 640f36f9b8..809667b2ad 100644 --- a/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro +++ b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pro @@ -14,5 +14,5 @@ INSTALLS += target wince*: { addFiles.files = main.cpp mainwindow.cpp addFiles.path = . - DEPLOYMENT += addFiles + INSTALLS += addFiles } diff --git a/examples/widgets/widgets/icons/icons.pro b/examples/widgets/widgets/icons/icons.pro index 51d8b79ba9..58e6c2137c 100644 --- a/examples/widgets/widgets/icons/icons.pro +++ b/examples/widgets/widgets/icons/icons.pro @@ -24,5 +24,5 @@ wince*: { } else { imageFiles.path = images } - DEPLOYMENT += imageFiles + INSTALLS += imageFiles } diff --git a/examples/widgets/widgets/movie/movie.pro b/examples/widgets/widgets/movie/movie.pro index 6d333edfa8..58925c98a0 100644 --- a/examples/widgets/widgets/movie/movie.pro +++ b/examples/widgets/widgets/movie/movie.pro @@ -14,5 +14,5 @@ INSTALLS += target wince*: { addFiles.files += *.gif addFiles.path = . - DEPLOYMENT += addFiles + INSTALLS += addFiles } diff --git a/examples/xml/dombookmarks/dombookmarks.pro b/examples/xml/dombookmarks/dombookmarks.pro index 93a5fb9ac9..a16cdadcfa 100644 --- a/examples/xml/dombookmarks/dombookmarks.pro +++ b/examples/xml/dombookmarks/dombookmarks.pro @@ -14,6 +14,6 @@ INSTALLS += target wince*: { addFiles.files = frank.xbel jennifer.xbel addFiles.path = "\\My Documents" - DEPLOYMENT += addFiles + INSTALLS += addFiles } diff --git a/examples/xml/htmlinfo/htmlinfo.pro b/examples/xml/htmlinfo/htmlinfo.pro index 9e58973db6..4ad40213fe 100644 --- a/examples/xml/htmlinfo/htmlinfo.pro +++ b/examples/xml/htmlinfo/htmlinfo.pro @@ -9,7 +9,7 @@ win32: CONFIG += console wince*:{ htmlfiles.files = *.html htmlfiles.path = . - DEPLOYMENT += htmlfiles + INSTALLS += htmlfiles } # install diff --git a/examples/xml/saxbookmarks/saxbookmarks.pro b/examples/xml/saxbookmarks/saxbookmarks.pro index 6723b0c6fc..aa84ee4f3e 100644 --- a/examples/xml/saxbookmarks/saxbookmarks.pro +++ b/examples/xml/saxbookmarks/saxbookmarks.pro @@ -16,5 +16,5 @@ INSTALLS += target wince*: { addFiles.files = frank.xbel jennifer.xbel addFiles.path = "\\My Documents" - DEPLOYMENT += addFiles + INSTALLS += addFiles } -- cgit v1.2.3 From 2b5fef7c839be12e9d8634e17454dd9c3b63b892 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 1 Jun 2015 17:06:20 +0200 Subject: remove now superfluous eval calls Change-Id: I743f1ec35101aad0ab71cf10932d144a1b04f7e6 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 464aca4d71..8e7b8bca0a 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -257,8 +257,8 @@ for(QT_CURRENT_VERIFY, $$list($$QT_PLUGIN_VERIFY)) { debug: QT_ITEM = $${QTPLUG}d4.dll else: QT_ITEM = $${QTPLUG}4.dll - eval(qt_additional_plugin_$${QTPLUG}.files = $$[QT_INSTALL_PLUGINS/get]/$${QT_PLUGINPATH}/$${QT_ITEM}) - eval(qt_additional_plugin_$${QTPLUG}.path = $${QT_PLUGINPATH}) + qt_additional_plugin_$${QTPLUG}.files = $$[QT_INSTALL_PLUGINS/get]/$${QT_PLUGINPATH}/$${QT_ITEM} + qt_additional_plugin_$${QTPLUG}.path = $${QT_PLUGINPATH} INSTALLS *= qt_additional_plugin_$${QTPLUG} } -- cgit v1.2.3 From b295afb064d728d8f59d0129979c019761624bca Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 26 May 2015 22:16:25 +0200 Subject: QStaticTextUserData: declare dtor out-of-line and export class De-duplicates vtables and enables RTTI on this class hierarchy. Export, as QOpenGLStaticTextUserData (QtOpenGL) inherits it. Change-Id: I0662870538c35f23baf6bde4594ec8b9055efae7 Reported-by: Volker Krause Task-number: QTBUG-45582 Reviewed-by: Konstantin Ritt Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/gui/text/qstatictext.cpp | 4 ++++ src/gui/text/qstatictext_p.h | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index fc95a859e7..c3be9b871c 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -39,6 +39,10 @@ QT_BEGIN_NAMESPACE +QStaticTextUserData::~QStaticTextUserData() +{ +} + /*! \class QStaticText \brief The QStaticText class enables optimized drawing of text when the text and its layout diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h index 088e49e2fc..49ca24d51c 100644 --- a/src/gui/text/qstatictext_p.h +++ b/src/gui/text/qstatictext_p.h @@ -52,7 +52,8 @@ QT_BEGIN_NAMESPACE -class QStaticTextUserData +// ### Qt 6: Unexport again, if QOpenGLStaticTextUserData (the one from QtOpenGL) is gone by then +class Q_GUI_EXPORT QStaticTextUserData { public: enum Type { @@ -61,7 +62,7 @@ public: }; QStaticTextUserData(Type t) : ref(0), type(t) {} - virtual ~QStaticTextUserData() {} + virtual ~QStaticTextUserData(); QAtomicInt ref; Type type; -- cgit v1.2.3 From 133e40283155852585b5fc409909a00e920cfcfc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 1 Jun 2015 00:22:35 +0200 Subject: De-duplicate vtables, part I: exported private classes By making the destructor (usually the first non-inline, non-pure, virtual function, and therefore the trigger for most compilers to emit the vtable and type_info structures for the class in that TU) out-of-line, vtables and, more importantly, type_info structures for the class are pinned to a single TU. This prevents false negative dynamic_cast and catch evaluation. In this first batch, we de-inline destructors of exported private classes. Since they are already exported, users of these classes are unaffected by the change, and since it's private API, we don't need to avoid adding code to the out-of-line destructor until Qt 6. Change-Id: I450707877d2cb6a77f79ae1dd355facb98d6c517 Reported-by: Volker Krause Task-number: QTBUG-45582 Reviewed-by: Oswald Buddenhagen Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll Reviewed-by: Konstantin Ritt Reviewed-by: Thiago Macieira --- src/corelib/itemmodels/qabstractitemmodel.cpp | 5 +++++ src/corelib/itemmodels/qabstractitemmodel_p.h | 2 ++ src/corelib/kernel/qobject.cpp | 10 ++++++++++ src/corelib/kernel/qobject_p.h | 4 +++- src/corelib/statemachine/qeventtransition.cpp | 4 ++++ src/corelib/statemachine/qeventtransition_p.h | 1 + src/gui/opengl/qopenglpaintdevice.cpp | 4 ++++ src/gui/opengl/qopenglpaintdevice_p.h | 2 +- src/gui/painting/qpagedpaintdevice.cpp | 4 ++++ src/gui/painting/qpagedpaintdevice_p.h | 4 +--- src/gui/painting/qpaintengine.cpp | 4 ++++ src/gui/painting/qpaintengine_p.h | 3 ++- src/widgets/effects/qgraphicseffect.cpp | 4 ++++ src/widgets/effects/qgraphicseffect_p.h | 1 + src/widgets/graphicsview/qgraphicsview.cpp | 4 ++++ src/widgets/graphicsview/qgraphicsview_p.h | 1 + 16 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 60ac75133c..2f3cfc1c0a 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -479,6 +479,11 @@ public: Q_GLOBAL_STATIC(QEmptyItemModel, qEmptyModel) + +QAbstractItemModelPrivate::~QAbstractItemModelPrivate() +{ +} + QAbstractItemModel *QAbstractItemModelPrivate::staticEmptyModel() { return qEmptyModel(); diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h index 075e6a9018..acf376eff1 100644 --- a/src/corelib/itemmodels/qabstractitemmodel_p.h +++ b/src/corelib/itemmodels/qabstractitemmodel_p.h @@ -71,6 +71,8 @@ class Q_CORE_EXPORT QAbstractItemModelPrivate : public QObjectPrivate public: QAbstractItemModelPrivate() : QObjectPrivate(), supportedDragActions(-1), roleNames(defaultRoleNames()) {} + ~QAbstractItemModelPrivate(); + void removePersistentIndexData(QPersistentModelIndexData *data); void movePersistentIndexes(const QVector &indexes, int change, const QModelIndex &parent, Qt::Orientation orientation); void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last); diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index fb4c5cceb9..3ca9c890e8 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -65,6 +65,16 @@ QT_BEGIN_NAMESPACE static int DIRECT_CONNECTION_ONLY = 0; + +QDynamicMetaObjectData::~QDynamicMetaObjectData() +{ +} + +QAbstractDynamicMetaObject::~QAbstractDynamicMetaObject() +{ +} + + struct QSlotObjectBaseDeleter { // for use with QScopedPointer static void cleanup(QtPrivate::QSlotObjectBase *slot) { if (slot) slot->destroyIfLastRef(); diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 1b64103e40..bd5ee006bf 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -406,7 +406,7 @@ void Q_CORE_EXPORT qDeleteInEventHandler(QObject *o); struct QAbstractDynamicMetaObject; struct Q_CORE_EXPORT QDynamicMetaObjectData { - virtual ~QDynamicMetaObjectData() {} + virtual ~QDynamicMetaObjectData(); virtual void objectDestroyed(QObject *) { delete this; } virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) = 0; @@ -415,6 +415,8 @@ struct Q_CORE_EXPORT QDynamicMetaObjectData struct Q_CORE_EXPORT QAbstractDynamicMetaObject : public QDynamicMetaObjectData, public QMetaObject { + ~QAbstractDynamicMetaObject(); + virtual QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *) Q_DECL_OVERRIDE { return this; } virtual int createProperty(const char *, const char *) { return -1; } virtual int metaCall(QObject *, QMetaObject::Call c, int _id, void **a) Q_DECL_OVERRIDE diff --git a/src/corelib/statemachine/qeventtransition.cpp b/src/corelib/statemachine/qeventtransition.cpp index 096d667bc3..c10127fa68 100644 --- a/src/corelib/statemachine/qeventtransition.cpp +++ b/src/corelib/statemachine/qeventtransition.cpp @@ -102,6 +102,10 @@ QEventTransitionPrivate::QEventTransitionPrivate() registered = false; } +QEventTransitionPrivate::~QEventTransitionPrivate() +{ +} + QEventTransitionPrivate *QEventTransitionPrivate::get(QEventTransition *q) { return q->d_func(); diff --git a/src/corelib/statemachine/qeventtransition_p.h b/src/corelib/statemachine/qeventtransition_p.h index 64ab945187..9e3ef111f9 100644 --- a/src/corelib/statemachine/qeventtransition_p.h +++ b/src/corelib/statemachine/qeventtransition_p.h @@ -55,6 +55,7 @@ class Q_CORE_EXPORT QEventTransitionPrivate : public QAbstractTransitionPrivate Q_DECLARE_PUBLIC(QEventTransition) public: QEventTransitionPrivate(); + ~QEventTransitionPrivate(); static QEventTransitionPrivate *get(QEventTransition *q); diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp index c0657feaa0..e509b26a95 100644 --- a/src/gui/opengl/qopenglpaintdevice.cpp +++ b/src/gui/opengl/qopenglpaintdevice.cpp @@ -169,6 +169,10 @@ QOpenGLPaintDevicePrivate::QOpenGLPaintDevicePrivate(const QSize &sz) { } +QOpenGLPaintDevicePrivate::~QOpenGLPaintDevicePrivate() +{ +} + class QOpenGLEngineThreadStorage { public: diff --git a/src/gui/opengl/qopenglpaintdevice_p.h b/src/gui/opengl/qopenglpaintdevice_p.h index 57d93ee80a..54ea09240d 100644 --- a/src/gui/opengl/qopenglpaintdevice_p.h +++ b/src/gui/opengl/qopenglpaintdevice_p.h @@ -56,7 +56,7 @@ class Q_GUI_EXPORT QOpenGLPaintDevicePrivate { public: QOpenGLPaintDevicePrivate(const QSize &size); - virtual ~QOpenGLPaintDevicePrivate() { } + virtual ~QOpenGLPaintDevicePrivate(); static QOpenGLPaintDevicePrivate *get(QOpenGLPaintDevice *dev) { return dev->d_func(); } diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp index 3adc5e9411..547cedf51f 100644 --- a/src/gui/painting/qpagedpaintdevice.cpp +++ b/src/gui/painting/qpagedpaintdevice.cpp @@ -36,6 +36,10 @@ QT_BEGIN_NAMESPACE +QPagedPaintDevicePrivate::~QPagedPaintDevicePrivate() +{ +} + /*! \class QPagedPaintDevice \inmodule QtGui diff --git a/src/gui/painting/qpagedpaintdevice_p.h b/src/gui/painting/qpagedpaintdevice_p.h index 62f69747db..30b1c0a1e6 100644 --- a/src/gui/painting/qpagedpaintdevice_p.h +++ b/src/gui/painting/qpagedpaintdevice_p.h @@ -61,9 +61,7 @@ public: { } - virtual ~QPagedPaintDevicePrivate() - { - } + virtual ~QPagedPaintDevicePrivate(); // ### Qt6 Remove these and make public class methods virtual virtual bool setPageLayout(const QPageLayout &newPageLayout) diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index 6271c8f9e6..bf1f31a85b 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -968,6 +968,10 @@ QRect QPaintEngine::systemRect() const return d_func()->systemRect; } +QPaintEnginePrivate::~QPaintEnginePrivate() +{ +} + void QPaintEnginePrivate::drawBoxTextItem(const QPointF &p, const QTextItemInt &ti) { if (!ti.glyphs.numGlyphs) diff --git a/src/gui/painting/qpaintengine_p.h b/src/gui/painting/qpaintengine_p.h index c58662ede4..918c98997b 100644 --- a/src/gui/painting/qpaintengine_p.h +++ b/src/gui/painting/qpaintengine_p.h @@ -60,7 +60,8 @@ class Q_GUI_EXPORT QPaintEnginePrivate public: QPaintEnginePrivate() : pdev(0), q_ptr(0), currentClipDevice(0), hasSystemTransform(0), hasSystemViewport(0) {} - virtual ~QPaintEnginePrivate() { } + virtual ~QPaintEnginePrivate(); + QPaintDevice *pdev; QPaintEngine *q_ptr; QRegion systemClip; diff --git a/src/widgets/effects/qgraphicseffect.cpp b/src/widgets/effects/qgraphicseffect.cpp index f53804e494..5a97be3d96 100644 --- a/src/widgets/effects/qgraphicseffect.cpp +++ b/src/widgets/effects/qgraphicseffect.cpp @@ -111,6 +111,10 @@ #ifndef QT_NO_GRAPHICSEFFECT QT_BEGIN_NAMESPACE +QGraphicsEffectPrivate::~QGraphicsEffectPrivate() +{ +} + /*! \internal \class QGraphicsEffectSource diff --git a/src/widgets/effects/qgraphicseffect_p.h b/src/widgets/effects/qgraphicseffect_p.h index 6e990cc52e..35264c0d30 100644 --- a/src/widgets/effects/qgraphicseffect_p.h +++ b/src/widgets/effects/qgraphicseffect_p.h @@ -142,6 +142,7 @@ class Q_WIDGETS_EXPORT QGraphicsEffectPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QGraphicsEffect) public: QGraphicsEffectPrivate() : source(0), isEnabled(1) {} + ~QGraphicsEffectPrivate(); inline void setGraphicsEffectSource(QGraphicsEffectSource *newSource) { diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index c270c4be88..decb455988 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -362,6 +362,10 @@ QGraphicsViewPrivate::QGraphicsViewPrivate() styleOptions.reserve(QGRAPHICSVIEW_PREALLOC_STYLE_OPTIONS); } +QGraphicsViewPrivate::~QGraphicsViewPrivate() +{ +} + /*! \internal */ diff --git a/src/widgets/graphicsview/qgraphicsview_p.h b/src/widgets/graphicsview/qgraphicsview_p.h index fec8336695..dcbffb1c39 100644 --- a/src/widgets/graphicsview/qgraphicsview_p.h +++ b/src/widgets/graphicsview/qgraphicsview_p.h @@ -63,6 +63,7 @@ class Q_WIDGETS_EXPORT QGraphicsViewPrivate : public QAbstractScrollAreaPrivate Q_DECLARE_PUBLIC(QGraphicsView) public: QGraphicsViewPrivate(); + ~QGraphicsViewPrivate(); void recalculateContentSize(); void centerView(QGraphicsView::ViewportAnchor anchor); -- cgit v1.2.3 From 8d9d609e637765572d949f01bae47dcc01f2c110 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 1 Jun 2015 00:22:35 +0200 Subject: De-duplicate vtables, part II: exported public classes By making the destructor (usually the first non-inline, non-pure, virtual function, and therefore the trigger for most compilers to emit the vtable and type_info structures for the class in that TU) out-of-line, vtables and, more importantly, type_info structures for the class are pinned to a single TU. This prevents false negative dynamic_cast and catch evaluation. In this second and last batch, we de-inline destructors of exported public classes. Since they are already exported, users of these classes are unaffected by the change, but since it's public API, and the dtors may have been de-virtualized and inlined into application code, we need to avoid adding code to the out-of-line destructor until Qt 6. Change-Id: Ieda9553cb4b0dae7217c37cc7cde321dd7302122 Reported-by: Volker Krause Task-number: QTBUG-45582 Reviewed-by: Friedemann Kleint Reviewed-by: Konstantin Ritt Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/corelib/plugin/plugin.pri | 1 + src/corelib/plugin/qfactoryinterface.cpp | 43 ++++++++++++++++++++++++++++ src/corelib/plugin/qfactoryinterface.h | 2 +- src/gui/kernel/qevent.cpp | 5 ++++ src/gui/kernel/qevent.h | 2 ++ src/gui/text/qabstracttextdocumentlayout.cpp | 5 ++++ src/gui/text/qabstracttextdocumentlayout.h | 2 +- 7 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 src/corelib/plugin/qfactoryinterface.cpp diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri index 338b3d0972..8b64f93467 100644 --- a/src/corelib/plugin/plugin.pri +++ b/src/corelib/plugin/plugin.pri @@ -13,6 +13,7 @@ HEADERS += \ plugin/qmachparser_p.h SOURCES += \ + plugin/qfactoryinterface.cpp \ plugin/qpluginloader.cpp \ plugin/qfactoryloader.cpp \ plugin/quuid.cpp \ diff --git a/src/corelib/plugin/qfactoryinterface.cpp b/src/corelib/plugin/qfactoryinterface.cpp new file mode 100644 index 0000000000..0307d58315 --- /dev/null +++ b/src/corelib/plugin/qfactoryinterface.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfactoryinterface.h" + +QT_BEGIN_NAMESPACE + +QFactoryInterface::~QFactoryInterface() +{ + // must be empty until ### Qt 6 +} + +QT_END_NAMESPACE diff --git a/src/corelib/plugin/qfactoryinterface.h b/src/corelib/plugin/qfactoryinterface.h index e20864cd31..86a46fabfa 100644 --- a/src/corelib/plugin/qfactoryinterface.h +++ b/src/corelib/plugin/qfactoryinterface.h @@ -42,7 +42,7 @@ QT_BEGIN_NAMESPACE struct Q_CORE_EXPORT QFactoryInterface { - virtual ~QFactoryInterface() {} + virtual ~QFactoryInterface(); virtual QStringList keys() const = 0; }; diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 006f4d6245..1dc3e69470 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -1971,6 +1971,11 @@ QInputMethodEvent::QInputMethodEvent(const QInputMethodEvent &other) { } +QInputMethodEvent::~QInputMethodEvent() +{ + // must be empty until ### Qt 6 +} + /*! Sets the commit string to \a commitString. diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 0cf0601db9..61316b0af5 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -531,6 +531,8 @@ public: }; QInputMethodEvent(); QInputMethodEvent(const QString &preeditText, const QList &attributes); + ~QInputMethodEvent(); + void setCommitString(const QString &commitString, int replaceFrom = 0, int replaceLength = 0); inline const QList &attributes() const { return attrs; } inline const QString &preeditString() const { return preedit; } diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp index 8d2da46ab3..7735fd6b46 100644 --- a/src/gui/text/qabstracttextdocumentlayout.cpp +++ b/src/gui/text/qabstracttextdocumentlayout.cpp @@ -44,6 +44,11 @@ QAbstractTextDocumentLayoutPrivate::~QAbstractTextDocumentLayoutPrivate() { } +QTextObjectInterface::~QTextObjectInterface() +{ + // must be empty until ### Qt 6 +} + /*! \class QAbstractTextDocumentLayout \reentrant diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h index 27135b0476..68e7a0e4e9 100644 --- a/src/gui/text/qabstracttextdocumentlayout.h +++ b/src/gui/text/qabstracttextdocumentlayout.h @@ -126,7 +126,7 @@ private: class Q_GUI_EXPORT QTextObjectInterface { public: - virtual ~QTextObjectInterface() {} + virtual ~QTextObjectInterface(); virtual QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format) = 0; virtual void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format) = 0; }; -- cgit v1.2.3 From f0eafa5672ded6d0f9aafb708c1bc794716f4284 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 2 Jun 2015 12:49:06 +0200 Subject: QAccessibleInterface: move implementation beside doc block Adjust doc text to what's used elsewhere in QAccessible. Change-Id: I8bd194e55374b8258361ae254817a4298c4fa3dc Reviewed-by: Friedemann Kleint --- src/gui/accessible/qaccessible.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index cc9d789c6a..36492def68 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -443,10 +443,11 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QAccessibleInterface::~QAccessibleInterface() - - Destroys the object. + Destroys the QAccessibleInterface. */ +QAccessibleInterface::~QAccessibleInterface() +{ +} /*! \typedef QAccessible::Id @@ -1254,10 +1255,6 @@ QColor QAccessibleInterface::backgroundColor() const return QColor(); } -QAccessibleInterface::~QAccessibleInterface() -{ -} - /*! \fn QAccessibleTextInterface *QAccessibleInterface::textInterface() */ -- cgit v1.2.3 From a21dfab54ed518266c42d3e87e02bd991de8486e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 1 Jun 2015 00:22:35 +0200 Subject: De-duplicate vtables III: QAccessible By making the destructor (usually the first non-inline, non-pure, virtual function, and therefore the trigger for most compilers to emit the vtable and type_info structures for the class in that TU) out-of-line, vtables and, more importantly, type_info strucures for the class are pinned to a single TU. This prevents false negative dynamic_cast and catch evaluation. In this third batch, we de-inline dtors of exported public classes from the QAccessible subsytem. Since they are already exported, users of these classes are unaffected by the change, but since it's public API, and the dtors may have been de-virtualized and inlined into application code, we need to avoid adding code to the out-of-line dtor until Qt 6. Change-Id: I5324bd1b3b9210a3ac5cf4eee9317a34e4a3b048 Reported-by: Volker Krause Task-number: QTBUG-45582 Reviewed-by: Thiago Macieira --- src/gui/accessible/qaccessible.cpp | 111 ++++++++++++++++++++++++++++++++++--- src/gui/accessible/qaccessible.h | 36 ++++++++---- 2 files changed, 127 insertions(+), 20 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 36492def68..f2a30e5a18 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -609,6 +609,11 @@ QAccessible::RootObjectHandler QAccessible::installRootObjectHandler(RootObjectH \sa installActivationObserver() */ +QAccessible::ActivationObserver::~ActivationObserver() +{ + // must be empty until ### Qt 6 +} + /*! \internal @@ -1326,9 +1331,13 @@ QColor QAccessibleInterface::backgroundColor() const the overload taking a \l QObject parameter as it might be cheaper. */ -/*! \fn QAccessibleEvent::~QAccessibleEvent() +/*! Destroys the event. */ +QAccessibleEvent::~QAccessibleEvent() +{ + // must be empty until ### Qt 6 +} /*! \fn QAccessible::Event QAccessibleEvent::type() const Returns the event type. @@ -1389,6 +1398,13 @@ QAccessible::Id QAccessibleEvent::uniqueId() const Returns the new value of the accessible object of this event. */ +/*! + \internal +*/ +QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent() +{ + // must be empty until ### Qt 6 +} /*! \class QAccessibleStateChangeEvent @@ -1418,7 +1434,13 @@ QAccessible::Id QAccessibleEvent::uniqueId() const other hand tells about the change and has focused set to \c true since the focus state is changed from \c true to \c false. */ - +/*! + \internal +*/ +QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent() +{ + // must be empty until ### Qt 6 +} /*! \class QAccessibleTableModelChangeEvent @@ -1475,6 +1497,13 @@ QAccessible::Id QAccessibleEvent::uniqueId() const /*! \fn void QAccessibleTableModelChangeEvent::setModelChangeType(ModelChangeType changeType) Sets the type of change to \a changeType. */ +/*! + \internal +*/ +QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent() +{ + // must be empty until ### Qt 6 +} /*! @@ -1496,6 +1525,14 @@ QAccessible::Id QAccessibleEvent::uniqueId() const /*! \fn void QAccessibleTextCursorEvent::setCursorPosition(int position) Sets the cursor \a position for this event. */ +/*! + \internal +*/ +QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent() +{ + // must be empty until ### Qt 6 +} + /*! \class QAccessibleTextInsertEvent @@ -1519,6 +1556,14 @@ QAccessible::Id QAccessibleEvent::uniqueId() const /*! \fn QString QAccessibleTextInsertEvent::textInserted() const Returns the text that has been inserted. */ +/*! + \internal +*/ +QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent() +{ + // must be empty until ### Qt 6 +} + /*! \class QAccessibleTextRemoveEvent @@ -1543,6 +1588,13 @@ QAccessible::Id QAccessibleEvent::uniqueId() const /*! \fn QString QAccessibleTextRemoveEvent::textRemoved() const Returns the text that has been removed. */ +/*! + \internal +*/ +QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent() +{ + // must be empty until ### Qt 6 +} /*! \class QAccessibleTextUpdateEvent @@ -1569,6 +1621,14 @@ QAccessible::Id QAccessibleEvent::uniqueId() const /*! \fn QString QAccessibleTextUpdateEvent::textRemoved() const Returns the removed text. */ +/*! + \internal +*/ +QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent() +{ + // must be empty until ### Qt 6 +} + /*! \class QAccessibleTextSelectionEvent @@ -1592,6 +1652,13 @@ QAccessible::Id QAccessibleEvent::uniqueId() const /*! \fn void QAccessibleTextSelectionEvent::setSelection(int start, int end) Sets the selection for this event from position \a start to \a end. */ +/*! + \internal +*/ +QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent() +{ + // must be empty until ### Qt 6 +} @@ -1830,9 +1897,12 @@ QDebug operator<<(QDebug d, const QAccessibleEvent &ev) */ /*! - \fn QAccessibleTextInterface::~QAccessibleTextInterface() Destroys the QAccessibleTextInterface. */ +QAccessibleTextInterface::~QAccessibleTextInterface() +{ + // must be empty until ### Qt 6 +} /*! \fn void QAccessibleTextInterface::addSelection(int startOffset, int endOffset) @@ -2212,9 +2282,12 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun */ /*! - \fn QAccessibleEditableTextInterface::~QAccessibleEditableTextInterface() Destroys the QAccessibleEditableTextInterface. */ +QAccessibleEditableTextInterface::~QAccessibleEditableTextInterface() +{ + // must be empty until ### Qt 6 +} /*! \fn void QAccessibleEditableTextInterface::deleteText(int startOffset, int endOffset) @@ -2253,9 +2326,12 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun */ /*! - \fn QAccessibleValueInterface::~QAccessibleValueInterface() - Destructor. + Destroys the QAccessibleValueInterface. */ +QAccessibleValueInterface::~QAccessibleValueInterface() +{ + // must be empty until ### Qt 6 +} /*! \fn QVariant QAccessibleValueInterface::currentValue() const @@ -2313,6 +2389,14 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun \l{IAccessible2 Specification} */ +/*! + Destroys the QAccessibleImageInterface. +*/ +QAccessibleImageInterface::~QAccessibleImageInterface() +{ + // must be empty until ### Qt 6 +} + /*! \class QAccessibleTableCellInterface \inmodule QtGui @@ -2325,9 +2409,12 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun */ /*! - \fn virtual QAccessibleTableCellInterface::~QAccessibleTableCellInterface() Destroys the QAccessibleTableCellInterface. */ +QAccessibleTableCellInterface::~QAccessibleTableCellInterface() +{ + // must be empty until ### Qt 6 +} /*! \fn virtual int QAccessibleTableCellInterface::columnExtent() const @@ -2381,9 +2468,12 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun */ /*! - \fn virtual QAccessibleTableInterface::~QAccessibleTableInterface() Destroys the QAccessibleTableInterface. */ +QAccessibleTableInterface::~QAccessibleTableInterface() +{ + // must be empty until ### Qt 6 +} /*! \fn virtual QAccessibleInterface *QAccessibleTableInterface::cellAt(int row, int column) const @@ -2534,9 +2624,12 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun */ /*! - \fn QAccessibleActionInterface::~QAccessibleActionInterface() Destroys the QAccessibleActionInterface. */ +QAccessibleActionInterface::~QAccessibleActionInterface() +{ + // must be empty until ### Qt 6 +} /*! \fn QStringList QAccessibleActionInterface::actionNames() const diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index faa8cd719d..66cd067ace 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -399,7 +399,7 @@ public: class ActivationObserver { public: - virtual ~ActivationObserver() {} + virtual ~ActivationObserver(); virtual void accessibilityActiveChanged(bool active) = 0; }; static void installActivationObserver(ActivationObserver *); @@ -514,7 +514,7 @@ protected: class Q_GUI_EXPORT QAccessibleTextInterface { public: - virtual ~QAccessibleTextInterface() {} + virtual ~QAccessibleTextInterface(); // selection virtual void selection(int selectionIndex, int *startOffset, int *endOffset) const = 0; virtual int selectionCount() const = 0; @@ -547,7 +547,7 @@ public: class Q_GUI_EXPORT QAccessibleEditableTextInterface { public: - virtual ~QAccessibleEditableTextInterface() {} + virtual ~QAccessibleEditableTextInterface(); virtual void deleteText(int startOffset, int endOffset) = 0; virtual void insertText(int offset, const QString &text) = 0; @@ -557,8 +557,7 @@ public: class Q_GUI_EXPORT QAccessibleValueInterface { public: - - virtual ~QAccessibleValueInterface() {} + virtual ~QAccessibleValueInterface(); virtual QVariant currentValue() const = 0; virtual void setCurrentValue(const QVariant &value) = 0; @@ -570,7 +569,7 @@ public: class Q_GUI_EXPORT QAccessibleTableCellInterface { public: - virtual ~QAccessibleTableCellInterface() {} + virtual ~QAccessibleTableCellInterface(); virtual bool isSelected() const = 0; @@ -587,7 +586,7 @@ public: class Q_GUI_EXPORT QAccessibleTableInterface { public: - virtual ~QAccessibleTableInterface() {} + virtual ~QAccessibleTableInterface(); virtual QAccessibleInterface *caption() const = 0; virtual QAccessibleInterface *summary() const = 0; @@ -622,7 +621,7 @@ class Q_GUI_EXPORT QAccessibleActionInterface { Q_DECLARE_TR_FUNCTIONS(QAccessibleActionInterface) public: - virtual ~QAccessibleActionInterface() {} + virtual ~QAccessibleActionInterface(); virtual QStringList actionNames() const = 0; virtual QString localizedActionName(const QString &name) const; @@ -647,7 +646,7 @@ public: class Q_GUI_EXPORT QAccessibleImageInterface { public: - virtual ~QAccessibleImageInterface() {} + virtual ~QAccessibleImageInterface(); virtual QString imageDescription() const = 0; virtual QSize imageSize() const = 0; @@ -691,8 +690,7 @@ public: m_uniqueId = QAccessible::uniqueId(iface); } - virtual ~QAccessibleEvent() - {} + virtual ~QAccessibleEvent(); QAccessible::Event type() const { return m_type; } QObject *object() const { return m_object; } @@ -726,6 +724,7 @@ public: { m_type = QAccessible::StateChanged; } + ~QAccessibleStateChangeEvent(); QAccessible::State changedStates() const { return m_changedStates; @@ -752,6 +751,8 @@ public: m_type = QAccessible::TextCaretMoved; } + ~QAccessibleTextCursorEvent(); + void setCursorPosition(int position) { m_cursorPosition = position; } int cursorPosition() const { return m_cursorPosition; } @@ -776,6 +777,8 @@ public: m_type = QAccessible::TextSelectionChanged; } + ~QAccessibleTextSelectionEvent(); + void setSelection(int start, int end) { m_selectionStart = start; m_selectionEnd = end; @@ -805,6 +808,8 @@ public: m_type = QAccessible::TextInserted; } + ~QAccessibleTextInsertEvent(); + QString textInserted() const { return m_text; } @@ -833,6 +838,8 @@ public: m_type = QAccessible::TextRemoved; } + ~QAccessibleTextRemoveEvent(); + QString textRemoved() const { return m_text; } @@ -860,6 +867,9 @@ public: { m_type = QAccessible::TextUpdated; } + + ~QAccessibleTextUpdateEvent(); + QString textRemoved() const { return m_oldText; } @@ -892,6 +902,8 @@ public: m_type = QAccessible::ValueChanged; } + ~QAccessibleValueChangeEvent(); + void setValue(const QVariant & val) { m_value= val; } QVariant value() const { return m_value; } @@ -926,6 +938,8 @@ public: m_type = QAccessible::TableModelChanged; } + ~QAccessibleTableModelChangeEvent(); + void setModelChangeType(ModelChangeType changeType) { m_modelChangeType = changeType; } ModelChangeType modelChangeType() const { return m_modelChangeType; } -- cgit v1.2.3 From dc2617f35be61b4827b8e3d192c85e2feacf7f6a Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 3 Jun 2015 10:44:49 +0200 Subject: Fix build on QNX 650 Commit 2fa7b3b317fa941064ec4ba62163e3244becf55a broke the build, the compiler (gcc 4.4) doesn't like the mismatch between constructor declaration and definition. Change-Id: Ied1f3293c21871276ce8d2db3d2e6c06c75ade90 Reviewed-by: Marc Mutz --- src/corelib/thread/qexception.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/corelib/thread/qexception.cpp b/src/corelib/thread/qexception.cpp index 550bdc8fe4..01bbe70c88 100644 --- a/src/corelib/thread/qexception.cpp +++ b/src/corelib/thread/qexception.cpp @@ -108,6 +108,9 @@ QT_BEGIN_NAMESPACE */ QException::~QException() +#ifndef Q_COMPILER_NOEXCEPT + throw() +#endif { // must stay empty until ### Qt 6 } @@ -124,6 +127,9 @@ QException *QException::clone() const } QUnhandledException::~QUnhandledException() +#ifndef Q_COMPILER_NOEXCEPT + throw() +#endif { // must stay empty until ### Qt 6 } -- cgit v1.2.3 From 80bc743406f55f2d4470ee83364c87cfdce52356 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 29 May 2015 09:45:36 +0200 Subject: Fix tst_qglobalstatic on OS X OS X has an unreasonably low default for the maximum number of open file descriptors (256). The unit test creates about 200 threads and each thread in Qt creates at least two file descriptors (pipe), so the test cannot execute. Change-Id: I656367bca6d0a40fb1edb8c72914304db0f429ac Reviewed-by: Oswald Buddenhagen --- .../global/qglobalstatic/tst_qglobalstatic.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp b/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp index e6b2f8a116..68129f9081 100644 --- a/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp +++ b/tests/auto/corelib/global/qglobalstatic/tst_qglobalstatic.cpp @@ -41,10 +41,17 @@ #include #include +#if defined(Q_OS_UNIX) +#include +#endif + class tst_QGlobalStatic : public QObject { Q_OBJECT +public Q_SLOTS: + void initTestCase(); + private Q_SLOTS: void beforeInitialization(); void api(); @@ -55,6 +62,20 @@ private Q_SLOTS: void afterDestruction(); }; +void tst_QGlobalStatic::initTestCase() +{ +#if defined(Q_OS_UNIX) + // The tests create a lot of threads, which require file descriptors. On systems like + // OS X low defaults such as 256 as the limit for the number of simultaneously + // open files is not sufficient. + struct rlimit numFiles; + if (getrlimit(RLIMIT_NOFILE, &numFiles) == 0 && numFiles.rlim_cur < 1024) { + numFiles.rlim_cur = qMin(rlim_t(1024), numFiles.rlim_max); + setrlimit(RLIMIT_NOFILE, &numFiles); + } +#endif +} + Q_GLOBAL_STATIC_WITH_ARGS(const int, constInt, (42)) Q_GLOBAL_STATIC_WITH_ARGS(volatile int, volatileInt, (-47)) -- cgit v1.2.3 From bf0bdc5fbbb2b66d3ec41a600ef76e526c8ac278 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 3 Jun 2015 15:55:39 +0200 Subject: Fix crash in tst_qfiledialog on OS X The test aggressively shows and hides dialogs and popups, and we would end up installing this global event monitor frequently. However we never cleaned up properly, for example if the window didn't get hidden properly or if the monitor was already installed for some reason. Change-Id: I6fa28eaeb03e089ced735912dbe29b0b8ad75d58 Reviewed-by: Andy Shaw --- src/plugins/platforms/cocoa/qcocoawindow.h | 2 ++ src/plugins/platforms/cocoa/qcocoawindow.mm | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index fba97c2629..e2ab71a890 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -245,6 +245,8 @@ public: // for QNSView friend class QCocoaBackingStore; friend class QCocoaNativeInterface; + void removeMonitor(); + NSView *m_contentView; QNSView *m_qtView; QCocoaNSWindow *m_nsWindow; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index fdc8b2d9ad..e5fedcd051 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -419,6 +419,8 @@ QCocoaWindow::~QCocoaWindow() [m_contentView removeFromSuperview]; } + removeMonitor(); + // Make sure to disconnect observer in all case if view is valid // to avoid notifications received when deleting when using Qt::AA_NativeWindows attribute if (m_qtView) { @@ -696,6 +698,7 @@ void QCocoaWindow::setVisible(bool visible) && [m_nsWindow isKindOfClass:[NSPanel class]]) { [(NSPanel *)m_nsWindow setWorksWhenModal:YES]; if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) { + removeMonitor(); monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDownMask|NSMouseMovedMask handler:^(NSEvent *e) { QPointF localPoint = qt_mac_flipPoint([NSEvent mouseLocation]); QWindowSystemInterface::handleMouseEvent(window(), window()->mapFromGlobal(localPoint.toPoint()), localPoint, @@ -744,10 +747,7 @@ void QCocoaWindow::setVisible(bool visible) } else { [m_contentView setHidden:YES]; } - if (monitor && window()->type() == Qt::Popup) { - [NSEvent removeMonitor:monitor]; - monitor = nil; - } + removeMonitor(); if (window()->type() == Qt::Popup) QCocoaIntegration::instance()->popupWindowStack()->removeAll(this); @@ -1480,6 +1480,14 @@ void QCocoaWindow::removeChildWindow(QCocoaWindow *child) [m_nsWindow removeChildWindow:child->m_nsWindow]; } +void QCocoaWindow::removeMonitor() +{ + if (!monitor) + return; + [NSEvent removeMonitor:monitor]; + monitor = nil; +} + // Returns the current global screen geometry for the nswindow associated with this window. QRect QCocoaWindow::windowGeometry() const { -- cgit v1.2.3 From b3d09eceb83e9d34906144d98f3de727679df6f0 Mon Sep 17 00:00:00 2001 From: Jorgen Lind Date: Wed, 3 Jun 2015 14:10:19 +0200 Subject: Move the function helper to its own file Also make it a class so a forward header is generated by syncqt Change-Id: Ibab6b925dc6e9dab1b617b9b4027a4144e4a3773 Reviewed-by: Timur Pocheptsov Reviewed-by: Laszlo Agocs --- src/platformheaders/helper/helper.pri | 2 + src/platformheaders/helper/qplatformheaderhelper.h | 87 ++++++++++++++++++++++ src/platformheaders/platformheaders.pro | 1 + .../xcbfunctions/qxcbfunctionshelper.h | 84 --------------------- .../xcbfunctions/qxcbintegrationfunctions.h | 4 +- .../xcbfunctions/qxcbwindowfunctions.h | 12 +-- sync.profile | 2 +- 7 files changed, 99 insertions(+), 93 deletions(-) create mode 100644 src/platformheaders/helper/helper.pri create mode 100644 src/platformheaders/helper/qplatformheaderhelper.h delete mode 100644 src/platformheaders/xcbfunctions/qxcbfunctionshelper.h diff --git a/src/platformheaders/helper/helper.pri b/src/platformheaders/helper/helper.pri new file mode 100644 index 0000000000..2f6e766214 --- /dev/null +++ b/src/platformheaders/helper/helper.pri @@ -0,0 +1,2 @@ +HEADERS += \ + $$PWD/qplatformheaderhelper.h diff --git a/src/platformheaders/helper/qplatformheaderhelper.h b/src/platformheaders/helper/qplatformheaderhelper.h new file mode 100644 index 0000000000..52302dbfba --- /dev/null +++ b/src/platformheaders/helper/qplatformheaderhelper.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMHEADERHELPER_H +#define QPLATFORMHEADERHELPER_H + +#include +#include + +#if 0 +#pragma qt_class(QPlatformHeaderHelper) +#endif + +QT_BEGIN_NAMESPACE + +namespace QPlatformHeaderHelper { + +template +ReturnT callPlatformFunction(const QByteArray &functionName) +{ + FunctionT func = reinterpret_cast(QGuiApplication::platformFunction(functionName)); + return func ? func() : ReturnT(); +} + +template +ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1) +{ + FunctionT func = reinterpret_cast(QGuiApplication::platformFunction(functionName)); + return func ? func(a1) : ReturnT(); +} + +template +ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1, Arg2 a2) +{ + FunctionT func = reinterpret_cast(QGuiApplication::platformFunction(functionName)); + return func ? func(a1, a2) : ReturnT(); +} + +template +ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1, Arg2 a2, Arg3 a3) +{ + FunctionT func = reinterpret_cast(QGuiApplication::platformFunction(functionName)); + return func ? func(a1, a2, a3) : ReturnT(); +} + +template +ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4) +{ + FunctionT func = reinterpret_cast(QGuiApplication::platformFunction(functionName)); + return func ? func(a1, a2, a3, a4) : ReturnT(); +} + +} + +QT_END_NAMESPACE + +#endif /*QPLATFORMHEADERHELPER_H*/ diff --git a/src/platformheaders/platformheaders.pro b/src/platformheaders/platformheaders.pro index 5e875f7d2d..6b6294d34c 100644 --- a/src/platformheaders/platformheaders.pro +++ b/src/platformheaders/platformheaders.pro @@ -7,6 +7,7 @@ include(nativecontexts/nativecontexts.pri) include(xcbfunctions/xcbfunctions.pri) include(eglfsfunctions/eglfsfunctions.pri) include(windowsfunctions/windowsfunctions.pri) +include(helper/helper.pri) QMAKE_DOCS = $$PWD/doc/qtplatformheaders.qdocconf diff --git a/src/platformheaders/xcbfunctions/qxcbfunctionshelper.h b/src/platformheaders/xcbfunctions/qxcbfunctionshelper.h deleted file mode 100644 index a9d734a387..0000000000 --- a/src/platformheaders/xcbfunctions/qxcbfunctionshelper.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QXCBFUNCTIONHELPER_H -#define QXCBFUNCTIONHELPER_H - -#include -#include - -QT_BEGIN_NAMESPACE - -namespace QXcbFunctionsHelper -{ - -template -ReturnT callPlatformFunction(const QByteArray &functionName) -{ - FunctionT func = reinterpret_cast(QGuiApplication::platformFunction(functionName)); - return func ? func() : ReturnT(); -} - -template -ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1) -{ - FunctionT func = reinterpret_cast(QGuiApplication::platformFunction(functionName)); - return func ? func(a1) : ReturnT(); -} - -template -ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1, Arg2 a2) -{ - FunctionT func = reinterpret_cast(QGuiApplication::platformFunction(functionName)); - return func ? func(a1, a2) : ReturnT(); -} - -template -ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1, Arg2 a2, Arg3 a3) -{ - FunctionT func = reinterpret_cast(QGuiApplication::platformFunction(functionName)); - return func ? func(a1, a2, a3) : ReturnT(); -} - -template -ReturnT callPlatformFunction(const QByteArray &functionName, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4) -{ - FunctionT func = reinterpret_cast(QGuiApplication::platformFunction(functionName)); - return func ? func(a1, a2, a3, a4) : ReturnT(); -} - -} - -QT_END_NAMESPACE - -#endif /*QXCBFUNCTIONHELPER_H*/ diff --git a/src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h b/src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h index 87e19e6a45..66bfb72307 100644 --- a/src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h +++ b/src/platformheaders/xcbfunctions/qxcbintegrationfunctions.h @@ -34,7 +34,7 @@ #ifndef QXCBINTEGRATIONFUNCTIONS_H #define QXCBINTEGRATIONFUNCTIONS_H -#include "qxcbfunctionshelper.h" +#include QT_BEGIN_NAMESPACE @@ -45,7 +45,7 @@ public: static const QByteArray xEmbedSystemTrayVisualHasAlphaChannelIdentifier() { return QByteArrayLiteral("XcbXEmbedSystemTrayVisualHasAlphaChannel"); } static bool xEmbedSystemTrayVisualHasAlphaChannel() { - return QXcbFunctionsHelper::callPlatformFunction(xEmbedSystemTrayVisualHasAlphaChannelIdentifier()); + return QPlatformHeaderHelper::callPlatformFunction(xEmbedSystemTrayVisualHasAlphaChannelIdentifier()); } }; diff --git a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h index d477a63ec7..0db2e2a09d 100644 --- a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h +++ b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h @@ -34,7 +34,7 @@ #ifndef QXCBWINDOWFUNCTIONS_H #define QXCBWINDOWFUNCTIONS_H -#include "qxcbfunctionshelper.h" +#include QT_BEGIN_NAMESPACE @@ -66,35 +66,35 @@ public: static const QByteArray setWmWindowTypeIdentifier() { return QByteArrayLiteral("XcbSetWmWindowType"); } static void setWmWindowType(QWindow *window, WmWindowType type) { - return QXcbFunctionsHelper::callPlatformFunction(setWmWindowTypeIdentifier(), window, type); + return QPlatformHeaderHelper::callPlatformFunction(setWmWindowTypeIdentifier(), window, type); } typedef void (*SetWmWindowIconText)(QWindow *window, const QString &text); static const QByteArray setWmWindowIconTextIdentifier() { return QByteArrayLiteral("XcbSetWmWindowIconText"); } static void setWmWindowIconText(QWindow *window, const QString &text) { - return QXcbFunctionsHelper::callPlatformFunction(setWmWindowIconTextIdentifier(), window, text); + return QPlatformHeaderHelper::callPlatformFunction(setWmWindowIconTextIdentifier(), window, text); } typedef void (*SetParentRelativeBackPixmap)(const QWindow *window); static const QByteArray setParentRelativeBackPixmapIdentifier() { return QByteArrayLiteral("XcbSetParentRelativeBackPixmap"); } static void setParentRelativeBackPixmap(const QWindow *window) { - return QXcbFunctionsHelper::callPlatformFunction(setParentRelativeBackPixmapIdentifier(), window); + return QPlatformHeaderHelper::callPlatformFunction(setParentRelativeBackPixmapIdentifier(), window); } typedef bool (*RequestSystemTrayWindowDock)(const QWindow *window); static const QByteArray requestSystemTrayWindowDockIdentifier() { return QByteArrayLiteral("XcbRequestSystemTrayWindowDockIdentifier"); } static bool requestSystemTrayWindowDock(const QWindow *window) { - return QXcbFunctionsHelper::callPlatformFunction(requestSystemTrayWindowDockIdentifier(), window); + return QPlatformHeaderHelper::callPlatformFunction(requestSystemTrayWindowDockIdentifier(), window); } typedef QRect (*SystemTrayWindowGlobalGeometry)(const QWindow *window); static const QByteArray systemTrayWindowGlobalGeometryIdentifier() { return QByteArrayLiteral("XcbSystemTrayWindowGlobalGeometryIdentifier"); } static QRect systemTrayWindowGlobalGeometry(const QWindow *window) { - return QXcbFunctionsHelper::callPlatformFunction(systemTrayWindowGlobalGeometryIdentifier(), window); + return QPlatformHeaderHelper::callPlatformFunction(systemTrayWindowGlobalGeometryIdentifier(), window); } typedef uint (*VisualId)(QWindow *window); diff --git a/sync.profile b/sync.profile index bf29ca6e26..1700d94fff 100644 --- a/sync.profile +++ b/sync.profile @@ -50,7 +50,7 @@ } ); -@qpa_headers = ( qr/^qplatform/, qr/^qwindowsystem/ ); +@qpa_headers = ( qr/^(?!qplatformheaderhelper)qplatform/, qr/^qwindowsystem/ ); my @angle_headers = ('egl.h', 'eglext.h', 'eglplatform.h', 'gl2.h', 'gl2ext.h', 'gl2platform.h', 'ShaderLang.h', 'khrplatform.h'); my @internal_zlib_headers = ( "crc32.h", "deflate.h", "gzguts.h", "inffast.h", "inffixed.h", "inflate.h", "inftrees.h", "trees.h", "zutil.h" ); my @zlib_headers = ( "zconf.h", "zlib.h" ); -- cgit v1.2.3 From 79a97be9f31f7092c39186084c9d9d609a9be385 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 4 Jun 2015 12:58:46 +0200 Subject: doc: Remove uses of \mainclass This qdoc command is deprecated. Task-number: QTBUG-46476 Change-Id: Iee36f91bdcf500c2e88022a5f8a9c3accc6048c2 Reviewed-by: Martin Smith --- src/corelib/io/qprocess.cpp | 1 - src/gui/text/qglyphrun.cpp | 1 - src/gui/text/qrawfont.cpp | 1 - src/gui/text/qstatictext.cpp | 1 - 4 files changed, 4 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 38bd588c37..da6e0c87af 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -110,7 +110,6 @@ QT_BEGIN_NAMESPACE \ingroup io \ingroup misc \ingroup shared - \mainclass \reentrant \since 4.6 diff --git a/src/gui/text/qglyphrun.cpp b/src/gui/text/qglyphrun.cpp index e6d6863134..642313d340 100644 --- a/src/gui/text/qglyphrun.cpp +++ b/src/gui/text/qglyphrun.cpp @@ -49,7 +49,6 @@ QT_BEGIN_NAMESPACE \ingroup text \ingroup shared - \mainclass When Qt displays a string of text encoded in Unicode, it will first convert the Unicode points into a list of glyph indexes and a list of positions based on one or more fonts. The Unicode diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 2631cf8d17..d5567e173d 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -55,7 +55,6 @@ QT_BEGIN_NAMESPACE \ingroup text \ingroup shared - \mainclass \note QRawFont is a low level class. For most purposes QFont is a more appropriate class. diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index c3be9b871c..5d31ab9711 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -53,7 +53,6 @@ QStaticTextUserData::~QStaticTextUserData() \ingroup multimedia \ingroup text \ingroup shared - \mainclass QStaticText provides a way to cache layout data for a block of text so that it can be drawn more efficiently than by using QPainter::drawText() in which the layout information is -- cgit v1.2.3 From e36de4bc5d62ab270314b195982014ad6aa7fe36 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 5 Jun 2015 10:40:28 +0200 Subject: doc: Remove uses of \returns It is a doxygen command that is not recognized by qdoc. Change-Id: I26b0c54a1aa715fc9d8b70e411502f46fc6bc0f1 Task-number: QTBUG-46495 Reviewed-by: Martin Smith --- src/widgets/widgets/qmainwindowlayout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index d41f3bad19..ee76720a27 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -311,7 +311,7 @@ QDockAreaLayoutInfo *QDockWidgetGroupWindow::layoutInfo() const } /*! \internal - \returns the currently active QDockWidget + Returns the currently active QDockWidget. */ QDockWidget *QDockWidgetGroupWindow::topDockWidget() const { @@ -2195,7 +2195,7 @@ void QMainWindowLayout::setCentralWidget(QWidget *widget) widget is part if QMainWindow::GroupedDragging is set. When \a group is false, the widget itself is always unplugged alone - \returns the QLayoutItem of the dragged element. + Returns the QLayoutItem of the dragged element. The layout item is kept in the layout but set as a gap item. */ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group) -- cgit v1.2.3 From 8b1746b09df51df17befdaccc661ce81a8dfb5e8 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 28 May 2015 12:07:05 +0200 Subject: qdoc: Just reformatting and removing dead code Whitespace only. Change-Id: I6e4b55ad55e22da4150530457202f144fcc7f416 Reviewed-by: Martin Smith --- src/tools/qdoc/codeparser.cpp | 27 --------------------------- src/tools/qdoc/cppcodeparser.cpp | 29 ++++++----------------------- 2 files changed, 6 insertions(+), 50 deletions(-) diff --git a/src/tools/qdoc/codeparser.cpp b/src/tools/qdoc/codeparser.cpp index 90823080ce..4f80ec80d9 100644 --- a/src/tools/qdoc/codeparser.cpp +++ b/src/tools/qdoc/codeparser.cpp @@ -423,33 +423,6 @@ void CodeParser::checkModuleInclusion(Node* n) .arg(n->name()).arg(Generator::defaultModuleName())); } break; -#if 0 - case Node::Document: - if (n->access() != Node::Private && !n->doc().isEmpty()) { - if (n->docSubtype() == Node::HeaderFile) { -#if 0 - n->doc().location().warning(tr("Header file with title \"%1\" has no \\inmodule command; " - "using project name by default: %2") - .arg(n->title()).arg(Generator::defaultModuleName())); -#endif - } - else if (n->docSubtype() == Node::Page) { -#if 0 - n->doc().location().warning(tr("Page with title \"%1\" has no \\inmodule command; " - "using project name by default: %2") - .arg(n->title()).arg(Generator::defaultModuleName())); -#endif - } - else if (n->docSubtype() == Node::Example) { -#if 0 - n->doc().location().warning(tr("Example with title \"%1\" has no \\inmodule command; " - "using project name by default: %2") - .arg(n->title()).arg(Generator::defaultModuleName())); -#endif - } - } - break; -#endif default: break; } diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index 90f91c5f06..0468f3691e 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -520,16 +520,6 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, else if (t == "ditamap") ptype = Node::DitaMapPage; } - -#if 0 - const Node* n = qdb_->checkForCollision(args[0]); - if (n) { - QString other = n->doc().location().fileName(); - doc.location().warning(tr("Name/title collision detected: '%1' in '\\%2'") - .arg(args[0]).arg(command), - tr("Also used here: %1").arg(other)); - } -#endif DocumentNode* dn = 0; if (ptype == Node::DitaMapPage) dn = new DitaMapNode(qdb_->primaryTreeRoot(), args[0]); @@ -892,8 +882,7 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, ((Aggregate *) node)->addInclude(arg); } else { - doc.location().warning(tr("Ignored '\\%1'") - .arg(COMMAND_INHEADERFILE)); + doc.location().warning(tr("Ignored '\\%1'").arg(COMMAND_INHEADERFILE)); } } else if (command == COMMAND_OVERLOAD) { @@ -932,9 +921,7 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, func->setReimplemented(true); } else { - doc.location().warning(tr("Ignored '\\%1' in %2") - .arg(COMMAND_REIMP) - .arg(node->name())); + doc.location().warning(tr("Ignored '\\%1' in %2").arg(COMMAND_REIMP).arg(node->name())); } } } @@ -2078,29 +2065,25 @@ bool CppCodeParser::matchDeclList(Aggregate *parent) case Tok_Q_DECLARE_SEQUENTIAL_ITERATOR: readToken(); if (match(Tok_LeftParen) && match(Tok_Ident)) - sequentialIteratorClasses.insert(previousLexeme(), - location().fileName()); + sequentialIteratorClasses.insert(previousLexeme(), location().fileName()); match(Tok_RightParen); break; case Tok_Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR: readToken(); if (match(Tok_LeftParen) && match(Tok_Ident)) - mutableSequentialIteratorClasses.insert(previousLexeme(), - location().fileName()); + mutableSequentialIteratorClasses.insert(previousLexeme(), location().fileName()); match(Tok_RightParen); break; case Tok_Q_DECLARE_ASSOCIATIVE_ITERATOR: readToken(); if (match(Tok_LeftParen) && match(Tok_Ident)) - associativeIteratorClasses.insert(previousLexeme(), - location().fileName()); + associativeIteratorClasses.insert(previousLexeme(), location().fileName()); match(Tok_RightParen); break; case Tok_Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR: readToken(); if (match(Tok_LeftParen) && match(Tok_Ident)) - mutableAssociativeIteratorClasses.insert(previousLexeme(), - location().fileName()); + mutableAssociativeIteratorClasses.insert(previousLexeme(), location().fileName()); match(Tok_RightParen); break; case Tok_Q_DECLARE_FLAGS: -- cgit v1.2.3 From 0dd0d2f9d5b333b215848ea3965e3af3dccaf599 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 28 May 2015 11:24:24 +0200 Subject: qdoc: fix invalid memory access in HtmlGenerator HtmlGenerator::highlightedCode() contained a potential out-of-range- memory reference, which is prevented by this fix. Change-Id: I3bc87a8287e1d51c2786f5ec42384dbac04c9636 Task-number: QTBUG-45643 Reviewed-by: Martin Smith --- src/tools/qdoc/htmlgenerator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index e80187ec93..d7a17fce26 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -3551,7 +3551,8 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, bool handled = false; for (int k = 0; k != 18; ++k) { const QString & tag = spanTags[2 * k]; - if (tag == QStringRef(&src, i, tag.length())) { + if (i + tag.length() <= src.length() && + tag == QStringRef(&src, i, tag.length())) { html += spanTags[2 * k + 1]; i += tag.length(); handled = true; -- cgit v1.2.3 From 181ee8f9ffacc51265ccc3a0005bf146f230cf85 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 4 Jun 2015 13:39:29 +0200 Subject: Keep the mouse timestamp for tests closer to the actual time Pass on the requested delay into the mouse events. We don't care about single msecs as the surrounding code also takes time that we don't consider and whenever we generate a release we add 500ms of time skew anyway. The initial press of a double click has to increment the timestamp, just like all other mouse events do. Change-Id: Ifb94830f9f878ce87d92bfd86c72a16b55052f3b Reviewed-by: Simon Hausmann Reviewed-by: Lars Knoll --- src/testlib/qtestmouse.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h index 83ea3dd0a5..cd3901ae6f 100644 --- a/src/testlib/qtestmouse.h +++ b/src/testlib/qtestmouse.h @@ -89,8 +89,10 @@ namespace QTest if (delay == -1 || delay < defaultMouseDelay()) delay = defaultMouseDelay(); - if (delay > 0) + if (delay > 0) { QTest::qWait(delay); + lastMouseTimestamp += delay; + } if (pos.isNull()) pos = window->geometry().center(); @@ -105,7 +107,7 @@ namespace QTest switch (action) { case MouseDClick: - qt_handleMouseEvent(w, pos, global, button, stateKey, lastMouseTimestamp); + qt_handleMouseEvent(w, pos, global, button, stateKey, ++lastMouseTimestamp); qt_handleMouseEvent(w, pos, global, Qt::NoButton, stateKey, ++lastMouseTimestamp); // fall through case MousePress: -- cgit v1.2.3 From 275a970c30ebe423cadbe4c3090eca6d1760dafc Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 5 Jun 2015 11:35:01 +0200 Subject: doc: Added Q_NEVER_INLINE to ignored tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This helps qdoc's parser. Change-Id: I4c7f2dff348b87659c93ddb14d012d5bf2e626f2 Task-number: QTBUG-46498 Reviewed-by: Topi Reiniö --- doc/global/qt-cpp-defines.qdocconf | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index 3491e00402..5f309d2a61 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -66,6 +66,7 @@ Cpp.ignoretokens += \ Q_POSITIONING_EXPORT \ Q_MULTIMEDIA_EXPORT \ Q_NETWORK_EXPORT \ + Q_NEVER_INLINE \ Q_NORETURN \ Q_OPENGL_EXPORT \ Q_OPENVG_EXPORT \ -- cgit v1.2.3 From d7f15e67f9bacb19a71376cf323d79b8f1a2e677 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 20 May 2015 15:36:42 +0200 Subject: Manual touch test: Add gestures. Add command line options for - Grabbing gestures - Suppressing mouse and touch events Add gesture events to the log. Add a hierarchy of gesture classes storing the parameters of finished gestures with drawing functionality and implement for pan and swipe. Task-number: QTBUG-46195 Change-Id: I019fe5b60116316a54e11b2c30e1d34f5e72bcf0 Reviewed-by: Shawn Rutledge --- tests/manual/touch/main.cpp | 249 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 236 insertions(+), 13 deletions(-) diff --git a/tests/manual/touch/main.cpp b/tests/manual/touch/main.cpp index 727e7a32b7..b7029767c9 100644 --- a/tests/manual/touch/main.cpp +++ b/tests/manual/touch/main.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include +#include #include #include #include @@ -47,10 +48,48 @@ #include #include #include +#include #include #include bool optIgnoreTouch = false; +QVector optGestures; + +static inline void drawCircle(const QPointF ¢er, qreal radius, const QColor &color, QPainter &painter) +{ + const QPen oldPen = painter.pen(); + QPen pen = oldPen; + pen.setColor(color); + painter.setPen(pen); + painter.drawEllipse(center, radius, radius); + painter.setPen(oldPen); +} + +static inline void fillCircle(const QPointF ¢er, qreal radius, const QColor &color, QPainter &painter) +{ + QPainterPath painterPath; + painterPath.addEllipse(center, radius, radius); + painter.fillPath(painterPath, color); +} + +// Draws an arrow assuming a mathematical coordinate system, Y axis pointing +// upwards, angle counterclockwise (that is, 45' is pointing up/right). +static void drawArrow(const QPointF ¢er, qreal length, qreal angleDegrees, + const QColor &color, int arrowSize, QPainter &painter) +{ + painter.save(); + painter.translate(center); // Transform center to (0,0) rotate and draw arrow pointing right. + painter.rotate(-angleDegrees); + QPen pen = painter.pen(); + pen.setColor(color); + pen.setWidth(2); + painter.setPen(pen); + const QPointF endPoint(length, 0); + painter.drawLine(QPointF(0, 0), endPoint); + painter.drawLine(endPoint, endPoint + QPoint(-arrowSize, -arrowSize)); + painter.drawLine(endPoint, endPoint + QPoint(-arrowSize, arrowSize)); + painter.restore(); +} QDebug operator<<(QDebug debug, const QTouchDevice *d) { @@ -70,6 +109,110 @@ QDebug operator<<(QDebug debug, const QTouchDevice *d) return debug; } +// Hierarchy of classes containing gesture parameters and drawing functionality. +class Gesture { + Q_DISABLE_COPY(Gesture) +public: + static Gesture *fromQGesture(const QWidget *w, const QGesture *source); + virtual ~Gesture() {} + + virtual void draw(const QRectF &rect, QPainter &painter) const = 0; + +protected: + explicit Gesture(const QWidget *w, const QGesture *source) : m_type(source->gestureType()) + , m_hotSpot(w->mapFromGlobal(source->hotSpot().toPoint())) + , m_hasHotSpot(source->hasHotSpot()) {} + + QPointF drawHotSpot(const QRectF &rect, QPainter &painter) const + { + const QPointF h = m_hasHotSpot ? m_hotSpot : rect.center(); + painter.drawEllipse(h, 15, 15); + return h; + } + +private: + Qt::GestureType m_type; + QPointF m_hotSpot; + bool m_hasHotSpot; +}; + +class PanGesture : public Gesture { +public: + explicit PanGesture(const QWidget *w, const QPanGesture *source) : Gesture(w, source) + , m_offset(source->offset()) {} + + void draw(const QRectF &rect, QPainter &painter) const Q_DECL_OVERRIDE + { + const QPointF hotSpot = drawHotSpot(rect, painter); + painter.drawLine(hotSpot, hotSpot + m_offset); + } + +private: + QPointF m_offset; +}; + +class SwipeGesture : public Gesture { +public: + explicit SwipeGesture(const QWidget *w, const QSwipeGesture *source) : Gesture(w, source) + , m_horizontal(source->horizontalDirection()), m_vertical(source->verticalDirection()) + , m_angle(source->swipeAngle()) {} + + void draw(const QRectF &rect, QPainter &painter) const Q_DECL_OVERRIDE; + +private: + QSwipeGesture::SwipeDirection m_horizontal; + QSwipeGesture::SwipeDirection m_vertical; + qreal m_angle; +}; + +static qreal swipeDirectionAngle(QSwipeGesture::SwipeDirection d) +{ + switch (d) { + case QSwipeGesture::NoDirection: + case QSwipeGesture::Right: + break; + case QSwipeGesture::Left: + return 180; + case QSwipeGesture::Up: + return 90; + case QSwipeGesture::Down: + return 270; + } + return 0; +} + +void SwipeGesture::draw(const QRectF &rect, QPainter &painter) const +{ + enum { arrowLength = 50, arrowHeadSize = 10 }; + const QPointF hotSpot = drawHotSpot(rect, painter); + drawArrow(hotSpot, arrowLength, swipeDirectionAngle(m_horizontal), Qt::red, arrowHeadSize, painter); + drawArrow(hotSpot, arrowLength, swipeDirectionAngle(m_vertical), Qt::green, arrowHeadSize, painter); + drawArrow(hotSpot, arrowLength, m_angle, Qt::blue, arrowHeadSize, painter); +} + +Gesture *Gesture::fromQGesture(const QWidget *w, const QGesture *source) +{ + Gesture *result = Q_NULLPTR; + switch (source->gestureType()) { + case Qt::TapGesture: + case Qt::TapAndHoldGesture: + case Qt::PanGesture: + result = new PanGesture(w, static_cast(source)); + break; + case Qt::PinchGesture: + case Qt::CustomGesture: + case Qt::LastGestureType: + break; + case Qt::SwipeGesture: + result = new SwipeGesture(w, static_cast(source)); + break; + } + return result; +} + +typedef QSharedPointer GesturePtr; +typedef QVector GesturePtrs; + typedef QVector EventTypeVector; class EventFilter : public QObject { @@ -91,7 +234,17 @@ bool EventFilter::eventFilter(QObject *o, QEvent *e) static int n = 0; if (m_types.contains(e->type())) { QString message; - QDebug(&message) << '#' << n++ << ' ' << o->objectName() << ' ' << e; + QDebug debug(&message); + debug << '#' << n++ << ' ' << o->objectName() << ' '; + switch (e->type()) { + case QEvent::Gesture: + case QEvent::GestureOverride: + debug << static_cast(e); // Special operator + break; + default: + debug << e; + break; + } emit eventReceived(message); } return false; @@ -141,6 +294,8 @@ public: explicit TouchTestWidget(QWidget *parent = 0) : QWidget(parent), m_drawPoints(true) { setAttribute(Qt::WA_AcceptTouchEvents); + foreach (Qt::GestureType t, optGestures) + grabGesture(t); } bool drawPoints() const { return m_drawPoints; } @@ -149,19 +304,26 @@ public slots: void clearPoints(); void setDrawPoints(bool drawPoints); +signals: + void logMessage(const QString &); + protected: bool event(QEvent *event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; private: - QVector m_points; - bool m_drawPoints; + void handleGestureEvent(QGestureEvent *gestureEvent); + + QVector m_points; + GesturePtrs m_gestures; + bool m_drawPoints; }; void TouchTestWidget::clearPoints() { - if (!m_points.isEmpty()) { + if (!m_points.isEmpty() || !m_gestures.isEmpty()) { m_points.clear(); + m_gestures.clear(); update(); } } @@ -201,12 +363,41 @@ bool TouchTestWidget::event(QEvent *event) else event->accept(); return true; + case QEvent::Gesture: + handleGestureEvent(static_cast(event)); + break; default: break; } return QWidget::event(event); } +void TouchTestWidget::handleGestureEvent(QGestureEvent *gestureEvent) +{ + foreach (QGesture *gesture, gestureEvent->gestures()) { + if (optGestures.contains(gesture->gestureType())) { + switch (gesture->state()) { + case Qt::NoGesture: + break; + case Qt::GestureStarted: + case Qt::GestureUpdated: + gestureEvent->accept(gesture); + break; + case Qt::GestureFinished: + gestureEvent->accept(gesture); + if (Gesture *g = Gesture::fromQGesture(this, gesture)) { + m_gestures.append(GesturePtr(g)); + update(); + } + break; + case Qt::GestureCanceled: + emit logMessage(QLatin1String("=== Qt::GestureCanceled ===")); + break; + } + } + } +} + void TouchTestWidget::paintEvent(QPaintEvent *) { // Draw touch points as dots, mouse press as light filled circles, mouse release as circles. @@ -216,15 +407,15 @@ void TouchTestWidget::paintEvent(QPaintEvent *) painter.drawRect(QRectF(geom.topLeft(), geom.bottomRight() - QPointF(1, 1))); foreach (const Point &point, m_points) { if (geom.contains(point.pos)) { - QPainterPath painterPath; const qreal radius = point.type == TouchPoint ? 1 : 4; - painterPath.addEllipse(point.pos, radius, radius); - if (point.type == MouseRelease) - painter.strokePath(painterPath, QPen(point.color())); - else - painter.fillPath(painterPath, point.color()); + if (point.type == MouseRelease) { + drawCircle(point.pos, radius, point.color(), painter); + } else + fillCircle(point.pos, radius, point.color(), painter); } } + foreach (const GesturePtr &gp, m_gestures) + gp->draw(geom, painter); } class MainWindow : public QMainWindow @@ -279,6 +470,7 @@ MainWindow::MainWindow() m_touchWidget->setObjectName(QStringLiteral("TouchWidget")); mainSplitter->addWidget(m_touchWidget); + connect(m_touchWidget, &TouchTestWidget::logMessage, this, &MainWindow::appendToLog); m_logTextEdit->setObjectName(QStringLiteral("LogTextEdit")); mainSplitter->addWidget(m_logTextEdit); @@ -314,8 +506,36 @@ int main(int argc, char *argv[]) const QCommandLineOption ignoreTouchOption(QStringLiteral("ignore"), QStringLiteral("Ignore touch events (for testing mouse emulation).")); parser.addOption(ignoreTouchOption); + const QCommandLineOption noTouchLogOption(QStringLiteral("notouchlog"), + QStringLiteral("Do not log touch events (for testing gestures).")); + parser.addOption(noTouchLogOption); + const QCommandLineOption noMouseLogOption(QStringLiteral("nomouselog"), + QStringLiteral("Do not log mouse events (for testing gestures).")); + parser.addOption(noMouseLogOption); + + const QCommandLineOption tapGestureOption(QStringLiteral("tap"), QStringLiteral("Grab tap gesture.")); + parser.addOption(tapGestureOption); + const QCommandLineOption tapAndHoldGestureOption(QStringLiteral("tap-and-hold"), + QStringLiteral("Grab tap-and-hold gesture.")); + parser.addOption(tapAndHoldGestureOption); + const QCommandLineOption panGestureOption(QStringLiteral("pan"), QStringLiteral("Grab pan gesture.")); + parser.addOption(panGestureOption); + const QCommandLineOption pinchGestureOption(QStringLiteral("pinch"), QStringLiteral("Grab pinch gesture.")); + parser.addOption(pinchGestureOption); + const QCommandLineOption swipeGestureOption(QStringLiteral("swipe"), QStringLiteral("Grab swipe gesture.")); + parser.addOption(swipeGestureOption); parser.process(QApplication::arguments()); optIgnoreTouch = parser.isSet(ignoreTouchOption); + if (parser.isSet(tapGestureOption)) + optGestures.append(Qt::TapGesture); + if (parser.isSet(tapAndHoldGestureOption)) + optGestures.append(Qt::TapAndHoldGesture); + if (parser.isSet(panGestureOption)) + optGestures.append(Qt::PanGesture); + if (parser.isSet(pinchGestureOption)) + optGestures.append(Qt::PinchGesture); + if (parser.isSet(swipeGestureOption)) + optGestures.append(Qt::SwipeGesture); MainWindow w; const QSize screenSize = QGuiApplication::primaryScreen()->availableGeometry().size(); @@ -325,11 +545,14 @@ int main(int argc, char *argv[]) w.show(); EventTypeVector eventTypes; - eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease - << QEvent::MouseButtonDblClick - << QEvent::TouchBegin << QEvent::TouchUpdate << QEvent::TouchEnd; + if (!parser.isSet(noMouseLogOption)) + eventTypes << QEvent::MouseButtonPress << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick; if (parser.isSet(mouseMoveOption)) eventTypes << QEvent::MouseMove; + if (!parser.isSet(noTouchLogOption)) + eventTypes << QEvent::TouchBegin << QEvent::TouchUpdate << QEvent::TouchEnd; + if (!optGestures.isEmpty()) + eventTypes << QEvent::Gesture << QEvent::GestureOverride; QObject *filterTarget = parser.isSet(globalFilterOption) ? static_cast(&a) : static_cast(w.touchWidget()); -- cgit v1.2.3 From 71388c37d2417d153fa0e1c596381d38aa6b2c49 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 2 Jun 2015 08:44:08 +0200 Subject: Clean up the qgraphicsscene autotest Change-Id: I8950a3eb9792dff90ed64cd3bf1d572745b05886 Reviewed-by: Simon Hausmann --- .../qgraphicsscene/tst_qgraphicsscene.cpp | 27 ++++------------------ 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index 7bd0393760..3b4ae73feb 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -1282,33 +1282,16 @@ void tst_QGraphicsScene::removeItem() view.show(); QApplication::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); - QTest::mouseMove(view.viewport(), QPoint(-1, -1)); - { - QMouseEvent moveEvent(QEvent::MouseMove, view.mapFromScene(hoverItem->scenePos() + QPointF(20, 20)), Qt::NoButton, 0, 0); - QApplication::sendEvent(view.viewport(), &moveEvent); - } - qApp->processEvents(); // update - qApp->processEvents(); // draw - QVERIFY(!hoverItem->isHovered); + QTest::mouseMove(view.viewport(), view.mapFromScene(hoverItem->scenePos() + QPointF(20, 20)), Qt::NoButton); + QTRY_VERIFY(!hoverItem->isHovered); - { - QTest::qWait(250); - QTest::mouseMove(view.viewport(), view.mapFromScene(hoverItem->scenePos()), Qt::NoButton); - QTest::qWait(10); - QMouseEvent moveEvent(QEvent::MouseMove, view.mapFromScene(hoverItem->scenePos()), Qt::NoButton, 0, 0); - QApplication::sendEvent(view.viewport(), &moveEvent); - } - qApp->processEvents(); // update - qApp->processEvents(); // draw - QVERIFY(hoverItem->isHovered); + QTest::mouseMove(view.viewport(), view.mapFromScene(hoverItem->scenePos()), Qt::NoButton); + QTRY_VERIFY(hoverItem->isHovered); scene.removeItem(hoverItem); hoverItem->setAcceptsHoverEvents(false); scene.addItem(hoverItem); - qApp->processEvents(); // <- delayed update is called - qApp->processEvents(); // <- scene schedules pending update - qApp->processEvents(); // <- pending update is sent to view - QVERIFY(!hoverItem->isHovered); + QTRY_VERIFY(!hoverItem->isHovered); } void tst_QGraphicsScene::focusItem() -- cgit v1.2.3 From 73cc3db4d5aa45ee76a72e9ad98cbc6f6b728b41 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 22 May 2015 13:34:48 +0200 Subject: Fix qgraphicswidget::initStyleOption autotest make sure it'll work with the new mouse handling as well. Change-Id: Ia2d567e618b77b0fa3532ee6c335cbdf5e496241 Reviewed-by: Simon Hausmann --- .../graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp | 2 ++ .../qgraphicswidget/tst_qgraphicswidget.cpp | 18 ++++-------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index 3b4ae73feb..ff29f99875 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -3492,6 +3492,8 @@ void tst_QGraphicsScene::task160653_selectionChanged() QSignalSpy spy(&scene, SIGNAL(selectionChanged())); QGraphicsView view(&scene); + view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); QTest::mouseClick( view.viewport(), Qt::LeftButton, 0, view.mapFromScene(scene.items().first()->scenePos())); QCOMPARE(spy.count(), 1); diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp index 9b92c34fb5..ec2203e615 100644 --- a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp @@ -182,14 +182,6 @@ private slots: void QTBUG_45867_send_itemChildAddedChange_to_parent(); }; - -static void sendMouseMove(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::NoButton, Qt::MouseButtons buttons = 0) -{ - QTest::mouseMove(widget, point); - QMouseEvent event(QEvent::MouseMove, point, button, buttons, 0); - QApplication::sendEvent(widget, &event); -} - // Subclass that exposes the protected functions. class SubQGraphicsWidget : public QGraphicsWidget { public: @@ -197,7 +189,7 @@ public: : QGraphicsWidget(parent, windowFlags), eventCount(0) { } - void initStyleOption(QStyleOption *option) + void initStyleOption(QStyleOption *option) const { QGraphicsWidget::initStyleOption(option); } void call_changeEvent(QEvent* event) @@ -1110,8 +1102,8 @@ void tst_QGraphicsWidget::initStyleOption() { QGraphicsScene scene; QGraphicsView view(&scene); + view.resize(300, 300); view.show(); - QApplication::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); view.setAlignment(Qt::AlignTop | Qt::AlignLeft); @@ -1133,10 +1125,8 @@ void tst_QGraphicsWidget::initStyleOption() } QFETCH(bool, underMouse); if (underMouse) { - view.resize(300, 300); - view.show(); - QVERIFY(QTest::qWaitForWindowActive(&view)); - sendMouseMove(view.viewport(), view.mapFromScene(widget->mapToScene(widget->boundingRect().center()))); + QCursor::setPos(view.viewport()->mapToGlobal(view.mapFromScene(widget->mapToScene(widget->boundingRect().center())))); + QTest::qWait(100); } QFETCH(QPalette, palette); -- cgit v1.2.3 From 3658b6278191ce0456ceffaa920c58da20f19685 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 1 Jun 2015 10:40:48 +0200 Subject: Fix the autotest on Mac Don't hit the scrollbar with the mouse click Change-Id: Ie82d8c5c058df9a482e7d5de2fe40681572f19ad Reviewed-by: Simon Hausmann --- tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index 9b8b306e00..b06a63365c 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -1221,7 +1221,7 @@ void tst_QListView::scrollTo() list << "Short item"; model.setStringList(list); lv.setModel(&model); - lv.setFixedSize(100, 200); + lv.setFixedSize(110, 200); topLevel.show(); QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); -- cgit v1.2.3 From 83eb09d591ea9aac59d1b5d105120e2d800a97e5 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 1 Jun 2015 11:53:14 +0200 Subject: Wait for the window being active before sending it events Change-Id: I2f5d6e37e630d70c4ba3ae81e807a89c447c8b26 Reviewed-by: Simon Hausmann --- tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp index 3a6f1f933d..f92eb7c8f9 100644 --- a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp +++ b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp @@ -483,6 +483,7 @@ void tst_QItemView::spider() view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); view->setModel(treeModel); view->show(); + QVERIFY(QTest::qWaitForWindowActive(view)); #if defined(Q_OS_WINCE) srandom(0); #else -- cgit v1.2.3 From 19ed646bcee99b0cc015c970a0978c3dbd86f890 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 2 Jun 2015 08:26:01 +0200 Subject: Make the test pass on high res mac displays Change-Id: I05f156faae85abe11edc954dd358ddfcfd320c74 Reviewed-by: Simon Hausmann --- tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index 9b3a6f6831..e5abd6bc46 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -4051,9 +4051,9 @@ void tst_QTableView::mouseWheel() QWheelEvent verticalEvent(pos, delta, 0, 0, Qt::Vertical); QWheelEvent horizontalEvent(pos, delta, 0, 0, Qt::Horizontal); QApplication::sendEvent(view.viewport(), &horizontalEvent); - QVERIFY(qAbs(view.horizontalScrollBar()->value() - horizontalPositon) < 10); + QVERIFY(qAbs(view.horizontalScrollBar()->value() - horizontalPositon) < 15); QApplication::sendEvent(view.viewport(), &verticalEvent); - QVERIFY(qAbs(view.verticalScrollBar()->value() - verticalPosition) < 10); + QVERIFY(qAbs(view.verticalScrollBar()->value() - verticalPosition) < 15); } #endif // !QT_NO_WHEELEVENT -- cgit v1.2.3 From f21d86b74766acc90b3bec7514a53441c43022d3 Mon Sep 17 00:00:00 2001 From: Bjoern Breitmeyer Date: Fri, 27 Mar 2015 15:46:05 +0100 Subject: Fix WEC2013 build of sqlite3. Change-Id: Iaa953df941d888b8ae1a590dd728a1d819d7e604 Reviewed-by: Konstantin Ritt Reviewed-by: Mark Brand --- src/3rdparty/sqlite/sqlite3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 086fb3bcd6..71f6c1036d 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -34875,6 +34875,7 @@ static void winLogIoerr(int nRetry){ ** create a substitute. */ /* #include */ +# if _WIN32_WCE < 0x800 struct tm *__cdecl localtime(const time_t *t) { static struct tm y; @@ -34896,6 +34897,7 @@ struct tm *__cdecl localtime(const time_t *t) y.tm_sec = pTm.wSecond; return &y; } +# endif #endif #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] -- cgit v1.2.3 From 657a8cf5beadafdbaae84ac50640707dba04c350 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Wed, 18 Mar 2015 12:56:47 +0300 Subject: Remove exec bits from files that should not be executable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I66f49c6db82eadc3b11cc9b1cf01375e9596a8e6 Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Oswald Buddenhagen Reviewed-by: Mark Brand --- examples/webkit/webkit-guide/js/anim_accord.js | 0 examples/webkit/webkit-guide/js/anim_gallery.js | 0 examples/webkit/webkit-guide/js/anim_panel.js | 0 examples/webkit/webkit-guide/js/anim_skew.js | 0 examples/webkit/webkit-guide/js/css3_backgrounds.js | 0 examples/webkit/webkit-guide/js/css3_border-img.js | 0 examples/webkit/webkit-guide/js/css3_grad-radial.js | 0 examples/webkit/webkit-guide/js/css3_mask-grad.js | 0 examples/webkit/webkit-guide/js/css3_mask-img.js | 0 examples/webkit/webkit-guide/js/css3_text-overflow.js | 0 examples/webkit/webkit-guide/js/form_tapper.js | 0 examples/webkit/webkit-guide/js/mob_condjs.js | 0 examples/webkit/webkit-guide/js/mobile.js | 0 examples/webkit/webkit-guide/js/storage.js | 0 mkspecs/macx-ios-clang/Info.plist.app | 0 src/3rdparty/sha3/KeccakF-1600-32-rvk.macros | 0 src/3rdparty/sha3/KeccakF-1600-32.macros | 0 src/3rdparty/sha3/KeccakF-1600-64.macros | 0 src/3rdparty/sha3/KeccakF-1600-int-set.h | 0 src/3rdparty/sha3/KeccakF-1600-interface.h | 0 src/3rdparty/sha3/KeccakF-1600-opt32-settings.h | 0 src/3rdparty/sha3/KeccakF-1600-opt32.c | 0 src/3rdparty/sha3/KeccakF-1600-opt64-settings.h | 0 src/3rdparty/sha3/KeccakF-1600-unrolling.macros | 0 src/3rdparty/sha3/KeccakNISTInterface.c | 0 src/3rdparty/sha3/KeccakNISTInterface.h | 0 src/3rdparty/sha3/KeccakSponge.c | 0 src/3rdparty/sha3/KeccakSponge.h | 0 src/3rdparty/sha3/brg_endian.h | 0 src/plugins/platforms/cocoa/qcocoasystemtrayicon.h | 0 src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm | 0 src/plugins/platforms/eglfs/cursor-atlas.png | Bin .../styles/bb10style/bright/button/core_button_inactive.png | Bin .../styles/bb10style/bright/button/core_button_pressed.png | Bin .../bb10style/bright/checkbox/core_checkbox_pressed.png | Bin .../styles/bb10style/bright/lineedit/core_textinput_bg.png | Bin .../bright/lineedit/core_textinput_bg_highlight.png | Bin .../bb10style/bright/listitem/core_listitem_active.png | Bin .../bb10style/bright/listitem/core_listitem_divider.png | Bin .../bright/progressbar/core_progressindicator_bg.png | Bin .../bright/radiobutton/core_radiobutton_inactive.png | Bin .../bright/radiobutton/core_radiobutton_pressed.png | Bin .../styles/bb10style/bright/scrollbar/core_scrollbar.png | Bin .../bb10style/bright/slider/core_slider_handle_pressed.png | Bin .../styles/bb10style/dark/button/core_button_inactive.png | Bin .../styles/bb10style/dark/button/core_button_pressed.png | Bin .../bb10style/dark/checkbox/core_checkbox_pressed.png | Bin .../styles/bb10style/dark/lineedit/core_textinput_bg.png | Bin .../bb10style/dark/lineedit/core_textinput_bg_highlight.png | Bin .../styles/bb10style/dark/listitem/core_listitem_active.png | Bin .../bb10style/dark/listitem/core_listitem_divider.png | Bin .../dark/progressbar/core_progressindicator_bg.png | Bin .../dark/radiobutton/core_radiobutton_inactive.png | Bin .../bb10style/dark/radiobutton/core_radiobutton_pressed.png | Bin .../styles/bb10style/dark/scrollbar/core_scrollbar.png | Bin .../bb10style/dark/slider/core_slider_handle_pressed.png | Bin src/widgets/doc/images/listview.png | Bin src/widgets/doc/images/modelview-combobox.png | Bin src/widgets/doc/images/tableview.png | Bin src/widgets/doc/snippets/macmainwindow.mm | 0 tests/auto/sql/kernel/qsqldatabase/testdata/qtest.mdb | Bin .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/001.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/002.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/004.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/005.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/006.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/007.ent | Bin .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/008.ent | Bin .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/009.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/011.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/012.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/013.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/014.ent | Bin .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/002.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/003-1.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/004-1.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/004-2.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/005-1.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/005-2.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/006.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/007.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/008.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/009.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/010.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/011.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/012.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/013.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/014.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/015.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/016.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/017.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/018.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/019.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/020.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/021.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/022.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/023.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/024.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/025.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/026.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/027.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/028.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/029.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/030.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/031-1.ent | 0 .../xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/031-2.ent | 0 106 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 examples/webkit/webkit-guide/js/anim_accord.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/anim_gallery.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/anim_panel.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/anim_skew.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/css3_backgrounds.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/css3_border-img.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/css3_grad-radial.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/css3_mask-grad.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/css3_mask-img.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/css3_text-overflow.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/form_tapper.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/mob_condjs.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/mobile.js mode change 100755 => 100644 examples/webkit/webkit-guide/js/storage.js mode change 100755 => 100644 mkspecs/macx-ios-clang/Info.plist.app mode change 100755 => 100644 src/3rdparty/sha3/KeccakF-1600-32-rvk.macros mode change 100755 => 100644 src/3rdparty/sha3/KeccakF-1600-32.macros mode change 100755 => 100644 src/3rdparty/sha3/KeccakF-1600-64.macros mode change 100755 => 100644 src/3rdparty/sha3/KeccakF-1600-int-set.h mode change 100755 => 100644 src/3rdparty/sha3/KeccakF-1600-interface.h mode change 100755 => 100644 src/3rdparty/sha3/KeccakF-1600-opt32-settings.h mode change 100755 => 100644 src/3rdparty/sha3/KeccakF-1600-opt32.c mode change 100755 => 100644 src/3rdparty/sha3/KeccakF-1600-opt64-settings.h mode change 100755 => 100644 src/3rdparty/sha3/KeccakF-1600-unrolling.macros mode change 100755 => 100644 src/3rdparty/sha3/KeccakNISTInterface.c mode change 100755 => 100644 src/3rdparty/sha3/KeccakNISTInterface.h mode change 100755 => 100644 src/3rdparty/sha3/KeccakSponge.c mode change 100755 => 100644 src/3rdparty/sha3/KeccakSponge.h mode change 100755 => 100644 src/3rdparty/sha3/brg_endian.h mode change 100755 => 100644 src/plugins/platforms/cocoa/qcocoasystemtrayicon.h mode change 100755 => 100644 src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm mode change 100755 => 100644 src/plugins/platforms/eglfs/cursor-atlas.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/button/core_button_inactive.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/button/core_button_pressed.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/listitem/core_listitem_active.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.png mode change 100755 => 100644 src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/button/core_button_inactive.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/button/core_button_pressed.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/listitem/core_listitem_active.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.png mode change 100755 => 100644 src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.png mode change 100755 => 100644 src/widgets/doc/images/listview.png mode change 100755 => 100644 src/widgets/doc/images/modelview-combobox.png mode change 100755 => 100644 src/widgets/doc/images/tableview.png mode change 100755 => 100644 src/widgets/doc/snippets/macmainwindow.mm mode change 100755 => 100644 tests/auto/sql/kernel/qsqldatabase/testdata/qtest.mdb mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/001.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/002.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/004.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/005.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/006.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/007.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/008.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/009.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/011.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/012.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/013.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/014.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/002.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/003-1.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/004-1.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/004-2.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/005-1.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/005-2.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/006.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/007.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/008.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/009.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/010.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/011.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/012.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/013.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/014.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/015.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/016.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/017.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/018.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/019.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/020.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/021.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/022.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/023.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/024.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/025.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/026.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/027.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/028.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/029.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/030.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/031-1.ent mode change 100755 => 100644 tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/031-2.ent diff --git a/examples/webkit/webkit-guide/js/anim_accord.js b/examples/webkit/webkit-guide/js/anim_accord.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/anim_gallery.js b/examples/webkit/webkit-guide/js/anim_gallery.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/anim_panel.js b/examples/webkit/webkit-guide/js/anim_panel.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/anim_skew.js b/examples/webkit/webkit-guide/js/anim_skew.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/css3_backgrounds.js b/examples/webkit/webkit-guide/js/css3_backgrounds.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/css3_border-img.js b/examples/webkit/webkit-guide/js/css3_border-img.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/css3_grad-radial.js b/examples/webkit/webkit-guide/js/css3_grad-radial.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/css3_mask-grad.js b/examples/webkit/webkit-guide/js/css3_mask-grad.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/css3_mask-img.js b/examples/webkit/webkit-guide/js/css3_mask-img.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/css3_text-overflow.js b/examples/webkit/webkit-guide/js/css3_text-overflow.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/form_tapper.js b/examples/webkit/webkit-guide/js/form_tapper.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/mob_condjs.js b/examples/webkit/webkit-guide/js/mob_condjs.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/mobile.js b/examples/webkit/webkit-guide/js/mobile.js old mode 100755 new mode 100644 diff --git a/examples/webkit/webkit-guide/js/storage.js b/examples/webkit/webkit-guide/js/storage.js old mode 100755 new mode 100644 diff --git a/mkspecs/macx-ios-clang/Info.plist.app b/mkspecs/macx-ios-clang/Info.plist.app old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakF-1600-32-rvk.macros b/src/3rdparty/sha3/KeccakF-1600-32-rvk.macros old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakF-1600-32.macros b/src/3rdparty/sha3/KeccakF-1600-32.macros old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakF-1600-64.macros b/src/3rdparty/sha3/KeccakF-1600-64.macros old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakF-1600-int-set.h b/src/3rdparty/sha3/KeccakF-1600-int-set.h old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakF-1600-interface.h b/src/3rdparty/sha3/KeccakF-1600-interface.h old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakF-1600-opt32-settings.h b/src/3rdparty/sha3/KeccakF-1600-opt32-settings.h old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakF-1600-opt32.c b/src/3rdparty/sha3/KeccakF-1600-opt32.c old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakF-1600-opt64-settings.h b/src/3rdparty/sha3/KeccakF-1600-opt64-settings.h old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakF-1600-unrolling.macros b/src/3rdparty/sha3/KeccakF-1600-unrolling.macros old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakNISTInterface.c b/src/3rdparty/sha3/KeccakNISTInterface.c old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakNISTInterface.h b/src/3rdparty/sha3/KeccakNISTInterface.h old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakSponge.c b/src/3rdparty/sha3/KeccakSponge.c old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/KeccakSponge.h b/src/3rdparty/sha3/KeccakSponge.h old mode 100755 new mode 100644 diff --git a/src/3rdparty/sha3/brg_endian.h b/src/3rdparty/sha3/brg_endian.h old mode 100755 new mode 100644 diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.h old mode 100755 new mode 100644 diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm old mode 100755 new mode 100644 diff --git a/src/plugins/platforms/eglfs/cursor-atlas.png b/src/plugins/platforms/eglfs/cursor-atlas.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/button/core_button_inactive.png b/src/plugins/styles/bb10style/bright/button/core_button_inactive.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/button/core_button_pressed.png b/src/plugins/styles/bb10style/bright/button/core_button_pressed.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.png b/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.png b/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.png b/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/listitem/core_listitem_active.png b/src/plugins/styles/bb10style/bright/listitem/core_listitem_active.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.png b/src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.png b/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.png b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.png b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.png b/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.png b/src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/button/core_button_inactive.png b/src/plugins/styles/bb10style/dark/button/core_button_inactive.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/button/core_button_pressed.png b/src/plugins/styles/bb10style/dark/button/core_button_pressed.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.png b/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.png b/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.png b/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/listitem/core_listitem_active.png b/src/plugins/styles/bb10style/dark/listitem/core_listitem_active.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.png b/src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.png b/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.png b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.png b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.png b/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.png old mode 100755 new mode 100644 diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.png b/src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.png old mode 100755 new mode 100644 diff --git a/src/widgets/doc/images/listview.png b/src/widgets/doc/images/listview.png old mode 100755 new mode 100644 diff --git a/src/widgets/doc/images/modelview-combobox.png b/src/widgets/doc/images/modelview-combobox.png old mode 100755 new mode 100644 diff --git a/src/widgets/doc/images/tableview.png b/src/widgets/doc/images/tableview.png old mode 100755 new mode 100644 diff --git a/src/widgets/doc/snippets/macmainwindow.mm b/src/widgets/doc/snippets/macmainwindow.mm old mode 100755 new mode 100644 diff --git a/tests/auto/sql/kernel/qsqldatabase/testdata/qtest.mdb b/tests/auto/sql/kernel/qsqldatabase/testdata/qtest.mdb old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/001.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/001.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/002.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/002.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/004.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/004.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/005.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/005.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/006.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/006.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/007.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/007.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/008.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/008.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/009.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/009.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/011.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/011.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/012.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/012.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/013.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/013.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/014.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/ext-sa/014.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/002.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/002.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/003-1.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/003-1.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/004-1.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/004-1.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/004-2.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/004-2.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/005-1.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/005-1.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/005-2.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/005-2.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/006.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/006.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/007.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/007.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/008.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/008.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/009.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/009.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/010.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/010.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/011.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/011.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/012.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/012.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/013.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/013.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/014.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/014.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/015.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/015.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/016.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/016.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/017.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/017.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/018.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/018.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/019.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/019.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/020.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/020.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/021.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/021.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/022.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/022.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/023.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/023.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/024.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/024.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/025.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/025.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/026.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/026.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/027.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/027.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/028.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/028.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/029.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/029.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/030.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/030.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/031-1.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/031-1.ent old mode 100755 new mode 100644 diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/031-2.ent b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/valid/not-sa/031-2.ent old mode 100755 new mode 100644 -- cgit v1.2.3 From ae4bc7e97ea30dfef03498fcada6f337dcfd4bd7 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 6 Jun 2015 16:37:27 +0200 Subject: Remove bogus call and comment from addressbook QMap::empty() does not empty the list but is the STL version to ask if the map is empty. Remove the comment and code as operator>> of QDataStream will clear the map. Fixes Coverity CID#89073 Change-Id: I259e518b44afd42b698368b42aedcc3b84240aca Reviewed-by: Simon Hausmann --- examples/widgets/tutorials/addressbook/part7/addressbook.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/widgets/tutorials/addressbook/part7/addressbook.cpp b/examples/widgets/tutorials/addressbook/part7/addressbook.cpp index 45ded876a7..6764423d71 100644 --- a/examples/widgets/tutorials/addressbook/part7/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part7/addressbook.cpp @@ -370,7 +370,6 @@ void AddressBook::loadFromFile() QDataStream in(&file); in.setVersion(QDataStream::Qt_4_3); - contacts.empty(); // empty existing contacts in >> contacts; QMap::iterator i = contacts.begin(); -- cgit v1.2.3 From 7e390967f39b7fb7173f50484686e211b04eceb0 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sat, 6 Jun 2015 16:53:30 +0200 Subject: Fix incorrect expression in directfb keyboard code Add missing equal sign to have the result of the OR stored inside the modifiers variable. Fixes Coverity CID#89071. Change-Id: I0ee1a080f5f6757ae7646733aa3bb5cf8c6cdeed Reviewed-by: Simon Hausmann --- src/plugins/platforms/directfb/qdirectfbconvenience.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp index e635d4fd22..e1d97d9628 100644 --- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp +++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp @@ -217,7 +217,7 @@ Qt::KeyboardModifiers QDirectFbConvenience::keyboardModifiers(DFBInputDeviceModi modifiers |= Qt::ControlModifier; } if (mask & DIMM_META) { - modifiers | Qt::MetaModifier; + modifiers |= Qt::MetaModifier; } return modifiers; } -- cgit v1.2.3 From 4bb00d9d069b58037c0ec01233069ac244fb7c22 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 8 Jun 2015 10:12:33 +0200 Subject: Export class QAccessible::ActivationObserver. Change a21dfab54ed518266c42d3e87e02bd991de8486e de-inlined its destructor, so, the class needs to be exported. Change-Id: I32d21622a944a93718f549060e5e5f7e71fd2646 Reviewed-by: Simon Hausmann --- src/gui/accessible/qaccessible.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 66cd067ace..a0281d1c11 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -396,7 +396,7 @@ public: static UpdateHandler installUpdateHandler(UpdateHandler); static RootObjectHandler installRootObjectHandler(RootObjectHandler); - class ActivationObserver + class Q_GUI_EXPORT ActivationObserver { public: virtual ~ActivationObserver(); -- cgit v1.2.3 From 896da75550738a08f44dfeb72f09ace3a147b0ee Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 4 Jun 2015 11:34:26 +0200 Subject: make the enums of QProcess known to the meta object system This enables users to construct enum values from strings and provides useful qDebug operators. Task-number: QTBUG-10777 Change-Id: Ia3592f00d559b980b4875ee8fb5e8ffb4328d464 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/io/qprocess.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index 078217ea0b..32fa4aa866 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -104,15 +104,21 @@ public: WriteError, UnknownError }; + Q_ENUM(ProcessError) + enum ProcessState { NotRunning, Starting, Running }; + Q_ENUM(ProcessState) + enum ProcessChannel { StandardOutput, StandardError }; + Q_ENUM(ProcessChannel) + enum ProcessChannelMode { SeparateChannels, MergedChannels, @@ -120,14 +126,19 @@ public: ForwardedOutputChannel, ForwardedErrorChannel }; + Q_ENUM(ProcessChannelMode) + enum InputChannelMode { ManagedInputChannel, ForwardedInputChannel }; + Q_ENUM(InputChannelMode) + enum ExitStatus { NormalExit, CrashExit }; + Q_ENUM(ExitStatus) explicit QProcess(QObject *parent = 0); virtual ~QProcess(); -- cgit v1.2.3 From af75a27de7c8c4afc628aef32007d40c61725175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Fri, 5 Jun 2015 19:13:15 +0100 Subject: itemsviews: Add 15 QList::reserve() calls Change-Id: I4ed8872ecd560d51c00cb3d2b93e082c5abdd8dc Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Marc Mutz --- src/widgets/itemviews/qcolumnview.cpp | 4 +++- src/widgets/itemviews/qfileiconprovider.cpp | 1 + src/widgets/itemviews/qlistwidget.cpp | 18 ++++++++++++++---- src/widgets/itemviews/qtablewidget.cpp | 17 +++++++++++++---- src/widgets/itemviews/qtreewidget.cpp | 8 ++++++-- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/widgets/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp index 5c317bbb0c..0ee03035a4 100644 --- a/src/widgets/itemviews/qcolumnview.cpp +++ b/src/widgets/itemviews/qcolumnview.cpp @@ -878,7 +878,9 @@ QList QColumnView::columnWidths() const { Q_D(const QColumnView); QList list; - for (int i = 0; i < d->columns.count(); ++i) + const int columnCount = d->columns.count(); + list.reserve(columnCount); + for (int i = 0; i < columnCount; ++i) list.append(d->columnSizes.at(i)); return list; } diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp index 1cc3a2a905..cab32619c5 100644 --- a/src/widgets/itemviews/qfileiconprovider.cpp +++ b/src/widgets/itemviews/qfileiconprovider.cpp @@ -117,6 +117,7 @@ public: if (themeSizes.isEmpty()) return sizes; + sizes.reserve(themeSizes.count()); foreach (int size, themeSizes) sizes << QSize(size, size); } diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index 66f965aa54..668bfda59d 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -299,7 +299,10 @@ void QListModel::sort(int column, Qt::SortOrder order) std::sort(sorting.begin(), sorting.end(), compare); QModelIndexList fromIndexes; QModelIndexList toIndexes; - for (int r = 0; r < sorting.count(); ++r) { + const int sortingCount = sorting.count(); + fromIndexes.reserve(sortingCount); + toIndexes.reserve(sortingCount); + for (int r = 0; r < sortingCount; ++r) { QListWidgetItem *item = sorting.at(r).first; toIndexes.append(createIndex(r, 0, item)); fromIndexes.append(createIndex(sorting.at(r).second, 0, sorting.at(r).first)); @@ -423,7 +426,9 @@ QMimeData *QListModel::internalMimeData() const QMimeData *QListModel::mimeData(const QModelIndexList &indexes) const { QList itemlist; - for (int i = 0; i < indexes.count(); ++i) + const int indexesCount = indexes.count(); + itemlist.reserve(indexesCount); + for (int i = 0; i < indexesCount; ++i) itemlist << at(indexes.at(i).row()); const QListWidget *view = qobject_cast(QObject::parent()); @@ -1710,7 +1715,9 @@ QList QListWidget::findItems(const QString &text, Qt::MatchFla QModelIndexList indexes = d->listModel()->match(model()->index(0, 0, QModelIndex()), Qt::DisplayRole, text, -1, flags); QList items; - for (int i = 0; i < indexes.size(); ++i) + const int indexesSize = indexes.size(); + items.reserve(indexesSize); + for (int i = 0; i < indexesSize; ++i) items.append(d->listModel()->at(indexes.at(i).row())); return items; } @@ -1795,6 +1802,7 @@ QMimeData *QListWidget::mimeData(const QList items) const // if non empty, it's called from the model's own mimeData if (cachedIndexes.isEmpty()) { + cachedIndexes.reserve(items.count()); foreach (QListWidgetItem *item, items) cachedIndexes << indexFromItem(item); @@ -1845,7 +1853,9 @@ void QListWidget::dropEvent(QDropEvent *event) { if (d->dropOn(event, &row, &col, &topIndex)) { QList selIndexes = selectedIndexes(); QList persIndexes; - for (int i = 0; i < selIndexes.count(); i++) + const int selIndexesCount = selIndexes.count(); + persIndexes.reserve(selIndexesCount); + for (int i = 0; i < selIndexesCount; i++) persIndexes.append(selIndexes.at(i)); if (persIndexes.contains(topIndex)) diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index 9ebcbc35a7..b2d4abe5ac 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -812,7 +812,9 @@ QMimeData *QTableModel::internalMimeData() const QMimeData *QTableModel::mimeData(const QModelIndexList &indexes) const { QList items; - for (int i = 0; i < indexes.count(); ++i) + const int indexesCount = indexes.count(); + items.reserve(indexesCount); + for (int i = 0; i < indexesCount; ++i) items << item(indexes.at(i)); const QTableWidget *view = qobject_cast(QObject::parent()); @@ -2326,7 +2328,9 @@ QList QTableWidget::selectedRanges() const { const QList ranges = selectionModel()->selection(); QList result; - for (int i = 0; i < ranges.count(); ++i) + const int rangesCount = ranges.count(); + result.reserve(rangesCount); + for (int i = 0; i < rangesCount; ++i) result.append(QTableWidgetSelectionRange(ranges.at(i).top(), ranges.at(i).left(), ranges.at(i).bottom(), @@ -2372,7 +2376,9 @@ QList QTableWidget::findItems(const QString &text, Qt::MatchF indexes += d->model->match(model()->index(0, column, QModelIndex()), Qt::DisplayRole, text, -1, flags); QList items; - for (int i = 0; i < indexes.size(); ++i) + const int indexCount = indexes.size(); + items.reserve(indexCount); + for (int i = 0; i < indexCount; ++i) items.append(d->tableModel()->item(indexes.at(i))); return items; } @@ -2565,6 +2571,7 @@ QMimeData *QTableWidget::mimeData(const QList items) const // if non empty, it's called from the model's own mimeData if (cachedIndexes.isEmpty()) { + cachedIndexes.reserve(items.count()); foreach (QTableWidgetItem *item, items) cachedIndexes << indexFromItem(item); @@ -2676,7 +2683,9 @@ void QTableWidget::dropEvent(QDropEvent *event) { } QList taken; - for (int i = 0; i < indexes.count(); ++i) + const int indexesCount = indexes.count(); + taken.reserve(indexesCount); + for (int i = 0; i < indexesCount; ++i) taken.append(takeItem(indexes.at(i).row(), indexes.at(i).column())); for (int i = 0; i < indexes.count(); ++i) { diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index 1366a00318..5970e94292 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -3042,7 +3042,9 @@ QList QTreeWidget::findItems(const QString &text, Qt::MatchFla QModelIndexList indexes = d->model->match(model()->index(0, column, QModelIndex()), Qt::DisplayRole, text, -1, flags); QList items; - for (int i = 0; i < indexes.size(); ++i) + const int indexesSize = indexes.size(); + items.reserve(indexesSize); + for (int i = 0; i < indexesSize; ++i) items.append(d->item(indexes.at(i))); return items; } @@ -3371,7 +3373,9 @@ void QTreeWidget::dropEvent(QDropEvent *event) { if (d->dropOn(event, &row, &col, &topIndex)) { QList idxs = selectedIndexes(); QList indexes; - for (int i = 0; i < idxs.count(); i++) + const int indexesCount = idxs.count(); + indexes.reserve(indexesCount); + for (int i = 0; i < indexesCount; i++) indexes.append(idxs.at(i)); if (indexes.contains(topIndex)) -- cgit v1.2.3 From eacfbbf64ef90dad8c5cb6b2c812ad64c1100779 Mon Sep 17 00:00:00 2001 From: Caroline Chao Date: Tue, 2 Jun 2015 14:47:55 +0200 Subject: Testlib: Export blacklist functions So they can be used in QtQuickTest. Change-Id: I64925feb243fb27234951276d81119bc1f6d5a56 Reviewed-by: Simon Hausmann --- src/testlib/qtestblacklist_p.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/testlib/qtestblacklist_p.h b/src/testlib/qtestblacklist_p.h index 0107e5d282..87f4dfdb5e 100644 --- a/src/testlib/qtestblacklist_p.h +++ b/src/testlib/qtestblacklist_p.h @@ -50,9 +50,10 @@ QT_BEGIN_NAMESPACE namespace QTestPrivate { - void parseBlackList(); - void parseGpuBlackList(); - void checkBlackLists(const char *slot, const char *data); + // Export functions so they can also be used by QQuickTest + Q_TESTLIB_EXPORT void parseBlackList(); + Q_TESTLIB_EXPORT void parseGpuBlackList(); + Q_TESTLIB_EXPORT void checkBlackLists(const char *slot, const char *data); } QT_END_NAMESPACE -- cgit v1.2.3