Merge remote-tracking branch 'origin/5.9' into 5.10

Conflicts:
	src/corelib/global/qconfig-bootstrapped.h
	src/corelib/global/qglobal.h
	src/corelib/tools/qcryptographichash.cpp
	src/corelib/tools/qcryptographichash.h
	src/corelib/tools/qmessageauthenticationcode.cpp
	src/plugins/platforms/windows/qwindowswindow.h
	tests/auto/gui/kernel/qwindow/BLACKLIST
	tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST

Change-Id: Ib68112de985a3d714c2071f47c10e907e4f0229a
This commit is contained in:
Liang Qi 2017-10-04 10:41:19 +02:00
commit bc5f45052f
62 changed files with 784 additions and 275 deletions

View File

@ -37,7 +37,7 @@ greaterThan(QMAKE_MSC_VER, 1699) {
# Visual Studio 2012 (11.0) / Visual C++ 17.0 and up # Visual Studio 2012 (11.0) / Visual C++ 17.0 and up
MSVC_VER = 11.0 MSVC_VER = 11.0
COMPAT_MKSPEC = win32-msvc2012 COMPAT_MKSPEC = win32-msvc2012
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0 QMAKE_CXXFLAGS_EXCEPTIONS_OFF = /wd4530 /wd4577
QT_CONFIG += c++11 QT_CONFIG += c++11
CONFIG += c++11 CONFIG += c++11
} }

View File

@ -52,7 +52,7 @@ QMAKE_CXXFLAGS_STL_OFF =
QMAKE_CXXFLAGS_RTTI_ON = -GR QMAKE_CXXFLAGS_RTTI_ON = -GR
QMAKE_CXXFLAGS_RTTI_OFF = QMAKE_CXXFLAGS_RTTI_OFF =
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0 QMAKE_CXXFLAGS_EXCEPTIONS_OFF = /wd4530 /wd4577
QMAKE_INCDIR = QMAKE_INCDIR =

View File

