Merge "Merge remote-tracking branch 'origin/5.13' into dev" into refs/staging/dev

This commit is contained in:
Liang Qi 2019-03-31 18:45:03 +00:00 committed by The Qt Project
commit e104c19728
62 changed files with 743 additions and 259 deletions

View File

@ -465,7 +465,9 @@ defineTest(reloadSpec) {
$$[QT_HOST_DATA/src]/mkspecs/features/mac/toolchain.prf \
$$[QT_HOST_DATA/src]/mkspecs/features/toolchain.prf
_SAVED_CONFIG = $$CONFIG
saved_variables = CONFIG QMAKE_CXXFLAGS
for (name, saved_variables): \
_SAVED_$$name = $$eval($$name)
load(spec_pre)
# qdevice.pri gets written too late (and we can't write it early
# enough, as it's populated in stages, with later ones depending
@ -474,7 +476,8 @@ defineTest(reloadSpec) {
eval($$l)
include($$QMAKESPEC/qmake.conf)
load(spec_post)
CONFIG += $$_SAVED_CONFIG
for (name, saved_variables): \
$$name += $$eval(_SAVED_$$name)
load(default_pre)
# ensure pristine environment for configuration. again.

View File

@ -70,7 +70,7 @@ static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options
static QVariantList listFromXml(QXmlStreamReader &xml, Converter::Options options)
{
QVariantList list;
while (!xml.atEnd() && !xml.isEndElement()) {
while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == QLatin1String("list"))) {
xml.readNext();
switch (xml.tokenType()) {
case QXmlStreamReader::StartElement:
@ -107,7 +107,7 @@ static QVariantList listFromXml(QXmlStreamReader &xml, Converter::Options option
static VariantOrderedMap::value_type mapEntryFromXml(QXmlStreamReader &xml, Converter::Options options)
{
QVariant key, value;
while (!xml.atEnd() && !xml.isEndElement()) {
while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == QLatin1String("entry"))) {
xml.readNext();
switch (xml.tokenType()) {
case QXmlStreamReader::StartElement:
@ -150,7 +150,7 @@ static QVariant mapFromXml(QXmlStreamReader &xml, Converter::Options options)
QVariantMap map1;
VariantOrderedMap map2;
while (!xml.atEnd() && !xml.isEndElement()) {
while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == QLatin1String("map"))) {
xml.readNext();
switch (xml.tokenType()) {
case QXmlStreamReader::StartElement:

View File

@ -17,8 +17,8 @@ os_directory = $$(INTEGRITY_DIR)
isEmpty(os_directory): \
error("This qmakespec requires $INTEGRITY_DIR to be set")
QMAKE_CC = cxintarm64 -U__ARM_NEON__ -U__ARM_NEON -bsp $$bsp_name -os_dir $$os_directory -non_shared
QMAKE_CXX = cxintarm64 -U__ARM_NEON__ -U__ARM_NEON -bsp $$bsp_name -os_dir $$os_directory -non_shared
QMAKE_CC = cxintarm64 -bsp $$bsp_name -os_dir $$os_directory -non_shared
QMAKE_CXX = cxintarm64 -bsp $$bsp_name -os_dir $$os_directory -non_shared
QMAKE_LINK = $$QMAKE_CXX
QMAKE_AR = $$QMAKE_CXX -archive -o

View File

@ -254,7 +254,7 @@ void NmakeMakefileGenerator::init()
ProString tgt = project->first("DESTDIR")
+ project->first("TARGET") + project->first("TARGET_VERSION_EXT");
if(project->isActiveConfig("shared")) {
if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("shared")) {
project->values("QMAKE_CLEAN").append(tgt + ".exp");
project->values("QMAKE_DISTCLEAN").append(tgt + ".lib");
}

View File

@ -11,6 +11,7 @@
"icu": "boolean",
"inotify": "boolean",
"journald": "boolean",
"mimetype-database": "boolean",
"pcre": { "type": "enum", "values": [ "no", "qt", "system" ] },
"posix-ipc": { "type": "boolean", "name": "ipc_posix" },
"pps": { "type": "boolean", "name": "qqnx_pps" },
@ -374,6 +375,16 @@
]
}
},
"glibc": {
"label": "GNU libc",
"type": "compile",
"test": {
"include": "stdlib.h",
"main": [
"return __GLIBC__;"
]
}
},
"inotify": {
"label": "inotify",
"type": "compile",
@ -593,6 +604,12 @@
"condition": "libs.glib",
"output": [ "privateFeature", "feature" ]
},
"glibc": {
"label": "GNU libc",
"autoDetect": "config.linux",
"condition": "tests.glibc",
"output": [ "privateFeature" ]
},
"iconv": {
"label": "iconv",
"purpose": "Provides internationalization on Unix.",
@ -662,6 +679,11 @@
"condition": "features.textcodec",
"output": [ "publicFeature", "feature" ]
},
"mimetype-database": {
"label": "Built-in copy of the MIME database",
"condition": "features.mimetype",
"output": [ "privateFeature" ]
},
"pcre2": {
"label": "PCRE2",
"disable": "input.pcre == 'no' || input.pcre == 'system'",
@ -1036,6 +1058,7 @@ Please apply the patch corresponding to your Standard Library vendor, found in
"glib",
"iconv",
"icu",
"mimetype-database",
{
"message": "Tracing backend",
"type": "firstAvailableFeature",

View File

@ -78,7 +78,11 @@ QT_BEGIN_NAMESPACE
* - statx 4.11 QT_CONFIG(statx)
*/
#if QT_CONFIG(statx)
#if QT_CONFIG(statx) && !QT_CONFIG(glibc)
// if using glibc, the statx() function in sysdeps/unix/sysv/linux/statx.c
// falls back to stat() for us.
// (Using QT_CONFIG(glibc) instead of __GLIBC__ because the macros aren't
// defined in assembler mode)
# define MINLINUX_MAJOR 4
# define MINLINUX_MINOR 11
# define MINLINUX_PATCH 0

View File

@ -2355,6 +2355,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
bool wrap = flags & Qt::MatchWrap;
bool allHits = (hits == -1);
QString text; // only convert to a string if it is needed
const int column = start.column();
QModelIndex p = parent(start);
int from = start.row();
int to = rowCount(p);
@ -2362,7 +2363,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
// iterates twice if wrapping
for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
for (int r = from; (r < to) && (allHits || result.count() < hits); ++r) {
QModelIndex idx = index(r, start.column(), p);
QModelIndex idx = index(r, column, p);
if (!idx.isValid())
continue;
QVariant v = data(idx, role);
@ -2401,10 +2402,13 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role,
result.append(idx);
}
}
if (recurse && hasChildren(idx)) { // search the hierarchy
result += match(index(0, idx.column(), idx), role,
(text.isEmpty() ? value : text),
(allHits ? -1 : hits - result.count()), flags);
if (recurse) {
const auto parent = column != 0 ? idx.sibling(idx.row(), 0) : idx;
if (hasChildren(parent)) { // search the hierarchy
result += match(index(0, column, parent), role,
(text.isEmpty() ? value : text),
(allHits ? -1 : hits - result.count()), flags);
}
}
}
// prepare for the next iteration

View File

@ -61,7 +61,7 @@ public:
/*!
\class QSignalMapper
\inmodule QtCore
\obsolete
\obsolete The recommended solution is connecting the signal to a lambda.
\brief The QSignalMapper class bundles signals from identifiable senders.
\ingroup objectmodel

View File

@ -21,5 +21,5 @@ qtConfig(mimetype) {
mimetypes/qmimeglobpattern.cpp \
mimetypes/qmimeprovider.cpp
RESOURCES += mimetypes/mimetypes.qrc
qtConfig(mimetype-database): RESOURCES += mimetypes/mimetypes.qrc
}

View File

@ -54,7 +54,9 @@
static void initResources()
{
#if QT_CONFIG(mimetype_database)
Q_INIT_RESOURCE(mimetypes);
#endif
}
QT_BEGIN_NAMESPACE

View File

@ -227,7 +227,7 @@ std::string EventCallback::contextPropertyName(const std::string &eventName)
return std::string("data-qtEventCallbackContext") + eventName;
}
EMSCRIPTEN_BINDINGS(QtStdwebCalback) {
EMSCRIPTEN_BINDINGS(qtStdwebCalback) {
emscripten::function("qtStdWebEventCallbackActivate", &EventCallback::activate);
}

View File

@ -331,6 +331,7 @@ public:
private:
void init(const QByteArray &ianaId);
QVector<QTimeZonePrivate::Data> getPosixTransitions(qint64 msNear) const;
Data dataForTzTransition(QTzTransitionTime tran) const;
QVector<QTzTransitionTime> m_tranTimes;

View File

@ -943,19 +943,21 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::dataForTzTransition(QTzTransitionTime
return data;
}
QVector<QTimeZonePrivate::Data> QTzTimeZonePrivate::getPosixTransitions(qint64 msNear) const
{
const int year = QDateTime::fromMSecsSinceEpoch(msNear, Qt::UTC).date().year();
// The Data::atMSecsSinceEpoch of the single entry if zone is constant:
qint64 atTime = m_tranTimes.isEmpty() ? msNear : m_tranTimes.last().atMSecsSinceEpoch;
return calculatePosixTransitions(m_posixRule, year - 1, year + 1, atTime);
}
QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const
{
// If we have no rules (so probably an invalid tz), return invalid data:
if (!m_tranTimes.size())
return invalidData();
// If the required time is after the last transition and we have a POSIX rule then use it
if (m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch
// If the required time is after the last transition (or there were none)
// and we have a POSIX rule then use it:
if ((m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch)
&& !m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) {
const int year = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch, Qt::UTC).date().year();
QVector<QTimeZonePrivate::Data> posixTrans =
calculatePosixTransitions(m_posixRule, year - 1, year + 1,
m_tranTimes.last().atMSecsSinceEpoch);
QVector<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(forMSecsSinceEpoch);
auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
[forMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
return at.atMSecsSinceEpoch <= forMSecsSinceEpoch;
@ -986,13 +988,11 @@ bool QTzTimeZonePrivate::hasTransitions() const
QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const
{
// If the required time is after the last transition and we have a POSIX rule then use it
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch
// If the required time is after the last transition (or there were none)
// and we have a POSIX rule then use it:
if ((m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch)
&& !m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) {
const int year = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch, Qt::UTC).date().year();
QVector<QTimeZonePrivate::Data> posixTrans =
calculatePosixTransitions(m_posixRule, year - 1, year + 1,
m_tranTimes.last().atMSecsSinceEpoch);
QVector<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(afterMSecsSinceEpoch);
auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
[afterMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch;
@ -1011,19 +1011,19 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince
QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const
{
// If the required time is after the last transition and we have a POSIX rule then use it
if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch
// If the required time is after the last transition (or there were none)
// and we have a POSIX rule then use it:
if ((m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch)
&& !m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) {
const int year = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch, Qt::UTC).date().year();
QVector<QTimeZonePrivate::Data> posixTrans =
calculatePosixTransitions(m_posixRule, year - 1, year + 1,
m_tranTimes.last().atMSecsSinceEpoch);
QVector<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(beforeMSecsSinceEpoch);
auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
[beforeMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch;
});
Q_ASSERT(it > posixTrans.cbegin());
return *--it;
if (it > posixTrans.cbegin())
return *--it;
// It fell between the last transition (if any) and the first of the POSIX rule:
return m_tranTimes.isEmpty() ? invalidData() : dataForTzTransition(m_tranTimes.last());
}
// Otherwise if we can find a valid tran then use its rule

View File

@ -52,65 +52,41 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons
const quint32 *const end = dst + len;
// align dst on 64 bits
const int offsetToAlignOn8Bytes = (reinterpret_cast<quintptr>(dst) >> 2) & 0x1;
for (int i = 0; i < offsetToAlignOn8Bytes; ++i) {
// align dst on 128 bits
const int offsetToAlignOn16Bytes = (reinterpret_cast<quintptr>(dst) >> 2) & 0x3;
for (int i = 0; i < offsetToAlignOn16Bytes; ++i) {
*dst++ = qRgb(src[0], src[1], src[2]);
src += 3;
}
if ((len - offsetToAlignOn8Bytes) >= 8) {
const quint32 *const simdEnd = end - 7;
#if !defined(Q_PROCESSOR_ARM_64)
register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff);
do {
if ((len - offsetToAlignOn16Bytes) >= 16) {
const quint32 *const simdEnd = end - 15;
uint8x16x4_t dstVector;
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
asm volatile (
"vld3.8 { d4, d5, d6 }, [%[SRC]] !\n\t"
"vst4.8 { d3, d4, d5, d6 }, [%[DST],:64] !\n\t"
: [DST]"+r" (dst), [SRC]"+r" (src)
: "w"(fullVector)
: "memory", "d4", "d5", "d6"
);
dstVector.val[0] = vdupq_n_u8(0xff);
#else
asm volatile (
"vld3.8 { d0, d1, d2 }, [%[SRC]] !\n\t"
"vswp d0, d2\n\t"
"vst4.8 { d0, d1, d2, d3 }, [%[DST],:64] !\n\t"
: [DST]"+r" (dst), [SRC]"+r" (src)
: "w"(fullVector)
: "memory", "d0", "d1", "d2"
);
dstVector.val[3] = vdupq_n_u8(0xff);
#endif
} while (dst < simdEnd);
#else
register uint8x8_t fullVector asm ("v3") = vdup_n_u8(0xff);
do {
uint8x16x3_t srcVector = vld3q_u8(src);
src += 3 * 16;
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
asm volatile (
"ld3 { v4.8b, v5.8b, v6.8b }, [%[SRC]], #24 \n\t"
"st4 { v3.8b, v4.8b, v5.8b, v6.8b }, [%[DST]], #32 \n\t"
: [DST]"+r" (dst), [SRC]"+r" (src)
: "w"(fullVector)
: "memory", "v4", "v5", "v6"
);
dstVector.val[1] = srcVector.val[0];
dstVector.val[2] = srcVector.val[1];
dstVector.val[3] = srcVector.val[2];
#else
asm volatile (
"ld3 { v0.8b, v1.8b, v2.8b }, [%[SRC]], #24 \n\t"
"mov v4.8b, v2.8b\n\t"
"mov v2.8b, v0.8b\n\t"
"mov v0.8b, v4.8b\n\t"
"st4 { v0.8b, v1.8b, v2.8b, v3.8b }, [%[DST]], #32 \n\t"
: [DST]"+r" (dst), [SRC]"+r" (src)
: "w"(fullVector)
: "memory", "v0", "v1", "v2", "v4"
);
dstVector.val[0] = srcVector.val[2];
dstVector.val[1] = srcVector.val[1];
dstVector.val[2] = srcVector.val[0];
#endif
vst4q_u8(reinterpret_cast<uint8_t*>(dst), dstVector);
dst += 16;
} while (dst < simdEnd);
#endif
}
while (dst != end) {
int i = 0;
int length = end - dst;
SIMD_EPILOGUE(i, length, 15) {
*dst++ = qRgb(src[0], src[1], src[2]);
src += 3;
}

View File

@ -1552,6 +1552,11 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
if (image.isNull())
return QPixmap();
if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
qWarning("QPixmap::fromImage: QPixmap cannot be created without a QGuiApplication");
return QPixmap();
}
QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImage(image, flags);
return QPixmap(data.take());
@ -1574,6 +1579,11 @@ QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
if (image.isNull())
return QPixmap();
if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
qWarning("QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
return QPixmap();
}
QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImageInPlace(image, flags);
return QPixmap(data.take());
@ -1593,6 +1603,11 @@ QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
*/
QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
{
if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
qWarning("QPixmap::fromImageReader: QPixmap cannot be created without a QGuiApplication");
return QPixmap();
}
QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImageReader(imageReader, flags);
return QPixmap(data.take());

View File

@ -708,10 +708,11 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QScreen *screen = effectiveScreen(w);
if (!screen)
return initialGeometry;
const auto *wp = qt_window_private(const_cast<QWindow*>(w));
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
if (qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
&& w->type() != Qt::Popup) {
if (wp->resizeAutomatic)
rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
if (wp->positionAutomatic && w->type() != Qt::Popup) {
const QRect availableGeometry = screen->availableGeometry();
// Center unless the geometry ( + unknown window frame) is too large for the screen).
if (rect.height() < (availableGeometry.height() * 8) / 9

View File

@ -90,6 +90,7 @@ public:
, receivedExpose(false)
, positionPolicy(WindowFrameExclusive)
, positionAutomatic(true)
, resizeAutomatic(true)
, contentOrientation(Qt::PrimaryOrientation)
, opacity(qreal(1.0))
, minimumSize(0, 0)
@ -156,6 +157,8 @@ public:
virtual void processSafeAreaMarginsChanged() {};
bool isPopup() const { return (windowFlags & Qt::WindowType_Mask) == Qt::Popup; }
void setAutomaticPositionAndResizeEnabled(bool a)
{ positionAutomatic = resizeAutomatic = a; }
static QWindowPrivate *get(QWindow *window) { return window->d_func(); }
@ -179,6 +182,11 @@ public:
bool receivedExpose;
PositionPolicy positionPolicy;
bool positionAutomatic;
// resizeAutomatic suppresses resizing by QPlatformWindow::initialGeometry().
// It also indicates that width/height=0 is acceptable (for example, for
// the QRollEffect widget) and is thus not cleared in setGeometry().
// An alternative approach might be using -1,-1 as a default size.
bool resizeAutomatic;
Qt::ScreenOrientation contentOrientation;
qreal opacity;
QRegion mask;

View File

@ -143,9 +143,11 @@ ARCH_HASWELL_SOURCES += painting/qdrawhelper_avx2.cpp
NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
NEON_HEADERS += painting/qdrawhelper_neon_p.h
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
!uikit:!win32:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as
!uikit:!win32:!contains(QT_ARCH, "arm64"): DEFINES += ENABLE_PIXMAN_DRAWHELPERS
!uikit:!win32:!integrity:!contains(QT_ARCH, "arm64") {
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
DEFINES += ENABLE_PIXMAN_DRAWHELPERS
}
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h

View File

@ -50,7 +50,18 @@ QT_BEGIN_NAMESPACE
void qt_memfill32(quint32 *dest, quint32 value, qsizetype count)
{
const int epilogueSize = count % 16;
#if !defined(Q_PROCESSOR_ARM_64)
#if defined(Q_CC_GHS) || defined(Q_CC_MSVC)
// inline assembler free version:
if (count >= 16) {
quint32 *const neonEnd = dest + count - epilogueSize;
const uint32x4_t valueVector1 = vdupq_n_u32(value);
const uint32x4x4_t valueVector4 = { valueVector1, valueVector1, valueVector1, valueVector1 };
do {
vst4q_u32(dest, valueVector4);
dest += 16;
} while (dest != neonEnd);
}
#elif !defined(Q_PROCESSOR_ARM_64)
if (count >= 16) {
quint32 *const neonEnd = dest + count - epilogueSize;
register uint32x4_t valueVector1 asm ("q0") = vdupq_n_u32(value);

View File

@ -1754,7 +1754,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si,
#ifdef Q_OS_DARWIN
if (actualFontEngine->type() == QFontEngine::Mac) {
if (actualFontEngine->fontDef.stretch != 100) {
if (actualFontEngine->fontDef.stretch != 100 && actualFontEngine->fontDef.stretch != QFont::AnyStretch) {
QFixed stretch = QFixed(int(actualFontEngine->fontDef.stretch)) / QFixed(100);
for (uint i = 0; i < num_glyphs; ++i)
g.advances[i] *= stretch;

View File

@ -191,8 +191,8 @@ bool QNetworkCacheMetaData::isValid() const
Some cache implementations can keep these cache items in memory for performance reasons,
but for security reasons they should not be written to disk.
Specifically with http, documents marked with Pragma: no-cache, or have a Cache-control set to
no-store or no-cache or any https document that doesn't have "Cache-control: public" set will
Specifically with http, documents with Cache-control set to no-store or any
https document that doesn't have "Cache-control: public" set will
set the saveToDisk to false.
\sa setSaveToDisk()

View File

@ -198,7 +198,7 @@ QHttp2ProtocolHandler::QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *chan
}
}
if (!channel->ssl) {
if (!channel->ssl && m_connection->connectionType() != QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
// We upgraded from HTTP/1.1 to HTTP/2. channel->request was already sent
// as HTTP/1.1 request. The response with status code 101 triggered
// protocol switch and now we are waiting for the real response, sent

View File

@ -87,15 +87,16 @@ bool QNetworkAccessCacheBackend::sendCacheContents()
setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, attributes.value(QNetworkRequest::HttpReasonPhraseAttribute));
// set the raw headers
QNetworkCacheMetaData::RawHeaderList rawHeaders = item.rawHeaders();
QNetworkCacheMetaData::RawHeaderList::ConstIterator it = rawHeaders.constBegin(),
end = rawHeaders.constEnd();
for ( ; it != end; ++it) {
if (it->first.toLower() == "cache-control" &&
it->second.toLower().contains("must-revalidate")) {
return false;
const QNetworkCacheMetaData::RawHeaderList rawHeaders = item.rawHeaders();
for (const auto &header : rawHeaders) {
if (header.first.toLower() == "cache-control") {
const QByteArray cacheControlValue = header.second.toLower();
if (cacheControlValue.contains("must-revalidate")
|| cacheControlValue.contains("no-cache")) {
return false;
}
}
setRawHeader(it->first, it->second);
setRawHeader(header.first, header.second);
}
// handle a possible redirect

View File

@ -524,6 +524,8 @@ bool QNetworkReplyHttpImplPrivate::loadFromCacheIfAllowed(QHttpNetworkRequest &h
QHash<QByteArray, QByteArray> cacheControl = parseHttpOptionHeader(it->second);
if (cacheControl.contains("must-revalidate"))
return false;
if (cacheControl.contains("no-cache"))
return false;
}
QDateTime currentDateTime = QDateTime::currentDateTimeUtc();
@ -1731,18 +1733,8 @@ QNetworkCacheMetaData QNetworkReplyHttpImplPrivate::fetchCacheMetaData(const QNe
if (httpRequest.operation() == QHttpNetworkRequest::Get) {
canDiskCache = true;
// 14.32
// HTTP/1.1 caches SHOULD treat "Pragma: no-cache" as if the client
// had sent "Cache-Control: no-cache".
it = cacheHeaders.findRawHeader("pragma");
if (it != cacheHeaders.rawHeaders.constEnd()
&& it->second == "no-cache")
canDiskCache = false;
// HTTP/1.1. Check the Cache-Control header
if (cacheControl.contains("no-cache"))
canDiskCache = false;
else if (cacheControl.contains("no-store"))
if (cacheControl.contains("no-store"))
canDiskCache = false;
// responses to POST might be cacheable

View File

@ -117,7 +117,7 @@ static void q_loadCallback(val event)
val blob = xhr["response"];
val reader = val::global("FileReader").new_();
reader.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_readBinary"));
reader.set("onload", val::module_property("qt_QNetworkReplyWasmImplPrivate_readBinary"));
reader.set("data-handler", xhr["data-handler"]);
reader.call<void>("readAsArrayBuffer", blob);
@ -174,12 +174,12 @@ static void q_readBinary(val event)
QCoreApplication::processEvents();
}
EMSCRIPTEN_BINDINGS(network_module) {
function("QNetworkReplyWasmImplPrivate_requestErrorCallback", q_requestErrorCallback);
function("QNetworkReplyWasmImplPrivate_progressCallback", q_progressCallback);
function("QNetworkReplyWasmImplPrivate_loadCallback", q_loadCallback);
function("QNetworkReplyWasmImplPrivate_responseHeadersCallback", q_responseHeadersCallback);
function("QNetworkReplyWasmImplPrivate_readBinary", q_readBinary);
EMSCRIPTEN_BINDINGS(qtNetworkModule) {
function("qt_QNetworkReplyWasmImplPrivate_requestErrorCallback", q_requestErrorCallback);
function("qt_QNetworkReplyWasmImplPrivate_progressCallback", q_progressCallback);
function("qt_QNetworkReplyWasmImplPrivate_loadCallback", q_loadCallback);
function("qt_QNetworkReplyWasmImplPrivate_responseHeadersCallback", q_responseHeadersCallback);
function("qt_QNetworkReplyWasmImplPrivate_readBinary", q_readBinary);
}
QNetworkReplyWasmImplPrivate::QNetworkReplyWasmImplPrivate()
@ -332,10 +332,10 @@ void QNetworkReplyWasmImplPrivate::doSendRequest()
m_xhr.call<void>("open", verb, request.url().toString().toStdString());
m_xhr.set("onerror", val::module_property("QNetworkReplyWasmImplPrivate_requestErrorCallback"));
m_xhr.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_loadCallback"));
m_xhr.set("onprogress", val::module_property("QNetworkReplyWasmImplPrivate_progressCallback"));
m_xhr.set("onreadystatechange", val::module_property("QNetworkReplyWasmImplPrivate_responseHeadersCallback"));
m_xhr.set("onerror", val::module_property("qt_QNetworkReplyWasmImplPrivate_requestErrorCallback"));
m_xhr.set("onload", val::module_property("qt_QNetworkReplyWasmImplPrivate_loadCallback"));
m_xhr.set("onprogress", val::module_property("qt_QNetworkReplyWasmImplPrivate_progressCallback"));
m_xhr.set("onreadystatechange", val::module_property("qt_QNetworkReplyWasmImplPrivate_responseHeadersCallback"));
m_xhr.set("data-handler", val(quintptr(reinterpret_cast<void *>(this))));

View File

@ -491,9 +491,11 @@ void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextIt
struct ConvertPathInfo
{
ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos) : path(newPath), pos(newPos) {}
ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos, qreal newStretch = 1.0) :
path(newPath), pos(newPos), stretch(newStretch) {}
QPainterPath *path;
QPointF pos;
qreal stretch;
};
static void convertCGPathToQPainterPath(void *info, const CGPathElement *element)
@ -501,25 +503,25 @@ static void convertCGPathToQPainterPath(void *info, const CGPathElement *element
ConvertPathInfo *myInfo = static_cast<ConvertPathInfo *>(info);
switch(element->type) {
case kCGPathElementMoveToPoint:
myInfo->path->moveTo(element->points[0].x + myInfo->pos.x(),
myInfo->path->moveTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(),
element->points[0].y + myInfo->pos.y());
break;
case kCGPathElementAddLineToPoint:
myInfo->path->lineTo(element->points[0].x + myInfo->pos.x(),
myInfo->path->lineTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(),
element->points[0].y + myInfo->pos.y());
break;
case kCGPathElementAddQuadCurveToPoint:
myInfo->path->quadTo(element->points[0].x + myInfo->pos.x(),
myInfo->path->quadTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(),
element->points[0].y + myInfo->pos.y(),
element->points[1].x + myInfo->pos.x(),
(element->points[1].x * myInfo->stretch) + myInfo->pos.x(),
element->points[1].y + myInfo->pos.y());
break;
case kCGPathElementAddCurveToPoint:
myInfo->path->cubicTo(element->points[0].x + myInfo->pos.x(),
myInfo->path->cubicTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(),
element->points[0].y + myInfo->pos.y(),
element->points[1].x + myInfo->pos.x(),
(element->points[1].x * myInfo->stretch) + myInfo->pos.x(),
element->points[1].y + myInfo->pos.y(),
element->points[2].x + myInfo->pos.x(),
(element->points[2].x * myInfo->stretch) + myInfo->pos.x(),
element->points[2].y + myInfo->pos.y());
break;
case kCGPathElementCloseSubpath:
@ -543,9 +545,10 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position
if (synthesisFlags & QFontEngine::SynthesizedItalic)
cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
qreal stretch = fontDef.stretch ? qreal(fontDef.stretch) / 100 : 1.0;
for (int i = 0; i < nGlyphs; ++i) {
QCFType<CGPathRef> cgpath = CTFontCreatePathForGlyph(ctfont, glyphs[i], &cgMatrix);
ConvertPathInfo info(path, positions[i].toPointF());
ConvertPathInfo info(path, positions[i].toPointF(), stretch);
CGPathApply(cgpath, &info, convertCGPathToQPainterPath);
}
}

View File

@ -702,8 +702,8 @@ static inline double qt_fixed_to_double(const FIXED &p) {
return ((p.value << 16) + p.fract) / 65536.0;
}
static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) {
return QPointF(qt_fixed_to_double(pt.x) * scale, -qt_fixed_to_double(pt.y) * scale);
static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale, qreal stretch) {
return QPointF(qt_fixed_to_double(pt.x) * scale * stretch, -qt_fixed_to_double(pt.y) * scale);
}
#ifndef GGO_UNHINTED
@ -711,7 +711,8 @@ static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) {
#endif
static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1)
QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0,
qreal scale = 1.0, qreal stretch = 1.0)
{
MAT2 mat;
mat.eM11.value = mat.eM22.value = 1;
@ -761,7 +762,7 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
while (headerOffset < bufferSize) {
const TTPOLYGONHEADER *ttph = reinterpret_cast<const TTPOLYGONHEADER *>(dataBuffer + headerOffset);
QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale));
QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale, stretch));
path->moveTo(lastPoint + oset);
offset += sizeof(TTPOLYGONHEADER);
while (offset < headerOffset + ttph->cb) {
@ -769,7 +770,7 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
switch (curve->wType) {
case TT_PRIM_LINE: {
for (int i=0; i<curve->cpfx; ++i) {
QPointF p = qt_to_qpointf(curve->apfx[i], scale) + oset;
QPointF p = qt_to_qpointf(curve->apfx[i], scale, stretch) + oset;
path->lineTo(p);
}
break;
@ -779,8 +780,8 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
QPointF prev(elm.x, elm.y);
QPointF endPoint;
for (int i=0; i<curve->cpfx - 1; ++i) {
QPointF p1 = qt_to_qpointf(curve->apfx[i], scale) + oset;
QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale) + oset;
QPointF p1 = qt_to_qpointf(curve->apfx[i], scale, stretch) + oset;
QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale, stretch) + oset;
if (i < curve->cpfx - 2) {
endPoint = QPointF((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2);
} else {
@ -795,9 +796,9 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
}
case TT_PRIM_CSPLINE: {
for (int i=0; i<curve->cpfx; ) {
QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + oset;
QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + oset;
QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + oset;
path->cubicTo(p2, p3, p4);
}
break;
@ -829,9 +830,11 @@ void QWindowsFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions
HDC hdc = m_fontEngineData->hdc;
HGDIOBJ oldfont = SelectObject(hdc, hf);
qreal scale = qreal(fontDef.pixelSize) / unitsPerEm;
qreal stretch = fontDef.stretch ? qreal(fontDef.stretch) / 100 : 1.0;
for(int i = 0; i < nglyphs; ++i) {
if (!addGlyphToPath(glyphs[i], positions[i], hdc, path, ttf, /*metric*/0,
qreal(fontDef.pixelSize) / unitsPerEm)) {
scale, stretch)) {
// Some windows fonts, like "Modern", are vector stroke
// fonts, which are reported as TMPF_VECTOR but do not
// support GetGlyphOutline, and thus we set this bit so

View File

@ -83,7 +83,7 @@ QTsLibMouseHandler::QTsLibMouseHandler(const QString &key,
if (fd >= 0) {
qCDebug(qLcTsLib) << "tslib device is" << device;
m_notify = new QSocketNotifier(fd, QSocketNotifier::Read, this);
connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData()));
connect(m_notify, &QSocketNotifier::activated, this, &QTsLibMouseHandler::readMouseData);
} else {
qErrnoWarning(errno, "tslib: Cannot open input device %s", device.constData());
}
@ -127,7 +127,9 @@ void QTsLibMouseHandler::readMouseData()
}
QPoint pos(x, y);
QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton);
QWindowSystemInterface::handleMouseEvent(nullptr, pos, pos,
pressed ? Qt::LeftButton : Qt::NoButton,
Qt::NoButton, QEvent::None);
m_x = x;
m_y = y;

View File

@ -250,6 +250,9 @@ void QCocoaMenu::syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUp
if (wasMerged) {
oldItem.enabled = NO;
oldItem.hidden = YES;
oldItem.keyEquivalent = @"";
oldItem.keyEquivalentModifierMask = NSEventModifierFlagCommand;
} else {
[m_nativeMenu removeItem:oldItem];
}

View File

@ -158,10 +158,13 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
pal.setColor(QPalette::Inactive, QPalette::WindowText, qc);
pal.setColor(QPalette::Active, QPalette::HighlightedText, qc);
pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc);
pal.setColor(QPalette::Active, QPalette::ButtonText, qc);
pal.setColor(QPalette::Inactive, QPalette::ButtonText, qc);
qc = qt_mac_toQColor(mac_widget_colors[i].inactive);
pal.setColor(QPalette::Disabled, QPalette::Text, qc);
pal.setColor(QPalette::Disabled, QPalette::WindowText, qc);
pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
pal.setColor(QPalette::Disabled, QPalette::ButtonText, qc);
}
if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette
|| mac_widget_colors[i].paletteRole == QPlatformTheme::MenuBarPalette) {

View File

@ -76,8 +76,8 @@ static void qClipboardCutTo(val event)
}
val module = val::global("Module");
val clipdata = module.call<val>("getClipboardData");
val clipFormat = module.call<val>("getClipboardFormat");
val clipdata = module.call<val>("qtGetClipboardData");
val clipFormat = module.call<val>("qtGetClipboardFormat");
event["clipboardData"].call<void>("setData", clipFormat, clipdata);
event.call<void>("preventDefault");
}
@ -91,8 +91,8 @@ static void qClipboardCopyTo(val event)
}
val module = val::global("Module");
val clipdata = module.call<val>("getClipboardData");
val clipFormat = module.call<val>("getClipboardFormat");
val clipdata = module.call<val>("qtGetClipboardData");
val clipFormat = module.call<val>("qtGetClipboardFormat");
event["clipboardData"].call<void>("setData", clipFormat, clipdata);
event.call<void>("preventDefault");
}
@ -101,7 +101,7 @@ static void qClipboardPasteTo(val event)
{
bool hasClipboardApi = QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi;
val clipdata = hasClipboardApi ?
val::global("Module").call<val>("getClipboardData") :
val::global("Module").call<val>("qtGetClipboardData") :
event["clipboardData"].call<val>("getData", std::string("text"));
const std::string data = clipdata.as<std::string>();
@ -113,14 +113,14 @@ static void qClipboardPasteTo(val event)
}
}
EMSCRIPTEN_BINDINGS(clipboard_module) {
function("getClipboardData", &getClipboardData);
function("getClipboardFormat", &getClipboardFormat);
function("pasteClipboardData", &pasteClipboardData);
function("qClipboardPromiseResolve", &qClipboardPromiseResolve);
function("qClipboardCutTo", &qClipboardCutTo);
function("qClipboardCopyTo", &qClipboardCopyTo);
function("qClipboardPasteTo", &qClipboardPasteTo);
EMSCRIPTEN_BINDINGS(qtClipboardModule) {
function("qtGetClipboardData", &getClipboardData);
function("qtGetClipboardFormat", &getClipboardFormat);
function("qtPasteClipboardData", &pasteClipboardData);
function("qtClipboardPromiseResolve", &qClipboardPromiseResolve);
function("qtClipboardCutTo", &qClipboardCutTo);
function("qtClipboardCopyTo", &qClipboardCopyTo);
function("qtClipboardPasteTo", &qClipboardPasteTo);
}
QWasmClipboard::QWasmClipboard()
@ -200,11 +200,11 @@ void QWasmClipboard::installEventHandlers(const QString &canvasId)
// Fallback path for browsers which do not support direct clipboard access
val canvas = val::global(canvasId.toUtf8().constData());
canvas.call<void>("addEventListener", std::string("cut"),
val::module_property("qClipboardCutTo"));
val::module_property("qtClipboardCutTo"));
canvas.call<void>("addEventListener", std::string("copy"),
val::module_property("qClipboardCopyTo"));
val::module_property("qtClipboardCopyTo"));
canvas.call<void>("addEventListener", std::string("paste"),
val::module_property("qClipboardPasteTo"));
val::module_property("qtClipboardPasteTo"));
}
void QWasmClipboard::readTextFromClipboard()
@ -212,7 +212,7 @@ void QWasmClipboard::readTextFromClipboard()
if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) {
val navigator = val::global("navigator");
val textPromise = navigator["clipboard"].call<val>("readText");
val readTextResolve = val::global("Module")["qClipboardPromiseResolve"];
val readTextResolve = val::global("Module")["qtClipboardPromiseResolve"];
textPromise.call<val>("then", readTextResolve);
}
}
@ -221,8 +221,8 @@ void QWasmClipboard::writeTextToClipboard()
{
if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) {
val module = val::global("Module");
val txt = module.call<val>("getClipboardData");
val format = module.call<val>("getClipboardFormat");
val txt = module.call<val>("qtGetClipboardData");
val format = module.call<val>("qtGetClipboardFormat");
val navigator = val::global("navigator");
navigator["clipboard"].call<void>("writeText", txt.as<std::string>());
}

View File

@ -316,8 +316,8 @@ static void mouseWheelEvent(emscripten::val event) {
}
}
EMSCRIPTEN_BINDINGS(mouse_module) {
function("mouseWheelEvent", &mouseWheelEvent);
EMSCRIPTEN_BINDINGS(qtMouseModule) {
function("qtMouseWheelEvent", &mouseWheelEvent);
}
QWasmEventTranslator::QWasmEventTranslator(QWasmScreen *screen)
@ -358,7 +358,7 @@ void QWasmEventTranslator::initEventHandlers()
emscripten::val::global(canvasId).call<void>("addEventListener",
std::string("wheel"),
val::module_property("mouseWheelEvent"));
val::module_property("qtMouseWheelEvent"));
}
}

