diff options
-rwxr-xr-x | configure | 52 | ||||
-rw-r--r-- | src/android/java/AndroidManifest.xml | 1 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 6 | ||||
-rw-r--r-- | src/corelib/io/qurl.cpp | 15 | ||||
-rw-r--r-- | src/corelib/io/qurl.h | 20 | ||||
-rw-r--r-- | src/corelib/thread/qthreadpool.cpp | 28 | ||||
-rw-r--r-- | src/corelib/tools/qdatetime.cpp | 15 | ||||
-rw-r--r-- | src/corelib/tools/qhash.h | 9 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 8 | ||||
-rw-r--r-- | src/widgets/widgets/qcombobox.cpp | 19 | ||||
-rw-r--r-- | src/widgets/widgets/qcombobox_p.h | 4 | ||||
-rw-r--r-- | tests/auto/corelib/io/qurl/tst_qurl.cpp | 56 | ||||
-rw-r--r-- | tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 12 | ||||
-rw-r--r-- | tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp | 5 | ||||
-rw-r--r-- | tests/benchmarks/corelib/thread/qthreadpool/qthreadpool.pro | 5 | ||||
-rw-r--r-- | tests/benchmarks/corelib/thread/qthreadpool/tst_qthreadpool.cpp | 92 | ||||
-rw-r--r-- | tests/benchmarks/corelib/thread/thread.pro | 3 | ||||
-rw-r--r-- | tests/manual/widgets/itemviews/delegate/example.cpp | 41 |
18 files changed, 297 insertions, 94 deletions
@@ -5267,29 +5267,6 @@ if [ "$CFG_TSLIB" != "no" ]; then fi fi -# Check we actually have X11 :-) -if compileTest x11/xlib "XLib"; then - QT_CONFIG="$QT_CONFIG xlib" -fi - -# auto-detect Xrender support -if [ "$CFG_XRENDER" != "no" ]; then - if compileTest x11/xrender "Xrender"; then - CFG_XRENDER=yes - QT_CONFIG="$QT_CONFIG xrender" - else - if [ "$CFG_XRENDER" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "Xrender support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_XRENDER=no - fi - fi -fi - if [ "$CFG_XCB" != "no" ]; then if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xcb >= 1.5" 2>/dev/null; then QMAKE_CFLAGS_XCB="`$PKG_CONFIG --cflags xcb 2>/dev/null`" @@ -5335,10 +5312,39 @@ if [ "$CFG_XCB" != "no" ]; then fi fi + # Check for X11. Eventually we should port everything to XCB, + # but for now the port is incomplete and Xlib is a requirement. + if compileTest x11/xlib "XLib"; then + QT_CONFIG="$QT_CONFIG xlib" + else + echo "The test for linking against Xlib failed!" + echo " You might need to install dependency packages." + echo " See src/plugins/platforms/xcb/README." + exit 1 + fi + if compileTest qpa/xcb-xlib "xcb-xlib" $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then QT_CONFIG="$QT_CONFIG xcb-xlib" fi + # auto-detect Xrender support + if [ "$CFG_XRENDER" != "no" ]; then + if compileTest x11/xrender "Xrender"; then + CFG_XRENDER=yes + QT_CONFIG="$QT_CONFIG xrender" + else + if [ "$CFG_XRENDER" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then + echo "Xrender support cannot be enabled due to functionality tests!" + echo " Turn on verbose messaging (-v) to $0 to see the final report." + echo " If you believe this message is in error you may use the continue" + echo " switch (-continue) to $0 to continue." + exit 101 + else + CFG_XRENDER=no + fi + fi + fi + # auto-detect XInput2 support. Needed by xcb too. if [ "$CFG_XINPUT2" != "no" ]; then if compileTest x11/xinput2 "XInput2"; then diff --git a/src/android/java/AndroidManifest.xml b/src/android/java/AndroidManifest.xml index 2a6f52b315..c0aa5c9abf 100644 --- a/src/android/java/AndroidManifest.xml +++ b/src/android/java/AndroidManifest.xml @@ -31,6 +31,7 @@ <!-- Splash screen --> </activity> </application> + <uses-sdk android:targetSdkVersion="14" android:minSdkVersion="9"/> <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index f9629ff430..41f21bb0dd 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -681,11 +681,13 @@ typedef void (*QFunctionPointer)(); # define Q_UNIMPLEMENTED() qWarning("%s:%d: %s: Unimplemented code.", __FILE__, __LINE__, Q_FUNC_INFO) #endif +Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2) Q_REQUIRED_RESULT; Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2) { return (qAbs(p1 - p2) * 1000000000000. <= qMin(qAbs(p1), qAbs(p2))); } +Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2) Q_REQUIRED_RESULT; Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2) { return (qAbs(p1 - p2) * 100000.f <= qMin(qAbs(p1), qAbs(p2))); @@ -694,6 +696,7 @@ Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2) /*! \internal */ +Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(double d) Q_REQUIRED_RESULT; Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(double d) { return qAbs(d) <= 0.000000000001; @@ -702,6 +705,7 @@ Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(double d) /*! \internal */ +Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(float f) Q_REQUIRED_RESULT; Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(float f) { return qAbs(f) <= 0.00001f; @@ -712,6 +716,7 @@ Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(float f) check whether the actual value is 0 or close to 0, but whether it is binary 0, disregarding sign. */ +static inline bool qIsNull(double d) Q_REQUIRED_RESULT; static inline bool qIsNull(double d) { union U { @@ -728,6 +733,7 @@ static inline bool qIsNull(double d) check whether the actual value is 0 or close to 0, but whether it is binary 0, disregarding sign. */ +static inline bool qIsNull(float f) Q_REQUIRED_RESULT; static inline bool qIsNull(float f) { union U { diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 9607f14853..9f9653ea94 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -1089,8 +1089,11 @@ inline void QUrlPrivate::setQuery(const QString &value, int from, int iend) inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions options) const { - // this is the only flag that matters - options &= QUrl::EncodeUnicode; + // EncodeUnicode is the only flag that matters + if ((options & QUrl::FullyDecoded) == QUrl::FullyDecoded) + options = 0; + else + options &= QUrl::EncodeUnicode; if (host.isEmpty()) return; if (host.at(0).unicode() == '[') { @@ -3249,8 +3252,8 @@ QUrl QUrl::adjusted(QUrl::FormattingOptions options) const that.setPath(QString()); } else if (options & (StripTrailingSlash | RemoveFilename | NormalizePathSegments)) { QString path; - d->appendPath(path, options, QUrlPrivate::Path); - that.setPath(path); + d->appendPath(path, options | FullyEncoded, QUrlPrivate::Path); + that.setPath(path, TolerantMode); } return that; } @@ -3964,9 +3967,9 @@ uint qHash(const QUrl &url, uint seed) Q_DECL_NOTHROW static QUrl adjustFtpPath(QUrl url) { if (url.scheme() == ftpScheme()) { - QString path = url.path(); + QString path = url.path(QUrl::PrettyDecoded); if (path.startsWith(QLatin1String("//"))) - url.setPath(QLatin1String("/%2F") + path.midRef(2)); + url.setPath(QLatin1String("/%2F") + path.midRef(2), QUrl::TolerantMode); } return url; } diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h index 457440bb89..abb7df0056 100644 --- a/src/corelib/io/qurl.h +++ b/src/corelib/io/qurl.h @@ -209,22 +209,22 @@ public: void setUserInfo(const QString &userInfo, ParsingMode mode = TolerantMode); QString userInfo(ComponentFormattingOptions options = PrettyDecoded) const; - void setUserName(const QString &userName, ParsingMode mode = TolerantMode); - QString userName(ComponentFormattingOptions options = PrettyDecoded) const; + void setUserName(const QString &userName, ParsingMode mode = DecodedMode); + QString userName(ComponentFormattingOptions options = FullyDecoded) const; - void setPassword(const QString &password, ParsingMode mode = TolerantMode); - QString password(ComponentFormattingOptions = PrettyDecoded) const; + void setPassword(const QString &password, ParsingMode mode = DecodedMode); + QString password(ComponentFormattingOptions = FullyDecoded) const; - void setHost(const QString &host, ParsingMode mode = TolerantMode); - QString host(ComponentFormattingOptions = PrettyDecoded) const; - QString topLevelDomain(ComponentFormattingOptions options = PrettyDecoded) const; + void setHost(const QString &host, ParsingMode mode = DecodedMode); + QString host(ComponentFormattingOptions = FullyDecoded) const; + QString topLevelDomain(ComponentFormattingOptions options = FullyDecoded) const; void setPort(int port); int port(int defaultPort = -1) const; - void setPath(const QString &path, ParsingMode mode = TolerantMode); - QString path(ComponentFormattingOptions options = PrettyDecoded) const; - QString fileName(ComponentFormattingOptions options = PrettyDecoded) const; + void setPath(const QString &path, ParsingMode mode = DecodedMode); + QString path(ComponentFormattingOptions options = FullyDecoded) const; + QString fileName(ComponentFormattingOptions options = FullyDecoded) const; bool hasQuery() const; void setQuery(const QString &query, ParsingMode mode = TolerantMode); diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index bee6790705..31c3f5a256 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -52,14 +52,14 @@ QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(QThreadPool, theInstance) /* - QThread wrapper, provides synchronizitaion against a ThreadPool + QThread wrapper, provides synchronization against a ThreadPool */ class QThreadPoolThread : public QThread { public: QThreadPoolThread(QThreadPoolPrivate *manager); void run(); - void registerTheadInactive(); + void registerThreadInactive(); QThreadPoolPrivate *manager; QRunnable *runnable; @@ -103,7 +103,7 @@ void QThreadPoolThread::run() qWarning("Qt Concurrent has caught an exception thrown from a worker thread.\n" "This is not supported, exceptions thrown in worker threads must be\n" "caught before control returns to Qt Concurrent."); - registerTheadInactive(); + registerThreadInactive(); throw; } #endif @@ -121,7 +121,7 @@ void QThreadPoolThread::run() } while (r != 0); if (manager->isExiting) { - registerTheadInactive(); + registerThreadInactive(); break; } @@ -129,7 +129,7 @@ void QThreadPoolThread::run() bool expired = manager->tooManyThreadsActive(); if (!expired) { ++manager->waitingThreads; - registerTheadInactive(); + registerThreadInactive(); // wait for work, exiting after the expiry timeout is reached expired = !manager->runnableReady.wait(locker.mutex(), manager->expiryTimeout); ++manager->activeThreads; @@ -139,13 +139,13 @@ void QThreadPoolThread::run() } if (expired) { manager->expiredThreads.enqueue(this); - registerTheadInactive(); + registerThreadInactive(); break; } } } -void QThreadPoolThread::registerTheadInactive() +void QThreadPoolThread::registerThreadInactive() { if (--manager->activeThreads == 0) manager->noActiveThreads.wakeAll(); @@ -223,8 +223,6 @@ void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority) int QThreadPoolPrivate::activeThreadCount() const { - // To improve scalability this function is called without holding - // the mutex lock -- keep it thread-safe. return (allThreads.count() - expiredThreads.count() - waitingThreads @@ -262,7 +260,7 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable) /*! \internal - Makes all threads exit, waits for each tread to exit and deletes it. + Makes all threads exit, waits for each thread to exit and deletes it. */ void QThreadPoolPrivate::reset() { @@ -322,8 +320,8 @@ void QThreadPoolPrivate::clear() /*! \internal - Seaches for \a runnable in the queue, removes it from the queue and - runs it if found. This functon does not return until the runnable + Searches for \a runnable in the queue, removes it from the queue and + runs it if found. This function does not return until the runnable has completed. */ void QThreadPoolPrivate::stealRunnable(QRunnable *runnable) @@ -485,12 +483,11 @@ bool QThreadPool::tryStart(QRunnable *runnable) Q_D(QThreadPool); - // To improve scalability perform a check on the thread count - // before locking the mutex. + QMutexLocker locker(&d->mutex); + if (d->allThreads.isEmpty() == false && d->activeThreadCount() >= d->maxThreadCount) return false; - QMutexLocker locker(&d->mutex); return d->tryStart(runnable); } @@ -564,6 +561,7 @@ void QThreadPool::setMaxThreadCount(int maxThreadCount) int QThreadPool::activeThreadCount() const { Q_D(const QThreadPool); + QMutexLocker locker(&d->mutex); return d->activeThreadCount(); } diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 7b99aa1e06..b47511c39c 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2716,7 +2716,10 @@ QString QDateTime::toString(const QString& format) const QDateTime QDateTime::addDays(qint64 ndays) const { - return QDateTime(d->date.addDays(ndays), d->time, timeSpec()); + QDateTime dt(*this); + dt.detach(); + dt.d->date = d->date.addDays(ndays); + return dt; } /*! @@ -2729,7 +2732,10 @@ QDateTime QDateTime::addDays(qint64 ndays) const QDateTime QDateTime::addMonths(int nmonths) const { - return QDateTime(d->date.addMonths(nmonths), d->time, timeSpec()); + QDateTime dt(*this); + dt.detach(); + dt.d->date = d->date.addMonths(nmonths); + return dt; } /*! @@ -2742,7 +2748,10 @@ QDateTime QDateTime::addMonths(int nmonths) const QDateTime QDateTime::addYears(int nyears) const { - return QDateTime(d->date.addYears(nyears), d->time, timeSpec()); + QDateTime dt(*this); + dt.detach(); + dt.d->date = d->date.addYears(nyears); + return dt; } QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 25029afe1f..ce9ab33903 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -513,15 +513,10 @@ private: bool isValidIterator(const iterator &it) const { #if defined(QT_DEBUG) && !defined(Q_HASH_NO_ITERATOR_DEBUG) - union { - QHashData *iteratorHashData; - QHashData::Node *node; - }; - node = it.i; + QHashData::Node *node = it.i; while (node->next) node = node->next; - - return (iteratorHashData == d); + return (static_cast<void *>(node) == d); #else Q_UNUSED(it); return true; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 85b01d74a0..61b23b71a7 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1535,9 +1535,11 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even #endif } else if (event->type == atom(QXcbAtom::_XEMBED)) { handleXEmbedMessage(event); - } else if (event->type == atom(QXcbAtom::MANAGER) || event->type == atom(QXcbAtom::_NET_ACTIVE_WINDOW)) { - // Ignore _NET_ACTIVE_WINDOW which is received when the user clicks on a system tray icon and - // MANAGER which indicates the creation of a system tray. + } else if (event->type == atom(QXcbAtom::MANAGER) || event->type == atom(QXcbAtom::_NET_ACTIVE_WINDOW) + || event->type == atom(QXcbAtom::_NET_WM_STATE) || event->type == atom(QXcbAtom::MANAGER) + || event->type == atom(QXcbAtom::WM_CHANGE_STATE)) { + // Ignore _NET_ACTIVE_WINDOW, _NET_WM_STATE, MANAGER which are relate to tray icons + // and other messages. } else { qWarning() << "QXcbWindow: Unhandled client message:" << connection()->atomName(event->type); } diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index bdd06da7fc..90310308c3 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -407,7 +407,7 @@ void QComboBoxPrivateContainer::leaveEvent(QEvent *) } QComboBoxPrivateContainer::QComboBoxPrivateContainer(QAbstractItemView *itemView, QComboBox *parent) - : QFrame(parent, Qt::Popup), combo(parent), view(0), top(0), bottom(0) + : QFrame(parent, Qt::Popup), combo(parent), view(0), top(0), bottom(0), maybeIgnoreMouseButtonRelease(false) { // we need the combobox and itemview Q_ASSERT(parent); @@ -667,10 +667,15 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e) } } break; + case QEvent::MouseButtonPress: + maybeIgnoreMouseButtonRelease = false; + break; case QEvent::MouseButtonRelease: { + bool ignoreEvent = maybeIgnoreMouseButtonRelease && popupTimer.elapsed() < QApplication::doubleClickInterval(); + QMouseEvent *m = static_cast<QMouseEvent *>(e); if (isVisible() && view->rect().contains(m->pos()) && view->currentIndex().isValid() - && !blockMouseReleaseTimer.isActive() + && !blockMouseReleaseTimer.isActive() && !ignoreEvent && (view->currentIndex().flags() & Qt::ItemIsEnabled) && (view->currentIndex().flags() & Qt::ItemIsSelectable)) { combo->hidePopup(); @@ -2562,6 +2567,7 @@ void QComboBox::showPopup() container->setUpdatesEnabled(false); #endif + bool startTimer = !container->isVisible(); container->raise(); container->show(); container->updateScrollers(); @@ -2581,6 +2587,10 @@ void QComboBox::showPopup() if (QApplication::keypadNavigationEnabled()) view()->setEditFocus(true); #endif + if (startTimer) { + container->popupTimer.start(); + container->maybeIgnoreMouseButtonRelease = true; + } } /*! @@ -2876,6 +2886,11 @@ void QComboBox::mousePressEvent(QMouseEvent *e) } #endif showPopup(); + // The code below ensures that regular mousepress and pick item still works + // If it was not called the viewContainer would ignore event since it didn't have + // a mousePressEvent first. + if (d->viewContainer()) + d->viewContainer()->maybeIgnoreMouseButtonRelease = false; } else { #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled() && sc == QStyle::SC_ComboBoxEditField && d->lineEdit) { diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index 07ba9b0925..1ad2aa455a 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -254,6 +254,10 @@ private: QAbstractItemView *view; QComboBoxPrivateScroller *top; QComboBoxPrivateScroller *bottom; + bool maybeIgnoreMouseButtonRelease; + QElapsedTimer popupTimer; + + friend class QComboBox; }; class QComboMenuDelegate : public QAbstractItemDelegate diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 2817e6d22c..81ee8f0be6 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -148,6 +148,8 @@ private slots: void stripTrailingSlash(); void hosts_data(); void hosts(); + void hostFlags_data(); + void hostFlags(); void setPort(); void toEncoded_data(); void toEncoded(); @@ -314,6 +316,8 @@ void tst_QUrl::comparison() QVERIFY(url3bisNoSlash.matches(url4bis, QUrl::NormalizePathSegments | QUrl::StripTrailingSlash)); QUrl url4EncodedDots = QUrl("example://a/.//b/%2E%2E%2F/b/c/"); + QCOMPARE(url4EncodedDots.path(QUrl::PrettyDecoded), QString("/.//b/..%2F/b/c/")); + QCOMPARE(url4EncodedDots.path(QUrl::FullyDecoded), QString("/.//b/..//b/c/")); QCOMPARE(QString::fromLatin1(url4EncodedDots.toEncoded()), QString::fromLatin1("example://a/.//b/..%2F/b/c/")); QCOMPARE(url4EncodedDots.toString(), QString("example://a/.//b/..%2F/b/c/")); QCOMPARE(url4EncodedDots.adjusted(QUrl::NormalizePathSegments).toString(), QString("example://a/b/..%2F/b/c/")); @@ -495,18 +499,20 @@ void tst_QUrl::setUrl() } { - QUrl url("http://user:pass@[56::56:56:56:127.0.0.1]:99"); + QUrl url("http://user%3A:pass%40@[56::56:56:56:127.0.0.1]:99"); QVERIFY(url.isValid()); QCOMPARE(url.scheme(), QString::fromLatin1("http")); QCOMPARE(url.path(), QString()); QVERIFY(url.encodedQuery().isEmpty()); - QCOMPARE(url.userInfo(), QString::fromLatin1("user:pass")); + QCOMPARE(url.userName(), QString::fromLatin1("user:")); + QCOMPARE(url.password(), QString::fromLatin1("pass@")); + QCOMPARE(url.userInfo(), QString::fromLatin1("user%3A:pass@")); QVERIFY(url.fragment().isEmpty()); QCOMPARE(url.host(), QString::fromLatin1("56::56:56:56:7f00:1")); - QCOMPARE(url.authority(), QString::fromLatin1("user:pass@[56::56:56:56:7f00:1]:99")); + QCOMPARE(url.authority(), QString::fromLatin1("user%3A:pass%40@[56::56:56:56:7f00:1]:99")); QCOMPARE(url.port(), 99); - QCOMPARE(url.url(), QString::fromLatin1("http://user:pass@[56::56:56:56:7f00:1]:99")); - QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://user@[56::56:56:56:7f00:1]:99")); + QCOMPARE(url.url(), QString::fromLatin1("http://user%3A:pass%40@[56::56:56:56:7f00:1]:99")); + QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://user%3A@[56::56:56:56:7f00:1]:99")); } { @@ -684,8 +690,8 @@ void tst_QUrl::setUrl() QUrl charles; charles.setPath("/home/charles/foo%20moo"); - QCOMPARE(charles.path(), QString::fromLatin1("/home/charles/foo moo")); - QCOMPARE(charles.path(QUrl::FullyEncoded), QString::fromLatin1("/home/charles/foo%20moo")); + QCOMPARE(charles.path(), QString::fromLatin1("/home/charles/foo%20moo")); + QCOMPARE(charles.path(QUrl::FullyEncoded), QString::fromLatin1("/home/charles/foo%2520moo")); QUrl charles2("file:/home/charles/foo%20moo"); QCOMPARE(charles2.path(), QString::fromLatin1("/home/charles/foo moo")); @@ -758,7 +764,7 @@ void tst_QUrl::setUrl() QVERIFY(url.isValid()); QCOMPARE(url.scheme(), QString("data")); QCOMPARE(url.host(), QString()); - QCOMPARE(url.path(), QString("text/javascript,d5 %3D 'five\\u0027s'%3B")); + QCOMPARE(url.path(), QString("text/javascript,d5 = 'five\\u0027s';")); QCOMPARE(url.encodedPath().constData(), "text/javascript,d5%20%3D%20'five%5Cu0027s'%3B"); } @@ -1212,11 +1218,11 @@ void tst_QUrl::fromLocalFile_data() QTest::newRow("data7") << QString::fromLatin1("/Mambo <#5>.mp3") << QString::fromLatin1("file:///Mambo <%235>.mp3") << QString::fromLatin1("/Mambo <#5>.mp3"); QTest::newRow("data8") << QString::fromLatin1("/a%.txt") << QString::fromLatin1("file:///a%25.txt") - << QString::fromLatin1("/a%25.txt"); + << QString::fromLatin1("/a%.txt"); QTest::newRow("data9") << QString::fromLatin1("/a%25.txt") << QString::fromLatin1("file:///a%2525.txt") - << QString::fromLatin1("/a%2525.txt"); + << QString::fromLatin1("/a%25.txt"); QTest::newRow("data10") << QString::fromLatin1("/%80.txt") << QString::fromLatin1("file:///%2580.txt") - << QString::fromLatin1("/%2580.txt"); + << QString::fromLatin1("/%80.txt"); } void tst_QUrl::fromLocalFile() @@ -2528,8 +2534,9 @@ void tst_QUrl::setEncodedFragment() void tst_QUrl::fromEncoded() { QUrl qurl2 = QUrl::fromEncoded("print:/specials/Print%20To%20File%20(PDF%252FAcrobat)", QUrl::TolerantMode); - QCOMPARE(qurl2.path(), QString::fromLatin1("/specials/Print To File (PDF%252FAcrobat)")); - QCOMPARE(QFileInfo(qurl2.path()).fileName(), QString::fromLatin1("Print To File (PDF%252FAcrobat)")); + QCOMPARE(qurl2.path(), QString::fromLatin1("/specials/Print To File (PDF%2FAcrobat)")); + QCOMPARE(QFileInfo(qurl2.path()).fileName(), QString::fromLatin1("Print To File (PDF%2FAcrobat)")); + QCOMPARE(qurl2.fileName(), QString::fromLatin1("Print To File (PDF%2FAcrobat)")); QCOMPARE(qurl2.toEncoded().constData(), "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)"); QUrl qurl = QUrl::fromEncoded("http://\303\244.de"); @@ -2637,6 +2644,29 @@ void tst_QUrl::hosts() QTEST(QUrl(url).host(), "host"); } +void tst_QUrl::hostFlags_data() +{ + QTest::addColumn<QString>("urlStr"); + QTest::addColumn<QUrl::FormattingOptions>("options"); + QTest::addColumn<QString>("expectedHost"); + + QString swedish = QString::fromUtf8("http://www.räksmörgås.se/pub?a=b&a=dø&a=f#vræl"); + QTest::newRow("se_fullydecoded") << swedish << QUrl::FormattingOptions(QUrl::FullyDecoded) << QString::fromUtf8("www.räksmörgås.se"); + QTest::newRow("se_fullyencoded") << swedish << QUrl::FormattingOptions(QUrl::FullyEncoded) << QString::fromUtf8("www.xn--rksmrgs-5wao1o.se"); + QTest::newRow("se_prettydecoded") << swedish << QUrl::FormattingOptions(QUrl::PrettyDecoded) << QString::fromUtf8("www.räksmörgås.se"); + QTest::newRow("se_encodespaces") << swedish << QUrl::FormattingOptions(QUrl::EncodeSpaces) << QString::fromUtf8("www.räksmörgås.se"); +} + +void tst_QUrl::hostFlags() +{ + QFETCH(QString, urlStr); + QFETCH(QUrl::FormattingOptions, options); + QFETCH(QString, expectedHost); + + QUrl url(urlStr); + QCOMPARE(url.host(options), expectedHost); +} + void tst_QUrl::setPort() { { diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index eb9ad81101..ea547ffae5 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -6040,11 +6040,13 @@ void tst_QNetworkReply::sslSessionSharingFromPersistentSession() QByteArray sslSession = warmupReply->sslConfiguration().session(); QCOMPARE(!sslSession.isEmpty(), sessionPersistenceEnabled); - // test server sends a life time hint of 0, which is not common - // practice; however it is good enough because the default is -1 - int expectedSessionTicketLifeTimeHint = sessionPersistenceEnabled ? 0 : -1; - QCOMPARE(warmupReply->sslConfiguration().sessionTicketLifeTimeHint(), - expectedSessionTicketLifeTimeHint); + // test server sends a life time hint of 0 (old server) or 300 (new server), + // without session ticket we get -1 + QList<int> expectedSessionTicketLifeTimeHint = sessionPersistenceEnabled + ? QList<int>() << 0 << 300 : QList<int>() << -1; + QVERIFY2(expectedSessionTicketLifeTimeHint.contains( + warmupReply->sslConfiguration().sessionTicketLifeTimeHint()), + "server did not send expected session life time hint"); warmupReply->deleteLater(); diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 494d4584b5..bf6d9abb18 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -808,6 +808,8 @@ void tst_QGraphicsProxyWidget::focusNextPrevChild() if (!hasScene) delete proxy; + if (!hasWidget) + delete widget; } void tst_QGraphicsProxyWidget::focusOutEvent_data() @@ -1393,6 +1395,9 @@ void tst_QGraphicsProxyWidget::sizePolicy() QCOMPARE(proxy.sizePolicy(), proxyPol); else QCOMPARE(proxy.sizePolicy(), widgetPol); + + if (!hasWidget) + delete widget; } } diff --git a/tests/benchmarks/corelib/thread/qthreadpool/qthreadpool.pro b/tests/benchmarks/corelib/thread/qthreadpool/qthreadpool.pro new file mode 100644 index 0000000000..47e16e8b4d --- /dev/null +++ b/tests/benchmarks/corelib/thread/qthreadpool/qthreadpool.pro @@ -0,0 +1,5 @@ +TEMPLATE = app +TARGET = tst_bench_qthreadpool + +SOURCES += tst_qthreadpool.cpp +QT = core testlib diff --git a/tests/benchmarks/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/benchmarks/corelib/thread/qthreadpool/tst_qthreadpool.cpp new file mode 100644 index 0000000000..8e32d194ef --- /dev/null +++ b/tests/benchmarks/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2013 David Faure <david.faure@kdab.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt 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 3.0 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 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qtest.h> +#include <QtCore> + +class tst_QThreadPool : public QObject +{ + Q_OBJECT + +public: + tst_QThreadPool(); + ~tst_QThreadPool(); + +private slots: + void startRunnables(); + void activeThreadCount(); +}; + +tst_QThreadPool::tst_QThreadPool() +{ +} + +tst_QThreadPool::~tst_QThreadPool() +{ +} + +class NoOpRunnable : public QRunnable +{ +public: + void run() Q_DECL_OVERRIDE { + } +}; + +void tst_QThreadPool::startRunnables() +{ + QThreadPool threadPool; + threadPool.setMaxThreadCount(10); + QBENCHMARK { + threadPool.start(new NoOpRunnable()); + } +} + +void tst_QThreadPool::activeThreadCount() +{ + QThreadPool threadPool; + threadPool.start(new NoOpRunnable()); + QBENCHMARK { + QVERIFY(threadPool.activeThreadCount() <= 10); + } +} + +QTEST_MAIN(tst_QThreadPool) +#include "tst_qthreadpool.moc" diff --git a/tests/benchmarks/corelib/thread/thread.pro b/tests/benchmarks/corelib/thread/thread.pro index 2affee5287..d7f65a911d 100644 --- a/tests/benchmarks/corelib/thread/thread.pro +++ b/tests/benchmarks/corelib/thread/thread.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs SUBDIRS = \ qmutex \ - qthreadstorage + qthreadstorage \ + qthreadpool \ diff --git a/tests/manual/widgets/itemviews/delegate/example.cpp b/tests/manual/widgets/itemviews/delegate/example.cpp index c65f49f266..dcebf437b1 100644 --- a/tests/manual/widgets/itemviews/delegate/example.cpp +++ b/tests/manual/widgets/itemviews/delegate/example.cpp @@ -45,6 +45,7 @@ #include <QStandardItemModel> #include <QItemDelegate> #include <QDebug> +#include <QComboBox> class ExampleEditor : public QLineEdit { @@ -56,13 +57,26 @@ public: class ExampleDelegate : public QItemDelegate { public: - ExampleDelegate():QItemDelegate() { m_editor = new ExampleEditor(0); } + ExampleDelegate() : QItemDelegate() + { + m_editor = new ExampleEditor(0); + m_combobox = new QComboBox(0); + m_combobox->addItem(QString::fromUtf8("item1")); + m_combobox->addItem(QString::fromUtf8("item2")); + } protected: - QWidget* createEditor(QWidget *p, const QStyleOptionViewItem &o, const QModelIndex &) const + QWidget* createEditor(QWidget *p, const QStyleOptionViewItem &o, const QModelIndex &i) const { - m_editor->setParent(p); - m_editor->setGeometry(o.rect); - return m_editor; + // doubleclick rownumber 3 (last row) to see the difference. + if (i.row() == 3) { + m_combobox->setParent(p); + m_combobox->setGeometry(o.rect); + return m_combobox; + } else { + m_editor->setParent(p); + m_editor->setGeometry(o.rect); + return m_editor; + } } void destroyEditor(QWidget *editor, const QModelIndex &) const { @@ -71,10 +85,25 @@ protected: } // Avoid setting data - and therefore show that the editor keeps its state. - void setEditorData(QWidget*, const QModelIndex &) const { } + void setEditorData(QWidget* w, const QModelIndex &) const + { + QComboBox *combobox = qobject_cast<QComboBox*>(w); + if (combobox) { + qDebug() << "Try to show popup at once"; + // Now we could try to make a call to + // QCoreApplication::processEvents(); + // But it does not matter. The fix: + // https://codereview.qt-project.org/40608 + // is blocking QComboBox from reacting to this doubleclick edit event + // and we need to do that since the mouseReleaseEvent has not yet happened, + // and therefore cannot be processed. + combobox->showPopup(); + } + } ~ExampleDelegate() { delete m_editor; } mutable ExampleEditor *m_editor; + mutable QComboBox *m_combobox; }; int main(int argc, char *argv[]) |