Merge "Merge remote-tracking branch 'origin/5.8' into 5.9" into refs/staging/5.9

bb10
Liang Qi 2017-03-22 07:10:41 +00:00 committed by The Qt Project
commit 495f914fb5
42 changed files with 891 additions and 505 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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"));

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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()));

View File

@ -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;

View File

@ -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
*/
/*!

View File

@ -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);

View File

@ -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();
for (int month=startMonth; month<=12; ++month) {
const QString monthName = l.monthName(month, type);
QString str2 = monthName.toLower();
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);
const SectionNode &sn = sectionNode(sectionIndex);
if (sn.type != MonthSection) {
qWarning("QDateTimeParser::findMonth Internal error");
return -1;
}
if (used) {
QDTPDEBUG << "used is set to" << bestCount;
*used = bestCount;
}
return bestMatch;
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));
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

View File

@ -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

View File

@ -118,7 +118,7 @@ public:
void maybeQuitOnLastWindowClosed();
#ifndef QT_NO_CURSOR
void setCursor(const QCursor *c = 0);
void applyCursor();
bool applyCursor();
#endif
void deliverUpdateRequest();

View File

@ -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);
}

View File

@ -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

View File

@ -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");

View File

@ -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 \

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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");
}

View File

@ -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": {

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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,
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,
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
};
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 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];
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];
}
return action_info [GOTO_INFO_OFFSET + yyn];
}
static inline int t_action (int state, int token)
{
const int yyn = action_index [state] + token;
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];
if (yyn < 0 || action_check [yyn] != token)
return - action_default [state];
return action_info [yyn];
}
return action_info [yyn];
}
};

View File

@ -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 ':'

View File

@ -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 ':'

View File

@ -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;

View File

@ -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);

View File

@ -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();

View File

@ -2,3 +2,5 @@
osx-10.9
[pauseAndPropertyAnimations]
*
[multipleSequentialGroups]
osx

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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?

View File

@ -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));
#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)
QVERIFY(ch == 0x20);
QVERIFY(!(ch != 0x20));
QVERIFY(0x20 == ch);
QVERIFY(!(0x20 != ch));
CHECK(0);
CHECK('\0');
#undef CHECK
}
{
const QChar ch = QLatin1Char('\0');
QVERIFY(ch == 0);
QVERIFY(!(ch != 0));
#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)
QVERIFY(ch != 0x20);
QVERIFY(!(ch == 0x20));
QVERIFY(0x20 != ch);
QVERIFY(!(0x20 == ch));
CHECK(0);
CHECK('\0');
#undef CHECK
}
}
QT_WARNING_POP
void tst_QChar::operators_data()
{
QTest::addColumn<QChar>("lhs");

View File

@ -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"

View File

@ -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"