View File

@ -56,14 +56,14 @@
using namespace emscripten;
QT_BEGIN_NAMESPACE
void browserBeforeUnload(emscripten::val)
static void browserBeforeUnload(emscripten::val)
{
QWasmIntegration::QWasmBrowserExit();
}
EMSCRIPTEN_BINDINGS(my_module)
EMSCRIPTEN_BINDINGS(qtQWasmIntegraton)
{
function("browserBeforeUnload", &browserBeforeUnload);
function("qtBrowserBeforeUnload", &browserBeforeUnload);
}
QWasmIntegration *QWasmIntegration::s_instance;
@ -92,7 +92,7 @@ QWasmIntegration::QWasmIntegration()
addScreen(canvasId);
}
emscripten::val::global("window").set("onbeforeunload", val::module_property("browserBeforeUnload"));
emscripten::val::global("window").set("onbeforeunload", val::module_property("qtBrowserBeforeUnload"));
}
QWasmIntegration::~QWasmIntegration()

View File

@ -1132,7 +1132,8 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
// TODO: No concept of WA_wasMoved yet that would indicate a
// CW_USEDEFAULT unless set. For now, assume that 0,0 means 'default'
// for toplevels.
if (geometry.isValid()) {
if (geometry.isValid()
|| !qt_window_private(const_cast<QWindow *>(w))->resizeAutomatic) {
frameX = geometry.x();
frameY = geometry.y();
const QMargins effectiveMargins = margins + customMargins;

View File

@ -2645,6 +2645,13 @@ bool QXRenderGlyphCache::addGlyphs(const QTextItemInt &ti,
if (glyph == 0 || glyph->format != glyphFormat())
return false;
if (glyph->format == QFontEngine::Format_Mono) {
// Must convert bitmap from msb to lsb bit order
QImage img(glyph->data, glyph->width, glyph->height, QImage::Format_Mono);
img = img.convertToFormat(QImage::Format_MonoLSB);
memcpy(glyph->data, img.constBits(), static_cast<size_t>(img.sizeInBytes()));
}
set->setGlyph(glyphs[i], spp, glyph);
Q_ASSERT(glyph->data || glyph->width == 0 || glyph->height == 0);

View File

@ -2,7 +2,7 @@
defineTest(qtConfLibrary_psqlConfig) {
pg_config = $$config.input.psql_config
isEmpty(pg_config): \
isEmpty(pg_config):!cross_compile: \
pg_config = $$qtConfFindInPath("pg_config")
!win32:!isEmpty(pg_config) {
qtRunLoggedCommand("$$pg_config --libdir", libdir)|return(false)
@ -33,7 +33,7 @@ defineTest(qtConfLibrary_psqlEnv) {
defineTest(qtConfLibrary_mysqlConfig) {
mysql_config = $$config.input.mysql_config
isEmpty(mysql_config): \
isEmpty(mysql_config):!cross_compile: \
mysql_config = $$qtConfFindInPath("mysql_config")
!isEmpty(mysql_config) {
qtRunLoggedCommand("$$mysql_config --version", version)|return(false)

View File

@ -356,15 +356,44 @@ static const qreal titleBarButtonSpacing = 8;
// active: window is active
// selected: tab is selected
// hovered: tab is hovered
static const QColor tabBarTabBackgroundActive(190, 190, 190);
static const QColor tabBarTabBackgroundActiveHovered(178, 178, 178);
static const QColor tabBarTabBackgroundActiveSelected(211, 211, 211);
static const QColor tabBarTabBackground(227, 227, 227);
static const QColor tabBarTabBackgroundSelected(246, 246, 246);
static const QColor tabBarTabLineActive(160, 160, 160);
static const QColor tabBarTabLineActiveHovered(150, 150, 150);
static const QColor tabBarTabLine(210, 210, 210);
static const QColor tabBarTabLineSelected(189, 189, 189);
bool isDarkMode() { return qt_mac_applicationIsInDarkMode(); }
static const QColor lightTabBarTabBackgroundActive(190, 190, 190);
static const QColor darkTabBarTabBackgroundActive(38, 38, 38);
static const QColor tabBarTabBackgroundActive() { return isDarkMode() ? darkTabBarTabBackgroundActive : lightTabBarTabBackgroundActive; }
static const QColor lightTabBarTabBackgroundActiveHovered(178, 178, 178);
static const QColor darkTabBarTabBackgroundActiveHovered(32, 32, 32);
static const QColor tabBarTabBackgroundActiveHovered() { return isDarkMode() ? darkTabBarTabBackgroundActiveHovered : lightTabBarTabBackgroundActiveHovered; }
static const QColor lightTabBarTabBackgroundActiveSelected(211, 211, 211);
static const QColor darkTabBarTabBackgroundActiveSelected(52, 52, 52);
static const QColor tabBarTabBackgroundActiveSelected() { return isDarkMode() ? darkTabBarTabBackgroundActiveSelected : lightTabBarTabBackgroundActiveSelected; }
static const QColor lightTabBarTabBackground(227, 227, 227);
static const QColor darkTabBarTabBackground(38, 38, 38);
static const QColor tabBarTabBackground() { return isDarkMode() ? darkTabBarTabBackground : lightTabBarTabBackground; }
static const QColor lightTabBarTabBackgroundSelected(246, 246, 246);
static const QColor darkTabBarTabBackgroundSelected(52, 52, 52);
static const QColor tabBarTabBackgroundSelected() { return isDarkMode() ? darkTabBarTabBackgroundSelected : lightTabBarTabBackgroundSelected; }
static const QColor lightTabBarTabLineActive(160, 160, 160);
static const QColor darkTabBarTabLineActive(90, 90, 90);
static const QColor tabBarTabLineActive() { return isDarkMode() ? darkTabBarTabLineActive : lightTabBarTabLineActive; }
static const QColor lightTabBarTabLineActiveHovered(150, 150, 150);
static const QColor darkTabBarTabLineActiveHovered(90, 90, 90);
static const QColor tabBarTabLineActiveHovered() { return isDarkMode() ? darkTabBarTabLineActiveHovered : lightTabBarTabLineActiveHovered; }
static const QColor lightTabBarTabLine(210, 210, 210);
static const QColor darkTabBarTabLine(90, 90, 90);
static const QColor tabBarTabLine() { return isDarkMode() ? darkTabBarTabLine : lightTabBarTabLine; }
static const QColor lightTabBarTabLineSelected(189, 189, 189);
static const QColor darkTabBarTabLineSelected(90, 90, 90);
static const QColor tabBarTabLineSelected() { return isDarkMode() ? darkTabBarTabLineSelected : lightTabBarTabLineSelected; }
static const QColor tabBarCloseButtonBackgroundHovered(162, 162, 162);
static const QColor tabBarCloseButtonBackgroundPressed(153, 153, 153);
static const QColor tabBarCloseButtonBackgroundSelectedHovered(192, 192, 192);
@ -561,7 +590,7 @@ void drawTabShape(QPainter *p, const QStyleOptionTab *tabOpt, bool isUnified, in
const bool active = (tabOpt->state & QStyle::State_Active);
const bool selected = (tabOpt->state & QStyle::State_Selected);
const QRect bodyRect(1, 1, width - 2, height - 2);
const QRect bodyRect(1, 2, width - 2, height - 3);
const QRect topLineRect(1, 0, width - 2, 1);
const QRect bottomLineRect(1, height - 1, width - 2, 1);
if (selected) {
@ -572,27 +601,27 @@ void drawTabShape(QPainter *p, const QStyleOptionTab *tabOpt, bool isUnified, in
p->fillRect(tabRect, QColor(Qt::transparent));
p->restore();
} else if (active) {
p->fillRect(bodyRect, tabBarTabBackgroundActiveSelected);
p->fillRect(bodyRect, tabBarTabBackgroundActiveSelected());
// top line
p->fillRect(topLineRect, tabBarTabLineSelected);
p->fillRect(topLineRect, tabBarTabLineSelected());
} else {
p->fillRect(bodyRect, tabBarTabBackgroundSelected);
p->fillRect(bodyRect, tabBarTabBackgroundSelected());
}
} else {
// when the mouse is over non selected tabs they get a new color
const bool hover = (tabOpt->state & QStyle::State_MouseOver);
if (hover) {
// fill body
p->fillRect(bodyRect, tabBarTabBackgroundActiveHovered);
p->fillRect(bodyRect, tabBarTabBackgroundActiveHovered());
// bottom line
p->fillRect(bottomLineRect, tabBarTabLineActiveHovered);
p->fillRect(bottomLineRect, isDarkMode() ? QColor(Qt::black) : tabBarTabLineActiveHovered());
}
}
// separator lines between tabs
const QRect leftLineRect(0, 1, 1, height - 2);
const QRect rightLineRect(width - 1, 1, 1, height - 2);
const QColor separatorLineColor = active ? tabBarTabLineActive : tabBarTabLine;
const QColor separatorLineColor = active ? tabBarTabLineActive() : tabBarTabLine();
p->fillRect(leftLineRect, separatorLineColor);
p->fillRect(rightLineRect, separatorLineColor);
}
@ -612,17 +641,20 @@ void drawTabBase(QPainter *p, const QStyleOptionTabBarBase *tbb, const QWidget *
// fill body
const QRect bodyRect(0, 1, width, height - 1);
const QColor bodyColor = active ? tabBarTabBackgroundActive : tabBarTabBackground;
const QColor bodyColor = active ? tabBarTabBackgroundActive() : tabBarTabBackground();
p->fillRect(bodyRect, bodyColor);
// top line
const QRect topLineRect(0, 0, width, 1);
const QColor topLineColor = active ? tabBarTabLineActive : tabBarTabLine;
const QColor topLineColor = active ? tabBarTabLineActive() : tabBarTabLine();
p->fillRect(topLineRect, topLineColor);
// bottom line
const QRect bottomLineRect(0, height - 1, width, 1);
const QColor bottomLineColor = active ? tabBarTabLineActive : tabBarTabLine;
bool isDocument = false;
if (const QTabBar *tabBar = qobject_cast<const QTabBar*>(w))
isDocument = tabBar->documentMode();
const QColor bottomLineColor = isDocument && isDarkMode() ? QColor(Qt::black) : active ? tabBarTabLineActive() : tabBarTabLine();
p->fillRect(bottomLineRect, bottomLineColor);
}
#endif
@ -1124,6 +1156,66 @@ static QStyleHelper::WidgetSizePolicy qt_aqua_guess_size(const QWidget *widg, QS
}
#endif
static NSColor *qt_convertColorForContext(CGContextRef context, NSColor *color)
{
Q_ASSERT(color);
Q_ASSERT(context);
CGColorSpaceRef targetCGColorSpace = CGBitmapContextGetColorSpace(context);
NSColorSpace *targetNSColorSpace = [[NSColorSpace alloc] initWithCGColorSpace:targetCGColorSpace];
NSColor *adjusted = [color colorUsingColorSpace:targetNSColorSpace];
[targetNSColorSpace release];
return adjusted;
}
static NSColor *qt_colorForContext(CGContextRef context, const CGFloat (&rgba)[4])
{
Q_ASSERT(context);
auto colorSpace = CGBitmapContextGetColorSpace(context);
if (!colorSpace)
return nil;
return qt_convertColorForContext(context, [NSColor colorWithSRGBRed:rgba[0] green:rgba[1] blue:rgba[2] alpha:rgba[3]]);
}
static void qt_drawDisclosureButton(CGContextRef context, NSInteger state, bool selected, CGRect rect)
{
Q_ASSERT(context);
static const CGFloat gray[] = {0.55, 0.55, 0.55, 0.97};
static const CGFloat white[] = {1.0, 1.0, 1.0, 0.9};
NSColor *fillColor = qt_colorForContext(context, selected ? white : gray);
[fillColor setFill];
if (state == NSOffState) {
static NSBezierPath *triangle = [[NSBezierPath alloc] init];
[triangle removeAllPoints];
// In off state, a disclosure button is an equilateral triangle
// ('pointing' to the right) with a bound rect that can be described
// as NSMakeRect(0, 0, 8, 9). Inside the 'rect' it's translated by
// (2, 4).
[triangle moveToPoint:NSMakePoint(rect.origin.x + 2, rect.origin.y + 4)];
[triangle lineToPoint:NSMakePoint(rect.origin.x + 2, rect.origin.y + 4 + 9)];
[triangle lineToPoint:NSMakePoint(rect.origin.x + 2 + 8, rect.origin.y + 4 + 4.5)];
[triangle closePath];
[triangle fill];
} else {
static NSBezierPath *openTriangle = [[NSBezierPath alloc] init];
[openTriangle removeAllPoints];
// In 'on' state, the button is an equilateral triangle (looking down)
// with the bounding rect NSMakeRect(0, 0, 9, 8). Inside the 'rect'
// it's translated by (1, 4).
[openTriangle moveToPoint:NSMakePoint(rect.origin.x + 1, rect.origin.y + 4 + 8)];
[openTriangle lineToPoint:NSMakePoint(rect.origin.x + 1 + 9, rect.origin.y + 4 + 8)];
[openTriangle lineToPoint:NSMakePoint(rect.origin.x + 1 + 4.5, rect.origin.y + 4)];
[openTriangle closePath];
[openTriangle fill];
}
}
void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const
{
QPainterPath focusRingPath;
@ -1227,11 +1319,17 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int
Q_UNREACHABLE();
}
const auto focusRingColor = qt_mac_toQColor(NSColor.keyboardFocusIndicatorColor.CGColor);
auto focusRingColor = qt_mac_toQColor(NSColor.keyboardFocusIndicatorColor.CGColor);
if (!qt_mac_applicationIsInDarkMode()) {
// This color already has alpha ~ 0.25, this value is too small - the ring is
// very pale and nothing like the native one. 0.39 makes it better (not ideal
// anyway). The color seems to be correct in dark more without any modification.
focusRingColor.setAlphaF(0.39);
}
p->save();
p->setRenderHint(QPainter::Antialiasing);
p->setOpacity(0.5);
if (cw.type == SegmentedControl_First) {
// TODO Flip left-right
}
@ -3203,8 +3301,15 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
CGContextScaleCTM(cg, 1, -1);
CGContextTranslateCTM(cg, -rect.origin.x, -rect.origin.y);
[triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]];
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave && !qt_mac_applicationIsInDarkMode()) {
// When the real system theme is one of the 'Dark' themes, and an application forces the 'Aqua' theme,
// under some conditions (see QTBUG-74515 for more details) NSButtonCell seems to select the 'Dark'
// code path and is becoming transparent, thus 'invisible' on the white background. To workaround this,
// we draw the disclose triangle manually:
qt_drawDisclosureButton(cg, triangleCell.state, (opt->state & State_Selected) && viewHasFocus, rect);
} else {
[triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]];
}
d->restoreNSGraphicsContext(cg);
break; }
@ -3536,7 +3641,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (tbstyle == Qt::ToolButtonTextOnly
|| (tbstyle != Qt::ToolButtonTextOnly && !down)) {
QPen pen = p->pen();
QColor light = down ? Qt::black : Qt::white;
QColor light = down || isDarkMode() ? Qt::black : Qt::white;
light.setAlphaF(0.375f);
p->setPen(light);
p->drawText(cr.adjusted(0, 1, 0, 1), alignment, tb->text);
@ -3958,6 +4063,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (!tabBar->tabTextColor(tabBar->currentIndex()).isValid())
myTab.palette.setColor(QPalette::WindowText, Qt::white);
if (myTab.documentMode && isDarkMode()) {
bool active = (myTab.state & State_Selected) && (myTab.state & State_Active);
myTab.palette.setColor(QPalette::WindowText, active ? Qt::white : Qt::gray);
}
int heightOffset = 0;
if (verticalTabs) {
heightOffset = -1;
@ -4444,16 +4554,17 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
p->fillRect(opt->rect, linearGrad);
p->save();
QRect toolbarRect = isDarkMode ? opt->rect.adjusted(0, 0, 0, 1) : opt->rect;
if (opt->state & State_Horizontal) {
p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientBegin.lighter(114));
p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
p->drawLine(toolbarRect.topLeft(), toolbarRect.topRight());
p->setPen(isDarkMode ? darkModeSeparatorLine :mainWindowGradientEnd.darker(114));
p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
p->drawLine(toolbarRect.bottomLeft(), toolbarRect.bottomRight());
} else {
p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientBegin.lighter(114));
p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
p->drawLine(toolbarRect.topLeft(), toolbarRect.bottomLeft());
p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientEnd.darker(114));
p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
p->drawLine(toolbarRect.topRight(), toolbarRect.bottomRight());
}
p->restore();

View File

@ -83,56 +83,56 @@ void QAppleTestLogger::leaveTestFunction()
testFunctionActivity.leave();
}
typedef QPair<QtMsgType, const char *> IncidentClassification;
static IncidentClassification incidentTypeToClassification(QAbstractTestLogger::IncidentTypes type)
struct MessageData
{
switch (type) {
case QAbstractTestLogger::Pass:
return IncidentClassification(QtInfoMsg, "pass");
case QAbstractTestLogger::XFail:
return IncidentClassification(QtInfoMsg, "xfail");
case QAbstractTestLogger::Fail:
return IncidentClassification(QtCriticalMsg, "fail");
case QAbstractTestLogger::XPass:
return IncidentClassification(QtInfoMsg, "xpass");
case QAbstractTestLogger::BlacklistedPass:
return IncidentClassification(QtWarningMsg, "bpass");
case QAbstractTestLogger::BlacklistedFail:
return IncidentClassification(QtInfoMsg, "bfail");
case QAbstractTestLogger::BlacklistedXPass:
return IncidentClassification(QtWarningMsg, "bxpass");
case QAbstractTestLogger::BlacklistedXFail:
return IncidentClassification(QtInfoMsg, "bxfail");
QtMsgType messageType = QtFatalMsg;
const char *categorySuffix = nullptr;
void generateCategory(QTestCharBuffer *category)
{
if (categorySuffix)
QTest::qt_asprintf(category, "qt.test.%s", categorySuffix);
else
QTest::qt_asprintf(category, "qt.test");
}
return IncidentClassification(QtFatalMsg, nullptr);
}
};
void QAppleTestLogger::addIncident(IncidentTypes type, const char *description,
const char *file, int line)
{
IncidentClassification incidentClassification = incidentTypeToClassification(type);
MessageData messageData = [=]() {
switch (type) {
case QAbstractTestLogger::Pass:
return MessageData{QtInfoMsg, "pass"};
case QAbstractTestLogger::XFail:
return MessageData{QtInfoMsg, "xfail"};
case QAbstractTestLogger::Fail:
return MessageData{QtCriticalMsg, "fail"};
case QAbstractTestLogger::XPass:
return MessageData{QtInfoMsg, "xpass"};
case QAbstractTestLogger::BlacklistedPass:
return MessageData{QtWarningMsg, "bpass"};
case QAbstractTestLogger::BlacklistedFail:
return MessageData{QtInfoMsg, "bfail"};
case QAbstractTestLogger::BlacklistedXPass:
return MessageData{QtWarningMsg, "bxpass"};
case QAbstractTestLogger::BlacklistedXFail:
return MessageData{QtInfoMsg, "bxfail"};
}
Q_UNREACHABLE();
}();
QTestCharBuffer category;
QTest::qt_asprintf(&category, "qt.test.%s", incidentClassification.second);
messageData.generateCategory(&category);
QMessageLogContext context(file, line, /* function = */ nullptr, category.data());
QTestCharBuffer subsystemBuffer;
// It would be nice to have the data tag as part of the subsystem too, but that
// will for some tests results in hundreds of thousands of log objects being
// created, so we limit the subsystem to test functions, which we can hope
// are reasonably limited.
generateTestIdentifier(&subsystemBuffer, TestObject | TestFunction);
QString subsystem = QString::fromLatin1(subsystemBuffer.data());
// We still want the full identifier as part of the message though
QTestCharBuffer testIdentifier;
generateTestIdentifier(&testIdentifier);
QString message = QString::fromLatin1(testIdentifier.data());
QString message = testIdentifier();
if (qstrlen(description))
message += QLatin1Char('\n') % QString::fromLatin1(description);
AppleUnifiedLogger::messageHandler(incidentClassification.first, context, message, subsystem);
AppleUnifiedLogger::messageHandler(messageData.messageType, context, message, subsystem());
}
void QAppleTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context, const QString &message)
@ -140,6 +140,62 @@ void QAppleTestLogger::addMessage(QtMsgType type, const QMessageLogContext &cont
AppleUnifiedLogger::messageHandler(type, context, message);
}
void QAppleTestLogger::addMessage(MessageTypes type, const QString &message, const char *file, int line)
{
MessageData messageData = [=]() {
switch (type) {
case QAbstractTestLogger::Warn:
case QAbstractTestLogger::QWarning:
return MessageData{QtWarningMsg, nullptr};
case QAbstractTestLogger::QDebug:
return MessageData{QtDebugMsg, nullptr};
case QAbstractTestLogger::QSystem:
return MessageData{QtWarningMsg, "system"};
case QAbstractTestLogger::QFatal:
return MessageData{QtFatalMsg, nullptr};
case QAbstractTestLogger::Skip:
return MessageData{QtInfoMsg, "skip"};
case QAbstractTestLogger::Info:
case QAbstractTestLogger::QInfo:
return MessageData{QtInfoMsg, nullptr};
}
Q_UNREACHABLE();
}();
QTestCharBuffer category;
messageData.generateCategory(&category);
QMessageLogContext context(file, line, /* function = */ nullptr, category.data());
QString msg = message;
if (type == Skip) {
if (!message.isNull())
msg.prepend(testIdentifier() + QLatin1Char('\n'));
else
msg = testIdentifier();
}
AppleUnifiedLogger::messageHandler(messageData.messageType, context, msg, subsystem());
}
QString QAppleTestLogger::subsystem() const
{
QTestCharBuffer buffer;
// It would be nice to have the data tag as part of the subsystem too, but that
// will for some tests result in hundreds of thousands of log objects being
// created, so we limit the subsystem to test functions, which we can hope
// are reasonably limited.
generateTestIdentifier(&buffer, TestObject | TestFunction);
return QString::fromLatin1(buffer.data());
}
QString QAppleTestLogger::testIdentifier() const
{
QTestCharBuffer buffer;
generateTestIdentifier(&buffer);
return QString::fromLatin1(buffer.data());
}
#endif // QT_USE_APPLE_UNIFIED_LOGGING
QT_END_NAMESPACE

View File

@ -73,11 +73,14 @@ public:
void addMessage(QtMsgType, const QMessageLogContext &,
const QString &) override;
void addMessage(MessageTypes type, const QString &message,
const char *file = 0, int line = 0) override
{ Q_UNUSED(type); Q_UNUSED(message); Q_UNUSED(file); Q_UNUSED(line); Q_UNREACHABLE(); }
const char *file = 0, int line = 0) override;
void addBenchmarkResult(const QBenchmarkResult &result) override
{ Q_UNUSED(result); }
private:
QString subsystem() const;
QString testIdentifier() const;
};
#endif