@ -120,7 +120,7 @@ isEmpty($${target_prefix}.INCDIRS) {
} }
} }
} }
!darwin:clang { if(!darwin:clang)|intel_icc {
# Clang on a non-Apple system (that is, a system without ld64 -- say, with GNU ld # Clang on a non-Apple system (that is, a system without ld64 -- say, with GNU ld
# or gold under Linux) will not print any library search path. Need to use another # or gold under Linux) will not print any library search path. Need to use another
# invocation with different options (which in turn doesn't print include search # invocation with different options (which in turn doesn't print include search
@ -205,7 +205,7 @@ isEmpty($${target_prefix}.COMPILER_MACROS) {
vars = $$qtVariablesFromGCC($$QMAKE_CXX) vars = $$qtVariablesFromGCC($$QMAKE_CXX)
} }
for (v, vars) { for (v, vars) {
isEmpty(v)|contains(v, $${LITERAL_HASH}.*): next() contains(v, $${LITERAL_HASH}.*)|contains(v, " *"): next()
# Set both <varname> for the outer scope ... # Set both <varname> for the outer scope ...
eval($$v) eval($$v)
v ~= s/ .*// v ~= s/ .*//

View File

@ -3800,8 +3800,8 @@
compiled (see QLibraryInfo::DataPath). compiled (see QLibraryInfo::DataPath).
\endlist \endlist
\note The \c QMAKESPEC path will automatically be added to the \note The \c QMAKESPEC path will be automatically added to the generated
\l{INCLUDEPATH} system variable. Makefile after the contents of the \l{INCLUDEPATH} system variable.
\target cache \target cache
\section1 Cache File \section1 Cache File

View File

@ -815,10 +815,16 @@
}, },
"timezone": { "timezone": {
"label": "QTimeZone", "label": "QTimeZone",
"purpose": "Provides support for timezone handling.", "purpose": "Provides support for time-zone handling.",
"section": "Utilities", "section": "Utilities",
"output": [ "publicFeature" ] "output": [ "publicFeature" ]
}, },
"datetimeparser": {
"label": "QDateTimeParser",
"purpose": "Provides support for parsing date-time texts.",
"section": "Utilities",
"output": [ "privateFeature" ]
},
"commandlineparser": { "commandlineparser": {
"label": "QCommandlineParser", "label": "QCommandlineParser",
"purpose": "Provides support for command line parsing.", "purpose": "Provides support for command line parsing.",

View File

@ -617,7 +617,7 @@ template<> class QTypeInfo<A> : public QTypeInfoMerger<A, B, C, D> {};
void overloadedFunction(int, QString); void overloadedFunction(int, QString);
void overloadedFunction(int, QString) const; void overloadedFunction(int, QString) const;
}; };
... qConstOverload<>(&Foo::overloadedFunction) ... qConstOverload<int, QString>(&Foo::overloadedFunction)
... qNonConstOverload<int, QString>(&Foo::overloadedFunction) ... qNonConstOverload<int, QString>(&Foo::overloadedFunction)
//! [54] //! [54]

View File

@ -66,8 +66,7 @@
#define QT_NO_USING_NAMESPACE #define QT_NO_USING_NAMESPACE
#define QT_NO_DEPRECATED #define QT_NO_DEPRECATED
#define QT_CRYPTOGRAPHICHASH_ONLY_SHA1 // Keep feature-test macros in alphabetic order by feature name:
#define QT_NO_DATASTREAM
#define QT_FEATURE_alloca 1 #define QT_FEATURE_alloca 1
#define QT_FEATURE_alloca_h -1 #define QT_FEATURE_alloca_h -1
#ifdef _WIN32 #ifdef _WIN32
@ -75,9 +74,13 @@
#else #else
# define QT_FEATURE_alloca_malloc_h -1 # define QT_FEATURE_alloca_malloc_h -1
#endif #endif
#define QT_CRYPTOGRAPHICHASH_ONLY_SHA1
#define QT_FEATURE_cxx11_random (QT_HAS_INCLUDE(<random>) ? 1 : -1) #define QT_FEATURE_cxx11_random (QT_HAS_INCLUDE(<random>) ? 1 : -1)
#define QT_NO_DATASTREAM
#define QT_FEATURE_datetimeparser -1
#define QT_FEATURE_getauxval (QT_HAS_INCLUDE(<sys/auxv.h>) ? 1 : -1) #define QT_FEATURE_getauxval (QT_HAS_INCLUDE(<sys/auxv.h>) ? 1 : -1)
#define QT_FEATURE_getentropy -1 #define QT_FEATURE_getentropy -1
#define QT_NO_GEOM_VARIANT
#define QT_FEATURE_iconv -1 #define QT_FEATURE_iconv -1
#define QT_FEATURE_icu -1 #define QT_FEATURE_icu -1
#define QT_FEATURE_journald -1 #define QT_FEATURE_journald -1
@ -86,20 +89,19 @@
#define QT_FEATURE_library -1 #define QT_FEATURE_library -1
#define QT_NO_QOBJECT #define QT_NO_QOBJECT
#define QT_FEATURE_process -1 #define QT_FEATURE_process -1
#define QT_NO_SYSTEMLOCALE
#define QT_FEATURE_renameat2 -1 #define QT_FEATURE_renameat2 -1
#define QT_FEATURE_sharedmemory -1
#define QT_FEATURE_slog2 -1 #define QT_FEATURE_slog2 -1
#define QT_FEATURE_statx -1 #define QT_FEATURE_statx -1
#define QT_FEATURE_syslog -1 #define QT_FEATURE_syslog -1
#define QT_NO_SYSTEMLOCALE
#define QT_FEATURE_systemsemaphore -1
#define QT_FEATURE_temporaryfile 1 #define QT_FEATURE_temporaryfile 1
#define QT_NO_THREAD #define QT_NO_THREAD
#define QT_FEATURE_timezone -1 #define QT_FEATURE_timezone -1
#define QT_FEATURE_topleveldomain -1 #define QT_FEATURE_topleveldomain -1
#define QT_NO_TRANSLATION #define QT_NO_TRANSLATION
#define QT_FEATURE_translation -1 #define QT_FEATURE_translation -1
#define QT_NO_GEOM_VARIANT
#define QT_FEATURE_sharedmemory -1
#define QT_FEATURE_systemsemaphore -1
#ifdef QT_BUILD_QMAKE #ifdef QT_BUILD_QMAKE
#define QT_FEATURE_commandlineparser -1 #define QT_FEATURE_commandlineparser -1

View File

@ -357,7 +357,7 @@ typedef double qreal;
#if !defined(QT_NAMESPACE) && defined(__cplusplus) && !defined(Q_QDOC) #if !defined(QT_NAMESPACE) && defined(__cplusplus) && !defined(Q_QDOC)
extern "C" extern "C"
#endif #endif
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION const char *qVersion() Q_DECL_NOTHROW; Q_CORE_EXPORT Q_DECL_CONST_FUNCTION const char *qVersion(void) Q_DECL_NOTHROW;
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -254,7 +254,9 @@ void QCryptographicHashPrivate::sha3Finish(int bitCount, Sha3Variant sha3Variant
\note In Qt versions before 5.9, when asked to generate a SHA3 hash sum, \note In Qt versions before 5.9, when asked to generate a SHA3 hash sum,
QCryptographicHash actually calculated Keccak. If you need compatibility with QCryptographicHash actually calculated Keccak. If you need compatibility with
SHA-3 hashes produced by those versions of Qt, use the \c{Keccak_} enumerators. SHA-3 hashes produced by those versions of Qt, use the \c{Keccak_}
enumerators. Alternatively, if source compatibility is required, define the
macro \c QT_SHA3_KECCAK_COMPAT.
\value Md4 Generate an MD4 hash sum \value Md4 Generate an MD4 hash sum
\value Md5 Generate an MD5 hash sum \value Md5 Generate an MD5 hash sum
@ -267,10 +269,14 @@ void QCryptographicHashPrivate::sha3Finish(int bitCount, Sha3Variant sha3Variant
\value Sha3_256 Generate an SHA3-256 hash sum. Introduced in Qt 5.1 \value Sha3_256 Generate an SHA3-256 hash sum. Introduced in Qt 5.1
\value Sha3_384 Generate an SHA3-384 hash sum. Introduced in Qt 5.1 \value Sha3_384 Generate an SHA3-384 hash sum. Introduced in Qt 5.1
\value Sha3_512 Generate an SHA3-512 hash sum. Introduced in Qt 5.1 \value Sha3_512 Generate an SHA3-512 hash sum. Introduced in Qt 5.1
\value Keccak_224 \deprecated Generate a Keccak-224 hash sum. Introduced in Qt 5.10 \value Keccak_224 Generate a Keccak-224 hash sum. Introduced in Qt 5.9.2
\value Keccak_256 \deprecated Generate a Keccak-256 hash sum. Introduced in Qt 5.10 \value Keccak_256 Generate a Keccak-256 hash sum. Introduced in Qt 5.9.2
\value Keccak_384 \deprecated Generate a Keccak-384 hash sum. Introduced in Qt 5.10 \value Keccak_384 Generate a Keccak-384 hash sum. Introduced in Qt 5.9.2
\value Keccak_512 \deprecated Generate a Keccak-512 hash sum. Introduced in Qt 5.10 \value Keccak_512 Generate a Keccak-512 hash sum. Introduced in Qt 5.9.2
\omitvalue RealSha3_224
\omitvalue RealSha3_256
\omitvalue RealSha3_384
\omitvalue RealSha3_512
*/ */
/*! /*!
@ -324,19 +330,19 @@ void QCryptographicHash::reset()
case Sha512: case Sha512:
SHA512Reset(&d->sha512Context); SHA512Reset(&d->sha512Context);
break; break;
case Sha3_224: case RealSha3_224:
case Keccak_224: case Keccak_224:
sha3Init(&d->sha3Context, 224); sha3Init(&d->sha3Context, 224);
break; break;
case Sha3_256: case RealSha3_256:
case Keccak_256: case Keccak_256:
sha3Init(&d->sha3Context, 256); sha3Init(&d->sha3Context, 256);
break; break;
case Sha3_384: case RealSha3_384:
case Keccak_384: case Keccak_384:
sha3Init(&d->sha3Context, 384); sha3Init(&d->sha3Context, 384);
break; break;
case Sha3_512: case RealSha3_512:
case Keccak_512: case Keccak_512:
sha3Init(&d->sha3Context, 512); sha3Init(&d->sha3Context, 512);
break; break;
@ -379,19 +385,19 @@ void QCryptographicHash::addData(const char *data, int length)
case Sha512: case Sha512:
SHA512Input(&d->sha512Context, reinterpret_cast<const unsigned char *>(data), length); SHA512Input(&d->sha512Context, reinterpret_cast<const unsigned char *>(data), length);
break; break;
case Sha3_224: case RealSha3_224:
case Keccak_224: case Keccak_224:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8);
break; break;
case Sha3_256: case RealSha3_256:
case Keccak_256: case Keccak_256:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8);
break; break;
case Sha3_384: case RealSha3_384:
case Keccak_384: case Keccak_384:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8);
break; break;
case Sha3_512: case RealSha3_512:
case Keccak_512: case Keccak_512:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8);
break; break;
@ -491,19 +497,19 @@ QByteArray QCryptographicHash::result() const
SHA512Result(&copy, reinterpret_cast<unsigned char *>(d->result.data())); SHA512Result(&copy, reinterpret_cast<unsigned char *>(d->result.data()));
break; break;
} }
case Sha3_224: { case RealSha3_224: {
d->sha3Finish(224, QCryptographicHashPrivate::Sha3Variant::Sha3); d->sha3Finish(224, QCryptographicHashPrivate::Sha3Variant::Sha3);
break; break;
} }
case Sha3_256: { case RealSha3_256: {
d->sha3Finish(256, QCryptographicHashPrivate::Sha3Variant::Sha3); d->sha3Finish(256, QCryptographicHashPrivate::Sha3Variant::Sha3);
break; break;
} }
case Sha3_384: { case RealSha3_384: {
d->sha3Finish(384, QCryptographicHashPrivate::Sha3Variant::Sha3); d->sha3Finish(384, QCryptographicHashPrivate::Sha3Variant::Sha3);
break; break;
} }
case Sha3_512: { case RealSha3_512: {
d->sha3Finish(512, QCryptographicHashPrivate::Sha3Variant::Sha3); d->sha3Finish(512, QCryptographicHashPrivate::Sha3Variant::Sha3);
break; break;
} }

View File

@ -65,15 +65,26 @@ public:
Sha256, Sha256,
Sha384, Sha384,
Sha512, Sha512,
Sha3_224,
Sha3_256, Keccak_224 = 7,
Sha3_384,
Sha3_512,
// ### Qt 6: remove the Keccak enumerators
Keccak_224,
Keccak_256, Keccak_256,
Keccak_384, Keccak_384,
Keccak_512 Keccak_512,
RealSha3_224 = 11,
RealSha3_256,
RealSha3_384,
RealSha3_512,
# ifndef QT_SHA3_KECCAK_COMPAT
Sha3_224 = RealSha3_224,
Sha3_256 = RealSha3_256,
Sha3_384 = RealSha3_384,
Sha3_512 = RealSha3_512
# else
Sha3_224 = Keccak_224,
Sha3_256 = Keccak_256,
Sha3_384 = Keccak_384,
Sha3_512 = Keccak_512
# endif
#endif #endif
}; };
Q_ENUM(Algorithm) Q_ENUM(Algorithm)

View File

@ -40,7 +40,9 @@
#include "qplatformdefs.h" #include "qplatformdefs.h"
#include "private/qdatetime_p.h" #include "private/qdatetime_p.h"
#if QT_CONFIG(datetimeparser)
#include "private/qdatetimeparser_p.h" #include "private/qdatetimeparser_p.h"
#endif
#include "qdatastream.h" #include "qdatastream.h"
#include "qset.h" #include "qset.h"
@ -1337,7 +1339,7 @@ QDate QDate::fromString(const QString& string, Qt::DateFormat format)
QDate QDate::fromString(const QString &string, const QString &format) QDate QDate::fromString(const QString &string, const QString &format)
{ {
QDate date; QDate date;
#if QT_CONFIG(timezone) #if QT_CONFIG(datetimeparser)
QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString); QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
// dt.setDefaultLocale(QLocale::c()); ### Qt 6 // dt.setDefaultLocale(QLocale::c()); ### Qt 6
if (dt.parseFormat(format)) if (dt.parseFormat(format))
@ -2055,7 +2057,7 @@ QTime QTime::fromString(const QString& string, Qt::DateFormat format)
QTime QTime::fromString(const QString &string, const QString &format) QTime QTime::fromString(const QString &string, const QString &format)
{ {
QTime time; QTime time;
#if QT_CONFIG(timezone) #if QT_CONFIG(datetimeparser)
QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString); QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
// dt.setDefaultLocale(QLocale::c()); ### Qt 6 // dt.setDefaultLocale(QLocale::c()); ### Qt 6
if (dt.parseFormat(format)) if (dt.parseFormat(format))
@ -5055,7 +5057,7 @@ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format)
QDateTime QDateTime::fromString(const QString &string, const QString &format) QDateTime QDateTime::fromString(const QString &string, const QString &format)
{ {
#if QT_CONFIG(timezone) #if QT_CONFIG(datetimeparser)
QTime time; QTime time;
QDate date; QDate date;

View File

@ -59,8 +59,6 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifndef QT_BOOTSTRAPPED
QDateTimeParser::~QDateTimeParser() QDateTimeParser::~QDateTimeParser()
{ {
} }
@ -1996,6 +1994,4 @@ bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::S
return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count); return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count);
} }
#endif // QT_BOOTSTRAPPED
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -63,6 +63,8 @@
#include "QtCore/qvector.h" #include "QtCore/qvector.h"
#include "QtCore/qcoreapplication.h" #include "QtCore/qcoreapplication.h"
QT_REQUIRE_CONFIG(datetimeparser);
#define QDATETIMEEDIT_TIME_MIN QTime(0, 0, 0, 0) #define QDATETIMEEDIT_TIME_MIN QTime(0, 0, 0, 0)
#define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999) #define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999)
#define QDATETIMEEDIT_DATE_MIN QDate(100, 1, 1) #define QDATETIMEEDIT_DATE_MIN QDate(100, 1, 1)
@ -75,8 +77,6 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifndef QT_BOOTSTRAPPED
class Q_CORE_EXPORT QDateTimeParser class Q_CORE_EXPORT QDateTimeParser
{ {
Q_DECLARE_TR_FUNCTIONS(QDateTimeParser) Q_DECLARE_TR_FUNCTIONS(QDateTimeParser)
@ -305,8 +305,6 @@ Q_CORE_EXPORT bool operator==(const QDateTimeParser::SectionNode &s1, const QDat
Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::Sections) Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::Sections)
Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::FieldInfo) Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::FieldInfo)
#endif // QT_BOOTSTRAPPED
QT_END_NAMESPACE QT_END_NAMESPACE
#endif // QDATETIME_P_H #endif // QDATETIME_P_H

View File

@ -54,7 +54,9 @@
#include "qlocale.h" #include "qlocale.h"
#include "qlocale_p.h" #include "qlocale_p.h"
#include "qlocale_tools_p.h" #include "qlocale_tools_p.h"
#if QT_CONFIG(datetimeparser)
#include "qdatetimeparser_p.h" #include "qdatetimeparser_p.h"
#endif
#include "qnamespace.h" #include "qnamespace.h"
#include "qdatetime.h" #include "qdatetime.h"
#include "qstringlist.h" #include "qstringlist.h"
@ -2084,7 +2086,7 @@ QDateTime QLocale::toDateTime(const QString &string, FormatType format) const
QTime QLocale::toTime(const QString &string, const QString &format) const QTime QLocale::toTime(const QString &string, const QString &format) const
{ {
QTime time; QTime time;
#ifndef QT_BOOTSTRAPPED #if QT_CONFIG(datetimeparser)
QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString); QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
dt.setDefaultLocale(*this); dt.setDefaultLocale(*this);
if (dt.parseFormat(format)) if (dt.parseFormat(format))
@ -2115,7 +2117,7 @@ QTime QLocale::toTime(const QString &string, const QString &format) const
QDate QLocale::toDate(const QString &string, const QString &format) const QDate QLocale::toDate(const QString &string, const QString &format) const
{ {
QDate date; QDate date;
#ifndef QT_BOOTSTRAPPED #if QT_CONFIG(datetimeparser)
QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString); QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
dt.setDefaultLocale(*this); dt.setDefaultLocale(*this);
if (dt.parseFormat(format)) if (dt.parseFormat(format))
@ -2145,7 +2147,7 @@ QDate QLocale::toDate(const QString &string, const QString &format) const
#ifndef QT_NO_DATESTRING #ifndef QT_NO_DATESTRING
QDateTime QLocale::toDateTime(const QString &string, const QString &format) const QDateTime QLocale::toDateTime(const QString &string, const QString &format) const
{ {
#ifndef QT_BOOTSTRAPPED #if QT_CONFIG(datetimeparser)
QTime time; QTime time;
QDate date; QDate date;

View File

@ -99,16 +99,16 @@ static int qt_hash_block_size(QCryptographicHash::Algorithm method)
return SHA384_Message_Block_Size; return SHA384_Message_Block_Size;
case QCryptographicHash::Sha512: case QCryptographicHash::Sha512:
return SHA512_Message_Block_Size; return SHA512_Message_Block_Size;
case QCryptographicHash::Sha3_224: case QCryptographicHash::RealSha3_224:
case QCryptographicHash::Keccak_224: case QCryptographicHash::Keccak_224:
return 144; return 144;
case QCryptographicHash::Sha3_256: case QCryptographicHash::RealSha3_256:
case QCryptographicHash::Keccak_256: case QCryptographicHash::Keccak_256:
return 136; return 136;
case QCryptographicHash::Sha3_384: case QCryptographicHash::RealSha3_384:
case QCryptographicHash::Keccak_384: case QCryptographicHash::Keccak_384:
return 104; return 104;
case QCryptographicHash::Sha3_512: case QCryptographicHash::RealSha3_512:
case QCryptographicHash::Keccak_512: case QCryptographicHash::Keccak_512:
return 72; return 72;
} }

View File

@ -340,13 +340,14 @@ Q_INLINE_TEMPLATE bool QSet<T>::intersects(const QSet<T> &other) const
template <class T> template <class T>
Q_INLINE_TEMPLATE QSet<T> &QSet<T>::subtract(const QSet<T> &other) Q_INLINE_TEMPLATE QSet<T> &QSet<T>::subtract(const QSet<T> &other)
{ {
QSet<T> copy1(*this); if (&other == this) {
QSet<T> copy2(other); clear();
typename QSet<T>::const_iterator i = copy1.constEnd(); } else {
while (i != copy1.constBegin()) { auto i = other.constEnd();
--i; while (i != other.constBegin()) {
if (copy2.contains(*i)) --i;
remove(*i); remove(*i);
}
} }
return *this; return *this;
} }

View File

@ -272,8 +272,9 @@ static void parseTzLeapSeconds(QDataStream &ds, int tzh_leapcnt, bool longTran)
{ {
// Parse tzh_leapcnt x pairs of leap seconds // Parse tzh_leapcnt x pairs of leap seconds
// We don't use leap seconds, so only read and don't store // We don't use leap seconds, so only read and don't store
qint64 val; qint32 val;
if (longTran) { if (longTran) {
// v2 file format, each entry is 12 bytes long
qint64 time; qint64 time;
for (int i = 0; i < tzh_leapcnt && ds.status() == QDataStream::Ok; ++i) { for (int i = 0; i < tzh_leapcnt && ds.status() == QDataStream::Ok; ++i) {
// Parse Leap Occurrence Time, 8 bytes // Parse Leap Occurrence Time, 8 bytes
@ -283,6 +284,7 @@ static void parseTzLeapSeconds(QDataStream &ds, int tzh_leapcnt, bool longTran)
ds >> val; ds >> val;
} }
} else { } else {
// v0 file format, each entry is 8 bytes long
for (int i = 0; i < tzh_leapcnt && ds.status() == QDataStream::Ok; ++i) { for (int i = 0; i < tzh_leapcnt && ds.status() == QDataStream::Ok; ++i) {
// Parse Leap Occurrence Time, 4 bytes // Parse Leap Occurrence Time, 4 bytes
ds >> val; ds >> val;

View File

@ -21,7 +21,6 @@ HEADERS += \
tools/qcryptographichash.h \ tools/qcryptographichash.h \
tools/qdatetime.h \ tools/qdatetime.h \
tools/qdatetime_p.h \ tools/qdatetime_p.h \
tools/qdatetimeparser_p.h \
tools/qdoublescanprint_p.h \ tools/qdoublescanprint_p.h \
tools/qeasingcurve.h \ tools/qeasingcurve.h \
tools/qfreelist_p.h \ tools/qfreelist_p.h \
@ -84,7 +83,6 @@ SOURCES += \
tools/qcollator.cpp \ tools/qcollator.cpp \
tools/qcryptographichash.cpp \ tools/qcryptographichash.cpp \
tools/qdatetime.cpp \ tools/qdatetime.cpp \
tools/qdatetimeparser.cpp \
tools/qeasingcurve.cpp \ tools/qeasingcurve.cpp \
tools/qfreelist.cpp \ tools/qfreelist.cpp \
tools/qhash.cpp \ tools/qhash.cpp \
@ -173,6 +171,11 @@ qtConfig(timezone) {
SOURCES += tools/qtimezoneprivate_icu.cpp SOURCES += tools/qtimezoneprivate_icu.cpp
} }
qtConfig(datetimeparser) {
HEADERS += tools/qdatetimeparser_p.h
SOURCES += tools/qdatetimeparser.cpp
}
qtConfig(regularexpression) { qtConfig(regularexpression) {
QMAKE_USE_PRIVATE += pcre2 QMAKE_USE_PRIVATE += pcre2

View File

@ -443,6 +443,7 @@
"xcb/xfixes.h", "xcb/xfixes.h",
"xcb/xcb_image.h", "xcb/xcb_image.h",
"xcb/xcb_keysyms.h", "xcb/xcb_keysyms.h",
"xcb/xinerama.h",
"xcb/sync.h", "xcb/sync.h",
"xcb/randr.h", "xcb/randr.h",
"xcb/shm.h" "xcb/shm.h"
@ -460,8 +461,8 @@
}, },
"sources": [ "sources": [
{ "type": "pkgConfig", { "type": "pkgConfig",
"args": "xcb xcb-shm xcb-sync xcb-xfixes xcb-randr xcb-image xcb-keysyms xcb-icccm xcb-shape" }, "args": "xcb xcb-shm xcb-sync xcb-xfixes xcb-xinerama xcb-randr xcb-image xcb-keysyms xcb-icccm xcb-shape" },
"-lxcb -lxcb-shm -lxcb-sync -lxcb-xfixes -lxcb-randr -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-shape" "-lxcb -lxcb-shm -lxcb-sync -lxcb-xfixes -lxcb-xinerama -lxcb-randr -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-shape"
] ]
}, },
"xcb_xlib": { "xcb_xlib": {

View File

@ -562,27 +562,12 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
} }
// this is also used in qmime_win.cpp // this is also used in qmime_win.cpp
bool qt_write_dib(QDataStream &s, QImage image) bool qt_write_dib(QDataStream &s, const QImage &image, int bpl, int bpl_bmp, int nbits)
{ {
int nbits;
int bpl_bmp;
int bpl = image.bytesPerLine();
QIODevice* d = s.device(); QIODevice* d = s.device();
if (!d->isWritable()) if (!d->isWritable())
return false; return false;
if (image.depth() == 8 && image.colorCount() <= 16) {
bpl_bmp = (((bpl+1)/2+3)/4)*4;
nbits = 4;
} else if (image.depth() == 32) {
bpl_bmp = ((image.width()*24+31)/32)*4;
nbits = 24;
} else {
bpl_bmp = bpl;
nbits = image.depth();
}
BMP_INFOHDR bi; BMP_INFOHDR bi;
bi.biSize = BMP_WIN; // build info header bi.biSize = BMP_WIN; // build info header
bi.biWidth = image.width(); bi.biWidth = image.width();
@ -617,9 +602,6 @@ bool qt_write_dib(QDataStream &s, QImage image)
delete [] color_table; delete [] color_table;
} }
if (image.format() == QImage::Format_MonoLSB)
image = image.convertToFormat(QImage::Format_Mono);
int y; int y;
if (nbits == 1 || nbits == 8) { // direct output if (nbits == 1 || nbits == 8) { // direct output
@ -769,21 +751,17 @@ bool QBmpHandler::read(QImage *image)
bool QBmpHandler::write(const QImage &img) bool QBmpHandler::write(const QImage &img)
{ {
if (m_format == DibFormat) {
QDataStream dibStream(device());
dibStream.setByteOrder(QDataStream::LittleEndian); // Intel byte order
return qt_write_dib(dibStream, img);
}
QImage image; QImage image;
switch (img.format()) { switch (img.format()) {
case QImage::Format_Mono: case QImage::Format_Mono:
case QImage::Format_MonoLSB:
case QImage::Format_Indexed8: case QImage::Format_Indexed8:
case QImage::Format_RGB32: case QImage::Format_RGB32:
case QImage::Format_ARGB32: case QImage::Format_ARGB32:
image = img; image = img;
break; break;
case QImage::Format_MonoLSB:
image = img.convertToFormat(QImage::Format_Mono);
break;
case QImage::Format_Alpha8: case QImage::Format_Alpha8:
case QImage::Format_Grayscale8: case QImage::Format_Grayscale8:
image = img.convertToFormat(QImage::Format_Indexed8); image = img.convertToFormat(QImage::Format_Indexed8);
@ -796,20 +774,31 @@ bool QBmpHandler::write(const QImage &img)
break; break;
} }
int nbits;
int bpl_bmp;
// Calculate a minimum bytes-per-line instead of using whatever value this QImage is using internally.
int bpl = ((image.width() * image.depth() + 31) >> 5) << 2;
if (image.depth() == 8 && image.colorCount() <= 16) {
bpl_bmp = (((bpl+1)/2+3)/4)*4;
nbits = 4;
} else if (image.depth() == 32) {
bpl_bmp = ((image.width()*24+31)/32)*4;
nbits = 24;
} else {
bpl_bmp = bpl;
nbits = image.depth();
}
if (m_format == DibFormat) {
QDataStream dibStream(device());
dibStream.setByteOrder(QDataStream::LittleEndian); // Intel byte order
return qt_write_dib(dibStream, img, bpl, bpl_bmp, nbits);
}
QIODevice *d = device(); QIODevice *d = device();
QDataStream s(d); QDataStream s(d);
BMP_FILEHDR bf; BMP_FILEHDR bf;
int bpl_bmp;
int bpl = image.bytesPerLine();
// Code partially repeated in qt_write_dib
if (image.depth() == 8 && image.colorCount() <= 16) {
bpl_bmp = (((bpl+1)/2+3)/4)*4;
} else if (image.depth() == 32) {
bpl_bmp = ((image.width()*24+31)/32)*4;
} else {
bpl_bmp = bpl;
}
// Intel byte order // Intel byte order
s.setByteOrder(QDataStream::LittleEndian); s.setByteOrder(QDataStream::LittleEndian);
@ -825,7 +814,7 @@ bool QBmpHandler::write(const QImage &img)
s << bf; s << bf;
// write image // write image
return qt_write_dib(s, image); return qt_write_dib(s, image, bpl, bpl_bmp, nbits);
} }
bool QBmpHandler::supportsOption(ImageOption option) const bool QBmpHandler::supportsOption(ImageOption option) const

View File

@ -1042,12 +1042,26 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader
} }
const auto httpReplyPrivate = httpReply->d_func(); const auto httpReplyPrivate = httpReply->d_func();
// For HTTP/1 'location' is handled (and redirect URL set) when a protocol
// handler emits channel->allDone(). Http/2 protocol handler never emits
// allDone, since we have many requests multiplexed in one channel at any
// moment and we are probably not done yet. So we extract url and set it
// here, if needed.
int statusCode = 0;
QUrl redirectUrl;
for (const auto &pair : headers) { for (const auto &pair : headers) {
const auto &name = pair.name; const auto &name = pair.name;
auto value = pair.value; auto value = pair.value;
// TODO: part of this code copies what SPDY protocol handler does when
// processing headers. Binary nature of HTTP/2 and SPDY saves us a lot
// of parsing and related errors/bugs, but it would be nice to have
// more detailed validation of headers.
if (name == ":status") { if (name == ":status") {
httpReply->setStatusCode(value.left(3).toInt()); statusCode = value.left(3).toInt();
httpReply->setStatusCode(statusCode);
httpReplyPrivate->reasonPhrase = QString::fromLatin1(value.mid(4)); httpReplyPrivate->reasonPhrase = QString::fromLatin1(value.mid(4));
} else if (name == ":version") { } else if (name == ":version") {
httpReplyPrivate->majorVersion = value.at(5) - '0'; httpReplyPrivate->majorVersion = value.at(5) - '0';
@ -1058,6 +1072,8 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader
if (ok) if (ok)
httpReply->setContentLength(length); httpReply->setContentLength(length);
} else { } else {
if (name == "location")
redirectUrl = QUrl::fromEncoded(value);
QByteArray binder(", "); QByteArray binder(", ");
if (name == "set-cookie") if (name == "set-cookie")
binder = "\n"; binder = "\n";
@ -1065,6 +1081,9 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader
} }
} }
if (QHttpNetworkReply::isHttpRedirect(statusCode) && redirectUrl.isValid())
httpReply->setRedirectUrl(redirectUrl);
if (connectionType == Qt::DirectConnection) if (connectionType == Qt::DirectConnection)
emit httpReply->headerChanged(); emit httpReply->headerChanged();
else else

View File

@ -75,6 +75,12 @@
#include <QHostInfo> #include <QHostInfo>
#if defined(Q_OS_MACOS)
#include <CoreServices/CoreServices.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <Security/SecKeychain.h>
#endif
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QNetworkAccessFileBackendFactory, fileBackend) Q_GLOBAL_STATIC(QNetworkAccessFileBackendFactory, fileBackend)
@ -87,11 +93,6 @@ Q_GLOBAL_STATIC(QNetworkAccessDebugPipeBackendFactory, debugpipeBackend)
#endif #endif
#if defined(Q_OS_MACX) #if defined(Q_OS_MACX)
#include <CoreServices/CoreServices.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <Security/SecKeychain.h>
bool getProxyAuth(const QString& proxyHostname, const QString &scheme, QString& username, QString& password) bool getProxyAuth(const QString& proxyHostname, const QString &scheme, QString& username, QString& password)
{ {
OSStatus err; OSStatus err;

View File

@ -1169,6 +1169,14 @@ void QNetworkReplyHttpImplPrivate::onRedirected(const QUrl &redirectUrl, int htt
redirectRequest = createRedirectRequest(originalRequest, url, maxRedirectsRemaining); redirectRequest = createRedirectRequest(originalRequest, url, maxRedirectsRemaining);
operation = getRedirectOperation(operation, httpStatus); operation = getRedirectOperation(operation, httpStatus);
if (const QNetworkCookieJar *const cookieJar = (manager ? manager->cookieJar() : nullptr)) {
auto cookies = cookieJar->cookiesForUrl(url);
if (!cookies.empty()) {
redirectRequest.setHeader(QNetworkRequest::KnownHeaders::CookieHeader,
QVariant::fromValue(cookies));
}
}
if (httpRequest.redirectPolicy() != QNetworkRequest::UserVerifiedRedirectPolicy) if (httpRequest.redirectPolicy() != QNetworkRequest::UserVerifiedRedirectPolicy)
followRedirect(); followRedirect();

View File

@ -565,7 +565,6 @@ QAbstractSocketPrivate::QAbstractSocketPrivate()
isBuffered(false), isBuffered(false),
hasPendingData(false), hasPendingData(false),
connectTimer(0), connectTimer(0),
disconnectTimer(0),
hostLookupId(-1), hostLookupId(-1),
socketType(QAbstractSocket::UnknownSocketType), socketType(QAbstractSocket::UnknownSocketType),
state(QAbstractSocket::UnconnectedState), state(QAbstractSocket::UnconnectedState),
@ -604,8 +603,6 @@ void QAbstractSocketPrivate::resetSocketLayer()
} }
if (connectTimer) if (connectTimer)
connectTimer->stop(); connectTimer->stop();
if (disconnectTimer)
disconnectTimer->stop();
} }
/*! \internal /*! \internal
@ -967,13 +964,17 @@ void QAbstractSocketPrivate::startConnectingByName(const QString &host)
emit q->stateChanged(state); emit q->stateChanged(state);
if (cachedSocketDescriptor != -1 || initSocketLayer(QAbstractSocket::UnknownNetworkLayerProtocol)) { if (cachedSocketDescriptor != -1 || initSocketLayer(QAbstractSocket::UnknownNetworkLayerProtocol)) {
if (socketEngine->connectToHostByName(host, port) || // Try to connect to the host. If it succeeds immediately
socketEngine->state() == QAbstractSocket::ConnectingState) { // (e.g. QSocks5SocketEngine in UDPASSOCIATE mode), emit
cachedSocketDescriptor = socketEngine->socketDescriptor(); // connected() and return.
if (socketEngine->connectToHostByName(host, port)) {
fetchConnectionParameters();
return; return;
} }
if (socketEngine->state() == QAbstractSocket::ConnectingState)
return;
// failed to connect // failed to connect
setError(socketEngine->error(), socketEngine->errorString()); setError(socketEngine->error(), socketEngine->errorString());
} }
@ -1220,15 +1221,6 @@ void QAbstractSocketPrivate::_q_abortConnectionAttempt()
} }
} }
void QAbstractSocketPrivate::_q_forceDisconnect()
{
Q_Q(QAbstractSocket);
if (socketEngine && socketEngine->isValid() && state == QAbstractSocket::ClosingState) {
socketEngine->close();
q->disconnectFromHost();
}
}
/*! \internal /*! \internal
Reads data from the socket layer into the read buffer. Returns Reads data from the socket layer into the read buffer. Returns
@ -2756,20 +2748,6 @@ void QAbstractSocket::disconnectFromHost()
// Wait for pending data to be written. // Wait for pending data to be written.
if (d->socketEngine && d->socketEngine->isValid() && (!d->allWriteBuffersEmpty() if (d->socketEngine && d->socketEngine->isValid() && (!d->allWriteBuffersEmpty()
|| d->socketEngine->bytesToWrite() > 0)) { || d->socketEngine->bytesToWrite() > 0)) {
// hack: when we are waiting for the socket engine to write bytes (only
// possible when using Socks5 or HTTP socket engine), then close
// anyway after 2 seconds. This is to prevent a timeout on Mac, where we
// sometimes just did not get the write notifier from the underlying
// CFSocket and no progress was made.
if (d->allWriteBuffersEmpty() && d->socketEngine->bytesToWrite() > 0) {
if (!d->disconnectTimer) {
d->disconnectTimer = new QTimer(this);
connect(d->disconnectTimer, SIGNAL(timeout()), this,
SLOT(_q_forceDisconnect()), Qt::DirectConnection);
}
if (!d->disconnectTimer->isActive())
d->disconnectTimer->start(2000);
}
d->socketEngine->setWriteNotificationEnabled(true); d->socketEngine->setWriteNotificationEnabled(true);
#if defined(QABSTRACTSOCKET_DEBUG) #if defined(QABSTRACTSOCKET_DEBUG)

View File

@ -231,7 +231,6 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_startConnecting(const QHostInfo &)) Q_PRIVATE_SLOT(d_func(), void _q_startConnecting(const QHostInfo &))
Q_PRIVATE_SLOT(d_func(), void _q_abortConnectionAttempt()) Q_PRIVATE_SLOT(d_func(), void _q_abortConnectionAttempt())
Q_PRIVATE_SLOT(d_func(), void _q_testConnection()) Q_PRIVATE_SLOT(d_func(), void _q_testConnection())
Q_PRIVATE_SLOT(d_func(), void _q_forceDisconnect())
}; };

View File

@ -95,7 +95,6 @@ public:
void _q_startConnecting(const QHostInfo &hostInfo); void _q_startConnecting(const QHostInfo &hostInfo);
void _q_testConnection(); void _q_testConnection();
void _q_abortConnectionAttempt(); void _q_abortConnectionAttempt();
void _q_forceDisconnect();
bool emittedReadyRead; bool emittedReadyRead;
bool emittedBytesWritten; bool emittedBytesWritten;
@ -148,7 +147,6 @@ public:
bool hasPendingData; bool hasPendingData;
QTimer *connectTimer; QTimer *connectTimer;
QTimer *disconnectTimer;
int hostLookupId; int hostLookupId;

View File

@ -172,7 +172,8 @@ bool QXcbSoftwareOpenGLEnforcer::forceSoftwareOpenGL = false;
template <class T> template <class T>
struct QXlibScopedPointerDeleter { struct QXlibScopedPointerDeleter {
static inline void cleanup(T *pointer) { static inline void cleanup(T *pointer) {
XFree(pointer); if (pointer)
XFree(pointer);
} }
}; };
@ -217,6 +218,8 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format
} }
QXlibPointer<XVisualInfo> visual(glXGetVisualFromFBConfig(display, candidate)); QXlibPointer<XVisualInfo> visual(glXGetVisualFromFBConfig(display, candidate));
if (visual.isNull())
continue;
const int actualRed = qPopulationCount(visual->red_mask); const int actualRed = qPopulationCount(visual->red_mask);
const int actualGreen = qPopulationCount(visual->green_mask); const int actualGreen = qPopulationCount(visual->green_mask);

View File

@ -55,6 +55,8 @@
#include <linux/input.h> #include <linux/input.h>
#endif #endif
#include <math.h>
#if QT_CONFIG(mtdev) #if QT_CONFIG(mtdev)
extern "C" { extern "C" {
#include <mtdev.h> #include <mtdev.h>

View File

@ -508,7 +508,7 @@ void QKmsDevice::createScreens()
} else { } else {
virtualPos = orderedScreen.vinfo.virtualPos; virtualPos = orderedScreen.vinfo.virtualPos;
} }
qCDebug(qLcKmsDebug) << "Adding QPlatformScren" << s << "(" << s->name() << ")" qCDebug(qLcKmsDebug) << "Adding QPlatformScreen" << s << "(" << s->name() << ")"
<< "to QPA with geometry" << s->geometry() << "to QPA with geometry" << s->geometry()
<< "and isPrimary=" << orderedScreen.vinfo.isPrimary; << "and isPrimary=" << orderedScreen.vinfo.isPrimary;
// The order in qguiapp's screens list will match the order set by // The order in qguiapp's screens list will match the order set by

View File

@ -1374,6 +1374,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
if (m_composingText.isEmpty()) { if (m_composingText.isEmpty()) {
m_sendKeyEvent = !QWindowSystemInterface::handleShortcutEvent(window, timestamp, keyCode, m_sendKeyEvent = !QWindowSystemInterface::handleShortcutEvent(window, timestamp, keyCode,
modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1); modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1);
// Handling a shortcut may result in closing the window
if (!m_platformWindow)
return true;
} }
QObject *fo = m_platformWindow->window()->focusObject(); QObject *fo = m_platformWindow->window()->focusObject();

View File

@ -101,6 +101,8 @@ enum WindowsEventType // Simplify event types
FocusOutEvent = WindowEventFlag + 18, FocusOutEvent = WindowEventFlag + 18,
WhatsThisEvent = WindowEventFlag + 19, WhatsThisEvent = WindowEventFlag + 19,
DpiChangedEvent = WindowEventFlag + 21, DpiChangedEvent = WindowEventFlag + 21,
EnterSizeMoveEvent = WindowEventFlag + 22,
ExitSizeMoveEvent = WindowEventFlag + 23,
MouseEvent = MouseEventFlag + 1, MouseEvent = MouseEventFlag + 1,
MouseWheelEvent = MouseEventFlag + 2, MouseWheelEvent = MouseEventFlag + 2,
CursorEvent = MouseEventFlag + 3, CursorEvent = MouseEventFlag + 3,
@ -282,6 +284,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
return HIWORD(wParamIn) ? QtWindows::AcceleratorCommandEvent : QtWindows::MenuCommandEvent; return HIWORD(wParamIn) ? QtWindows::AcceleratorCommandEvent : QtWindows::MenuCommandEvent;
case WM_DPICHANGED: case WM_DPICHANGED:
return QtWindows::DpiChangedEvent; return QtWindows::DpiChangedEvent;
case WM_ENTERSIZEMOVE:
return QtWindows::EnterSizeMoveEvent;
case WM_EXITSIZEMOVE:
return QtWindows::ExitSizeMoveEvent;
default: default:
break; break;
} }

View File

@ -1081,6 +1081,13 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
if (platformWindow->frameStrutEventsEnabled()) if (platformWindow->frameStrutEventsEnabled())
return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
break; break;
case QtWindows::EnterSizeMoveEvent:
platformWindow->setFlag(QWindowsWindow::ResizeMoveActive);
return true;
case QtWindows::ExitSizeMoveEvent:
platformWindow->clearFlag(QWindowsWindow::ResizeMoveActive);
platformWindow->checkForScreenChanged();
return true;
case QtWindows::ScrollEvent: case QtWindows::ScrollEvent:
return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result); return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result);
case QtWindows::MouseWheelEvent: case QtWindows::MouseWheelEvent:

View File

@ -233,6 +233,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
// Check for events synthesized from touch. Lower 7 bits are touch/pen index, bit 8 indicates touch. // Check for events synthesized from touch. Lower 7 bits are touch/pen index, bit 8 indicates touch.
// However, when tablet support is active, extraInfo is a packet serial number. This is not a problem // However, when tablet support is active, extraInfo is a packet serial number. This is not a problem
// since we do not want to ignore mouse events coming from a tablet. // since we do not want to ignore mouse events coming from a tablet.
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms703320.aspx
const quint64 extraInfo = quint64(GetMessageExtraInfo()); const quint64 extraInfo = quint64(GetMessageExtraInfo());
if ((extraInfo & signatureMask) == miWpSignature) { if ((extraInfo & signatureMask) == miWpSignature) {
if (extraInfo & 0x80) { // Bit 7 indicates touch event, else tablet pen. if (extraInfo & 0x80) { // Bit 7 indicates touch event, else tablet pen.

View File

@ -566,4 +566,19 @@ const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const
return Q_NULLPTR; return Q_NULLPTR;
} }
const QWindowsScreen *QWindowsScreenManager::screenForHwnd(HWND hwnd) const
{
HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
if (hMonitor == NULL)
return nullptr;
const auto it =
std::find_if(m_screens.cbegin(), m_screens.cend(),
[hMonitor](const QWindowsScreen *s)
{
return s->data().hMonitor == hMonitor
&& (s->data().flags & QWindowsScreenData::VirtualDesktop) != 0;
});
return it != m_screens.cend() ? *it : nullptr;
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -134,6 +134,7 @@ public:
const WindowsScreenList &screens() const { return m_screens; } const WindowsScreenList &screens() const { return m_screens; }
const QWindowsScreen *screenAtDp(const QPoint &p) const; const QWindowsScreen *screenAtDp(const QPoint &p) const;
const QWindowsScreen *screenForHwnd(HWND hwnd) const;
private: private:
void removeScreen(int index); void removeScreen(int index);

View File

@ -896,7 +896,9 @@ void QWindowsBaseWindow::hide_sys() // Normal hide, do not activate other window
void QWindowsBaseWindow::raise_sys() void QWindowsBaseWindow::raise_sys()
{ {
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window(); qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
if (window()->type() == Qt::Popup const Qt::WindowType type = window()->type();
if (type == Qt::Popup
|| type == Qt::SubWindow // Special case for QTBUG-63121: MDI subwindows with WindowStaysOnTopHint
|| (window()->flags() & (Qt::WindowStaysOnTopHint | Qt::WindowStaysOnBottomHint)) == 0) { || (window()->flags() & (Qt::WindowStaysOnTopHint | Qt::WindowStaysOnBottomHint)) == 0) {
SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
} }
@ -1629,6 +1631,26 @@ void QWindowsWindow::handleResized(int wParam)
} }
} }
void QWindowsWindow::checkForScreenChanged()
{
if (parent())
return;
QPlatformScreen *currentScreen = screen();
const auto &screenManager = QWindowsContext::instance()->screenManager();
// QTBUG-62971: When dragging a window by its border, detect by mouse position
// to prevent it from oscillating between screens when it resizes
const QWindowsScreen *newScreen = testFlag(ResizeMoveActive)
? screenManager.screenAtDp(QWindowsCursor::mousePosition())
: screenManager.screenForHwnd(m_data.hwnd);
if (newScreen != nullptr && newScreen != currentScreen) {
qCDebug(lcQpaWindows).noquote().nospace() << __FUNCTION__
<< ' ' << window() << " \"" << currentScreen->name()
<< "\"->\"" << newScreen->name() << '"';
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
}
}
void QWindowsWindow::handleGeometryChange() void QWindowsWindow::handleGeometryChange()
{ {
const QRect previousGeometry = m_data.geometry; const QRect previousGeometry = m_data.geometry;
@ -1642,17 +1664,9 @@ void QWindowsWindow::handleGeometryChange()
&& !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) { && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true); fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true);
} }
if (!parent() && previousGeometry.topLeft() != m_data.geometry.topLeft()) {
HMONITOR hMonitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONULL); checkForScreenChanged();
QPlatformScreen *currentScreen = screen();
const auto screens = QWindowsContext::instance()->screenManager().screens();
auto newScreenIt = std::find_if(screens.begin(), screens.end(), [&](QWindowsScreen *s) {
return s->data().hMonitor == hMonitor
&& s->data().flags & QWindowsScreenData::VirtualDesktop;
});
if (newScreenIt != screens.end() && *newScreenIt != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), (*newScreenIt)->screen());
}
if (testFlag(SynchronousGeometryChangeEvent)) if (testFlag(SynchronousGeometryChangeEvent))
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);

View File

@ -217,7 +217,8 @@ public:
Compositing = 0x200000, Compositing = 0x200000,
HasBorderInFullScreen = 0x400000, HasBorderInFullScreen = 0x400000,
WithinDpiChanged = 0x800000, WithinDpiChanged = 0x800000,
VulkanSurface = 0x1000000 VulkanSurface = 0x1000000,
ResizeMoveActive = 0x2000000
}; };
QWindowsWindow(QWindow *window, const QWindowsWindowData &data); QWindowsWindow(QWindow *window, const QWindowsWindowData &data);
@ -328,6 +329,8 @@ public:
void alertWindow(int durationMs = 0); void alertWindow(int durationMs = 0);
void stopAlertWindow(); void stopAlertWindow();
void checkForScreenChanged();
static void setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes); static void setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes);
void registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes = QWindowsWindowFunctions::NormalTouch); void registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes = QWindowsWindowFunctions::NormalTouch);
static void setHasBorderInFullScreenStatic(QWindow *window, bool border); static void setHasBorderInFullScreenStatic(QWindow *window, bool border);

View File

@ -83,7 +83,6 @@ qtConfig(vulkan) {
!qtConfig(system-xcb) { !qtConfig(system-xcb) {
QMAKE_USE += xcb-static xcb QMAKE_USE += xcb-static xcb
} else { } else {
LIBS += -lxcb-xinerama ### there is no configure test for this!
qtConfig(xkb): QMAKE_USE += xcb_xkb qtConfig(xkb): QMAKE_USE += xcb_xkb
qtConfig(xcb-render): QMAKE_USE += xcb_render qtConfig(xcb-render): QMAKE_USE += xcb_render
QMAKE_USE += xcb_syslibs QMAKE_USE += xcb_syslibs

View File

@ -1159,16 +1159,22 @@ static void qLibraryInit()
} }
# endif // MYSQL_VERSION_ID # endif // MYSQL_VERSION_ID
#endif // Q_NO_MYSQL_EMBEDDED #endif // Q_NO_MYSQL_EMBEDDED
#ifdef MARIADB_BASE_VERSION
qAddPostRoutine(mysql_server_end);
#endif
} }
static void qLibraryEnd() static void qLibraryEnd()
{ {
#ifndef Q_NO_MYSQL_EMBEDDED #if !defined(MARIADB_BASE_VERSION)
# if MYSQL_VERSION_ID > 40000 # if !defined(Q_NO_MYSQL_EMBEDDED)
# if (MYSQL_VERSION_ID >= 40110 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50003 # if MYSQL_VERSION_ID > 40000
mysql_library_end(); # if (MYSQL_VERSION_ID >= 40110 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50003
# else mysql_library_end();
mysql_server_end(); # else
mysql_server_end();
# endif
# endif # endif
# endif # endif
#endif #endif

View File

@ -206,6 +206,7 @@ protected:
QVariant lastInsertId() const Q_DECL_OVERRIDE; QVariant lastInsertId() const Q_DECL_OVERRIDE;
bool execBatch(bool arrayBind = false) Q_DECL_OVERRIDE; bool execBatch(bool arrayBind = false) Q_DECL_OVERRIDE;
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE; void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
bool fetchNext() override;
}; };
class QOCIResultPrivate: public QSqlCachedResultPrivate class QOCIResultPrivate: public QSqlCachedResultPrivate
@ -2097,6 +2098,14 @@ void QOCIResult::virtual_hook(int id, void *data)
QSqlCachedResult::virtual_hook(id, data); QSqlCachedResult::virtual_hook(id, data);
} }
bool QOCIResult::fetchNext()
{
Q_D(QOCIResult);
if (isForwardOnly())
d->cache.clear();
return QSqlCachedResult::fetchNext();
}
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////

View File

@ -562,14 +562,14 @@ void Generator::generateCode()
fprintf(out, "\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->qualified.constData()); fprintf(out, "\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->qualified.constData());
fprintf(out, " if (!_clname) return nullptr;\n"); fprintf(out, " if (!_clname) return nullptr;\n");
fprintf(out, " if (!strcmp(_clname, qt_meta_stringdata_%s.stringdata0))\n" fprintf(out, " if (!strcmp(_clname, qt_meta_stringdata_%s.stringdata0))\n"
" return static_cast<void*>(const_cast< %s*>(this));\n", " return static_cast<void*>(this);\n",
qualifiedClassNameIdentifier.constData(), cdef->classname.constData()); qualifiedClassNameIdentifier.constData());
for (int i = 1; i < cdef->superclassList.size(); ++i) { // for all superclasses but the first one for (int i = 1; i < cdef->superclassList.size(); ++i) { // for all superclasses but the first one
if (cdef->superclassList.at(i).second == FunctionDef::Private) if (cdef->superclassList.at(i).second == FunctionDef::Private)
continue; continue;
const char *cname = cdef->superclassList.at(i).first.constData(); const char *cname = cdef->superclassList.at(i).first.constData();
fprintf(out, " if (!strcmp(_clname, \"%s\"))\n return static_cast< %s*>(const_cast< %s*>(this));\n", fprintf(out, " if (!strcmp(_clname, \"%s\"))\n return static_cast< %s*>(this);\n",
cname, cname, cdef->classname.constData()); cname, cname);
} }
for (int i = 0; i < cdef->interfaceList.size(); ++i) { for (int i = 0; i < cdef->interfaceList.size(); ++i) {
const QVector<ClassDef::Interface> &iface = cdef->interfaceList.at(i); const QVector<ClassDef::Interface> &iface = cdef->interfaceList.at(i);
@ -577,8 +577,7 @@ void Generator::generateCode()
fprintf(out, " if (!strcmp(_clname, %s))\n return ", iface.at(j).interfaceId.constData()); fprintf(out, " if (!strcmp(_clname, %s))\n return ", iface.at(j).interfaceId.constData());
for (int k = j; k >= 0; --k) for (int k = j; k >= 0; --k)
fprintf(out, "static_cast< %s*>(", iface.at(k).className.constData()); fprintf(out, "static_cast< %s*>(", iface.at(k).className.constData());
fprintf(out, "const_cast< %s*>(this)%s;\n", fprintf(out, "this%s;\n", QByteArray(j + 1, ')').constData());
cdef->classname.constData(), QByteArray(j+1, ')').constData());
} }
} }
if (!purestSuperClass.isEmpty() && !isQObject) { if (!purestSuperClass.isEmpty() && !isQObject) {
@ -1263,7 +1262,6 @@ void Generator::generateStaticMetacall()
Q_ASSERT(needElse); // if there is signal, there was method. Q_ASSERT(needElse); // if there is signal, there was method.
fprintf(out, " else if (_c == QMetaObject::IndexOfMethod) {\n"); fprintf(out, " else if (_c == QMetaObject::IndexOfMethod) {\n");
fprintf(out, " int *result = reinterpret_cast<int *>(_a[0]);\n"); fprintf(out, " int *result = reinterpret_cast<int *>(_a[0]);\n");
fprintf(out, " void **func = reinterpret_cast<void **>(_a[1]);\n");
bool anythingUsed = false; bool anythingUsed = false;
for (int methodindex = 0; methodindex < cdef->signalList.size(); ++methodindex) { for (int methodindex = 0; methodindex < cdef->signalList.size(); ++methodindex) {
const FunctionDef &f = cdef->signalList.at(methodindex); const FunctionDef &f = cdef->signalList.at(methodindex);
@ -1289,14 +1287,14 @@ void Generator::generateStaticMetacall()
fprintf(out, ") const;\n"); fprintf(out, ") const;\n");
else else
fprintf(out, ");\n"); fprintf(out, ");\n");
fprintf(out, " if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&%s::%s)) {\n", fprintf(out, " if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&%s::%s)) {\n",
cdef->classname.constData(), f.name.constData()); cdef->classname.constData(), f.name.constData());
fprintf(out, " *result = %d;\n", methodindex); fprintf(out, " *result = %d;\n", methodindex);
fprintf(out, " return;\n"); fprintf(out, " return;\n");
fprintf(out, " }\n }\n"); fprintf(out, " }\n }\n");
} }
if (!anythingUsed) if (!anythingUsed)
fprintf(out, " Q_UNUSED(result);\n Q_UNUSED(func);\n"); fprintf(out, " Q_UNUSED(result);\n");
fprintf(out, " }"); fprintf(out, " }");
needElse = true; needElse = true;
} }

View File

@ -129,7 +129,7 @@
"label": "QDateTimeEdit", "label": "QDateTimeEdit",
"purpose": "Supports editing dates and times.", "purpose": "Supports editing dates and times.",
"section": "Widgets", "section": "Widgets",
"condition": "features.calendarwidget && features.datestring && features.textdate", "condition": "features.calendarwidget && features.datestring && features.textdate && features.datetimeparser",
"output": [ "publicFeature", "feature" ] "output": [ "publicFeature", "feature" ]
}, },
"stackedwidget": { "stackedwidget": {

View File

@ -2230,7 +2230,7 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
QAbstractScrollArea::focusInEvent(event); QAbstractScrollArea::focusInEvent(event);
const QItemSelectionModel* model = selectionModel(); const QItemSelectionModel* model = selectionModel();
const bool currentIndexValid = currentIndex().isValid(); bool currentIndexValid = currentIndex().isValid();
if (model if (model
&& !d->currentIndexSet && !d->currentIndexSet
@ -2238,19 +2238,16 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
bool autoScroll = d->autoScroll; bool autoScroll = d->autoScroll;
d->autoScroll = false; d->autoScroll = false;
QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index
if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason) if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason) {
selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate); selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
currentIndexValid = true;
}
d->autoScroll = autoScroll; d->autoScroll = autoScroll;
} }
if (model && currentIndexValid) { if (model && currentIndexValid)
if (currentIndex().flags() != Qt::ItemIsEditable) setAttribute(Qt::WA_InputMethodEnabled, (currentIndex().flags() & Qt::ItemIsEditable));
setAttribute(Qt::WA_InputMethodEnabled, false); else if (!currentIndexValid)
else
setAttribute(Qt::WA_InputMethodEnabled);
}
if (!currentIndexValid)
setAttribute(Qt::WA_InputMethodEnabled, false); setAttribute(Qt::WA_InputMethodEnabled, false);
d->viewport->update(); d->viewport->update();
@ -3665,6 +3662,7 @@ void QAbstractItemView::currentChanged(const QModelIndex &current, const QModelI
d->shouldScrollToCurrentOnShow = d->autoScroll; d->shouldScrollToCurrentOnShow = d->autoScroll;
} }
} }
setAttribute(Qt::WA_InputMethodEnabled, (current.isValid() && (current.flags() & Qt::ItemIsEditable)));
} }
#ifndef QT_NO_DRAGANDDROP #ifndef QT_NO_DRAGANDDROP

View File

@ -244,6 +244,36 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni
return state; return state;
} }
static bool logIgnoredEvent(QEvent::Type t)
{
bool result = false;
switch (t) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
case QEvent::MouseMove:
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchCancel:
case QEvent::TouchEnd:
case QEvent::TabletEnterProximity:
case QEvent::TabletLeaveProximity:
case QEvent::TabletMove:
case QEvent::TabletPress:
case QEvent::TabletRelease:
case QEvent::GraphicsSceneMouseDoubleClick:
case QEvent::GraphicsSceneMousePress:
case QEvent::GraphicsSceneMouseRelease:
case QEvent::GraphicsSceneMouseMove:
result = true;
break;
default:
break;
}
return result;
}
bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *, bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
Qt::GestureType> &contexts, Qt::GestureType> &contexts,
QEvent *event) QEvent *event)
@ -289,10 +319,13 @@ bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
qCDebug(lcGestureManager) << "QGestureManager:Recognizer: not gesture: " << state << event; qCDebug(lcGestureManager) << "QGestureManager:Recognizer: not gesture: " << state << event;
notGestures << state; notGestures << state;
} else if (recognizerState == QGestureRecognizer::Ignore) { } else if (recognizerState == QGestureRecognizer::Ignore) {
qCDebug(lcGestureManager) << "QGestureManager:Recognizer: ignored the event: " << state << event; if (logIgnoredEvent(event->type()))
qCDebug(lcGestureManager) << "QGestureManager:Recognizer: ignored the event: " << state << event;
} else { } else {
qCDebug(lcGestureManager) << "QGestureManager:Recognizer: hm, lets assume the recognizer" if (logIgnoredEvent(event->type())) {
qCDebug(lcGestureManager) << "QGestureManager:Recognizer: hm, lets assume the recognizer"
<< "ignored the event: " << state << event; << "ignored the event: " << state << event;
}
} }
if (resultHint & QGestureRecognizer::ConsumeEventHint) { if (resultHint & QGestureRecognizer::ConsumeEventHint) {
qCDebug(lcGestureManager) << "QGestureManager: we were asked to consume the event: " qCDebug(lcGestureManager) << "QGestureManager: we were asked to consume the event: "

View File

@ -5912,7 +5912,7 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
pixmapOffset -= effectRect.topLeft(); pixmapOffset -= effectRect.topLeft();
const qreal dpr = context->painter->device()->devicePixelRatio(); const qreal dpr = context->painter->device()->devicePixelRatioF();
QPixmap pixmap(effectRect.size() * dpr); QPixmap pixmap(effectRect.size() * dpr);
pixmap.setDevicePixelRatio(dpr); pixmap.setDevicePixelRatio(dpr);

View File

@ -89,7 +89,7 @@ public:
void updateUsesNativeWidgets() void updateUsesNativeWidgets()
{ {
if (usesNativeWidgets || window->parent() == 0) if (window->parent() == 0)
return; return;
Q_Q(QWindowContainer); Q_Q(QWindowContainer);
if (q->internalWinId()) { if (q->internalWinId()) {
@ -97,6 +97,7 @@ public:
usesNativeWidgets = true; usesNativeWidgets = true;
return; return;
} }
bool nativeWidgetSet = false;
QWidget *p = q->parentWidget(); QWidget *p = q->parentWidget();
while (p) { while (p) {
if (false if (false
@ -108,11 +109,12 @@ public:
#endif #endif
) { ) {
q->winId(); q->winId();
usesNativeWidgets = true; nativeWidgetSet = true;
break; break;
} }
p = p->parentWidget(); p = p->parentWidget();
} }
usesNativeWidgets = nativeWidgetSet;
} }
void markParentChain() { void markParentChain() {

View File

@ -101,6 +101,9 @@ public:
void _q_autoResizePopup(); void _q_autoResizePopup();
void _q_fileSystemModelDirectoryLoaded(const QString &path); void _q_fileSystemModelDirectoryLoaded(const QString &path);
void setCurrentIndex(QModelIndex, bool = true); void setCurrentIndex(QModelIndex, bool = true);
static QCompleterPrivate *get(QCompleter *o) { return o->d_func(); }
static const QCompleterPrivate *get(const QCompleter *o) { return o->d_func(); }
}; };
class QIndexMapper class QIndexMapper

View File

@ -39,7 +39,9 @@
#include <qplatformdefs.h> #include <qplatformdefs.h>
#include <private/qabstractspinbox_p.h> #include <private/qabstractspinbox_p.h>
#if QT_CONFIG(datetimeparser)
#include <private/qdatetimeparser_p.h> #include <private/qdatetimeparser_p.h>
#endif
#include <private/qlineedit_p.h> #include <private/qlineedit_p.h>
#include <qabstractspinbox.h> #include <qabstractspinbox.h>
@ -47,9 +49,6 @@
#include <qstylehints.h> #include <qstylehints.h>
#include <qclipboard.h> #include <qclipboard.h>
#include <qdatetime.h> #include <qdatetime.h>
#if QT_CONFIG(datetimeedit)
#include <qdatetimeedit.h>
#endif
#include <qevent.h> #include <qevent.h>
#if QT_CONFIG(menu) #if QT_CONFIG(menu)
#include <qmenu.h> #include <qmenu.h>
@ -1962,12 +1961,15 @@ QVariant operator+(const QVariant &arg1, const QVariant &arg2)
break; break;
} }
case QVariant::Double: ret = QVariant(arg1.toDouble() + arg2.toDouble()); break; case QVariant::Double: ret = QVariant(arg1.toDouble() + arg2.toDouble()); break;
#if QT_CONFIG(datetimeparser)
case QVariant::DateTime: { case QVariant::DateTime: {
QDateTime a2 = arg2.toDateTime(); QDateTime a2 = arg2.toDateTime();
QDateTime a1 = arg1.toDateTime().addDays(QDATETIMEEDIT_DATETIME_MIN.daysTo(a2)); QDateTime a1 = arg1.toDateTime().addDays(QDATETIMEEDIT_DATETIME_MIN.daysTo(a2));
a1.setTime(a1.time().addMSecs(QTime().msecsTo(a2.time()))); a1.setTime(a1.time().addMSecs(QTime().msecsTo(a2.time())));
ret = QVariant(a1); ret = QVariant(a1);
break;
} }
#endif // datetimeparser
default: break; default: break;
} }
return ret; return ret;
@ -2022,6 +2024,7 @@ QVariant operator*(const QVariant &arg1, double multiplier)
ret = static_cast<int>(qBound<double>(INT_MIN, arg1.toInt() * multiplier, INT_MAX)); ret = static_cast<int>(qBound<double>(INT_MIN, arg1.toInt() * multiplier, INT_MAX));
break; break;
case QVariant::Double: ret = QVariant(arg1.toDouble() * multiplier); break; case QVariant::Double: ret = QVariant(arg1.toDouble() * multiplier); break;
#if QT_CONFIG(datetimeparser)
case QVariant::DateTime: { case QVariant::DateTime: {
double days = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDateTime().date()) * multiplier; double days = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDateTime().date()) * multiplier;
int daysInt = (int)days; int daysInt = (int)days;
@ -2031,6 +2034,7 @@ QVariant operator*(const QVariant &arg1, double multiplier)
ret = QDateTime(QDate().addDays(int(days)), QTime().addMSecs(msecs)); ret = QDateTime(QDate().addDays(int(days)), QTime().addMSecs(msecs));
break; break;
} }
#endif // datetimeparser
default: ret = arg1; break; default: ret = arg1; break;
} }
@ -2053,11 +2057,14 @@ double operator/(const QVariant &arg1, const QVariant &arg2)
a1 = arg1.toDouble(); a1 = arg1.toDouble();
a2 = arg2.toDouble(); a2 = arg2.toDouble();
break; break;
#if QT_CONFIG(datetimeparser)
case QVariant::DateTime: case QVariant::DateTime:
a1 = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDate()); a1 = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDate());
a2 = QDATETIMEEDIT_DATE_MIN.daysTo(arg2.toDate()); a2 = QDATETIMEEDIT_DATE_MIN.daysTo(arg2.toDate());
a1 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg1.toDateTime().time()) / (long)(3600 * 24 * 1000); a1 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg1.toDateTime().time()) / (long)(3600 * 24 * 1000);
a2 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg2.toDateTime().time()) / (long)(3600 * 24 * 1000); a2 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg2.toDateTime().time()) / (long)(3600 * 24 * 1000);
break;
#endif // datetimeparser
default: break; default: break;
} }

View File

@ -72,6 +72,7 @@
#include <private/qabstractitemmodel_p.h> #include <private/qabstractitemmodel_p.h>
#include <private/qabstractscrollarea_p.h> #include <private/qabstractscrollarea_p.h>
#include <private/qlineedit_p.h> #include <private/qlineedit_p.h>
#include <private/qcompleter_p.h>
#include <qdebug.h> #include <qdebug.h>
#if QT_CONFIG(effects) #if QT_CONFIG(effects)
# include <private/qeffects_p.h> # include <private/qeffects_p.h>
@ -1227,8 +1228,27 @@ Qt::MatchFlags QComboBoxPrivate::matchFlags() const
void QComboBoxPrivate::_q_editingFinished() void QComboBoxPrivate::_q_editingFinished()
{ {
Q_Q(QComboBox); Q_Q(QComboBox);
if (lineEdit && !lineEdit->text().isEmpty() && itemText(currentIndex) != lineEdit->text()) { if (!lineEdit)
const int index = q_func()->findText(lineEdit->text(), matchFlags()); return;
const auto leText = lineEdit->text();
if (!leText.isEmpty() && itemText(currentIndex) != leText) {
#if QT_CONFIG(completer)
const auto *leCompleter = lineEdit->completer();
const auto *popup = leCompleter ? QCompleterPrivate::get(leCompleter)->popup : nullptr;
if (popup && popup->isVisible()) {
// QLineEdit::editingFinished() will be emitted before the code flow returns
// to QCompleter::eventFilter(), where QCompleter::activated() may be emitted.
// We know that the completer popup will still be visible at this point, and
// that any selection should be valid.
const QItemSelectionModel *selModel = popup->selectionModel();
const QModelIndex curIndex = popup->currentIndex();
const bool completerIsActive = selModel && selModel->selectedIndexes().contains(curIndex);
if (completerIsActive)
return;
}
#endif
const int index = q_func()->findText(leText, matchFlags());
if (index != -1) { if (index != -1) {
q->setCurrentIndex(index); q->setCurrentIndex(index);
emitActivated(currentIndex); emitActivated(currentIndex);
@ -3163,13 +3183,13 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
Q_D(QComboBox); Q_D(QComboBox);
#if QT_CONFIG(completer) #if QT_CONFIG(completer)
if (d->lineEdit if (const auto *cmpltr = completer()) {
&& d->lineEdit->completer() const auto *popup = QCompleterPrivate::get(cmpltr)->popup;
&& d->lineEdit->completer()->popup() if (popup && popup->isVisible()) {
&& d->lineEdit->completer()->popup()->isVisible()) { // provide same autocompletion support as line edit
// provide same autocompletion support as line edit d->lineEdit->event(e);
d->lineEdit->event(e); return;
return; }
} }
#endif #endif

View File

@ -289,7 +289,7 @@ void QMenuBarPrivate::setKeyboardMode(bool b)
keyboardState = b; keyboardState = b;
if(b) { if(b) {
QWidget *fw = QApplication::focusWidget(); QWidget *fw = QApplication::focusWidget();
if (fw != q) if (fw && fw != q && fw->window() != QApplication::activePopupWidget())
keyboardFocusWidget = fw; keyboardFocusWidget = fw;
focusFirstAction(); focusFirstAction();
q->setFocus(Qt::MenuBarFocusReason); q->setFocus(Qt::MenuBarFocusReason);
@ -1707,6 +1707,7 @@ void QMenuBarPrivate::_q_internalShortcutActivated(int id)
} }
} }
keyboardFocusWidget = QApplication::focusWidget();
setCurrentAction(act, true, true); setCurrentAction(act, true, true);
if (act && !act->menu()) { if (act && !act->menu()) {
activateAction(act, QAction::Trigger); activateAction(act, QAction::Trigger);

View File

@ -196,6 +196,8 @@ public:
void _q_tabMoved(int from, int to); void _q_tabMoved(int from, int to);
void init(); void init();
void initBasicStyleOption(QStyleOptionTabWidgetFrame *option) const;
QTabBar *tabs; QTabBar *tabs;
QStackedWidget *stack; QStackedWidget *stack;
QRect panelRect; QRect panelRect;
@ -258,6 +260,43 @@ bool QTabWidget::hasHeightForWidth() const
return has; return has;
} }
/*!
\internal
Initialize only time inexpensive parts of the style option
for QTabWidget::setUpLayout()'s non-visible code path.
*/
void QTabWidgetPrivate::initBasicStyleOption(QStyleOptionTabWidgetFrame *option) const
{
Q_Q(const QTabWidget);
option->initFrom(q);
if (q->documentMode())
option->lineWidth = 0;
else
option->lineWidth = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, q);
switch (pos) {
case QTabWidget::North:
option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedNorth
: QTabBar::TriangularNorth;
break;
case QTabWidget::South:
option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedSouth
: QTabBar::TriangularSouth;
break;
case QTabWidget::West:
option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedWest
: QTabBar::TriangularWest;
break;
case QTabWidget::East:
option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedEast
: QTabBar::TriangularEast;
break;
}
option->tabBarRect = q->tabBar()->geometry();
}
/*! /*!
Initialize \a option with the values from this QTabWidget. This method is useful Initialize \a option with the values from this QTabWidget. This method is useful
@ -272,12 +311,7 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
return; return;
Q_D(const QTabWidget); Q_D(const QTabWidget);
option->initFrom(this); d->initBasicStyleOption(option);
if (documentMode())
option->lineWidth = 0;
else
option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this);
int exth = style()->pixelMetric(QStyle::PM_TabBarBaseHeight, 0, this); int exth = style()->pixelMetric(QStyle::PM_TabBarBaseHeight, 0, this);
QSize t(0, d->stack->frameWidth()); QSize t(0, d->stack->frameWidth());
@ -308,31 +342,10 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
option->leftCornerWidgetSize = QSize(0, 0); option->leftCornerWidgetSize = QSize(0, 0);
} }
switch (d->pos) {
case QTabWidget::North:
option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedNorth
: QTabBar::TriangularNorth;
break;
case QTabWidget::South:
option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedSouth
: QTabBar::TriangularSouth;
break;
case QTabWidget::West:
option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedWest
: QTabBar::TriangularWest;
break;
case QTabWidget::East:
option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedEast
: QTabBar::TriangularEast;
break;
}
option->tabBarSize = t; option->tabBarSize = t;
QRect tbRect = tabBar()->geometry();
QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex()); QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex());
option->tabBarRect = tbRect; selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + option->tabBarRect.topLeft());
selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft());
option->selectedTabRect = selectedTabRect; option->selectedTabRect = selectedTabRect;
} }
@ -764,17 +777,19 @@ void QTabWidget::setUpLayout(bool onlyCheck)
if (onlyCheck && !d->dirty) if (onlyCheck && !d->dirty)
return; // nothing to do return; // nothing to do
QStyleOptionTabWidgetFrame option;
initStyleOption(&option);
// this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &option);
if (!isVisible()) { if (!isVisible()) {
// this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
QStyleOptionTabWidgetFrame basicOption;
d->initBasicStyleOption(&basicOption);
d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &basicOption);
d->dirty = true; d->dirty = true;
return; // we'll do it later return; // we'll do it later
} }
QStyleOptionTabWidgetFrame option;
initStyleOption(&option);
d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &option);
QRect tabRect = style()->subElementRect(QStyle::SE_TabWidgetTabBar, &option, this); QRect tabRect = style()->subElementRect(QStyle::SE_TabWidgetTabBar, &option, this);
d->panelRect = style()->subElementRect(QStyle::SE_TabWidgetTabPane, &option, this); d->panelRect = style()->subElementRect(QStyle::SE_TabWidgetTabPane, &option, this);
QRect contentsRect = style()->subElementRect(QStyle::SE_TabWidgetTabContents, &option, this); QRect contentsRect = style()->subElementRect(QStyle::SE_TabWidgetTabContents, &option, this);

View File

@ -44,6 +44,7 @@
#endif #endif
#include "qclipboard.h" #include "qclipboard.h"
#include <private/qguiapplication_p.h> #include <private/qguiapplication_p.h>
#include <private/qcompleter_p.h>
#include <qpa/qplatformtheme.h> #include <qpa/qplatformtheme.h>
#include <qstylehints.h> #include <qstylehints.h>
#ifndef QT_NO_ACCESSIBILITY #ifndef QT_NO_ACCESSIBILITY
@ -1484,7 +1485,8 @@ void QWidgetLineControl::complete(int key)
} else { } else {
#ifndef QT_KEYPAD_NAVIGATION #ifndef QT_KEYPAD_NAVIGATION
if (text.isEmpty()) { if (text.isEmpty()) {
m_completer->popup()->hide(); if (auto *popup = QCompleterPrivate::get(m_completer)->popup)
popup->hide();
return; return;
} }
#endif #endif
@ -1630,25 +1632,16 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
#if QT_CONFIG(completer) #if QT_CONFIG(completer)
if (m_completer) { if (m_completer) {
QCompleter::CompletionMode completionMode = m_completer->completionMode(); QCompleter::CompletionMode completionMode = m_completer->completionMode();
auto *popup = QCompleterPrivate::get(m_completer)->popup;
if ((completionMode == QCompleter::PopupCompletion if ((completionMode == QCompleter::PopupCompletion
|| completionMode == QCompleter::UnfilteredPopupCompletion) || completionMode == QCompleter::UnfilteredPopupCompletion)
&& m_completer->popup() && popup && popup->isVisible()) {
&& m_completer->popup()->isVisible()) {
// The following keys are forwarded by the completer to the widget // The following keys are forwarded by the completer to the widget
// Ignoring the events lets the completer provide suitable default behavior // Ignoring the events lets the completer provide suitable default behavior
switch (event->key()) { switch (event->key()) {
case Qt::Key_Escape: case Qt::Key_Escape:
event->ignore(); event->ignore();
return; return;
case Qt::Key_Enter:
case Qt::Key_Return:
case Qt::Key_F4:
#ifdef QT_KEYPAD_NAVIGATION
case Qt::Key_Select:
if (!QApplication::keypadNavigationEnabled())
break;
#endif
m_completer->popup()->hide(); // just hide. will end up propagating to parent
default: default:
break; // normal key processing break; // normal key processing
} }

View File

@ -23,3 +23,5 @@ osx
osx-10.11 ci osx-10.11 ci
osx-10.12 ci osx-10.12 ci
[testInputEvents]
rhel-7.4

View File

@ -487,6 +487,7 @@ private Q_SLOTS:
void ioHttpRedirectPolicyErrors(); void ioHttpRedirectPolicyErrors();
void ioHttpUserVerifiedRedirect_data(); void ioHttpUserVerifiedRedirect_data();
void ioHttpUserVerifiedRedirect(); void ioHttpUserVerifiedRedirect();
void ioHttpCookiesDuringRedirect();
#ifndef QT_NO_SSL #ifndef QT_NO_SSL
void putWithServerClosingConnectionImmediately(); void putWithServerClosingConnectionImmediately();
#endif #endif
@ -8410,6 +8411,33 @@ void tst_QNetworkReply::ioHttpUserVerifiedRedirect()
QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), statusCode); QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), statusCode);
} }
void tst_QNetworkReply::ioHttpCookiesDuringRedirect()
{
MiniHttpServer target(httpEmpty200Response, false);
const QString cookieHeader = QStringLiteral("Set-Cookie: hello=world; Path=/;\r\n");
QString redirect = tempRedirectReplyStr();
// Insert 'cookieHeader' before the final \r\n
redirect.insert(redirect.length() - 2, cookieHeader);
QUrl url("http://localhost/");
url.setPort(target.serverPort());
redirect = redirect.arg(url.toString());
MiniHttpServer redirectServer(redirect.toLatin1(), false);
url = QUrl("http://localhost/");
url.setPort(redirectServer.serverPort());
QNetworkRequest request(url);
auto oldRedirectPolicy = manager.redirectPolicy();
manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy);
QNetworkReplyPtr reply(manager.get(request));
// Set policy back to whatever it was
manager.setRedirectPolicy(oldRedirectPolicy);
QVERIFY(waitForFinish(reply) == Success);
QVERIFY(target.receivedData.contains("\r\nCookie: hello=world\r\n"));
}
#ifndef QT_NO_SSL #ifndef QT_NO_SSL
class PutWithServerClosingConnectionImmediatelyHandler: public QObject class PutWithServerClosingConnectionImmediatelyHandler: public QObject

View File

@ -256,8 +256,8 @@ void tst_QNetworkProxyFactory::genericSystemProxy()
QFETCH(QString, hostName); QFETCH(QString, hostName);
QFETCH(int, port); QFETCH(int, port);
// The generic system proxy is only available on the following platforms // We can only use the generic system proxy where available:
#if (!defined Q_OS_WIN) && (!defined Q_OS_OSX) && !QT_CONFIG(libproxy) #if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS) && !QT_CONFIG(libproxy)
qputenv(envVar, url); qputenv(envVar, url);
const QList<QNetworkProxy> systemProxy = QNetworkProxyFactory::systemProxyForQuery(); const QList<QNetworkProxy> systemProxy = QNetworkProxyFactory::systemProxyForQuery();
QCOMPARE(systemProxy.size(), 1); QCOMPARE(systemProxy.size(), 1);

View File

@ -168,29 +168,59 @@ void tst_QSslSocket_onDemandCertificates_member::proxyAuthenticationRequired(con
#ifndef QT_NO_OPENSSL #ifndef QT_NO_OPENSSL
static bool waitForEncrypted(QSslSocket *socket)
{
Q_ASSERT(socket);
QEventLoop eventLoop;
QTimer connectionTimeoutWatcher;
connectionTimeoutWatcher.setSingleShot(true);
connectionTimeoutWatcher.connect(&connectionTimeoutWatcher, &QTimer::timeout,
[&eventLoop]() {
eventLoop.exit();
});
bool encrypted = false;
socket->connect(socket, &QSslSocket::encrypted, [&eventLoop, &encrypted](){
eventLoop.exit();
encrypted = true;
});
socket->connect(socket, QOverload<const QList<QSslError>&>::of(&QSslSocket::sslErrors),
[&eventLoop](){
eventLoop.exit();
});
// Wait for 30 s. maximum - the default timeout in our QSslSocket::waitForEncrypted ...
connectionTimeoutWatcher.start(30000);
eventLoop.exec();
return encrypted;
}
void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMethods() void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMethods()
{ {
QString host("www.qt.io"); const QString host("www.qt.io");
// not using any root certs -> should not work // not using any root certs -> should not work
QSslSocketPtr socket2 = newSocket(); QSslSocketPtr socket2 = newSocket();
this->socket = socket2.data(); this->socket = socket2.data();
socket2->setCaCertificates(QList<QSslCertificate>()); socket2->setCaCertificates(QList<QSslCertificate>());
socket2->connectToHostEncrypted(host, 443); socket2->connectToHostEncrypted(host, 443);
QVERIFY(!socket2->waitForEncrypted()); QVERIFY(!waitForEncrypted(socket2.data()));
// default: using on demand loading -> should work // default: using on demand loading -> should work
QSslSocketPtr socket = newSocket(); QSslSocketPtr socket = newSocket();
this->socket = socket.data(); this->socket = socket.data();
socket->connectToHostEncrypted(host, 443); socket->connectToHostEncrypted(host, 443);
QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString())); QVERIFY2(waitForEncrypted(socket.data()), qPrintable(socket->errorString()));
// not using any root certs again -> should not work // not using any root certs again -> should not work
QSslSocketPtr socket3 = newSocket(); QSslSocketPtr socket3 = newSocket();
this->socket = socket3.data(); this->socket = socket3.data();
socket3->setCaCertificates(QList<QSslCertificate>()); socket3->setCaCertificates(QList<QSslCertificate>());
socket3->connectToHostEncrypted(host, 443); socket3->connectToHostEncrypted(host, 443);
QVERIFY(!socket3->waitForEncrypted()); QVERIFY(!waitForEncrypted(socket3.data()));
// setting empty SSL configuration explicitly -> depends on on-demand loading // setting empty SSL configuration explicitly -> depends on on-demand loading
QSslSocketPtr socket4 = newSocket(); QSslSocketPtr socket4 = newSocket();
@ -199,24 +229,16 @@ void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMe
socket4->setSslConfiguration(conf); socket4->setSslConfiguration(conf);
socket4->connectToHostEncrypted(host, 443); socket4->connectToHostEncrypted(host, 443);
#ifdef QT_BUILD_INTERNAL #ifdef QT_BUILD_INTERNAL
bool rootCertLoadingAllowed = QSslSocketPrivate::rootCertOnDemandLoadingSupported(); const bool works = QSslSocketPrivate::rootCertOnDemandLoadingSupported();
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
QCOMPARE(rootCertLoadingAllowed, true); QCOMPARE(works, true);
#elif defined(Q_OS_MAC) #elif defined(Q_OS_MAC)
QCOMPARE(rootCertLoadingAllowed, false); QCOMPARE(works, false);
#endif // other platforms: undecided (Windows: depends on the version) #endif // other platforms: undecided.
// when we allow on demand loading, it is enabled by default, // When we *allow* on-demand loading, we enable it by default; so, on Unix,
// so on Unix it will work without setting any certificates. Otherwise, // it will work without setting any certificates. Otherwise, the configuration
// the configuration contains an empty set of certificates // contains an empty set of certificates, so on-demand loading shall fail.
// and will fail. QCOMPARE(waitForEncrypted(socket4.data()), works);
bool works;
#if defined (Q_OS_WIN)
works = false; // on Windows, this won't work even though we use on demand loading
Q_UNUSED(rootCertLoadingAllowed)
#else
works = rootCertLoadingAllowed;
#endif
QCOMPARE(socket4->waitForEncrypted(), works);
#endif // QT_BUILD_INTERNAL #endif // QT_BUILD_INTERNAL
} }

View File

@ -55,6 +55,8 @@
#include <qproxystyle.h> #include <qproxystyle.h>
#include <qdialog.h> #include <qdialog.h>
Q_DECLARE_METATYPE(Qt::ItemFlags);
static inline void setFrameless(QWidget *w) static inline void setFrameless(QWidget *w)
{ {
Qt::WindowFlags flags = w->windowFlags(); Qt::WindowFlags flags = w->windowFlags();
@ -154,6 +156,8 @@ private slots:
void testDialogAsEditor(); void testDialogAsEditor();
void QTBUG46785_mouseout_hover_state(); void QTBUG46785_mouseout_hover_state();
void testClearModelInClickedSignal(); void testClearModelInClickedSignal();
void inputMethodEnabled_data();
void inputMethodEnabled();
}; };
class MyAbstractItemDelegate : public QAbstractItemDelegate class MyAbstractItemDelegate : public QAbstractItemDelegate
@ -2295,5 +2299,107 @@ void tst_QAbstractItemView::testClearModelInClickedSignal()
QCOMPARE(view.model(), nullptr); QCOMPARE(view.model(), nullptr);
} }
void tst_QAbstractItemView::inputMethodEnabled_data()
{
QTest::addColumn<QByteArray>("viewType");
QTest::addColumn<Qt::ItemFlags>("itemFlags");
QTest::addColumn<bool>("result");
QList<QByteArray> widgets;
widgets << "QListView" << "QTreeView" << "QTableView";
for (const QByteArray &widget : qAsConst(widgets)) {
QTest::newRow(widget + ": no flags") << widget << Qt::ItemFlags(Qt::NoItemFlags) << false;
QTest::newRow(widget + ": checkable") << widget << Qt::ItemFlags(Qt::ItemIsUserCheckable) << false;
QTest::newRow(widget + ": selectable") << widget << Qt::ItemFlags(Qt::ItemIsSelectable) << false;
QTest::newRow(widget + ": enabled") << widget << Qt::ItemFlags(Qt::ItemIsEnabled) << false;
QTest::newRow(widget + ": selectable|enabled")
<< widget << Qt::ItemFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled) << false;
QTest::newRow(widget + ": editable|enabled")
<< widget << Qt::ItemFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled) << true;
QTest::newRow(widget + ": editable|enabled|selectable")
<< widget << Qt::ItemFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable) << true;
}
}
void tst_QAbstractItemView::inputMethodEnabled()
{
QFETCH(QByteArray, viewType);
QFETCH(Qt::ItemFlags, itemFlags);
QFETCH(bool, result);
QScopedPointer<QAbstractItemView> view;
if (viewType == "QListView")
view.reset(new QListView());
else if (viewType == "QTableView")
view.reset(new QTableView());
else if (viewType == "QTreeView")
view.reset(new QTreeView());
else
QVERIFY(0);
centerOnScreen(view.data());
view->show();
QVERIFY(QTest::qWaitForWindowExposed(view.data()));
QStandardItemModel *model = new QStandardItemModel(view.data());
QStandardItem *item = new QStandardItem("first item");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
model->appendRow(item);
QStandardItem *secondItem = new QStandardItem("test item");
secondItem->setFlags(Qt::ItemFlags(itemFlags));
model->appendRow(secondItem);
view->setModel(model);
// Check current changed
view->setCurrentIndex(model->index(0, 0));
QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled));
view->setCurrentIndex(model->index(1, 0));
QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
view->setCurrentIndex(model->index(0, 0));
QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled));
// Check focus by switching the activation of the window to force a focus in
view->setCurrentIndex(model->index(1, 0));
QApplication::setActiveWindow(0);
QApplication::setActiveWindow(view.data());
QVERIFY(QTest::qWaitForWindowActive(view.data()));
QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
view->setCurrentIndex(QModelIndex());
QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled));
QApplication::setActiveWindow(0);
QApplication::setActiveWindow(view.data());
QVERIFY(QTest::qWaitForWindowActive(view.data()));
QModelIndex index = model->index(1, 0);
QPoint p = view->visualRect(index).center();
QTest::mouseClick(view->viewport(), Qt::LeftButton, Qt::NoModifier, p);
if (itemFlags & Qt::ItemIsEnabled)
QCOMPARE(view->currentIndex(), index);
QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
index = model->index(0, 0);
QApplication::setActiveWindow(0);
QApplication::setActiveWindow(view.data());
QVERIFY(QTest::qWaitForWindowActive(view.data()));
p = view->visualRect(index).center();
QTest::mouseClick(view->viewport(), Qt::LeftButton, Qt::NoModifier, p);
QCOMPARE(view->currentIndex(), index);
QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled));
// There is a case when it goes to the first visible item so we
// make the flags of the first item match the ones we are testing
// to check the attribute correctly
QApplication::setActiveWindow(0);
view->setCurrentIndex(QModelIndex());
view->reset();
item->setFlags(Qt::ItemFlags(itemFlags));
QApplication::setActiveWindow(view.data());
QVERIFY(QTest::qWaitForWindowActive(view.data()));
QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
}
QTEST_MAIN(tst_QAbstractItemView) QTEST_MAIN(tst_QAbstractItemView)
#include "tst_qabstractitemview.moc" #include "tst_qabstractitemview.moc"

View File

@ -1,2 +1,4 @@
[enterKey] [enterKey]
opensuse-42.3 opensuse-42.3 ci
[testLineEditValidation]
opensuse-42.3 ci

View File

@ -74,6 +74,7 @@ private slots:
void testOwnership(); void testOwnership();
void testBehindTheScenesDeletion(); void testBehindTheScenesDeletion();
void testUnparenting(); void testUnparenting();
void testUnparentReparent();
void testActivation(); void testActivation();
void testAncestorChange(); void testAncestorChange();
void testDockWidget(); void testDockWidget();
@ -241,6 +242,31 @@ void tst_QWindowContainer::testUnparenting()
QVERIFY(!window->isVisible()); QVERIFY(!window->isVisible());
} }
void tst_QWindowContainer::testUnparentReparent()
{
QWidget root;
QWindow *window = new QWindow();
QScopedPointer<QWidget> container(QWidget::createWindowContainer(window, &root));
container->setWindowTitle(QTest::currentTestFunction());
container->setGeometry(m_availableGeometry.x() + 100, m_availableGeometry.y() + 100, 200, 100);
root.show();
QVERIFY(QTest::qWaitForWindowExposed(&root));
QTRY_VERIFY(window->isVisible());
container->setParent(nullptr);
QTRY_VERIFY(!window->isVisible());
container->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
QTRY_VERIFY(window->isVisible());
container->setParent(&root); // This should not crash (QTBUG-63168)
}
void tst_QWindowContainer::testAncestorChange() void tst_QWindowContainer::testAncestorChange()
{ {
QWidget root; QWidget root;

View File

@ -143,6 +143,8 @@ private slots:
void task253125_lineEditCompletion(); void task253125_lineEditCompletion();
void task247560_keyboardNavigation(); void task247560_keyboardNavigation();
void QTBUG_14292_filesystem(); void QTBUG_14292_filesystem();
void QTBUG_52028_tabAutoCompletes();
void QTBUG_51889_activatedSentTwice();
private: private:
void filter(bool assync = false); void filter(bool assync = false);
@ -1742,5 +1744,108 @@ void tst_QCompleter::QTBUG_14292_filesystem()
QVERIFY(!comp.popup()->isVisible()); QVERIFY(!comp.popup()->isVisible());
} }
void tst_QCompleter::QTBUG_52028_tabAutoCompletes()
{
QStringList words;
words << "foobar1" << "foobar2" << "hux";
QWidget w;
w.setLayout(new QVBoxLayout);
QComboBox cbox;
cbox.setEditable(true);
cbox.setInsertPolicy(QComboBox::NoInsert);
cbox.addItems(words);
cbox.completer()->setCaseSensitivity(Qt::CaseInsensitive);
cbox.completer()->setCompletionMode(QCompleter::PopupCompletion);
w.layout()->addWidget(&cbox);
// Adding a line edit is a good reason for tab to do something unrelated
QLineEdit le;
w.layout()->addWidget(&le);
const auto pos = QApplication::desktop()->availableGeometry(&w).topLeft() + QPoint(200,200);
w.move(pos);
w.show();
QApplication::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
QSignalSpy activatedSpy(&cbox, QOverload<int>::of(&QComboBox::activated));
// Tab key will complete but not activate
cbox.lineEdit()->clear();
QTest::keyClick(&cbox, Qt::Key_H);
QVERIFY(cbox.completer()->popup());
QTRY_VERIFY(cbox.completer()->popup()->isVisible());
QTest::keyClick(cbox.completer()->popup(), Qt::Key_Tab);
QCOMPARE(cbox.completer()->currentCompletion(), QLatin1String("hux"));
QCOMPARE(activatedSpy.count(), 0);
QEXPECT_FAIL("", "QTBUG-52028 will not be fixed today.", Abort);
QCOMPARE(cbox.currentText(), QLatin1String("hux"));
QCOMPARE(activatedSpy.count(), 0);
QVERIFY(!le.hasFocus());
}
void tst_QCompleter::QTBUG_51889_activatedSentTwice()
{
QStringList words;
words << "foobar1" << "foobar2" << "bar" <<"hux";
QWidget w;
w.setLayout(new QVBoxLayout);
QComboBox cbox;
setFrameless(&cbox);
cbox.setEditable(true);
cbox.setInsertPolicy(QComboBox::NoInsert);
cbox.addItems(words);
cbox.completer()->setCaseSensitivity(Qt::CaseInsensitive);
cbox.completer()->setCompletionMode(QCompleter::PopupCompletion);
w.layout()->addWidget(&cbox);
QLineEdit le;
w.layout()->addWidget(&le);
const auto pos = QApplication::desktop()->availableGeometry(&w).topLeft() + QPoint(200,200);
w.move(pos);
w.show();
QApplication::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
QSignalSpy activatedSpy(&cbox, QOverload<int>::of(&QComboBox::activated));
// Navigate + enter activates only once (first item)
cbox.lineEdit()->clear();
QTest::keyClick(&cbox, Qt::Key_F);
QVERIFY(cbox.completer()->popup());
QTRY_VERIFY(cbox.completer()->popup()->isVisible());
QTest::keyClick(cbox.completer()->popup(), Qt::Key_Down);
QTest::keyClick(cbox.completer()->popup(), Qt::Key_Return);
QTRY_COMPARE(activatedSpy.count(), 1);
// Navigate + enter activates only once (non-first item)
cbox.lineEdit()->clear();
activatedSpy.clear();
QTest::keyClick(&cbox, Qt::Key_H);
QVERIFY(cbox.completer()->popup());
QTRY_VERIFY(cbox.completer()->popup()->isVisible());
QTest::keyClick(cbox.completer()->popup(), Qt::Key_Down);
QTest::keyClick(cbox.completer()->popup(), Qt::Key_Return);
QTRY_COMPARE(activatedSpy.count(), 1);
// Full text + enter activates only once
cbox.lineEdit()->clear();
activatedSpy.clear();
QTest::keyClicks(&cbox, "foobar1");
QVERIFY(cbox.completer()->popup());
QTRY_VERIFY(cbox.completer()->popup()->isVisible());
QTest::keyClick(&cbox, Qt::Key_Return);
QTRY_COMPARE(activatedSpy.count(), 1);
}
QTEST_MAIN(tst_QCompleter) QTEST_MAIN(tst_QCompleter)
#include "tst_qcompleter.moc" #include "tst_qcompleter.moc"

View File

@ -39,6 +39,7 @@
#include <qstyleoption.h> #include <qstyleoption.h>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QLabel> #include <QLabel>
#include <QPlainTextEdit>
#include <qscreen.h> #include <qscreen.h>
#include <qobject.h> #include <qobject.h>
@ -106,6 +107,7 @@ private slots:
void allowActiveAndDisabled(); void allowActiveAndDisabled();
#endif #endif
void taskQTBUG56860_focus();
void check_endKey(); void check_endKey();
void check_homeKey(); void check_homeKey();
@ -710,6 +712,52 @@ void tst_QMenuBar::check_cursorKeys3()
} }
#endif #endif
void tst_QMenuBar::taskQTBUG56860_focus()
{
#if defined(Q_OS_DARWIN)
QSKIP("Native key events are needed to test menu action activation on macOS.");
#endif
QMainWindow w;
QMenuBar *mb = w.menuBar();
if (mb->platformMenuBar())
QSKIP("This test requires the Qt menubar.");
QMenu *em = mb->addMenu("&Edit");
em->setObjectName("EditMenu");
em->addAction("&Cut");
em->addAction("C&opy");
QPlainTextEdit *e = new QPlainTextEdit;
e->setObjectName("edit");
w.setCentralWidget(e);
w.show();
QApplication::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
QTRY_COMPARE(QApplication::focusWidget(), e);
// Open menu
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_E, Qt::AltModifier );
QTRY_COMPARE(QApplication::activePopupWidget(), em);
// key down to trigger focus
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down );
// and press ENTER to close
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter );
QTRY_COMPARE(QApplication::activePopupWidget(), nullptr);
// focus should have returned to the editor by now
QTRY_COMPARE(QApplication::focusWidget(), e);
// Now do it all over again...
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_E, Qt::AltModifier );
QTRY_COMPARE(QApplication::activePopupWidget(), em);
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down );
QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter );
QTRY_COMPARE(QApplication::activePopupWidget(), nullptr);
QTRY_COMPARE(QApplication::focusWidget(), e);
}
/*! /*!
If a popupmenu is active you can use home to go quickly to the first item in the menu. If a popupmenu is active you can use home to go quickly to the first item in the menu.
*/ */

View File

@ -79,6 +79,14 @@ const char *algoname(int i)
return "sha3_384-"; return "sha3_384-";
case QCryptographicHash::Sha3_512: case QCryptographicHash::Sha3_512:
return "sha3_512-"; return "sha3_512-";
case QCryptographicHash::Keccak_224:
return "keccak_224-";
case QCryptographicHash::Keccak_256:
return "keccak_256-";
case QCryptographicHash::Keccak_384:
return "keccak_384-";
case QCryptographicHash::Keccak_512:
return "keccak_512-";
} }
Q_UNREACHABLE(); Q_UNREACHABLE();
return 0; return 0;