summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-03-21 19:07:53 +0100
committerLiang Qi <liang.qi@qt.io>2017-03-21 19:07:53 +0100
commit65faf4565595d91996ddec4af25af5e97c7f0317 (patch)
treea7415e90db3fa1e46f638e1c31d2f2b9a5d0ec4a
parenta9383ef99a29c333a1edd32695ddc29ea0ba805d (diff)
parent26bc4ac5cb56ce8f2d3d10125fa9c6a72140573a (diff)
Merge remote-tracking branch 'origin/5.8' into 5.9
Conflicts: src/plugins/platforms/eglfs/eglfs-plugin.pro Change-Id: Id76cdbb41b7758572a3b8ea4dcb40d49bac968db
-rw-r--r--qmake/Makefile.win324
-rw-r--r--src/corelib/arch/qatomic_cxx11.h8
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp15
-rw-r--r--src/corelib/io/qlockfile.cpp3
-rw-r--r--src/corelib/io/qlockfile_unix.cpp2
-rw-r--r--src/corelib/io/qlockfile_win.cpp2
-rw-r--r--src/corelib/io/qstandardpaths_mac.mm5
-rw-r--r--src/corelib/io/qurl.cpp11
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp15
-rw-r--r--src/corelib/kernel/qmetatype.cpp6
-rw-r--r--src/corelib/tools/qchar.cpp4
-rw-r--r--src/corelib/tools/qchar.h26
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp154
-rw-r--r--src/gui/kernel/qwindow.cpp17
-rw-r--r--src/gui/kernel/qwindow_p.h2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp54
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h3
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp30
-rw-r--r--src/network/network.pro22
-rw-r--r--src/plugins/bearer/generic/generic.pro2
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp9
-rw-r--r--src/plugins/platforms/eglfs/eglfs-plugin.pro3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp20
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp13
-rw-r--r--src/printsupport/configure.json2
-rw-r--r--src/testlib/qtestsystem.h6
-rw-r--r--src/tools/qlalr/cppgenerator.cpp243
-rw-r--r--src/tools/qlalr/grammar.cpp128
-rw-r--r--src/tools/qlalr/grammar_p.h124
-rw-r--r--src/tools/qlalr/lalr.g14
-rw-r--r--src/tools/qlalr/recognizer.cpp10
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp1
-rw-r--r--src/widgets/widgets/qtoolbox.cpp10
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp47
-rw-r--r--tests/auto/corelib/animation/qpauseanimation/BLACKLIST2
-rw-r--r--tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp28
-rw-r--r--tests/auto/corelib/io/qurl/tst_qurl.cpp6
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp11
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp2
-rw-r--r--tests/auto/corelib/tools/qchar/tst_qchar.cpp61
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp53
-rw-r--r--tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp236
42 files changed, 900 insertions, 514 deletions
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 559870ff0e..7639d09ffd 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -21,8 +21,7 @@ CFLAGS_EXTRA = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-v
!else
CXX = cl
LINKER = link
-CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS \
- /wd4577 $(CFLAGS_CRT)
+CFLAGS_EXTRA = /MP /wd4577 $(CFLAGS_CRT)
!endif # !win32-icc
!if "$(QMAKESPEC)" != "win32-clang-msvc"
@@ -37,6 +36,7 @@ CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \
-I$(INC_PATH) -I$(INC_PATH)\QtCore -I$(INC_PATH)\QtCore\$(QT_VERSION) -I$(INC_PATH)\QtCore\$(QT_VERSION)\QtCore \
-I$(BUILD_PATH)\src\corelib\global \
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \
+ -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS \
-DQT_VERSION_STR=\"$(QT_VERSION)\" -DQT_VERSION_MAJOR=$(QT_MAJOR_VERSION) -DQT_VERSION_MINOR=$(QT_MINOR_VERSION) -DQT_VERSION_PATCH=$(QT_PATCH_VERSION) \
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \
-DQT_NO_FOREACH -DUNICODE
diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h
index 63b23b71ab..484ec73e7f 100644
--- a/src/corelib/arch/qatomic_cxx11.h
+++ b/src/corelib/arch/qatomic_cxx11.h
@@ -278,7 +278,7 @@ template <typename X> struct QAtomicOps
template <typename T>
static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
{
- bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed, std::memory_order_relaxed);
if (currentValue)
*currentValue = expectedValue;
return tmp;
@@ -287,7 +287,7 @@ template <typename X> struct QAtomicOps
template <typename T>
static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
{
- bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire, std::memory_order_acquire);
if (currentValue)
*currentValue = expectedValue;
return tmp;
@@ -296,7 +296,7 @@ template <typename X> struct QAtomicOps
template <typename T>
static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
{
- bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release, std::memory_order_relaxed);
if (currentValue)
*currentValue = expectedValue;
return tmp;
@@ -305,7 +305,7 @@ template <typename X> struct QAtomicOps
template <typename T>
static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
{
- bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel, std::memory_order_acquire);
if (currentValue)
*currentValue = expectedValue;
return tmp;
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index ca5af924e9..e152b035e2 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -688,6 +688,19 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const
uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags)
{
+#if (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && Q_PROCESSOR_WORDSIZE == 4
+ // The Linux mmap2 system call on 32-bit takes a page-shifted 32-bit
+ // integer so the maximum offset is 1 << (32+12) (the shift is always 12,
+ // regardless of the actual page size). Unfortunately, the mmap64()
+ // function is known to be broken in all Linux libcs (glibc, uclibc, musl
+ // and Bionic): all of them do the right shift, but don't confirm that the
+ // result fits into the 32-bit parameter to the kernel.
+
+ static qint64 MaxFileOffset = (Q_INT64_C(1) << (32+12)) - 1;
+#else
+ static qint64 MaxFileOffset = std::numeric_limits<QT_OFF_T>::max();
+#endif
+
Q_Q(QFSFileEngine);
Q_UNUSED(flags);
if (openMode == QIODevice::NotOpen) {
@@ -695,7 +708,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
return 0;
}
- if (offset < 0 || offset != qint64(QT_OFF_T(offset))
+ if (offset < 0 || offset > MaxFileOffset
|| size < 0 || quint64(size) > quint64(size_t(-1))) {
q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
return 0;
diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp
index cb1ff93ad3..48317d07e0 100644
--- a/src/corelib/io/qlockfile.cpp
+++ b/src/corelib/io/qlockfile.cpp
@@ -44,6 +44,7 @@
#include <QtCore/qthread.h>
#include <QtCore/qdeadlinetimer.h>
#include <QtCore/qdatetime.h>
+#include <QtCore/qfileinfo.h>
QT_BEGIN_NAMESPACE
@@ -226,6 +227,8 @@ bool QLockFile::tryLock(int timeout)
return false;
case LockFailedError:
if (!d->isLocked && d->isApparentlyStale()) {
+ if (Q_UNLIKELY(QFileInfo(d->fileName).lastModified() > QDateTime::currentDateTime()))
+ qInfo("QLockFile: Lock file '%ls' has a modification time in the future", qUtf16Printable(d->fileName));
// Stale lock from another thread/process
// Ensure two processes don't remove it at the same time
QLockFile rmlock(d->fileName + QLatin1String(".rmlock"));
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index 3a80014c00..5a02741727 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -247,7 +247,7 @@ bool QLockFilePrivate::isApparentlyStale() const
}
}
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
- return staleLockTime > 0 && age > staleLockTime;
+ return staleLockTime > 0 && qAbs(age) > staleLockTime;
}
QString QLockFilePrivate::processNameByPid(qint64 pid)
diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp
index baaff8da17..4b43181686 100644
--- a/src/corelib/io/qlockfile_win.cpp
+++ b/src/corelib/io/qlockfile_win.cpp
@@ -160,7 +160,7 @@ bool QLockFilePrivate::isApparentlyStale() const
Q_UNUSED(appname);
#endif // Q_OS_WINRT
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
- return staleLockTime > 0 && age > staleLockTime;
+ return staleLockTime > 0 && qAbs(age) > staleLockTime;
}
QString QLockFilePrivate::processNameByPid(qint64 pid)
diff --git a/src/corelib/io/qstandardpaths_mac.mm b/src/corelib/io/qstandardpaths_mac.mm
index a293d4862f..e25339a7d1 100644
--- a/src/corelib/io/qstandardpaths_mac.mm
+++ b/src/corelib/io/qstandardpaths_mac.mm
@@ -204,13 +204,14 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
CFBundleRef mainBundle = CFBundleGetMainBundle();
if (mainBundle) {
CFURLRef bundleUrl = CFBundleCopyBundleURL(mainBundle);
- CFStringRef cfBundlePath = CFURLCopyPath(bundleUrl);
+ CFStringRef cfBundlePath = CFURLCopyFileSystemPath(bundleUrl, kCFURLPOSIXPathStyle);
QString bundlePath = QString::fromCFString(cfBundlePath);
CFRelease(cfBundlePath);
CFRelease(bundleUrl);
CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(mainBundle);
- CFStringRef cfResourcesPath = CFURLCopyPath(resourcesUrl);
+ CFStringRef cfResourcesPath = CFURLCopyFileSystemPath(resourcesUrl,
+ kCFURLPOSIXPathStyle);
QString resourcesPath = QString::fromCFString(cfResourcesPath);
CFRelease(cfResourcesPath);
CFRelease(resourcesUrl);
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 18ad59f1cb..b5772b5ce2 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -4169,12 +4169,15 @@ QUrl QUrl::fromUserInput(const QString &userInput, const QString &workingDirecto
return url;
}
+ const QFileInfo fileInfo(QDir(workingDirectory), userInput);
+ if (fileInfo.exists()) {
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ }
+
QUrl url = QUrl(userInput, QUrl::TolerantMode);
// Check both QUrl::isRelative (to detect full URLs) and QDir::isAbsolutePath (since on Windows drive letters can be interpreted as schemes)
- if (url.isRelative() && !QDir::isAbsolutePath(userInput)) {
- QFileInfo fileInfo(QDir(workingDirectory), userInput);
- if ((options & AssumeLocalFile) || fileInfo.exists())
- return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ if ((options & AssumeLocalFile) && url.isRelative() && !QDir::isAbsolutePath(userInput)) {
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
}
return fromUserInput(trimmedString);
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 79146dac34..74fa2d8d50 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -407,7 +407,9 @@ void QEventDispatcherWin32Private::unregisterTimer(WinTimerInfo *t)
} else if (internalHwnd) {
KillTimer(internalHwnd, t->timerId);
}
- delete t;
+ t->timerId = -1;
+ if (!t->inTimerEvent)
+ delete t;
}
void QEventDispatcherWin32Private::sendTimerEvent(int timerId)
@@ -424,8 +426,9 @@ void QEventDispatcherWin32Private::sendTimerEvent(int timerId)
QCoreApplication::sendEvent(t->obj, &e);
// timer could have been removed
- t = timerDict.value(timerId);
- if (t) {
+ if (t->timerId == -1) {
+ delete t;
+ } else {
t->inTimerEvent = false;
}
}
@@ -1013,8 +1016,10 @@ bool QEventDispatcherWin32::event(QEvent *e)
QTimerEvent te(zte->timerId());
QCoreApplication::sendEvent(t->obj, &te);
- t = d->timerDict.value(zte->timerId());
- if (t) {
+ // timer could have been removed
+ if (t->timerId == -1) {
+ delete t;
+ } else {
if (t->interval == 0 && t->inTimerEvent) {
// post the next zero timer event as long as the timer was not restarted
QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId()));
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 38e0d6055c..fc8d7dcfea 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -1341,7 +1341,6 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
case QMetaType::UnknownType:
case QMetaType::Void:
case QMetaType::VoidStar:
- case QMetaType::Nullptr:
case QMetaType::QObjectStar:
case QMetaType::QModelIndex:
case QMetaType::QPersistentModelIndex:
@@ -1350,6 +1349,8 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
case QMetaType::QJsonArray:
case QMetaType::QJsonDocument:
return false;
+ case QMetaType::Nullptr:
+ return true;
case QMetaType::Long:
stream << qlonglong(*static_cast<const long *>(data));
break;
@@ -1563,7 +1564,6 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
case QMetaType::UnknownType:
case QMetaType::Void:
case QMetaType::VoidStar:
- case QMetaType::Nullptr:
case QMetaType::QObjectStar:
case QMetaType::QModelIndex:
case QMetaType::QPersistentModelIndex:
@@ -1572,6 +1572,8 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
case QMetaType::QJsonArray:
case QMetaType::QJsonDocument:
return false;
+ case QMetaType::Nullptr:
+ return true;
case QMetaType::Long: {
qlonglong l;
stream >> l;
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index 5d5ea4c8a1..1d3293e85e 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -624,9 +624,9 @@ QT_BEGIN_NAMESPACE
Constructs a QChar corresponding to ASCII/Latin-1 character \a ch.
\note This constructor is not available when \c QT_NO_CAST_FROM_ASCII
- is defined.
+ or QT_RESTRICTED_CAST_FROM_ASCII is defined.
- \sa QT_NO_CAST_FROM_ASCII
+ \sa QT_NO_CAST_FROM_ASCII, QT_RESTRICTED_CAST_FROM_ASCII
*/
/*!
diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h
index a83e5e6f98..81ef67d116 100644
--- a/src/corelib/tools/qchar.h
+++ b/src/corelib/tools/qchar.h
@@ -578,17 +578,21 @@ Q_DECL_CONSTEXPR inline bool operator>=(QChar c1, QChar c2) Q_DECL_NOTHROW { ret
Q_DECL_CONSTEXPR inline bool operator> (QChar c1, QChar c2) Q_DECL_NOTHROW { return operator< (c2, c1); }
Q_DECL_CONSTEXPR inline bool operator<=(QChar c1, QChar c2) Q_DECL_NOTHROW { return !operator< (c2, c1); }
-// disambiguate QChar == int (but only that, so constrain template to exactly 'int'):
-template <typename T>
-Q_DECL_DEPRECATED_X("don't compare ints to QChars, compare them to QChar::unicode() instead")
-Q_DECL_CONSTEXPR inline
-typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, int>::value, bool>::type
-operator==(QChar lhs, T rhs) Q_DECL_NOEXCEPT { return lhs == QChar(rhs); }
-template <typename T>
-Q_DECL_DEPRECATED_X("don't compare ints to QChars, compare them to QChar::unicode() instead")
-Q_DECL_CONSTEXPR inline
-typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, int>::value, bool>::type
-operator!=(QChar lhs, T rhs) Q_DECL_NOEXCEPT { return lhs != QChar(rhs); }
+
+Q_DECL_CONSTEXPR inline bool operator==(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return lhs.isNull(); }
+Q_DECL_CONSTEXPR inline bool operator< (QChar, std::nullptr_t) Q_DECL_NOTHROW { return false; }
+Q_DECL_CONSTEXPR inline bool operator==(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return rhs.isNull(); }
+Q_DECL_CONSTEXPR inline bool operator< (std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !rhs.isNull(); }
+
+Q_DECL_CONSTEXPR inline bool operator!=(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return !operator==(lhs, nullptr); }
+Q_DECL_CONSTEXPR inline bool operator>=(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return !operator< (lhs, nullptr); }
+Q_DECL_CONSTEXPR inline bool operator> (QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return operator< (nullptr, lhs); }
+Q_DECL_CONSTEXPR inline bool operator<=(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return !operator< (nullptr, lhs); }
+
+Q_DECL_CONSTEXPR inline bool operator!=(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !operator==(nullptr, rhs); }
+Q_DECL_CONSTEXPR inline bool operator>=(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !operator< (nullptr, rhs); }
+Q_DECL_CONSTEXPR inline bool operator> (std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return operator< (rhs, nullptr); }
+Q_DECL_CONSTEXPR inline bool operator<=(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !operator< (rhs, nullptr); }
#ifndef QT_NO_DATASTREAM
Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QChar);
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index c8aa4fbc89..62dd25e072 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -1243,6 +1243,49 @@ end:
#endif // QT_NO_DATESTRING
#ifndef QT_NO_TEXTDATE
+
+/*
+ \internal
+ \brief Returns the index in \a entries with the best prefix match to \a text
+
+ Scans \a entries looking for an entry overlapping \a text as much as possible
+ (an exact match beats any prefix match; a match of the full entry as prefix of
+ text beats any entry but one matching a longer prefix; otherwise, the match of
+ longest prefix wins, earlier entries beating later on a draw). Records the
+ length of overlap in *used (if \a used is non-NULL) and the first entry that
+ overlapped this much in *usedText (if \a usedText is non-NULL).
+ */
+static int findTextEntry(const QString &text, const QVector<QString> &entries, QString *usedText, int *used)
+{
+ if (text.isEmpty())
+ return -1;
+
+ int bestMatch = -1;
+ int bestCount = 0;
+ for (int n = 0; n < entries.size(); ++n)
+ {
+ const QString &name = entries.at(n);
+
+ const int limit = qMin(text.size(), name.size());
+ int i = 0;
+ while (i < limit && text.at(i) == name.at(i).toLower())
+ ++i;
+ // Full match beats an equal prefix match:
+ if (i > bestCount || (i == bestCount && i == name.size())) {
+ bestCount = i;
+ bestMatch = n;
+ if (i == name.size() && i == text.size())
+ break; // Exact match, name == text, wins.
+ }
+ }
+ if (usedText && bestMatch != -1)
+ *usedText = entries.at(bestMatch);
+ if (used)
+ *used = bestCount;
+
+ return bestMatch;
+}
+
/*!
\internal
finds the first possible monthname that \a str1 can
@@ -1252,99 +1295,40 @@ end:
int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex,
QString *usedMonth, int *used) const
{
- int bestMatch = -1;
- int bestCount = 0;
- if (!str1.isEmpty()) {
- const SectionNode &sn = sectionNode(sectionIndex);
- if (sn.type != MonthSection) {
- qWarning("QDateTimeParser::findMonth Internal error");
- return -1;
- }
-
- QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
- QLocale l = locale();
+ const SectionNode &sn = sectionNode(sectionIndex);
+ if (sn.type != MonthSection) {
+ qWarning("QDateTimeParser::findMonth Internal error");
+ return -1;
+ }
- for (int month=startMonth; month<=12; ++month) {
- const QString monthName = l.monthName(month, type);
- QString str2 = monthName.toLower();
+ QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat;
+ QLocale l = locale();
+ QVector<QString> monthNames;
+ monthNames.reserve(13 - startMonth);
+ for (int month = startMonth; month <= 12; ++month)
+ monthNames.append(l.monthName(month, type));
- if (str1.startsWith(str2)) {
- if (used) {
- QDTPDEBUG << "used is set to" << str2.size();
- *used = str2.size();
- }
- if (usedMonth)
- *usedMonth = monthName;
-
- return month;
- }
- if (context == FromString)
- continue;
-
- const int limit = qMin(str1.size(), str2.size());
-
- QDTPDEBUG << "limit is" << limit << str1 << str2;
- bool equal = true;
- for (int i=0; i<limit; ++i) {
- if (str1.at(i) != str2.at(i)) {
- equal = false;
- if (i > bestCount) {
- bestCount = i;
- bestMatch = month;
- }
- break;
- }
- }
- if (equal) {
- if (used)
- *used = limit;
- if (usedMonth)
- *usedMonth = monthName;
- return month;
- }
- }
- if (usedMonth && bestMatch != -1)
- *usedMonth = l.monthName(bestMatch, type);
- }
- if (used) {
- QDTPDEBUG << "used is set to" << bestCount;
- *used = bestCount;
- }
- return bestMatch;
+ const int index = findTextEntry(str1, monthNames, usedMonth, used);
+ return index < 0 ? index : index + startMonth;
}
int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const
{
- int bestMatch = -1;
- int bestCount = 0;
- if (!str1.isEmpty()) {
- const SectionNode &sn = sectionNode(sectionIndex);
- if (!(sn.type & DaySectionMask)) {
- qWarning("QDateTimeParser::findDay Internal error");
- return -1;
- }
- const QLocale l = locale();
- for (int day=startDay; day<=7; ++day) {
- const QString dayName = l.dayName(day, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
- const QString str2 = dayName.toLower();
-
- const int limit = qMin(str1.size(), str2.size());
- int i = 0;
- while (i < limit && str1.at(i) == str2.at(i))
- ++i;
- if (i > bestCount) {
- bestCount = i;
- bestMatch = day;
- }
- }
- if (usedDay && bestMatch != -1) {
- *usedDay = l.dayName(bestMatch, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat);
- }
+ const SectionNode &sn = sectionNode(sectionIndex);
+ if (!(sn.type & DaySectionMask)) {
+ qWarning("QDateTimeParser::findDay Internal error");
+ return -1;
}
- if (used)
- *used = bestCount;
- return bestMatch;
+ QLocale::FormatType type = sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat;
+ QLocale l = locale();
+ QVector<QString> daysOfWeek;
+ daysOfWeek.reserve(8 - startDay);
+ for (int day = startDay; day <= 7; ++day)
+ daysOfWeek.append(l.dayName(day, type));
+
+ const int index = findTextEntry(str1, daysOfWeek, usedDay, used);
+ return index < 0 ? index : index + startDay;
}
#endif // QT_NO_TEXTDATE
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index c94ea0922a..d44bfabc04 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -2697,26 +2697,29 @@ void QWindowPrivate::setCursor(const QCursor *newCursor)
cursor = QCursor(Qt::ArrowCursor);
hasCursor = false;
}
- // Only attempt to set cursor and emit signal if there is an actual platform cursor
- QScreen* screen = q->screen();
- if (screen && screen->handle()->cursor()) {
- applyCursor();
+ // Only attempt to emit signal if there is an actual platform cursor
+ if (applyCursor()) {
QEvent event(QEvent::CursorChange);
QGuiApplication::sendEvent(q, &event);
}
}
-void QWindowPrivate::applyCursor()
+// Apply the cursor and returns true iff the platform cursor exists
+bool QWindowPrivate::applyCursor()
{
Q_Q(QWindow);
- if (platformWindow) {
- if (QPlatformCursor *platformCursor = q->screen()->handle()->cursor()) {
+ if (QScreen *screen = q->screen()) {
+ if (QPlatformCursor *platformCursor = screen->handle()->cursor()) {
+ if (!platformWindow)
+ return true;
QCursor *c = QGuiApplication::overrideCursor();
if (!c && hasCursor)
c = &cursor;
platformCursor->changeCursor(c, q);
+ return true;
}
}
+ return false;
}
#endif // QT_NO_CURSOR
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 59016e4551..dd282a671d 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -118,7 +118,7 @@ public:
void maybeQuitOnLastWindowClosed();
#ifndef QT_NO_CURSOR
void setCursor(const QCursor *c = 0);
- void applyCursor();
+ bool applyCursor();
#endif
void deliverUpdateRequest();
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index c2458152a3..72feffda8c 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -82,27 +82,31 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host
: state(RunningState),
networkLayerState(Unknown),
hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true)
+ , activeChannelCount(type == QHttpNetworkConnection::ConnectionTypeHTTP2
#ifndef QT_NO_SSL
-, channelCount((type == QHttpNetworkConnection::ConnectionTypeSPDY || type == QHttpNetworkConnection::ConnectionTypeHTTP2)
- ? 1 : defaultHttpChannelCount)
-#else
-, channelCount(type == QHttpNetworkConnection::ConnectionTypeHTTP2 ? 1 : defaultHttpChannelCount)
-#endif // QT_NO_SSL
+ || type == QHttpNetworkConnection::ConnectionTypeSPDY
+#endif
+ ? 1 : defaultHttpChannelCount)
+ , channelCount(defaultHttpChannelCount)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
, preConnectRequests(0)
, connectionType(type)
{
+ // We allocate all 6 channels even if it's SPDY or HTTP/2 enabled
+ // connection: in case the protocol negotiation via NPN/ALPN fails,
+ // we will have normally working HTTP/1.1.
+ Q_ASSERT(channelCount >= activeChannelCount);
channels = new QHttpNetworkConnectionChannel[channelCount];
}
-QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 channelCount, const QString &hostName,
+QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(quint16 connectionCount, const QString &hostName,
quint16 port, bool encrypt,
QHttpNetworkConnection::ConnectionType type)
: state(RunningState), networkLayerState(Unknown),
hostName(hostName), port(port), encrypt(encrypt), delayIpv4(true),
- channelCount(channelCount)
+ activeChannelCount(connectionCount), channelCount(connectionCount)
#ifndef QT_NO_NETWORKPROXY
, networkProxy(QNetworkProxy::NoProxy)
#endif
@@ -147,7 +151,7 @@ void QHttpNetworkConnectionPrivate::pauseConnection()
state = PausedState;
// Disable all socket notifiers
- for (int i = 0; i < channelCount; i++) {
+ for (int i = 0; i < activeChannelCount; i++) {
if (channels[i].socket) {
#ifndef QT_NO_SSL
if (encrypt)
@@ -163,7 +167,7 @@ void QHttpNetworkConnectionPrivate::resumeConnection()
{
state = RunningState;
// Enable all socket notifiers
- for (int i = 0; i < channelCount; i++) {
+ for (int i = 0; i < activeChannelCount; i++) {
if (channels[i].socket) {
#ifndef QT_NO_SSL
if (encrypt)
@@ -184,7 +188,7 @@ void QHttpNetworkConnectionPrivate::resumeConnection()
int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const
{
- for (int i = 0; i < channelCount; ++i)
+ for (int i = 0; i < activeChannelCount; ++i)
if (channels[i].socket == socket)
return i;
@@ -210,7 +214,7 @@ bool QHttpNetworkConnectionPrivate::shouldEmitChannelError(QAbstractSocket *sock
channels[otherSocket].ensureConnection();
}
- if (channelCount == 1) {
+ if (activeChannelCount < channelCount) {
if (networkLayerState == HostLookupPending || networkLayerState == IPv4or6)
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
channels[0].close();
@@ -405,7 +409,7 @@ void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthentica
// select another channel
QAuthenticator* otherAuth = 0;
- for (int i = 0; i < channelCount; ++i) {
+ for (int i = 0; i < activeChannelCount; ++i) {
if (i == fromChannel)
continue;
if (isProxy)
@@ -900,7 +904,7 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply)
Q_Q(QHttpNetworkConnection);
// check if the reply is currently being processed or it is pipelined in
- for (int i = 0; i < channelCount; ++i) {
+ for (int i = 0; i < activeChannelCount; ++i) {
// is the reply associated the currently processing of this channel?
if (channels[i].reply == reply) {
channels[i].reply = 0;
@@ -1003,7 +1007,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
return;
//resend the necessary ones.
- for (int i = 0; i < channelCount; ++i) {
+ for (int i = 0; i < activeChannelCount; ++i) {
if (channels[i].resendCurrent && (channels[i].state != QHttpNetworkConnectionChannel::ClosingState)) {
channels[i].resendCurrent = false;
@@ -1023,7 +1027,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
return;
// try to get a free AND connected socket
- for (int i = 0; i < channelCount; ++i) {
+ for (int i = 0; i < activeChannelCount; ++i) {
if (channels[i].socket) {
if (!channels[i].reply && !channels[i].isSocketBusy() && channels[i].socket->state() == QAbstractSocket::ConnectedState) {
if (dequeueRequest(channels[i].socket))
@@ -1061,7 +1065,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
// return fast if there is nothing to pipeline
if (highPriorityQueue.isEmpty() && lowPriorityQueue.isEmpty())
return;
- for (int i = 0; i < channelCount; i++)
+ for (int i = 0; i < activeChannelCount; i++)
if (channels[i].socket && channels[i].socket->state() == QAbstractSocket::ConnectedState)
fillPipeline(channels[i].socket);
@@ -1077,7 +1081,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
int normalRequests = queuedRequests - preConnectRequests;
neededOpenChannels = qMax(normalRequests, preConnectRequests);
}
- for (int i = 0; i < channelCount && neededOpenChannels > 0; ++i) {
+ for (int i = 0; i < activeChannelCount && neededOpenChannels > 0; ++i) {
bool connectChannel = false;
if (channels[i].socket) {
if ((channels[i].socket->state() == QAbstractSocket::ConnectingState)
@@ -1107,7 +1111,7 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply)
{
- for (int i = 0 ; i < channelCount; ++i) {
+ for (int i = 0 ; i < activeChannelCount; ++i) {
if (channels[i].reply == reply) {
// emulate a readyRead() from the socket
QMetaObject::invokeMethod(&channels[i], "_q_readyRead", Qt::QueuedConnection);
@@ -1226,7 +1230,7 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info)
// connection will then be disconnected.
void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup()
{
- if (channelCount > 1) {
+ if (activeChannelCount > 1) {
// At this time all channels should be unconnected.
Q_ASSERT(!channels[0].isSocketBusy());
Q_ASSERT(!channels[1].isSocketBusy());
@@ -1264,7 +1268,7 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup()
void QHttpNetworkConnectionPrivate::networkLayerDetected(QAbstractSocket::NetworkLayerProtocol protocol)
{
- for (int i = 0 ; i < channelCount; ++i) {
+ for (int i = 0 ; i < activeChannelCount; ++i) {
if ((channels[i].networkLayerPreference != protocol) && (channels[i].state == QHttpNetworkConnectionChannel::ConnectingState)) {
channels[i].close();
}
@@ -1361,7 +1365,7 @@ void QHttpNetworkConnection::setCacheProxy(const QNetworkProxy &networkProxy)
d->networkProxy = networkProxy;
// update the authenticator
if (!d->networkProxy.user().isEmpty()) {
- for (int i = 0; i < d->channelCount; ++i) {
+ for (int i = 0; i < d->activeChannelCount; ++i) {
d->channels[i].proxyAuthenticator.setUser(d->networkProxy.user());
d->channels[i].proxyAuthenticator.setPassword(d->networkProxy.password());
}
@@ -1377,7 +1381,7 @@ QNetworkProxy QHttpNetworkConnection::cacheProxy() const
void QHttpNetworkConnection::setTransparentProxy(const QNetworkProxy &networkProxy)
{
Q_D(QHttpNetworkConnection);
- for (int i = 0; i < d->channelCount; ++i)
+ for (int i = 0; i < d->activeChannelCount; ++i)
d->channels[i].setProxy(networkProxy);
}
@@ -1409,7 +1413,7 @@ void QHttpNetworkConnection::setSslConfiguration(const QSslConfiguration &config
return;
// set the config on all channels
- for (int i = 0; i < d->channelCount; ++i)
+ for (int i = 0; i < d->activeChannelCount; ++i)
d->channels[i].setSslConfiguration(config);
}
@@ -1432,7 +1436,7 @@ void QHttpNetworkConnection::ignoreSslErrors(int channel)
return;
if (channel == -1) { // ignore for all channels
- for (int i = 0; i < d->channelCount; ++i) {
+ for (int i = 0; i < d->activeChannelCount; ++i) {
d->channels[i].ignoreSslErrors();
}
@@ -1448,7 +1452,7 @@ void QHttpNetworkConnection::ignoreSslErrors(const QList<QSslError> &errors, int
return;
if (channel == -1) { // ignore for all channels
- for (int i = 0; i < d->channelCount; ++i) {
+ for (int i = 0; i < d->activeChannelCount; ++i) {
d->channels[i].ignoreSslErrors(errors);
}
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 430c715717..3dd9bde9bd 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -243,6 +243,9 @@ public:
bool encrypt;
bool delayIpv4;
+ // Number of channels we are trying to use at the moment:
+ int activeChannelCount;
+ // The total number of channels we reserved:
const int channelCount;
QTimer delayedConnectionTimer;
QHttpNetworkConnectionChannel *channels; // parallel connections to the server
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 668409a988..c86cc9d8c9 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -1083,12 +1083,36 @@ void QHttpNetworkConnectionChannel::_q_encrypted()
}
}
Q_FALLTHROUGH();
- case QSslConfiguration::NextProtocolNegotiationNone:
+ case QSslConfiguration::NextProtocolNegotiationNone: {
protocolHandler.reset(new QHttpProtocolHandler(this));
+
+ QList<QByteArray> protocols = sslConfiguration.allowedNextProtocols();
+ const int nProtocols = protocols.size();
+ // Clear the protocol that we failed to negotiate, so we do not try
+ // it again on other channels that our connection can create/open.
+ if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2)
+ protocols.removeAll(QSslConfiguration::ALPNProtocolHTTP2);
+ else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY)
+ protocols.removeAll(QSslConfiguration::NextProtocolSpdy3_0);
+
+ if (nProtocols > protocols.size()) {
+ sslConfiguration.setAllowedNextProtocols(protocols);
+ const int channelCount = connection->d_func()->channelCount;
+ for (int i = 0; i < channelCount; ++i)
+ connection->d_func()->channels[i].setSslConfiguration(sslConfiguration);
+ }
+
connection->setConnectionType(QHttpNetworkConnection::ConnectionTypeHTTP);
- // re-queue requests from SPDY queue to HTTP queue, if any
- requeueSpdyRequests();
+ // We use only one channel for SPDY or HTTP/2, but normally six for
+ // HTTP/1.1 - let's restore this number to the reserved number of
+ // channels:
+ if (connection->d_func()->activeChannelCount < connection->d_func()->channelCount) {
+ connection->d_func()->activeChannelCount = connection->d_func()->channelCount;
+ // re-queue requests from SPDY queue to HTTP queue, if any
+ requeueSpdyRequests();
+ }
break;
+ }
default:
emitFinishedWithError(QNetworkReply::SslHandshakeFailedError,
"detected unknown Next Protocol Negotiation protocol");
diff --git a/src/network/network.pro b/src/network/network.pro
index 75105bd681..98fbf82275 100644
--- a/src/network/network.pro
+++ b/src/network/network.pro
@@ -22,16 +22,18 @@ include(ssl/ssl.pri)
QMAKE_LIBS += $$QMAKE_LIBS_NETWORK
-ANDROID_BUNDLED_JAR_DEPENDENCIES = \
- jar/QtAndroidBearer-bundled.jar
-ANDROID_JAR_DEPENDENCIES = \
- jar/QtAndroidBearer.jar
-ANDROID_LIB_DEPENDENCIES = \
- plugins/bearer/libqandroidbearer.so
-MODULE_PLUGIN_TYPES = \
- bearer
-ANDROID_PERMISSIONS += \
- android.permission.ACCESS_NETWORK_STATE
+qtConfig(bearermanagement) {
+ ANDROID_BUNDLED_JAR_DEPENDENCIES = \
+ jar/QtAndroidBearer-bundled.jar
+ ANDROID_JAR_DEPENDENCIES = \
+ jar/QtAndroidBearer.jar
+ ANDROID_LIB_DEPENDENCIES = \
+ plugins/bearer/libqandroidbearer.so
+ MODULE_PLUGIN_TYPES = \
+ bearer
+ ANDROID_PERMISSIONS += \
+ android.permission.ACCESS_NETWORK_STATE
+}
MODULE_WINRT_CAPABILITIES = \
internetClient \
diff --git a/src/plugins/bearer/generic/generic.pro b/src/plugins/bearer/generic/generic.pro
index 02b3e96bfa..f30bdc4951 100644
--- a/src/plugins/bearer/generic/generic.pro
+++ b/src/plugins/bearer/generic/generic.pro
@@ -12,7 +12,7 @@ SOURCES += qgenericengine.cpp \
OTHER_FILES += generic.json
-win32:!winrt:LIBS += -lIphlpapi
+win32:!winrt:LIBS += -liphlpapi
PLUGIN_TYPE = bearer
PLUGIN_CLASS_NAME = QGenericEnginePlugin
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index 3b1ce6d21d..eeaecd53b4 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -49,6 +49,7 @@
#include <QtCore/qmath.h>
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/private/qjni_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include "qdebug.h"
@@ -137,7 +138,7 @@ namespace QtAndroidAccessibility
QRect rect;
QAccessibleInterface *iface = interfaceFromId(objectId);
if (iface && iface->isValid()) {
- rect = iface->rect();
+ rect = QHighDpi::toNativePixels(iface->rect(), iface->window());
}
jclass rectClass = env->FindClass("android/graphics/Rect");
@@ -150,11 +151,13 @@ namespace QtAndroidAccessibility
{
QAccessibleInterface *root = interfaceFromId(-1);
if (root) {
- QAccessibleInterface *child = root->childAt((int)x, (int)y);
+ QPoint pos = QHighDpi::fromNativePixels(QPoint(int(x), int(y)), root->window());
+
+ QAccessibleInterface *child = root->childAt(pos.x(), pos.y());
QAccessibleInterface *lastChild = 0;
while (child && (child != lastChild)) {
lastChild = child;
- child = child->childAt((int)x, (int)y);
+ child = child->childAt(pos.x(), pos.y());
}
if (lastChild)
return QAccessible::uniqueId(lastChild);
diff --git a/src/plugins/platforms/eglfs/eglfs-plugin.pro b/src/plugins/platforms/eglfs/eglfs-plugin.pro
index 3844328ee0..ec229796e5 100644
--- a/src/plugins/platforms/eglfs/eglfs-plugin.pro
+++ b/src/plugins/platforms/eglfs/eglfs-plugin.pro
@@ -4,6 +4,9 @@ QT += eglfsdeviceintegration-private
CONFIG += egl
+# Avoid X11 header collision, use generic EGL native types
+DEFINES += QT_EGL_NO_X11
+
SOURCES += $$PWD/qeglfsmain.cpp
OTHER_FILES += $$PWD/eglfs.json
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 3f0493669f..f6fa903ec2 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -898,19 +898,17 @@ void QXcbWindow::hide()
}
}
-static QWindow *tlWindow(QWindow *window)
-{
- if (window && window->parent())
- return tlWindow(window->parent());
- return window;
-}
-
bool QXcbWindow::relayFocusToModalWindow() const
{
- QWindow *w = tlWindow(static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver());
- QWindow *modal_window = 0;
- if (QGuiApplicationPrivate::instance()->isWindowBlocked(w,&modal_window) && modal_window != w) {
- modal_window->requestActivate();
+ QWindow *w = static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver();
+ // get top-level window
+ while (w && w->parent())
+ w = w->parent();
+
+ QWindow *modalWindow = 0;
+ const bool blocked = QGuiApplicationPrivate::instance()->isWindowBlocked(w, &modalWindow);
+ if (blocked && modalWindow != w) {
+ modalWindow->requestActivate();
connection()->flush();
return true;
}
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index e0f9222902..19de9a8003 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -50,7 +50,7 @@
#include <qsqlquery.h>
#include <qsocketnotifier.h>
#include <qstringlist.h>
-#include <qmutex.h>
+#include <qlocale.h>
#include <QtSql/private/qsqlresult_p.h>
#include <QtSql/private/qsqldriver_p.h>
@@ -618,13 +618,10 @@ static QString qCreateParamString(const QVector<QVariant> &boundValues, const QS
return params;
}
-Q_GLOBAL_STATIC(QMutex, qMutex)
QString qMakePreparedStmtId()
{
- qMutex()->lock();
- static unsigned int qPreparedStmtCount = 0;
- QString id = QLatin1String("qpsqlpstmt_") + QString::number(++qPreparedStmtCount, 16);
- qMutex()->unlock();
+ static QBasicAtomicInt qPreparedStmtCount = Q_BASIC_ATOMIC_INITIALIZER(0);
+ QString id = QLatin1String("qpsqlpstmt_") + QString::number(qPreparedStmtCount.fetchAndAddRelaxed(1) + 1, 16);
return id;
}
@@ -1311,7 +1308,9 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
// we force the value to be considered with a timezone information, and we force it to be UTC
// this is safe since postgresql stores only the UTC value and not the timezone offset (only used
// while parsing), so we have correct behavior in both case of with timezone and without tz
- r = QLatin1String("TIMESTAMP WITH TIME ZONE ") + QLatin1Char('\'') + field.value().toDateTime().toUTC().toString(QLatin1String("yyyy-MM-ddThh:mm:ss.zzz")) + QLatin1Char('Z') + QLatin1Char('\'');
+ r = QLatin1String("TIMESTAMP WITH TIME ZONE ") + QLatin1Char('\'') +
+ QLocale::c().toString(field.value().toDateTime().toUTC(), QLatin1String("yyyy-MM-ddThh:mm:ss.zzz")) +
+ QLatin1Char('Z') + QLatin1Char('\'');
} else {
r = QLatin1String("NULL");
}
diff --git a/src/printsupport/configure.json b/src/printsupport/configure.json
index 93d345840f..cd775644c9 100644
--- a/src/printsupport/configure.json
+++ b/src/printsupport/configure.json
@@ -48,7 +48,7 @@
"label": "QPrinter",
"purpose": "Provides a printer backend of QPainter.",
"section": "Painting",
- "condition": "!config.android && !config.uikit && !config.winrt && features.picture && features.temporaryfile && features.pdf",
+ "condition": "!config.uikit && !config.winrt && features.picture && features.temporaryfile && features.pdf",
"output": [ "publicFeature", "feature" ]
},
"printpreviewwidget": {
diff --git a/src/testlib/qtestsystem.h b/src/testlib/qtestsystem.h
index 4c611aab6b..f38a156936 100644
--- a/src/testlib/qtestsystem.h
+++ b/src/testlib/qtestsystem.h
@@ -114,14 +114,14 @@ namespace QTest
#endif
#ifdef QT_WIDGETS_LIB
- inline static bool qWaitForWindowActive(QWidget *widget, int timeout = 1000)
+ inline static bool qWaitForWindowActive(QWidget *widget, int timeout = 5000)
{
if (QWindow *window = widget->window()->windowHandle())
return qWaitForWindowActive(window, timeout);
return false;
}
- inline static bool qWaitForWindowExposed(QWidget *widget, int timeout = 1000)
+ inline static bool qWaitForWindowExposed(QWidget *widget, int timeout = 5000)
{
if (QWindow *window = widget->window()->windowHandle())
return qWaitForWindowExposed(window, timeout);
@@ -131,7 +131,7 @@ namespace QTest
#if QT_DEPRECATED_SINCE(5, 0)
# ifdef QT_WIDGETS_LIB
- QT_DEPRECATED inline static bool qWaitForWindowShown(QWidget *widget, int timeout = 1000)
+ QT_DEPRECATED inline static bool qWaitForWindowShown(QWidget *widget, int timeout = 5000)
{
return qWaitForWindowExposed(widget, timeout);
}
diff --git a/src/tools/qlalr/cppgenerator.cpp b/src/tools/qlalr/cppgenerator.cpp
index efceb8c520..ed0f53d43e 100644
--- a/src/tools/qlalr/cppgenerator.cpp
+++ b/src/tools/qlalr/cppgenerator.cpp
@@ -36,6 +36,29 @@
#include <QtCore/qfile.h>
#include <QtCore/qmap.h>
+namespace {
+
+void generateSeparator(int i, QTextStream &out)
+{
+ if (!(i % 10)) {
+ if (i)
+ out << ",";
+ out << endl << " ";
+ } else {
+ out << ", ";
+ }
+}
+
+void generateList(const QVector<int> &list, QTextStream &out)
+{
+ for (int i = 0; i < list.size(); ++i) {
+ generateSeparator(i, out);
+
+ out << list[i];
+ }
+}
+
+}
QString CppGenerator::copyrightHeader() const
{
@@ -47,7 +70,7 @@ QString CppGenerator::copyrightHeader() const
"**\n"
"** This file is part of the Qt Toolkit.\n"
"**\n"
- "** $QT_BEGIN_LICENSE:LGPL$\n"
+ "** $QT_BEGIN_LICENSE:GPL-EXCEPT$\n"
"** Commercial License Usage\n"
"** Licensees holding valid commercial Qt licenses may use this file in\n"
"** accordance with the commercial license agreement provided with the\n"
@@ -56,24 +79,13 @@ QString CppGenerator::copyrightHeader() const
"** and conditions see https://www.qt.io/terms-conditions. For further\n"
"** information use the contact form at https://www.qt.io/contact-us.\n"
"**\n"
- "** GNU Lesser General Public License Usage\n"
- "** Alternatively, this file may be used under the terms of the GNU Lesser\n"
- "** General Public License version 3 as published by the Free Software\n"
- "** Foundation and appearing in the file LICENSE.LGPL3 included in the\n"
- "** packaging of this file. Please review the following information to\n"
- "** ensure the GNU Lesser General Public License version 3 requirements\n"
- "** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.\n"
- "**\n"
"** GNU General Public License Usage\n"
"** Alternatively, this file may be used under the terms of the GNU\n"
- "** General Public License version 2.0 or (at your option) the GNU General\n"
- "** Public license version 3 or any later version approved by the KDE Free\n"
- "** Qt Foundation. The licenses are as published by the Free Software\n"
- "** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3\n"
+ "** General Public License version 3 as published by the Free Software\n"
+ "** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT\n"
"** included in the packaging of this file. Please review the following\n"
"** information to ensure the GNU General Public License requirements will\n"
- "** be met: https://www.gnu.org/licenses/gpl-2.0.html and\n"
- "** https://www.gnu.org/licenses/gpl-3.0.html.\n"
+ "** be met: https://www.gnu.org/licenses/gpl-3.0.html.\n"
"**\n"
"** $QT_END_LICENSE$\n"
"**\n"
@@ -446,7 +458,7 @@ void CppGenerator::generateDecl (QTextStream &out)
out << "class " << grammar.table_name << endl
<< "{" << endl
<< "public:" << endl
- << " enum VariousConstants {" << endl;
+ << " enum VariousConstants {" << endl;
for (Name t : qAsConst(grammar.terminals))
{
@@ -462,59 +474,59 @@ void CppGenerator::generateDecl (QTextStream &out)
else
name.prepend (grammar.token_prefix);
- out << " " << name << " = " << value << "," << endl;
+ out << " " << name << " = " << value << "," << endl;
}
out << endl
- << " ACCEPT_STATE = " << accept_state << "," << endl
- << " RULE_COUNT = " << grammar.rules.size () << "," << endl
- << " STATE_COUNT = " << state_count << "," << endl
- << " TERMINAL_COUNT = " << terminal_count << "," << endl
- << " NON_TERMINAL_COUNT = " << non_terminal_count << "," << endl
+ << " ACCEPT_STATE = " << accept_state << "," << endl
+ << " RULE_COUNT = " << grammar.rules.size () << "," << endl
+ << " STATE_COUNT = " << state_count << "," << endl
+ << " TERMINAL_COUNT = " << terminal_count << "," << endl
+ << " NON_TERMINAL_COUNT = " << non_terminal_count << "," << endl
<< endl
- << " GOTO_INDEX_OFFSET = " << compressed_action.index.size () << "," << endl
- << " GOTO_INFO_OFFSET = " << compressed_action.info.size () << "," << endl
- << " GOTO_CHECK_OFFSET = " << compressed_action.check.size () << endl
- << " };" << endl
+ << " GOTO_INDEX_OFFSET = " << compressed_action.index.size () << "," << endl
+ << " GOTO_INFO_OFFSET = " << compressed_action.info.size () << "," << endl
+ << " GOTO_CHECK_OFFSET = " << compressed_action.check.size () << endl
+ << " };" << endl
<< endl
- << " static const char *const spell [];" << endl
- << " static const short lhs [];" << endl
- << " static const short rhs [];" << endl;
+ << " static const char *const spell[];" << endl
+ << " static const short lhs[];" << endl
+ << " static const short rhs[];" << endl;
if (debug_info)
{
QString prot = debugInfoProt();
out << endl << "#ifndef " << prot << endl
- << " static const int rule_index [];" << endl
- << " static const int rule_info [];" << endl
+ << " static const int rule_index[];" << endl
+ << " static const int rule_info[];" << endl
<< "#endif // " << prot << endl << endl;
}
- out << " static const short goto_default [];" << endl
- << " static const short action_default [];" << endl
- << " static const short action_index [];" << endl
- << " static const short action_info [];" << endl
- << " static const short action_check [];" << endl
+ out << " static const short goto_default[];" << endl
+ << " static const short action_default[];" << endl
+ << " static const short action_index[];" << endl
+ << " static const short action_info[];" << endl
+ << " static const short action_check[];" << endl
<< endl
- << " static inline int nt_action (int state, int nt)" << endl
- << " {" << endl
- << " const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;" << endl
- << " if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)" << endl
- << " return goto_default [nt];" << endl
+ << " static inline int nt_action (int state, int nt)" << endl
+ << " {" << endl
+ << " const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;" << endl
+ << " if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)" << endl
+ << " return goto_default [nt];" << endl
<< endl
- << " return action_info [GOTO_INFO_OFFSET + yyn];" << endl
- << " }" << endl
+ << " return action_info [GOTO_INFO_OFFSET + yyn];" << endl
+ << " }" << endl
<< endl
- << " static inline int t_action (int state, int token)" << endl
- << " {" << endl
- << " const int yyn = action_index [state] + token;" << endl
+ << " static inline int t_action (int state, int token)" << endl
+ << " {" << endl
+ << " const int yyn = action_index [state] + token;" << endl
<< endl
- << " if (yyn < 0 || action_check [yyn] != token)" << endl
- << " return - action_default [state];" << endl
+ << " if (yyn < 0 || action_check [yyn] != token)" << endl
+ << " return - action_default [state];" << endl
<< endl
- << " return action_info [yyn];" << endl
- << " }" << endl
+ << " return action_info [yyn];" << endl
+ << " }" << endl
<< "};" << endl
<< endl
<< endl;
@@ -539,11 +551,7 @@ void CppGenerator::generateImpl (QTextStream &out)
name_ids.insert (t, idx);
- if (idx)
- out << ", ";
-
- if (! (idx % 10))
- out << endl << " ";
+ generateSeparator(idx, out);
if (terminal)
{
@@ -569,35 +577,27 @@ void CppGenerator::generateImpl (QTextStream &out)
if (debug_info)
out << endl << "#endif // " << debugInfoProt() << endl;
- out << "};" << endl << endl;
+ out << endl << "};" << endl << endl;
out << "const short " << grammar.table_name << "::lhs [] = {";
idx = 0;
for (RulePointer rule = grammar.rules.begin (); rule != grammar.rules.end (); ++rule, ++idx)
{
- if (idx)
- out << ", ";
-
- if (! (idx % 10))
- out << endl << " ";
+ generateSeparator(idx, out);
out << aut.id (rule->lhs);
}
- out << "};" << endl << endl;
+ out << endl << "};" << endl << endl;
out << "const short " << grammar.table_name << "::rhs [] = {";
idx = 0;
for (RulePointer rule = grammar.rules.begin (); rule != grammar.rules.end (); ++rule, ++idx)
{
- if (idx)
- out << ", ";
-
- if (! (idx % 10))
- out << endl << " ";
+ generateSeparator(idx, out);
out << rule->rhs.size ();
}
- out << "};" << endl << endl;
+ out << endl << "};" << endl << endl;
if (debug_info)
{
@@ -608,35 +608,26 @@ void CppGenerator::generateImpl (QTextStream &out)
idx = 0;
for (auto rule = grammar.rules.cbegin (); rule != grammar.rules.cend (); ++rule, ++idx)
{
- out << endl << " ";
-
- if (idx)
- out << ", ";
- else
- out << " ";
+ generateSeparator(idx, out);
out << name_ids.value(rule->lhs);
for (const Name &n : rule->rhs)
out << ", " << name_ids.value (n);
}
- out << "};" << endl << endl;
+ out << endl << "};" << endl << endl;
out << "const int " << grammar.table_name << "::rule_index [] = {";
idx = 0;
int offset = 0;
for (RulePointer rule = grammar.rules.begin (); rule != grammar.rules.end (); ++rule, ++idx)
{
- if (idx)
- out << ", ";
-
- if (! (idx % 10))
- out << endl << " ";
+ generateSeparator(idx, out);
out << offset;
offset += rule->rhs.size () + 1;
}
- out << "};" << endl
+ out << endl << "};" << endl
<< "#endif // " << prot << endl << endl;
}
@@ -644,92 +635,34 @@ void CppGenerator::generateImpl (QTextStream &out)
idx = 0;
for (StatePointer state = aut.states.begin (); state != aut.states.end (); ++state, ++idx)
{
- if (state != aut.states.begin ())
- out << ", ";
-
- if (! (idx % 10))
- out << endl << " ";
+ generateSeparator(idx, out);
if (state->defaultReduce != grammar.rules.end ())
out << aut.id (state->defaultReduce);
else
out << "0";
}
- out << "};" << endl << endl;
+ out << endl << "};" << endl << endl;
out << "const short " << grammar.table_name << "::goto_default [] = {";
- for (int i = 0; i < defgoto.size (); ++i)
- {
- if (i)
- out << ", ";
-
- if (! (i % 10))
- out << endl << " ";
-
- out << defgoto [i];
- }
- out << "};" << endl << endl;
+ generateList(defgoto, out);
+ out << endl << "};" << endl << endl;
out << "const short " << grammar.table_name << "::action_index [] = {";
- for (int i = 0; i < compressed_action.index.size (); ++i)
- {
- if (! (i % 10))
- out << endl << " ";
-
- out << compressed_action.index [i] << ", ";
- }
- out << endl;
- for (int i = 0; i < compressed_goto.index.size (); ++i)
- {
- if (i)
- out << ", ";
-
- if (! (i % 10))
- out << endl << " ";
-
- out << compressed_goto.index [i];
- }
- out << "};" << endl << endl;
+ generateList(compressed_action.index, out);
+ out << "," << endl;
+ generateList(compressed_goto.index, out);
+ out << endl << "};" << endl << endl;
out << "const short " << grammar.table_name << "::action_info [] = {";
- for (int i = 0; i < compressed_action.info.size (); ++i)
- {
- if (! (i % 10))
- out << endl << " ";
-
- out << compressed_action.info [i] << ", ";
- }
- out << endl;
- for (int i = 0; i < compressed_goto.info.size (); ++i)
- {
- if (i)
- out << ", ";
-
- if (! (i % 10))
- out << endl << " ";
-
- out << compressed_goto.info [i];
- }
- out << "};" << endl << endl;
+ generateList(compressed_action.info, out);
+ out << "," << endl;
+ generateList(compressed_goto.info, out);
+ out << endl << "};" << endl << endl;
out << "const short " << grammar.table_name << "::action_check [] = {";
- for (int i = 0; i < compressed_action.check.size (); ++i)
- {
- if (! (i % 10))
- out << endl << " ";
-
- out << compressed_action.check [i] << ", ";
- }
- out << endl;
- for (int i = 0; i < compressed_goto.check.size (); ++i)
- {
- if (i)
- out << ", ";
-
- if (! (i % 10))
- out << endl << " ";
-
- out << compressed_goto.check [i];
- }
- out << "};" << endl << endl;
+ generateList(compressed_action.check, out);
+ out << "," << endl;
+ generateList(compressed_goto.check, out);
+ out << endl << "};" << endl << endl;
}
diff --git a/src/tools/qlalr/grammar.cpp b/src/tools/qlalr/grammar.cpp
index 1891a54860..f633962815 100644
--- a/src/tools/qlalr/grammar.cpp
+++ b/src/tools/qlalr/grammar.cpp
@@ -32,83 +32,89 @@
QT_BEGIN_NAMESPACE
const char *const grammar::spell [] = {
- "end of file", "identifier", "string literal", "%decl", "%expect", "%expect-lr", "%impl", "%left", "%merged_output", "%nonassoc",
- "%parser", "%prec", "%right", "%start", "%token", "%token_prefix", ":", "|", ";", 0,
- 0, 0};
+ "end of file", "identifier", "string literal", "%decl", "%expect", "%expect-lr", "%impl", "%left", "%merged_output", "%nonassoc",
+ "%parser", "%prec", "%right", "%start", "%token", "%token_prefix", ":", "|", ";", 0,
+ 0, 0
+};
const short grammar::lhs [] = {
- 22, 23, 23, 29, 25, 28, 28, 28, 28, 28,
- 28, 28, 24, 24, 31, 32, 32, 33, 33, 34,
- 34, 34, 31, 35, 35, 36, 37, 37, 38, 38,
- 30, 30, 26, 26, 40, 39, 41, 41, 44, 43,
- 43, 42, 42, 27, 45};
+ 22, 23, 23, 29, 25, 28, 28, 28, 28, 28,
+ 28, 28, 24, 24, 31, 32, 32, 33, 33, 34,
+ 34, 34, 31, 35, 35, 36, 37, 37, 38, 38,
+ 30, 30, 26, 26, 40, 39, 41, 41, 44, 43,
+ 43, 42, 42, 27, 45
+};
const short grammar::rhs [] = {
- 4, 1, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 1, 2, 2, 1, 2, 2, 2, 1,
- 1, 1, 2, 1, 2, 1, 1, 1, 1, 2,
- 0, 1, 1, 2, 2, 4, 3, 6, 0, 0,
- 2, 1, 2, 0, 2};
+ 4, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 1, 2, 2, 1, 2, 2, 2, 1,
+ 1, 1, 2, 1, 2, 1, 1, 1, 1, 2,
+ 0, 1, 1, 2, 2, 4, 3, 6, 0, 0,
+ 2, 1, 2, 0, 2
+};
const short grammar::action_default [] = {
- 44, 2, 44, 0, 0, 0, 0, 13, 0, 0,
- 3, 0, 0, 0, 8, 10, 11, 9, 7, 6,
- 12, 20, 22, 0, 21, 0, 44, 31, 0, 14,
- 26, 24, 23, 25, 4, 33, 1, 0, 34, 44,
- 35, 42, 39, 40, 0, 31, 44, 40, 43, 0,
- 31, 41, 29, 27, 28, 32, 38, 30, 36, 31,
- 37, 5, 44, 16, 15, 18, 19, 17, 45};
+ 44, 2, 44, 0, 0, 0, 0, 13, 0, 0,
+ 3, 0, 0, 0, 8, 10, 11, 9, 7, 6,
+ 12, 20, 22, 0, 21, 0, 44, 31, 0, 14,
+ 26, 24, 23, 25, 4, 33, 1, 0, 34, 44,
+ 35, 42, 39, 40, 0, 31, 44, 40, 43, 0,
+ 31, 41, 29, 27, 28, 32, 38, 30, 36, 31,
+ 37, 5, 44, 16, 15, 18, 19, 17, 45
+};
const short grammar::goto_default [] = {
- 3, 2, 13, 26, 36, 41, 10, 27, 61, 29,
- 64, 63, 23, 32, 31, 52, 55, 38, 39, 42,
- 43, 59, 44, 0};
+ 3, 2, 13, 26, 36, 41, 10, 27, 61, 29,
+ 64, 63, 23, 32, 31, 52, 55, 38, 39, 42,
+ 43, 59, 44, 0
+};
const short grammar::action_index [] = {
- -22, -22, 54, 1, 5, 15, 20, -22, -1, 6,
- -22, 3, 2, 35, -22, -22, -22, -22, -22, -22,
- -22, -22, -22, 10, -22, 7, -22, 14, 9, -22,
- -22, -22, 8, -22, -22, -22, 11, -2, -22, -22,
- -22, -22, -3, 16, 13, 14, -22, 17, -22, 4,
- 14, -22, -22, -22, -22, 14, -22, -22, -22, 14,
- -22, -22, 0, -22, 12, -22, -22, -22, -22,
+ -22, -22, 30, 1, 2, 3, 4, -22, 5, 6,
+ -22, 8, -1, 35, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, 13, -22, 7, -22, -2, 20, -22,
+ -22, -22, 11, -22, -22, -22, 15, -6, -22, -22,
+ -22, -22, -3, 19, -4, 12, -22, 18, -22, 10,
+ -2, -22, -22, -22, -22, -2, -22, -22, -22, -2,
+ -22, -22, 0, -22, 20, -22, -22, -22, -22,
- 2, -24, -2, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, -24, -4, -24, -24, -24,
- -24, -24, -14, -24, -24, -24, -24, -24, -24, -24,
- -24, -24, -24, -24, -24, 0, -16, -15, -24, -24,
- 15, -24, -24, -24, -24, -10, -24, -24, -24, 1,
- -24, -24, -3, -24, -1, -24, -24, -24, -24};
+ 0, -24, 3, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -2, -24, -24, -24,
+ -24, -24, -7, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, 17, -19, -11, -24, -24,
+ 1, -24, -24, -24, -24, -15, -24, -24, -24, -6,
+ -24, -24, -1, -24, -5, -24, -24, -24, -24
+};
const short grammar::action_info [] = {
- 17, 68, 66, 20, 19, 51, 14, 18, 34, 30,
- 62, 30, 37, 62, 40, 45, 15, 48, 48, 0,
- 0, 16, 0, 0, 0, 0, 0, 49, 49, 0,
- 46, 0, 0, 53, 54, 0, 0, 0, 0, 0,
- 0, 0, 21, 0, 22, 0, 0, 24, 25, 28,
- 0, 0, 0, 0, 0, 0, 0, 4, 5, 6,
- 8, 0, 9, 0, 11, 0, 0, 0, 0, 12,
- 0, 0, 0, 0, 0, 0,
+ 20, 68, 66, 14, 15, 16, 17, 18, 34, 19,
+ 40, 51, 30, 46, 30, 45, 37, 53, 54, 48,
+ 48, 62, 0, 0, 0, 0, 0, 0, 0, 49,
+ 49, 53, 54, 4, 5, 6, 8, 0, 9, 0,
+ 11, 0, 21, 0, 22, 12, 0, 24, 25, 28,
+ 0, 0, 0, 0, 0, 0, 0,
- 33, 35, 65, 7, 47, 57, 50, 1, 58, 60,
- 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 56, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ 57, 47, 60, 35, 65, 1, 67, 33, 7, 56,
+ 50, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 58, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0
+};
const short grammar::action_check [] = {
- 1, 0, 2, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 16, 18, 1, 1, 1, -1,
- -1, 1, -1, -1, -1, -1, -1, 11, 11, -1,
- 17, -1, -1, 19, 20, -1, -1, -1, -1, -1,
- -1, -1, 7, -1, 9, -1, -1, 12, 13, 14,
- -1, -1, -1, -1, -1, -1, -1, 3, 4, 5,
- 6, -1, 8, -1, 10, -1, -1, -1, -1, 15,
- -1, -1, -1, -1, -1, -1,
+ 1, 0, 2, 1, 1, 1, 1, 1, 1, 1,
+ 16, 1, 1, 17, 1, 18, 1, 19, 20, 1,
+ 1, 1, -1, -1, -1, -1, -1, -1, -1, 11,
+ 11, 19, 20, 3, 4, 5, 6, -1, 8, -1,
+ 10, -1, 7, -1, 9, 15, -1, 12, 13, 14,
+ -1, -1, -1, -1, -1, -1, -1,
- 14, 5, 5, 5, 20, 15, 21, 5, 8, 8,
- 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 8, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1};
+ 15, 20, 8, 5, 5, 5, 11, 14, 5, 8,
+ 21, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1
+};
QT_END_NAMESPACE
diff --git a/src/tools/qlalr/grammar_p.h b/src/tools/qlalr/grammar_p.h
index 1230a29b1c..8482f9bfe1 100644
--- a/src/tools/qlalr/grammar_p.h
+++ b/src/tools/qlalr/grammar_p.h
@@ -48,68 +48,68 @@ QT_BEGIN_NAMESPACE
class grammar
{
public:
- enum VariousConstants {
- EOF_SYMBOL = 0,
- COLON = 16,
- DECL = 19,
- DECL_FILE = 3,
- ERROR = 21,
- EXPECT = 4,
- EXPECT_RR = 5,
- ID = 1,
- IMPL = 20,
- IMPL_FILE = 6,
- LEFT = 7,
- MERGED_OUTPUT = 8,
- NONASSOC = 9,
- OR = 17,
- PARSER = 10,
- PREC = 11,
- RIGHT = 12,
- SEMICOLON = 18,
- START = 13,
- STRING_LITERAL = 2,
- TOKEN = 14,
- TOKEN_PREFIX = 15,
-
- ACCEPT_STATE = 68,
- RULE_COUNT = 45,
- STATE_COUNT = 69,
- TERMINAL_COUNT = 22,
- NON_TERMINAL_COUNT = 24,
-
- GOTO_INDEX_OFFSET = 69,
- GOTO_INFO_OFFSET = 76,
- GOTO_CHECK_OFFSET = 76
- };
-
- static const char *const spell [];
- static const short lhs [];
- static const short rhs [];
- static const short goto_default [];
- static const short action_default [];
- static const short action_index [];
- static const short action_info [];
- static const short action_check [];
-
- static inline int nt_action (int state, int nt)
- {
- const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;
- if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)
- return goto_default [nt];
-
- return action_info [GOTO_INFO_OFFSET + yyn];
- }
-
- static inline int t_action (int state, int token)
- {
- const int yyn = action_index [state] + token;
-
- if (yyn < 0 || action_check [yyn] != token)
- return - action_default [state];
-
- return action_info [yyn];
- }
+ enum VariousConstants {
+ EOF_SYMBOL = 0,
+ COLON = 16,
+ DECL = 19,
+ DECL_FILE = 3,
+ ERROR = 21,
+ EXPECT = 4,
+ EXPECT_RR = 5,
+ ID = 1,
+ IMPL = 20,
+ IMPL_FILE = 6,
+ LEFT = 7,
+ MERGED_OUTPUT = 8,
+ NONASSOC = 9,
+ OR = 17,
+ PARSER = 10,
+ PREC = 11,
+ RIGHT = 12,
+ SEMICOLON = 18,
+ START = 13,
+ STRING_LITERAL = 2,
+ TOKEN = 14,
+ TOKEN_PREFIX = 15,
+
+ ACCEPT_STATE = 68,
+ RULE_COUNT = 45,
+ STATE_COUNT = 69,
+ TERMINAL_COUNT = 22,
+ NON_TERMINAL_COUNT = 24,
+
+ GOTO_INDEX_OFFSET = 69,
+ GOTO_INFO_OFFSET = 57,
+ GOTO_CHECK_OFFSET = 57
+ };
+
+ static const char *const spell[];
+ static const short lhs[];
+ static const short rhs[];
+ static const short goto_default[];
+ static const short action_default[];
+ static const short action_index[];
+ static const short action_info[];
+ static const short action_check[];
+
+ static inline int nt_action (int state, int nt)
+ {
+ const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;
+ if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)
+ return goto_default [nt];
+
+ return action_info [GOTO_INFO_OFFSET + yyn];
+ }
+
+ static inline int t_action (int state, int token)
+ {
+ const int yyn = action_index [state] + token;
+
+ if (yyn < 0 || action_check [yyn] != token)
+ return - action_default [state];
+
+ return action_info [yyn];
+ }
};
diff --git a/src/tools/qlalr/lalr.g b/src/tools/qlalr/lalr.g
index 65a63f8312..5e335c5a3b 100644
--- a/src/tools/qlalr/lalr.g
+++ b/src/tools/qlalr/lalr.g
@@ -61,8 +61,7 @@
%start Specification
-/:
-/****************************************************************************
+/:/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
@@ -163,8 +162,7 @@ protected:
};
:/
-/.
-/****************************************************************************
+/./****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
@@ -194,6 +192,8 @@ protected:
#include "recognizer.h"
+#include <QtCore/qdir.h>
+
#include <cstdlib>
#include <cstring>
#include <cctype>
@@ -344,7 +344,8 @@ int Recognizer::nextToken()
text.clear ();
if (! _M_no_lines)
- text += QLatin1String ("\n#line ") + QString::number (_M_action_line) + " \"" + _M_input_file + "\"\n";
+ text += QLatin1String("\n#line ") + QString::number(_M_action_line) +
+ QLatin1String(" \"") + QDir::fromNativeSeparators(_M_input_file) + QLatin1String("\"\n");
inp (); // skip ':'
forever
@@ -381,7 +382,8 @@ int Recognizer::nextToken()
text.clear ();
if (! _M_no_lines)
- text += QLatin1String ("\n#line ") + QString::number (_M_action_line) + " \"" + _M_input_file + "\"\n";
+ text += QLatin1String("\n#line ") + QString::number(_M_action_line) +
+ QLatin1String(" \"") + QDir::fromNativeSeparators(_M_input_file) + QLatin1String("\"\n");
inp (); // skip ':'
diff --git a/src/tools/qlalr/recognizer.cpp b/src/tools/qlalr/recognizer.cpp
index 69dad1a6c1..8c7665f1b9 100644
--- a/src/tools/qlalr/recognizer.cpp
+++ b/src/tools/qlalr/recognizer.cpp
@@ -28,6 +28,8 @@
#include "recognizer.h"
+#include <QtCore/qdir.h>
+
#include <cstdlib>
#include <cstring>
#include <cctype>
@@ -178,8 +180,8 @@ int Recognizer::nextToken()
text.clear ();
if (! _M_no_lines)
- text += QLatin1String("\n#line ") + QString::number (_M_action_line)
- + QLatin1String(" \"") + _M_input_file + QLatin1String("\"\n");
+ text += QLatin1String("\n#line ") + QString::number(_M_action_line) +
+ QLatin1String(" \"") + QDir::fromNativeSeparators(_M_input_file) + QLatin1String("\"\n");
inp (); // skip ':'
forever
@@ -216,8 +218,8 @@ int Recognizer::nextToken()
text.clear ();
if (! _M_no_lines)
- text += QLatin1String ("\n#line ") + QString::number (_M_action_line) +
- QLatin1String(" \"") + _M_input_file + QLatin1String("\"\n");
+ text += QLatin1String("\n#line ") + QString::number(_M_action_line) +
+ QLatin1String(" \"") + QDir::fromNativeSeparators(_M_input_file) + QLatin1String("\"\n");
inp (); // skip ':'
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 939e2a3d79..20002b1f82 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1703,6 +1703,7 @@ bool QAbstractItemView::viewportEvent(QEvent *event)
d->viewportEnteredNeeded = true;
break;
case QEvent::Leave:
+ d->setHoverIndex(QModelIndex()); // If we've left, no hover should be needed anymore
#ifndef QT_NO_STATUSTIP
if (d->shouldClearStatusTip && d->parent) {
QString empty;
diff --git a/src/widgets/widgets/qtoolbox.cpp b/src/widgets/widgets/qtoolbox.cpp
index 2c74b5fa9d..8413827e30 100644
--- a/src/widgets/widgets/qtoolbox.cpp
+++ b/src/widgets/widgets/qtoolbox.cpp
@@ -117,7 +117,7 @@ public:
void _q_buttonClicked();
void _q_widgetDestroyed(QObject*);
- const Page *page(QWidget *widget) const;
+ const Page *page(const QObject *widget) const;
const Page *page(int index) const;
Page *page(int index);
@@ -129,7 +129,7 @@ public:
Page *currentPage;
};
-const QToolBoxPrivate::Page *QToolBoxPrivate::page(QWidget *widget) const
+const QToolBoxPrivate::Page *QToolBoxPrivate::page(const QObject *widget) const
{
if (!widget)
return 0;
@@ -449,11 +449,9 @@ void QToolBoxPrivate::relayout()
void QToolBoxPrivate::_q_widgetDestroyed(QObject *object)
{
Q_Q(QToolBox);
- // no verification - vtbl corrupted already
- QWidget *p = (QWidget*)object;
- const QToolBoxPrivate::Page *c = page(p);
- if (!p || !c)
+ const QToolBoxPrivate::Page * const c = page(object);
+ if (!c)
return;
layout->removeWidget(c->sv);
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index f5672bd87a..dacb4806ce 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -2052,16 +2052,59 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
preeditCursor = a.start;
hideCursor = !a.length;
} else if (a.type == QInputMethodEvent::TextFormat) {
- QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
+ QTextCharFormat f = cursor.charFormat();
+ f.merge(qvariant_cast<QTextFormat>(a.value).toCharFormat());
if (f.isValid()) {
QTextLayout::FormatRange o;
o.start = a.start + cursor.position() - block.position();
o.length = a.length;
o.format = f;
- overrides.append(o);
+
+ // Make sure list is sorted by start index
+ QVector<QTextLayout::FormatRange>::iterator it = overrides.end();
+ while (it != overrides.begin()) {
+ QVector<QTextLayout::FormatRange>::iterator previous = it - 1;
+ if (o.start >= previous->start) {
+ overrides.insert(it, o);
+ break;
+ }
+ it = previous;
+ }
+
+ if (it == overrides.begin())
+ overrides.prepend(o);
}
}
}
+
+ if (cursor.charFormat().isValid()) {
+ int start = cursor.position() - block.position();
+ int end = start + e->preeditString().length();
+
+ QVector<QTextLayout::FormatRange>::iterator it = overrides.begin();
+ while (it != overrides.end()) {
+ QTextLayout::FormatRange range = *it;
+ int rangeStart = range.start;
+ if (rangeStart > start) {
+ QTextLayout::FormatRange o;
+ o.start = start;
+ o.length = rangeStart - start;
+ o.format = cursor.charFormat();
+ it = overrides.insert(it, o) + 1;
+ }
+
+ ++it;
+ start = range.start + range.length;
+ }
+
+ if (start < end) {
+ QTextLayout::FormatRange o;
+ o.start = start;
+ o.length = end - start;
+ o.format = cursor.charFormat();
+ overrides.append(o);
+ }
+ }
layout->setFormats(overrides);
cursor.endEditBlock();
diff --git a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
index 3b2cd84749..8fc1b07502 100644
--- a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
+++ b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
@@ -2,3 +2,5 @@
osx-10.9
[pauseAndPropertyAnimations]
*
+[multipleSequentialGroups]
+osx
diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
index a13ff0358a..d2f345feb5 100644
--- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
+++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp
@@ -34,6 +34,7 @@
#include <qsysinfo.h>
#if defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
#include <unistd.h>
+#include <sys/time.h>
#elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
# include <qt_windows.h>
#endif
@@ -59,6 +60,7 @@ private slots:
void noPermissions();
void noPermissionsWindows();
void corruptedLockFile();
+ void corruptedLockFileInTheFuture();
private:
static bool overwritePidInLockFile(const QString &filePath, qint64 pid);
@@ -521,6 +523,32 @@ void tst_QLockFile::corruptedLockFile()
QCOMPARE(int(secondLock.error()), int(QLockFile::NoError));
}
+void tst_QLockFile::corruptedLockFileInTheFuture()
+{
+#if !defined(Q_OS_UNIX)
+ QSKIP("This tests needs utimes");
+#else
+ // This test is the same as the previous one, but the corruption was so there is a corrupted
+ // .rmlock whose timestamp is in the future
+
+ const QString fileName = dir.path() + "/corruptedLockFile.rmlock";
+
+ {
+ QFile file(fileName);
+ QVERIFY(file.open(QFile::WriteOnly));
+ }
+
+ struct timeval times[2];
+ gettimeofday(times, 0);
+ times[1].tv_sec = (times[0].tv_sec += 600);
+ times[1].tv_usec = times[0].tv_usec;
+ utimes(fileName.toLocal8Bit(), times);
+
+ QTest::ignoreMessage(QtInfoMsg, "QLockFile: Lock file '" + fileName.toUtf8() + "' has a modification time in the future");
+ corruptedLockFile();
+#endif
+}
+
bool tst_QLockFile::overwritePidInLockFile(const QString &filePath, qint64 pid)
{
QFile f(filePath);
diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp
index ee18151e4a..ebc240c285 100644
--- a/tests/auto/corelib/io/qurl/tst_qurl.cpp
+++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp
@@ -3088,7 +3088,11 @@ void tst_QUrl::fromUserInputWithCwd_data()
}
// Existing files
- for (const char *fileName : {"file.txt", "file#a.txt", "file .txt", "file.txt "}) {
+ for (const char *fileName : {"file.txt", "file#a.txt", "file .txt", "file.txt "
+#ifndef Q_OS_WIN
+ , "file:colon.txt"
+#endif
+ }) {
const QString filePath = base + '/' + fileName;
QFile file(filePath);
QVERIFY2(file.open(QIODevice::WriteOnly), qPrintable(filePath));
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index f693d14029..143bf2f95d 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -1563,7 +1563,6 @@ DECLARE_NONSTREAMABLE(QJsonArray)
DECLARE_NONSTREAMABLE(QJsonDocument)
DECLARE_NONSTREAMABLE(QObject*)
DECLARE_NONSTREAMABLE(QWidget*)
-DECLARE_NONSTREAMABLE(std::nullptr_t)
#define DECLARE_GUI_CLASS_NONSTREAMABLE(MetaTypeName, MetaTypeId, RealType) \
DECLARE_NONSTREAMABLE(RealType)
@@ -1602,7 +1601,10 @@ void tst_QMetaType::saveAndLoadBuiltin()
if (isStreamable) {
QVERIFY(QMetaType::load(stream, type, value)); // Hmmm, shouldn't it return false?
- QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
+
+ // std::nullptr_t is nullary: it doesn't actually read anything
+ if (type != QMetaType::Nullptr)
+ QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
}
stream.device()->seek(0);
@@ -1612,7 +1614,10 @@ void tst_QMetaType::saveAndLoadBuiltin()
if (isStreamable) {
QVERIFY(QMetaType::load(stream, type, value)); // Hmmm, shouldn't it return false?
- QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
+
+ // std::nullptr_t is nullary: it doesn't actually read anything
+ if (type != QMetaType::Nullptr)
+ QCOMPARE(stream.status(), QDataStream::ReadPastEnd);
}
QMetaType::destroy(type, value);
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
index 02ba987ccd..280e3f77a4 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
@@ -861,7 +861,7 @@ void tst_QMimeDatabase::fromThreads()
#if QT_CONFIG(process)
enum {
- UpdateMimeDatabaseTimeout = 120 * 1000 // 2min
+ UpdateMimeDatabaseTimeout = 4 * 60 * 1000 // 4min
};
static bool runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDatabase method?
diff --git a/tests/auto/corelib/tools/qchar/tst_qchar.cpp b/tests/auto/corelib/tools/qchar/tst_qchar.cpp
index 13898ace7b..e5a6e953d3 100644
--- a/tests/auto/corelib/tools/qchar/tst_qchar.cpp
+++ b/tests/auto/corelib/tools/qchar/tst_qchar.cpp
@@ -36,7 +36,7 @@ class tst_QChar : public QObject
{
Q_OBJECT
private slots:
- void operator_eqeq_int();
+ void operator_eqeq_null();
void operators_data();
void operators();
void toUpper();
@@ -72,35 +72,54 @@ private slots:
void unicodeVersion();
};
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
-
-void tst_QChar::operator_eqeq_int()
+void tst_QChar::operator_eqeq_null()
{
{
const QChar ch = QLatin1Char(' ');
- QVERIFY(ch != 0);
- QVERIFY(!(ch == 0));
-
- QVERIFY(ch == 0x20);
- QVERIFY(!(ch != 0x20));
- QVERIFY(0x20 == ch);
- QVERIFY(!(0x20 != ch));
+#define CHECK(NUL) \
+ do { \
+ QVERIFY(!(ch == NUL)); \
+ QVERIFY( ch != NUL ); \
+ QVERIFY(!(ch < NUL)); \
+ QVERIFY( ch > NUL ); \
+ QVERIFY(!(ch <= NUL)); \
+ QVERIFY( ch >= NUL ); \
+ QVERIFY(!(NUL == ch )); \
+ QVERIFY( NUL != ch ); \
+ QVERIFY( NUL < ch ); \
+ QVERIFY(!(NUL > ch )); \
+ QVERIFY( NUL <= ch ); \
+ QVERIFY(!(NUL >= ch )); \
+ } while (0)
+
+ CHECK(0);
+ CHECK('\0');
+#undef CHECK
}
{
const QChar ch = QLatin1Char('\0');
- QVERIFY(ch == 0);
- QVERIFY(!(ch != 0));
-
- QVERIFY(ch != 0x20);
- QVERIFY(!(ch == 0x20));
- QVERIFY(0x20 != ch);
- QVERIFY(!(0x20 == ch));
+#define CHECK(NUL) \
+ do { \
+ QVERIFY( ch == NUL ); \
+ QVERIFY(!(ch != NUL)); \
+ QVERIFY(!(ch < NUL)); \
+ QVERIFY(!(ch > NUL)); \
+ QVERIFY( ch <= NUL ); \
+ QVERIFY( ch >= NUL ); \
+ QVERIFY( NUL == ch ); \
+ QVERIFY(!(NUL != ch )); \
+ QVERIFY(!(NUL < ch )); \
+ QVERIFY(!(NUL > ch )); \
+ QVERIFY( NUL <= ch ); \
+ QVERIFY( NUL >= ch ); \
+ } while (0)
+
+ CHECK(0);
+ CHECK('\0');
+#undef CHECK
}
}
-QT_WARNING_POP
-
void tst_QChar::operators_data()
{
QTest::addColumn<QChar>("lhs");
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
index d241296a6b..f2cf78e8ac 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
@@ -45,6 +45,7 @@
#include <qpushbutton.h>
#include <qscrollbar.h>
#include <qboxlayout.h>
+#include <qitemdelegate.h>
#include <qlineedit.h>
#include <qscreen.h>
#include <qscopedpointer.h>
@@ -151,6 +152,7 @@ private slots:
void testSelectionModelInSyncWithView();
void testClickToSelect();
void testDialogAsEditor();
+ void QTBUG46785_mouseout_hover_state();
};
class MyAbstractItemDelegate : public QAbstractItemDelegate
@@ -2213,5 +2215,56 @@ void tst_QAbstractItemView::testDialogAsEditor()
QCOMPARE(delegate.result, QDialog::Accepted);
}
+class HoverItemDelegate : public QItemDelegate
+{
+public:
+ HoverItemDelegate()
+ : QItemDelegate()
+ , m_paintedWithoutHover(false)
+ { }
+
+ void paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index) const override
+ {
+ Q_UNUSED(painter);
+
+ if (!(opt.state & QStyle::State_MouseOver)) {
+
+ // We don't want to set m_paintedWithoutHover for any item so check for the item at 0,0
+ if (index.row() == 0 && index.column() == 0) {
+ m_paintedWithoutHover = true;
+ }
+ }
+ }
+
+ mutable bool m_paintedWithoutHover;
+};
+
+void tst_QAbstractItemView::QTBUG46785_mouseout_hover_state()
+{
+ HoverItemDelegate delegate;
+
+ QTableWidget table(5, 5);
+ table.verticalHeader()->hide();
+ table.horizontalHeader()->hide();
+ table.setMouseTracking(true);
+ table.setItemDelegate(&delegate);
+ centerOnScreen(&table);
+ table.show();
+ QVERIFY(QTest::qWaitForWindowActive(&table));
+
+ QModelIndex item = table.model()->index(0, 0);
+ QRect itemRect = table.visualRect(item);
+
+ // Move the mouse into the center of the item at 0,0 to cause a paint event to occur
+ QTest::mouseMove(table.viewport(), itemRect.center());
+ QTest::mouseClick(table.viewport(), Qt::LeftButton, 0, itemRect.center());
+
+ delegate.m_paintedWithoutHover = false;
+
+ QTest::mouseMove(table.viewport(), QPoint(-50, 0));
+
+ QTRY_VERIFY(delegate.m_paintedWithoutHover);
+}
+
QTEST_MAIN(tst_QAbstractItemView)
#include "tst_qabstractitemview.moc"
diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
index b9ea310d80..bc94e2a05b 100644
--- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
@@ -46,6 +46,7 @@
#include <qcommonstyle.h>
#include <qlayout.h>
#include <qdir.h>
+#include <qpaintengine.h>
#include <qabstracttextdocumentlayout.h>
#include <qtextdocumentfragment.h>
@@ -60,6 +61,8 @@ typedef QPair<Qt::Key, Qt::KeyboardModifier> keyPairType;
typedef QList<keyPairType> pairListType;
Q_DECLARE_METATYPE(keyPairType);
+Q_DECLARE_METATYPE(QList<QInputMethodEvent::Attribute>);
+
QT_FORWARD_DECLARE_CLASS(QTextEdit)
class tst_QTextEdit : public QObject
@@ -200,6 +203,9 @@ private slots:
void wheelEvent();
#endif
+ void preeditCharFormat_data();
+ void preeditCharFormat();
+
private:
void createSelection();
int blockCount() const;
@@ -2594,5 +2600,235 @@ void tst_QTextEdit::wheelEvent()
#endif
+namespace {
+ class MyPaintEngine : public QPaintEngine
+ {
+ public:
+ bool begin(QPaintDevice *)
+ {
+ return true;
+ }
+
+ bool end()
+ {
+ return true;
+ }
+
+ void updateState(const QPaintEngineState &)
+ {
+ }
+
+ void drawPixmap(const QRectF &, const QPixmap &, const QRectF &)
+ {
+ }
+
+ void drawTextItem(const QPointF &, const QTextItem &textItem) Q_DECL_OVERRIDE
+ {
+ itemFonts.append(qMakePair(textItem.text(), textItem.font()));
+ }
+
+ Type type() const { return User; }
+
+
+ QList<QPair<QString, QFont> > itemFonts;
+ };
+
+ class MyPaintDevice : public QPaintDevice
+ {
+ public:
+ MyPaintDevice() : m_paintEngine(new MyPaintEngine)
+ {
+ }
+
+
+ QPaintEngine *paintEngine () const
+ {
+ return m_paintEngine;
+ }
+
+ int metric (QPaintDevice::PaintDeviceMetric metric) const {
+ switch (metric) {
+ case QPaintDevice::PdmWidth:
+ case QPaintDevice::PdmHeight:
+ case QPaintDevice::PdmWidthMM:
+ case QPaintDevice::PdmHeightMM:
+ case QPaintDevice::PdmNumColors:
+ return INT_MAX;
+ case QPaintDevice::PdmDepth:
+ return 32;
+ case QPaintDevice::PdmDpiX:
+ case QPaintDevice::PdmDpiY:
+ case QPaintDevice::PdmPhysicalDpiX:
+ case QPaintDevice::PdmPhysicalDpiY:
+ return 72;
+ case QPaintDevice::PdmDevicePixelRatio:
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ ; // fall through
+ }
+ return 0;
+ }
+
+ MyPaintEngine *m_paintEngine;
+ };
+}
+
+void tst_QTextEdit::preeditCharFormat_data()
+{
+ QTest::addColumn<QList<QInputMethodEvent::Attribute> >("imeAttributes");
+ QTest::addColumn<QStringList>("substrings");
+ QTest::addColumn<QList<bool> >("boldnessList");
+ QTest::addColumn<QList<bool> >("italicnessList");
+ QTest::addColumn<QList<int> >("pointSizeList");
+
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(13);
+ tcf.setFontItalic(true);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 1, 1, tcf));
+ }
+
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(8);
+ tcf.setFontWeight(QFont::Normal);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 4, 2, tcf));
+ }
+
+ QTest::newRow("Two formats, middle, in order")
+ << attributes
+ << (QStringList() << "P" << "r" << "eE" << "di" << "tText")
+ << (QList<bool>() << true << true << true << false << true)
+ << (QList<bool>() << false << true << false << false << false)
+ << (QList<int>() << 20 << 13 << 20 << 8 << 20);
+ }
+
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(8);
+ tcf.setFontWeight(QFont::Normal);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 4, 2, tcf));
+ }
+
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(13);
+ tcf.setFontItalic(true);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 1, 1, tcf));
+ }
+
+ QTest::newRow("Two formats, middle, out of order")
+ << attributes
+ << (QStringList() << "P" << "r" << "eE" << "di" << "tText")
+ << (QList<bool>() << true << true << true << false << true)
+ << (QList<bool>() << false << true << false << false << false)
+ << (QList<int>() << 20 << 13 << 20 << 8 << 20);
+ }
+
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(13);
+ tcf.setFontItalic(true);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, 1, tcf));
+ }
+
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(8);
+ tcf.setFontWeight(QFont::Normal);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 4, 2, tcf));
+ }
+
+ QTest::newRow("Two formats, front, in order")
+ << attributes
+ << (QStringList() << "P" << "reE" << "di" << "tText")
+ << (QList<bool>() << true << true << false << true)
+ << (QList<bool>() << true << false << false << false)
+ << (QList<int>() << 13 << 20 << 8 << 20);
+ }
+
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(8);
+ tcf.setFontWeight(QFont::Normal);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 4, 2, tcf));
+ }
+
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(13);
+ tcf.setFontItalic(true);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, 1, tcf));
+ }
+
+ QTest::newRow("Two formats, front, out of order")
+ << attributes
+ << (QStringList() << "P" << "reE" << "di" << "tText")
+ << (QList<bool>() << true << true << false << true)
+ << (QList<bool>() << true << false << false << false)
+ << (QList<int>() << 13 << 20 << 8 << 20);
+ }
+}
+
+void tst_QTextEdit::preeditCharFormat()
+{
+ QFETCH(QList<QInputMethodEvent::Attribute>, imeAttributes);
+ QFETCH(QStringList, substrings);
+ QFETCH(QList<bool>, boldnessList);
+ QFETCH(QList<bool>, italicnessList);
+ QFETCH(QList<int>, pointSizeList);
+
+ QTextEdit *w = new QTextEdit;
+ w->show();
+ QVERIFY(QTest::qWaitForWindowExposed(w));
+
+ // Set main char format
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(20);
+ tcf.setFontWeight(QFont::Bold);
+ w->mergeCurrentCharFormat(tcf);
+ }
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.prepend(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
+ w->textCursor().position(),
+ 0,
+ QVariant()));
+
+ attributes += imeAttributes;
+
+ QInputMethodEvent event("PreEditText", attributes);
+ QApplication::sendEvent(w, &event);
+
+ MyPaintDevice device;
+ {
+ QPainter p(&device);
+ w->document()->drawContents(&p);
+ }
+
+ QCOMPARE(device.m_paintEngine->itemFonts.size(), substrings.size());
+ for (int i = 0; i < substrings.size(); ++i)
+ QCOMPARE(device.m_paintEngine->itemFonts.at(i).first, substrings.at(i));
+
+ for (int i = 0; i < substrings.size(); ++i)
+ QCOMPARE(device.m_paintEngine->itemFonts.at(i).second.bold(), boldnessList.at(i));
+
+ for (int i = 0; i < substrings.size(); ++i)
+ QCOMPARE(device.m_paintEngine->itemFonts.at(i).second.italic(), italicnessList.at(i));
+
+ for (int i = 0; i < substrings.size(); ++i)
+ QCOMPARE(device.m_paintEngine->itemFonts.at(i).second.pointSize(), pointSizeList.at(i));
+
+ delete w;
+}
+
QTEST_MAIN(tst_QTextEdit)
#include "tst_qtextedit.moc"