View File

@ -1538,14 +1538,19 @@ void QWidgetPrivate::createTLSysExtra()
extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh));
if (extra->topextra->opacity != 255 && q->isWindow())
extra->topextra->window->setOpacity(qreal(extra->topextra->opacity) / qreal(255));
const bool isTipLabel = q->inherits("QTipLabel");
const bool isAlphaWidget = !isTipLabel && q->inherits("QAlphaWidget");
#ifdef Q_OS_WIN
// Pass on native parent handle for Widget embedded into Active X.
const QVariant activeXNativeParentHandle = q->property(activeXNativeParentHandleProperty);
if (activeXNativeParentHandle.isValid())
extra->topextra->window->setProperty(activeXNativeParentHandleProperty, activeXNativeParentHandle);
if (q->inherits("QTipLabel") || q->inherits("QAlphaWidget"))
if (isTipLabel || isAlphaWidget)
extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true));
#endif
if (isTipLabel || isAlphaWidget || q->inherits("QRollEffect"))
qt_window_private(extra->topextra->window)->setAutomaticPositionAndResizeEnabled(false);
}
}

View File

@ -751,6 +751,10 @@ void QDoubleSpinBox::setPrefix(const QString &prefix)
d->prefix = prefix;
d->updateEdit();
d->cachedSizeHint = QSize();
d->cachedMinimumSizeHint = QSize(); // minimumSizeHint cares about the prefix
updateGeometry();
}
/*!

View File

@ -32,10 +32,13 @@
#include <QStandardItemModel>
#include <QStringListModel>
#include <QTest>
#include <QLoggingCategory>
#include "dynamictreemodel.h"
#include "qidentityproxymodel.h"
Q_LOGGING_CATEGORY(lcItemModels, "qt.corelib.tests.itemmodels")
class DataChangedModel : public QAbstractListModel
{
public:
@ -390,7 +393,7 @@ void dump(QAbstractItemModel* model, QString const& indent = " - ", QModelIndex
for (auto row = 0; row < model->rowCount(parent); ++row)
{
auto idx = model->index(row, 0, parent);
qDebug() << (indent + idx.data().toString());
qCDebug(lcItemModels) << (indent + idx.data().toString());
dump(model, indent + "- ", idx);
}
}

View File

@ -125,6 +125,7 @@ private:
tst_QItemModel::tst_QItemModel()
{
qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
qRegisterMetaType<QList<QPersistentModelIndex>>();
}
void tst_QItemModel::init()
@ -181,7 +182,7 @@ void tst_QItemModel::nonDestructiveBasicTest()
currentModel->hasChildren(QModelIndex());
currentModel->hasIndex(0, 0);
currentModel->headerData(0, Qt::Horizontal);
currentModel->index(0,0), QModelIndex();
currentModel->index(0,0);
currentModel->itemData(QModelIndex());
QVariant cache;
currentModel->match(QModelIndex(), -1, cache);

View File

@ -38,6 +38,8 @@
#include <qdebug.h>
Q_LOGGING_CATEGORY(lcItemModels, "qt.corelib.tests.itemmodels")
// Testing get/set functions
void tst_QSortFilterProxyModel::getSetCheck()
{
@ -2361,6 +2363,45 @@ void tst_QSortFilterProxyModel::match()
QCOMPARE(indexes.at(i).row(), expectedProxyItems.at(i));
}
QList<QStandardItem *> createStandardItemList(const QString &prefix, int n)
{
QList<QStandardItem *> result;
for (int i = 0; i < n; ++i)
result.append(new QStandardItem(prefix + QString::number(i)));
return result;
}
// QTBUG-73864, recursive search in a tree model.
void tst_QSortFilterProxyModel::matchTree()
{
QStandardItemModel model(0, 2);
// Header00 Header01
// Header10 Header11
// Item00 Item01
// Item10 Item11
model.appendRow(createStandardItemList(QLatin1String("Header0"), 2));
auto headerRow = createStandardItemList(QLatin1String("Header1"), 2);
model.appendRow(headerRow);
headerRow.first()->appendRow(createStandardItemList(QLatin1String("Item0"), 2));
headerRow.first()->appendRow(createStandardItemList(QLatin1String("Item1"), 2));
auto item11 = model.match(model.index(1, 1), Qt::DisplayRole, QLatin1String("Item11"), 20,
Qt::MatchRecursive).value(0);
QVERIFY(item11.isValid());
QCOMPARE(item11.data().toString(), QLatin1String("Item11"));
// Repeat in proxy model
QSortFilterProxyModel proxy;
proxy.setSourceModel(&model);
auto proxyItem11 = proxy.match(proxy.index(1, 1), Qt::DisplayRole, QLatin1String("Item11"), 20,
Qt::MatchRecursive).value(0);
QVERIFY(proxyItem11.isValid());
QCOMPARE(proxyItem11.data().toString(), QLatin1String("Item11"));
QCOMPARE(proxy.mapToSource(proxyItem11).internalId(), item11.internalId());
}
void tst_QSortFilterProxyModel::insertIntoChildrenlessItem()
{
QStandardItemModel model;
@ -4277,7 +4318,7 @@ public:
QModelIndex index(int, int, const QModelIndex& parent = QModelIndex()) const override
{
// QTBUG-44962: Would we always expect the parent to belong to the model
qDebug() << parent.model() << this;
qCDebug(lcItemModels) << parent.model() << this;
Q_ASSERT(!parent.isValid() || parent.model() == this);
quintptr parentId = (parent.isValid()) ? parent.internalId() : 0;
@ -4363,7 +4404,7 @@ void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes()
// The use of qDebug here makes sufficient use of the heap to
// cause corruption at runtime with normal use on linux (before
// the fix). valgrind confirms the fix.
qDebug() << persistentIndex.parent();
qCDebug(lcItemModels) << persistentIndex.parent();
QVERIFY(persistentIndex.parent().isValid());
}

View File

@ -109,6 +109,7 @@ private slots:
void selectionFilteredOut();
void match_data();
void match();
void matchTree();
void insertIntoChildrenlessItem();
void invalidateMappedChildren();
void insertRowIntoFilteredParent();
@ -186,4 +187,6 @@ private:
Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint)
Q_DECLARE_LOGGING_CATEGORY(lcItemModels)
#endif // TST_QSORTFILTERPROXYMODEL_H

View File

@ -0,0 +1,4 @@
CONFIG += testcase
TARGET = tst_qdatastream_core_pixmap
QT += testlib
SOURCES = tst_qdatastream_core_pixmap.cpp

View File

@ -0,0 +1,68 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QtGui/QBitmap>
#include <QtGui/QPalette>
#include <QtGui/QPixmap>
#include <QtGui/QPicture>
#include <QtGui/QTextLength>
#include <QtGui/QPainter>
#include <QtGui/QPen>
class tst_QDataStream : public QObject
{
Q_OBJECT
private slots:
void stream_with_pixmap();
};
void tst_QDataStream::stream_with_pixmap()
{
// This is a QVariantMap with a 3x3 red QPixmap and two strings inside
const QByteArray ba = QByteArray::fromBase64("AAAAAwAAAAIAegAAAAoAAAAACgB0AGgAZQByAGUAAAACAHAAAABBAAAAAAGJUE5HDQoaCgAAAA1JSERSAAAAAwAAAAMIAgAAANlKIugAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAQSURBVAiZY/zPAAVMDJgsAB1bAQXZn5ieAAAAAElFTkSuQmCCAAAAAgBhAAAACgAAAAAKAGgAZQBsAGwAbw==");
QImage dummy; // Needed to make sure qtGui is loaded
QTest::ignoreMessage(QtWarningMsg, "QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
QVariantMap map;
QDataStream d(ba);
d.setVersion(QDataStream::Qt_5_12);
d >> map;
QCOMPARE(map["a"].toString(), QString("hello"));
QCOMPARE(map["p"].value<QPixmap>(), QPixmap()); // the pixmap is null because this is not a QGuiApplication
QCOMPARE(map["z"].toString(), QString("there"));
}
QTEST_GUILESS_MAIN(tst_QDataStream)
#include "tst_qdatastream_core_pixmap.moc"

View File

@ -6,6 +6,7 @@ SUBDIRS = \
qcborvalue \
qcborvalue_json \
qdatastream \
qdatastream_core_pixmap \
qtextstream \
qxmlstream

View File

@ -538,6 +538,8 @@ void tst_QTimeZone::checkOffset_data()
int year, month, day, hour, min, sec;
int std, dst;
} table[] = {
// Zone with no transitions (QTBUG-74614, when TZ backend uses minimalist data)
{ "Etc/UTC", "epoch", 1970, 1, 1, 0, 0, 0, 0, 0 },
// Kiev: regression test for QTBUG-64122 (on MS):
{ "Europe/Kiev", "summer", 2017, 10, 27, 12, 0, 0, 2 * 3600, 3600 },
{ "Europe/Kiev", "winter", 2017, 10, 29, 12, 0, 0, 2 * 3600, 0 }
@ -550,6 +552,8 @@ void tst_QTimeZone::checkOffset_data()
<< QDateTime(QDate(entry.year, entry.month, entry.day),
QTime(entry.hour, entry.min, entry.sec), zone)
<< entry.dst + entry.std << entry.std << entry.dst;
} else {
qWarning("Skipping %s@%s test as zone is invalid", entry.zone, entry.nick);
}
}
}

View File

@ -256,9 +256,14 @@ void tst_QAbstractNetworkCache::cacheControl_data()
QTest::newRow("200-1") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol-expire.cgi" << false;
QTest::newRow("200-2") << QNetworkRequest::AlwaysNetwork << "httpcachetest_cachecontrol.cgi?no-cache" << AlwaysFalse;
QTest::newRow("200-3") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?no-cache" << false;
QTest::newRow("200-3") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?no-cache" << true;
QTest::newRow("200-4") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?no-cache" << false;
QTest::newRow("200-5") << QNetworkRequest::PreferCache << "httpcachetest_cachecontrol.cgi?no-cache" << false;
QTest::newRow("200-5") << QNetworkRequest::PreferCache << "httpcachetest_cachecontrol.cgi?no-cache" << true;
QTest::newRow("200-6") << QNetworkRequest::AlwaysNetwork << "httpcachetest_cachecontrol.cgi?no-store" << AlwaysFalse;
QTest::newRow("200-7") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?no-store" << false;
QTest::newRow("200-8") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?no-store" << false;
QTest::newRow("200-9") << QNetworkRequest::PreferCache << "httpcachetest_cachecontrol.cgi?no-store" << false;
QTest::newRow("304-0") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?max-age=1000" << true;

View File

@ -3976,7 +3976,7 @@ void tst_QNetworkReply::ioGetFromHttpWithCache_data()
"HTTP/1.0 200\r\n"
"Connection: keep-alive\r\n"
"Content-Type: text/plain\r\n"
"Cache-control: no-cache\r\n"
"Cache-control: no-store\r\n"
"Content-length: 8\r\n"
"\r\n"
"Reloaded";
@ -4002,6 +4002,33 @@ void tst_QNetworkReply::ioGetFromHttpWithCache_data()
content.second = "Not-reloaded";
content.first.setLastModified(past);
// "no-cache"
rawHeaders.clear();
rawHeaders << QNetworkCacheMetaData::RawHeader("Date", QLocale::c().toString(past, dateFormat).toLatin1())
<< QNetworkCacheMetaData::RawHeader("Cache-control", "no-cache");
content.first.setRawHeaders(rawHeaders);
content.first.setLastModified(past);
content.first.setExpirationDate(future);
// "no-cache" does not mean "no cache", just that we must consult remote first
QTest::newRow("no-cache,200,always-network")
<< reply200 << "Reloaded" << content << int(QNetworkRequest::AlwaysNetwork) << QStringList() << false << true;
QTest::newRow("no-cache,200,prefer-network")
<< reply200 << "Reloaded" << content << int(QNetworkRequest::PreferNetwork) << QStringList() << false << true;
QTest::newRow("no-cache,200,prefer-cache")
<< reply200 << "Reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << false << true;
// We're not allowed by the spec to deliver cached data without checking if it is still
// up-to-date.
QTest::newRow("no-cache,200,always-cache")
<< reply200 << QString() << content << int(QNetworkRequest::AlwaysCache) << QStringList() << false << false;
QTest::newRow("no-cache,304,prefer-network")
<< reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << QStringList() << true << true;
QTest::newRow("no-cache,304,prefer-cache")
<< reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << true << true;
QTest::newRow("no-cache,304,always-cache")
<< reply304 << QString() << content << int(QNetworkRequest::AlwaysCache) << QStringList() << false << false;
//
// Set to expired
//

View File

@ -4,3 +4,5 @@
windows ci
[blockingLookup:a-plus-aaaa]
windows ci
[reverseLookup:google-public-dns-a.google.com]
ci

View File

@ -1,2 +0,0 @@
[onDemandRootCertLoadingMemberMethods]
linux

View File

@ -31,7 +31,7 @@
#include <QProcess>
#include <QDir>
static QString targetName( BuildType buildMode, const QString& target, const QString& version )
QString TestCompiler::targetName(BuildType buildMode, const QString& target, const QString& version)
{
Q_UNUSED(version);
QString targetName = target;
@ -257,7 +257,8 @@ bool TestCompiler::qmakeProject( const QString &workDir, const QString &proName
return runCommand(qmakeCmd_, QStringList() << "-project" << "-o" << projectFile << "DESTDIR=./");
}
bool TestCompiler::qmake( const QString &workDir, const QString &proName, const QString &buildDir )
bool TestCompiler::qmake(const QString &workDir, const QString &proName, const QString &buildDir,
const QStringList &additionalArguments)
{
QDir D;
D.setCurrent( workDir );
@ -274,7 +275,8 @@ bool TestCompiler::qmake( const QString &workDir, const QString &proName, const
makeFile += "Makefile";
// Now start qmake and generate the makefile
return runCommand(qmakeCmd_, QStringList(qmakeArgs_) << projectFile << "-o" << makeFile);
return runCommand(qmakeCmd_, QStringList(qmakeArgs_) << projectFile << "-o" << makeFile
<< additionalArguments);
}
bool TestCompiler::make( const QString &workPath, const QString &target, bool expectFail )

View File

@ -49,6 +49,8 @@ public:
void resetEnvironment();
void addToEnvironment( QString varAssignment );
static QString targetName(BuildType buildMode, const QString& target, const QString& version);
// executes a make clean in the specified workPath
bool makeClean( const QString &workPath );
// executes a make dist clean in the specified workPath
@ -56,7 +58,8 @@ public:
// executes a qmake -project on the specified workDir
bool qmakeProject( const QString &workDir, const QString &proName );
// executes a qmake on proName in the specified workDir, output goes to buildDir or workDir if it's null
bool qmake( const QString &workDir, const QString &proName, const QString &buildDir = QString() );
bool qmake(const QString &workDir, const QString &proName, const QString &buildDir = QString(),
const QStringList &additionalArguments = QStringList());
// executes a make in the specified workPath, with an optional target (eg. install)
bool make( const QString &workPath, const QString &target = QString(), bool expectFail = false );
// checks if the executable exists in destDir

View File

@ -5,3 +5,8 @@ SOURCES = test_file.cpp \
RESOURCES = test.qrc
TARGET = "simple app"
DESTDIR = "dest dir"
target.path = $$OUT_PWD/dist
INSTALLS += target
!build_pass:msvc:CONFIG(debug, debug|release):message("check for pdb, please")

View File

@ -58,6 +58,7 @@ private slots:
void simple_app();
void simple_app_shadowbuild();
void simple_app_shadowbuild2();
void simple_app_versioned();
void simple_lib();
void simple_dll();
void subdirs();
@ -173,10 +174,15 @@ void tst_qmake::simple_app()
{
QString workDir = base_path + "/testdata/simple_app";
QString destDir = workDir + "/dest dir";
QString installDir = workDir + "/dist";
QVERIFY( test_compiler.qmake( workDir, "simple_app" ));
QVERIFY( test_compiler.qmake( workDir, "simple_app", QString() ));
QVERIFY( test_compiler.make( workDir ));
QVERIFY( test_compiler.exists( destDir, "simple app", Exe, "1.0.0" ));
QVERIFY(test_compiler.make(workDir, "install"));
QVERIFY(test_compiler.exists(installDir, "simple app", Exe, "1.0.0"));
QVERIFY( test_compiler.makeClean( workDir ));
QVERIFY( test_compiler.exists( destDir, "simple app", Exe, "1.0.0" )); // Should still exist after a make clean
QVERIFY( test_compiler.makeDistClean( workDir ));
@ -216,6 +222,43 @@ void tst_qmake::simple_app_shadowbuild2()
QVERIFY( test_compiler.removeMakefile( buildDir ) );
}
void tst_qmake::simple_app_versioned()
{
QString workDir = base_path + "/testdata/simple_app";
QString buildDir = base_path + "/testdata/simple_app_versioned_build";
QString destDir = buildDir + "/dest dir";
QString installDir = buildDir + "/dist";
QString version = "4.5.6";
QVERIFY(test_compiler.qmake(workDir, "simple_app", buildDir, QStringList{ "VERSION=" + version }));
QString qmakeOutput = test_compiler.commandOutput();
QVERIFY(test_compiler.make(buildDir));
QVERIFY(test_compiler.exists(destDir, "simple app", Exe, version));
QString pdbFilePath;
bool checkPdb = qmakeOutput.contains("Project MESSAGE: check for pdb, please");
if (checkPdb) {
QString targetBase = QFileInfo(TestCompiler::targetName(Exe, "simple app", version))
.completeBaseName();
pdbFilePath = destDir + '/' + targetBase + ".pdb";
QVERIFY2(QFile::exists(pdbFilePath), qPrintable(pdbFilePath));
QVERIFY(test_compiler.make(buildDir, "install"));
QString installedPdbFilePath = installDir + '/' + targetBase + ".pdb";
QEXPECT_FAIL("", "QTBUG-74265", Continue);
QVERIFY2(QFile::exists(installedPdbFilePath), qPrintable(installedPdbFilePath));
}
QVERIFY(test_compiler.makeClean(buildDir));
QVERIFY(test_compiler.exists(destDir, "simple app", Exe, version));
QVERIFY(test_compiler.makeDistClean(buildDir));
QVERIFY(!test_compiler.exists(destDir, "simple app", Exe, version));
if (checkPdb) {
QEXPECT_FAIL("", "QTBUG-74265", Continue);
QVERIFY(!QFile::exists(pdbFilePath));
}
QVERIFY(test_compiler.removeMakefile(buildDir));
}
void tst_qmake::simple_dll()
{
QString workDir = base_path + "/testdata/simple_dll";

View File

@ -0,0 +1,3 @@
# QTBUG-74760
[sorting]
opensuse-42.3

View File

@ -10,6 +10,7 @@ osx
ubuntu-16.04
ubuntu-18.04
rhel-7.4
rhel-7.6
osx
[focusProxyAndInputMethods]
linux

View File

@ -326,14 +326,26 @@ void tst_QDoubleSpinBox::setPrefixSuffix()
QDoubleSpinBox spin(0);
spin.setDecimals(decimals);
const QSize size1 = spin.sizeHint();
spin.setPrefix(prefix);
const QSize size2 = spin.sizeHint();
spin.setSuffix(suffix);
const QSize size3 = spin.sizeHint();
spin.setValue(value);
if (show)
spin.show();
QCOMPARE(spin.text(), expectedText);
QCOMPARE(spin.cleanText(), expectedCleanText);
if (!prefix.isEmpty() && !suffix.isEmpty()) {
QVERIFY(size1.width() < size2.width());
QVERIFY(size2.width() < size3.width());
spin.setSuffix(QString());
QCOMPARE(spin.sizeHint(), size2);
spin.setPrefix(QString());
QCOMPARE(spin.sizeHint(), size1);
}
}
void tst_QDoubleSpinBox::valueChangedHelper(const QString &text)

View File

@ -1343,8 +1343,10 @@ void tst_QMainWindow::restoreState()
{
QMainWindow mw;
QToolBar tb(&mw);
tb.setObjectName(QLatin1String("toolBar"));
mw.addToolBar(Qt::TopToolBarArea, &tb);
QDockWidget dw(&mw);
dw.setObjectName(QLatin1String("dock"));
mw.addDockWidget(Qt::LeftDockWidgetArea, &dw);
QByteArray state;

View File

@ -462,8 +462,11 @@ void tst_QSpinBox::setPrefixSuffix()
QFETCH(bool, show);
QSpinBox spin(0);
const QSize size1 = spin.sizeHint();
spin.setPrefix(prefix);
const QSize size2 = spin.sizeHint();
spin.setSuffix(suffix);
const QSize size3 = spin.sizeHint();
spin.setValue(value);
if (show)
spin.show();
@ -472,6 +475,15 @@ void tst_QSpinBox::setPrefixSuffix()
QCOMPARE(spin.suffix(), suffix);
QCOMPARE(spin.text(), expectedText);
QCOMPARE(spin.cleanText(), expectedCleanText);
if (!prefix.isEmpty() && !suffix.isEmpty()) {
QVERIFY(size1.width() < size2.width());
QVERIFY(size2.width() < size3.width());
spin.setSuffix(QString());
QCOMPARE(spin.sizeHint(), size2);
spin.setPrefix(QString());
QCOMPARE(spin.sizeHint(), size1);
}
}
void tst_QSpinBox::textChangedHelper(const QString &text)