apply patches

This commit is contained in:
openKylinBot 2022-05-14 17:41:02 +08:00
commit 45a58851a9
37 changed files with 474 additions and 150 deletions

View File

@ -94,11 +94,6 @@ $(document).ready(function($) {
}); });
$( window ).load(function() { $( window ).load(function() {
load_sdk('script', 'facebook-jssdk','//connect.facebook.net/en_US/sdk.js#xfbml=1&appId=207346529386114&version=v2.0');
load_sdk('script', 'twitter-wjs', '//platform.twitter.com/widgets.js');
$.getScript("//www.google.com/jsapi", function(){
google.load("feeds", "1", {"callback": oneQt.liveFeeds});
});
}); });
var oneQt = { var oneQt = {

View File

@ -1,6 +1,5 @@
TEMPLATE = subdirs TEMPLATE = subdirs
SUBDIRS = htmlinfo \ SUBDIRS = xmlstreamlint
xmlstreamlint
qtHaveModule(widgets) { qtHaveModule(widgets) {
SUBDIRS += dombookmarks \ SUBDIRS += dombookmarks \

View File

@ -98,6 +98,10 @@ doc_command = $$QDOC $$QMAKE_DOCS
prepare_docs { prepare_docs {
prepare_docs.commands += $$doc_command -prepare $$PREP_DOC_INDEXES -no-link-errors $$QDOC_INCLUDE_PATHS prepare_docs.commands += $$doc_command -prepare $$PREP_DOC_INDEXES -no-link-errors $$QDOC_INCLUDE_PATHS
generate_docs.commands += $$doc_command -generate $$DOC_INDEXES $$QDOC_INCLUDE_PATHS generate_docs.commands += $$doc_command -generate $$DOC_INDEXES $$QDOC_INCLUDE_PATHS
for (incdir, QMAKE_DEFAULT_INCDIRS) {
prepare_docs.commands += -I$$shell_quote($$incdir)
generate_docs.commands += -I$$shell_quote($$incdir)
}
prepare_docs.depends += qtattributionsscanner prepare_docs.depends += qtattributionsscanner
} else { } else {
html_docs.commands += $$doc_command $$DOC_INDEXES $(QDOC_INCLUDE_PATHS) html_docs.commands += $$doc_command $$DOC_INDEXES $(QDOC_INCLUDE_PATHS)

View File

@ -215,6 +215,8 @@ defineTest(qtAddTargetEnv) {
deppath.name = PATH deppath.name = PATH
} else:contains(QMAKE_HOST.os, Linux|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|HP-UX|QNX|GNU) { } else:contains(QMAKE_HOST.os, Linux|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|HP-UX|QNX|GNU) {
deppath.name = LD_LIBRARY_PATH deppath.name = LD_LIBRARY_PATH
} else:contains(QMAKE_HOST.os, ^GNU/.*) {
deppath.name = LD_LIBRARY_PATH
} else:contains(QMAKE_HOST.os, Haiku) { } else:contains(QMAKE_HOST.os, Haiku) {
deppath.name = LIBRARY_PATH deppath.name = LIBRARY_PATH
} else:equals(QMAKE_HOST.os, Darwin) { } else:equals(QMAKE_HOST.os, Darwin) {

View File

@ -0,0 +1,54 @@
#
# qmake configuration for gnukfreebsd-g++
#
MAKEFILE_GENERATOR = UNIX
QMAKE_PLATFORM += gnukfreebsd
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
QMAKE_CFLAGS_THREAD += -D_REENTRANT
QMAKE_CXXFLAGS_THREAD += $$QMAKE_CFLAGS_THREAD
QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections
QMAKE_INCDIR =
QMAKE_LIBDIR =
QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL =
QMAKE_LIBDIR_OPENGL =
QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL
QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL
QMAKE_INCDIR_EGL =
QMAKE_LIBDIR_EGL =
QMAKE_INCDIR_OPENVG =
QMAKE_LIBDIR_OPENVG =
QMAKE_LIBS =
QMAKE_LIBS_DYNLOAD = -ldl
QMAKE_LIBS_X11 = -lXext -lX11 -lm
QMAKE_LIBS_NIS = -lnsl
QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
QMAKE_LIBS_OPENVG = -lOpenVG
QMAKE_LIBS_THREAD = -lpthread
QMAKE_CFLAGS_XCB =
QMAKE_LIBS_XCB =
QMAKE_DEFINES_XCB =
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_NM = nm -P
QMAKE_RANLIB =
QMAKE_STRIP = strip
QMAKE_STRIPFLAGS_LIB += --strip-unneeded
QMAKE_INSTALL_FILE = install -m 644 -p
QMAKE_INSTALL_PROGRAM = install -m 755 -p
include(../common/unix.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
load(qt_config)

View File

@ -0,0 +1,84 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the qmake spec of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QPLATFORMDEFS_H
#define QPLATFORMDEFS_H
// Get Qt defines/settings
#include "qglobal.h"
// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
// 1) need to reset default environment if _BSD_SOURCE is defined
// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0
// 3) it seems older glibc need this to include the X/Open stuff
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <unistd.h>
// We are hot - unistd.h should have turned on the specific APIs we requested
#include <pthread.h>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <signal.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/ipc.h>
#include <sys/time.h>
#include <sys/shm.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <netinet/in.h>
#ifndef QT_NO_IPV6IFNAME
#include <net/if.h>
#endif
#include "../common/posix/qplatformdefs.h"
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
#define QT_SNPRINTF ::snprintf
#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H

View File

@ -228,7 +228,7 @@ bool IoUtils::touchFile(const QString &targetFileName, const QString &referenceF
*errorString = fL1S("Cannot stat() reference file %1: %2.").arg(referenceFileName, fL1S(strerror(errno))); *errorString = fL1S("Cannot stat() reference file %1: %2.").arg(referenceFileName, fL1S(strerror(errno)));
return false; return false;
} }
# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L # if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L && defined(UTIME_NOW)
const struct timespec times[2] = { { 0, UTIME_NOW }, st.st_mtim }; const struct timespec times[2] = { { 0, UTIME_NOW }, st.st_mtim };
const bool utimeError = utimensat(AT_FDCWD, targetFileName.toLocal8Bit().constData(), times, 0) < 0; const bool utimeError = utimensat(AT_FDCWD, targetFileName.toLocal8Bit().constData(), times, 0) < 0;
# else # else

View File

@ -247,8 +247,8 @@ template <>
class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void> class ThreadEngineStarter<void> : public ThreadEngineStarterBase<void>
{ {
public: public:
ThreadEngineStarter<void>(ThreadEngine<void> *_threadEngine) ThreadEngineStarter(ThreadEngine<void> *_threadEngine)
:ThreadEngineStarterBase<void>(_threadEngine) {} : ThreadEngineStarterBase<void>(_threadEngine) {}
void startBlocking() void startBlocking()
{ {

View File

@ -331,6 +331,7 @@
"label": "O_CLOEXEC", "label": "O_CLOEXEC",
"type": "compile", "type": "compile",
"test": { "test": {
"qmake": "QMAKE_LFLAGS += -Wl,--fatal-warnings",
"head": "#define _GNU_SOURCE 1", "head": "#define _GNU_SOURCE 1",
"include": [ "sys/types.h", "sys/socket.h", "fcntl.h", "unistd.h" ], "include": [ "sys/types.h", "sys/socket.h", "fcntl.h", "unistd.h" ],
"main": [ "main": [
@ -386,6 +387,7 @@
"include": "sys/stat.h", "include": "sys/stat.h",
"main": "futimens(-1, 0);", "main": "futimens(-1, 0);",
"qmake": [ "qmake": [
"QMAKE_LFLAGS += -Wl,--fatal-warnings",
"# Block futimens() on Apple platforms unless it's available on ALL", "# Block futimens() on Apple platforms unless it's available on ALL",
"# deployment targets. This simplifies the logic at the call site", "# deployment targets. This simplifies the logic at the call site",
"# dramatically, as it isn't strictly needed compared to futimes().", "# dramatically, as it isn't strictly needed compared to futimes().",
@ -414,6 +416,7 @@
"label": "getentropy()", "label": "getentropy()",
"type": "compile", "type": "compile",
"test": { "test": {
"qmake": "QMAKE_LFLAGS += -Wl,--fatal-warnings",
"include": "unistd.h", "include": "unistd.h",
"main": [ "main": [
"char buf[32];", "char buf[32];",

View File

@ -132,6 +132,8 @@
# elif defined(__ARM_ARCH_5TEJ__) \ # elif defined(__ARM_ARCH_5TEJ__) \
|| defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TE__)
# define Q_PROCESSOR_ARM 5 # define Q_PROCESSOR_ARM 5
# elif defined(__ARM_ARCH_4T__)
# define Q_PROCESSOR_ARM 4
# else # else
# define Q_PROCESSOR_ARM 0 # define Q_PROCESSOR_ARM 0
# endif # endif
@ -146,6 +148,9 @@
# endif # endif
# if Q_PROCESSOR_ARM >= 5 # if Q_PROCESSOR_ARM >= 5
# define Q_PROCESSOR_ARM_V5 # define Q_PROCESSOR_ARM_V5
# endif
# if Q_PROCESSOR_ARM >= 4
# define Q_PROCESSOR_ARM_V4
# else # else
# error "ARM architecture too old" # error "ARM architecture too old"
# endif # endif

View File

@ -689,7 +689,11 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
Q_UNUSED(data); Q_UNUSED(data);
return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath())); return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath()));
#else #else
#ifdef PATH_MAX
char stack_result[PATH_MAX+1]; char stack_result[PATH_MAX+1];
#else
char stack_result[4096+1];
#endif
char *resolved_name = nullptr; char *resolved_name = nullptr;
# if defined(Q_OS_DARWIN) || defined(Q_OS_ANDROID) # if defined(Q_OS_DARWIN) || defined(Q_OS_ANDROID)
// On some Android and macOS versions, realpath() will return a path even if // On some Android and macOS versions, realpath() will return a path even if
@ -1595,7 +1599,7 @@ bool QFileSystemEngine::setFileTime(int fd, const QDateTime &newDate, QAbstractF
return false; return false;
} }
#if QT_CONFIG(futimens) #if QT_CONFIG(futimens) && defined(UTIME_OMIT)
struct timespec ts[2]; struct timespec ts[2];
ts[0].tv_sec = ts[1].tv_sec = 0; ts[0].tv_sec = ts[1].tv_sec = 0;

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation. ** Copyright (C) 2022 Intel Corporation.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the QtCore module of the Qt Toolkit. ** This file is part of the QtCore module of the Qt Toolkit.
@ -422,14 +422,15 @@ void QProcessPrivate::startProcess()
// Add the program name to the argument list. // Add the program name to the argument list.
argv[0] = nullptr; argv[0] = nullptr;
if (!program.contains(QLatin1Char('/'))) { if (!program.contains(QLatin1Char('/'))) {
// findExecutable() returns its argument if it's an absolute path,
// otherwise it searches $PATH; returns empty if not found (we handle
// that case much later)
const QString &exeFilePath = QStandardPaths::findExecutable(program); const QString &exeFilePath = QStandardPaths::findExecutable(program);
if (!exeFilePath.isEmpty()) { const QByteArray &tmp = QFile::encodeName(exeFilePath);
const QByteArray &tmp = QFile::encodeName(exeFilePath); argv[0] = ::strdup(tmp.constData());
argv[0] = ::strdup(tmp.constData()); } else {
}
}
if (!argv[0])
argv[0] = ::strdup(encodedProgramName.constData()); argv[0] = ::strdup(encodedProgramName.constData());
}
// Add every argument to the list // Add every argument to the list
for (int i = 0; i < arguments.count(); ++i) for (int i = 0; i < arguments.count(); ++i)
@ -983,15 +984,16 @@ bool QProcessPrivate::startDetached(qint64 *pid)
envp = _q_dupEnvironment(environment.d.constData()->vars, &envc); envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
} }
QByteArray tmp;
if (!program.contains(QLatin1Char('/'))) { if (!program.contains(QLatin1Char('/'))) {
// findExecutable() returns its argument if it's an absolute path,
// otherwise it searches $PATH; returns empty if not found (we handle
// that case much later)
const QString &exeFilePath = QStandardPaths::findExecutable(program); const QString &exeFilePath = QStandardPaths::findExecutable(program);
if (!exeFilePath.isEmpty()) const QByteArray &tmp = QFile::encodeName(exeFilePath);
tmp = QFile::encodeName(exeFilePath); argv[0] = ::strdup(tmp.constData());
} else {
argv[0] = ::strdup(QFile::encodeName(program));
} }
if (tmp.isEmpty())
tmp = QFile::encodeName(program);
argv[0] = tmp.data();
if (envp) if (envp)
qt_safe_execve(argv[0], argv, envp); qt_safe_execve(argv[0], argv, envp);

View File

@ -566,6 +566,7 @@ inline QByteArray QStorageIterator::fileSystemType() const
inline QByteArray QStorageIterator::device() const inline QByteArray QStorageIterator::device() const
{ {
#ifdef Q_OS_LINUX
// check that the device exists // check that the device exists
if (mnt.mnt_fsname[0] == '/' && access(mnt.mnt_fsname, F_OK) != 0) { if (mnt.mnt_fsname[0] == '/' && access(mnt.mnt_fsname, F_OK) != 0) {
// It doesn't, so let's try to resolve the dev_t from /dev/block. // It doesn't, so let's try to resolve the dev_t from /dev/block.
@ -581,6 +582,7 @@ inline QByteArray QStorageIterator::device() const
return dev; return dev;
} }
} }
#endif
return QByteArray(mnt.mnt_fsname); return QByteArray(mnt.mnt_fsname);
} }

View File

@ -389,20 +389,23 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
// Disambiguate conflicting extensions (if magic matching found something) // Disambiguate conflicting extensions (if magic matching found something)
if (candidateByData.isValid() && magicAccuracy > 0) { if (candidateByData.isValid() && magicAccuracy > 0) {
const QString sniffedMime = candidateByData.name(); const QString sniffedMime = candidateByData.name();
// If the sniffedMime matches a glob match, use it // If the sniffedMime matches a highest-weight glob match, use it
if (candidatesByName.m_matchingMimeTypes.contains(sniffedMime)) { if (candidatesByName.m_matchingMimeTypes.contains(sniffedMime)) {
*accuracyPtr = 100; *accuracyPtr = 100;
return candidateByData; return candidateByData;
} }
for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) { for (const QString &m : qAsConst(candidatesByName.m_allMatchingMimeTypes)) {
if (inherits(m, sniffedMime)) { if (inherits(m, sniffedMime)) {
// We have magic + pattern pointing to this, so it's a pretty good match // We have magic + pattern pointing to this, so it's a pretty good match
*accuracyPtr = 100; *accuracyPtr = 100;
return mimeTypeForName(m); return mimeTypeForName(m);
} }
} }
*accuracyPtr = magicAccuracy; if (candidatesByName.m_allMatchingMimeTypes.isEmpty()) {
return candidateByData; // No glob, use magic
*accuracyPtr = magicAccuracy;
return candidateByData;
}
} }
} }

View File

@ -83,7 +83,10 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
} }
if (!m_matchingMimeTypes.contains(mimeType)) { if (!m_matchingMimeTypes.contains(mimeType)) {
m_matchingMimeTypes.append(mimeType); m_matchingMimeTypes.append(mimeType);
m_allMatchingMimeTypes.append(mimeType); if (replace)
m_allMatchingMimeTypes.prepend(mimeType); // highest-weight first
else
m_allMatchingMimeTypes.append(mimeType);
m_knownSuffixLength = knownSuffixLength; m_knownSuffixLength = knownSuffixLength;
} }
} }

View File

@ -42,6 +42,8 @@
#include <QtCore/qbytearray.h> #include <QtCore/qbytearray.h>
#include <limits>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -838,9 +838,9 @@
], ],
"include": [ "EGL/egl.h", "X11/Xlib.h" ], "include": [ "EGL/egl.h", "X11/Xlib.h" ],
"main": [ "main": [
"Display *dpy = EGL_DEFAULT_DISPLAY;", "Display *dpy = reinterpret_cast<Display *>(EGL_DEFAULT_DISPLAY);",
"EGLNativeDisplayType egldpy = XOpenDisplay(\"\");", "EGLNativeDisplayType egldpy = XOpenDisplay(\"\");",
"dpy = egldpy;", "dpy = reinterpret_cast<Display *>(egldpy);",
"EGLNativeWindowType w = XCreateWindow(dpy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);", "EGLNativeWindowType w = XCreateWindow(dpy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);",
"XDestroyWindow(dpy, w);", "XDestroyWindow(dpy, w);",
"XCloseDisplay(dpy);" "XCloseDisplay(dpy);"

View File

@ -385,10 +385,10 @@ QPainterState *QPaintEngineEx::createState(QPainterState *orig) const
Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &inPen)
{ {
#ifdef QT_DEBUG_DRAW #ifdef QT_DEBUG_DRAW
qDebug() << "QPaintEngineEx::stroke()" << pen; qDebug() << "QPaintEngineEx::stroke()" << inPen;
#endif #endif
Q_D(QPaintEngineEx); Q_D(QPaintEngineEx);
@ -403,6 +403,38 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
d->stroker.setCubicToHook(qpaintengineex_cubicTo); d->stroker.setCubicToHook(qpaintengineex_cubicTo);
} }
QRectF clipRect;
QPen pen = inPen;
if (pen.style() > Qt::SolidLine) {
QRectF cpRect = path.controlPointRect();
const QTransform &xf = state()->matrix;
if (qt_pen_is_cosmetic(pen, state()->renderHints)) {
clipRect = d->exDeviceRect;
cpRect.translate(xf.dx(), xf.dy());
} else {
clipRect = xf.inverted().mapRect(QRectF(d->exDeviceRect));
}
// Check to avoid generating unwieldy amount of dashes that will not be visible anyway
qreal pw = pen.widthF() ? pen.widthF() : 1;
QRectF extentRect = cpRect.adjusted(-pw, -pw, pw, pw) & clipRect;
qreal extent = qMax(extentRect.width(), extentRect.height());
qreal patternLength = 0;
const QVector<qreal> pattern = pen.dashPattern();
const int patternSize = qMin(pattern.size(), 32);
for (int i = 0; i < patternSize; i++)
patternLength += qMax(pattern.at(i), qreal(0));
patternLength *= pw;
if (qFuzzyIsNull(patternLength)) {
pen.setStyle(Qt::NoPen);
} else if (extent / patternLength > 10000) {
// approximate stream of tiny dashes with semi-transparent solid line
pen.setStyle(Qt::SolidLine);
QColor color(pen.color());
color.setAlpha(color.alpha() / 2);
pen.setColor(color);
}
}
if (!qpen_fast_equals(pen, d->strokerPen)) { if (!qpen_fast_equals(pen, d->strokerPen)) {
d->strokerPen = pen; d->strokerPen = pen;
d->stroker.setJoinStyle(pen.joinStyle()); d->stroker.setJoinStyle(pen.joinStyle());
@ -430,14 +462,8 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
return; return;
} }
if (pen.style() > Qt::SolidLine) { if (!clipRect.isNull())
if (qt_pen_is_cosmetic(pen, state()->renderHints)){ d->activeStroker->setClipRect(clipRect);
d->activeStroker->setClipRect(d->exDeviceRect);
} else {
QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect));
d->activeStroker->setClipRect(clipRect);
}
}
if (d->activeStroker == &d->stroker) if (d->activeStroker == &d->stroker)
d->stroker.setForceOpen(path.hasExplicitOpen()); d->stroker.setForceOpen(path.hasExplicitOpen());

View File

@ -1173,10 +1173,17 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang
QRectF fullLineRect(tl.rect()); QRectF fullLineRect(tl.rect());
fullLineRect.translate(position); fullLineRect.translate(position);
fullLineRect.setRight(QFIXED_MAX); fullLineRect.setRight(QFIXED_MAX);
if (!selectionEndInLine)
region.addRect(clipIfValid(QRectF(lineRect.topRight(), fullLineRect.bottomRight()), clip)); const bool rightToLeft = d->isRightToLeft();
if (!selectionStartInLine)
region.addRect(clipIfValid(QRectF(fullLineRect.topLeft(), lineRect.bottomLeft()), clip)); if (!selectionEndInLine) {
region.addRect(clipIfValid(rightToLeft ? QRectF(fullLineRect.topLeft(), lineRect.bottomLeft())
: QRectF(lineRect.topRight(), fullLineRect.bottomRight()), clip));
}
if (!selectionStartInLine) {
region.addRect(clipIfValid(rightToLeft ? QRectF(lineRect.topRight(), fullLineRect.bottomRight())
: QRectF(fullLineRect.topLeft(), lineRect.bottomLeft()), clip));
}
} else if (!selectionEndInLine } else if (!selectionEndInLine
&& isLastLineInBlock && isLastLineInBlock
&&!(d->option.flags() & QTextOption::ShowLineAndParagraphSeparators)) { &&!(d->option.flags() & QTextOption::ShowLineAndParagraphSeparators)) {

View File

@ -409,7 +409,7 @@ init_context:
break; break;
case QSsl::DtlsV1_0OrLater: case QSsl::DtlsV1_0OrLater:
minVersion = DTLS1_VERSION; minVersion = DTLS1_VERSION;
maxVersion = DTLS_MAX_VERSION; maxVersion = 0;
break; break;
case QSsl::DtlsV1_2: case QSsl::DtlsV1_2:
minVersion = DTLS1_2_VERSION; minVersion = DTLS1_2_VERSION;
@ -417,7 +417,7 @@ init_context:
break; break;
case QSsl::DtlsV1_2OrLater: case QSsl::DtlsV1_2OrLater:
minVersion = DTLS1_2_VERSION; minVersion = DTLS1_2_VERSION;
maxVersion = DTLS_MAX_VERSION; maxVersion = 0;
break; break;
case QSsl::TlsV1_3OrLater: case QSsl::TlsV1_3OrLater:
#ifdef TLS1_3_VERSION #ifdef TLS1_3_VERSION

View File

@ -59,57 +59,6 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifdef OPENSSL_NO_DEPRECATED_3_0
static int q_DH_check(DH *dh, int *status)
{
// DH_check was first deprecated in OpenSSL 3.0.0, as low-level
// API; the EVP_PKEY family of functions was advised as an alternative.
// As of now EVP_PKEY_params_check ends up calling ... DH_check,
// which is good enough.
Q_ASSERT(dh);
Q_ASSERT(status);
EVP_PKEY *key = q_EVP_PKEY_new();
if (!key) {
qCWarning(lcSsl, "EVP_PKEY_new failed");
QSslSocketBackendPrivate::logAndClearErrorQueue();
return 0;
}
const auto keyDeleter = qScopeGuard([key](){
q_EVP_PKEY_free(key);
});
if (!q_EVP_PKEY_set1_DH(key, dh)) {
qCWarning(lcSsl, "EVP_PKEY_set1_DH failed");
QSslSocketBackendPrivate::logAndClearErrorQueue();
return 0;
}
EVP_PKEY_CTX *keyCtx = q_EVP_PKEY_CTX_new(key, nullptr);
if (!keyCtx) {
qCWarning(lcSsl, "EVP_PKEY_CTX_new failed");
QSslSocketBackendPrivate::logAndClearErrorQueue();
return 0;
}
const auto ctxDeleter = qScopeGuard([keyCtx]{
q_EVP_PKEY_CTX_free(keyCtx);
});
const int result = q_EVP_PKEY_param_check(keyCtx);
QSslSocketBackendPrivate::logAndClearErrorQueue();
// Note: unlike DH_check, we cannot obtain the 'status',
// if the 'result' is 0 (actually the result is 1 only
// if this 'status' was 0). We could probably check the
// errors from the error queue, but it's not needed anyway
// - see the 'isSafeDH' below, how it returns immediately
// on 0.
Q_UNUSED(status)
return result;
}
#endif // OPENSSL_NO_DEPRECATED_3_0
static bool isSafeDH(DH *dh) static bool isSafeDH(DH *dh)
{ {
int status = 0; int status = 0;

View File

@ -148,7 +148,6 @@ DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
DEFINEFUNC2(EVP_PKEY_CTX *, EVP_PKEY_CTX_new, EVP_PKEY *pkey, pkey, ENGINE *e, e, return nullptr, return) DEFINEFUNC2(EVP_PKEY_CTX *, EVP_PKEY_CTX_new, EVP_PKEY *pkey, pkey, ENGINE *e, e, return nullptr, return)
DEFINEFUNC(int, EVP_PKEY_param_check, EVP_PKEY_CTX *ctx, ctx, return 0, return) DEFINEFUNC(int, EVP_PKEY_param_check, EVP_PKEY_CTX *ctx, ctx, return 0, return)
DEFINEFUNC(void, EVP_PKEY_CTX_free, EVP_PKEY_CTX *ctx, ctx, return, return) DEFINEFUNC(void, EVP_PKEY_CTX_free, EVP_PKEY_CTX *ctx, ctx, return, return)
DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return) DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return) DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return) DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return)
@ -368,7 +367,15 @@ DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr
DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return) DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return)
DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return) DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return)
DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return) DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return)
#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
DEFINEFUNC(X509 *, SSL_get1_peer_certificate, SSL *a, a, return nullptr, return)
DEFINEFUNC(int, EVP_PKEY_get_base_id, const EVP_PKEY *pkey, pkey, return -1, return)
#else
DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return) DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return)
DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
#endif // OPENSSL_VERSION_MAJOR >= 3
DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return) DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return)
DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return) DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return)
DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return) DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return)
@ -489,9 +496,7 @@ DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG) DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return) DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return)
DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return) DEFINEFUNC2(int, i2d_DHparams, DH *a, a, unsigned char **p, p, return -1, return)
#ifndef OPENSSL_NO_DEPRECATED_3_0
DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return) DEFINEFUNC2(int, DH_check, DH *dh, dh, int *codes, codes, return 0, return)
#endif // OPENSSL_NO_DEPRECATED_3_0
DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return nullptr, return) DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return nullptr, return)
#ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_EC
@ -852,7 +857,6 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_PKEY_CTX_new) RESOLVEFUNC(EVP_PKEY_CTX_new)
RESOLVEFUNC(EVP_PKEY_param_check) RESOLVEFUNC(EVP_PKEY_param_check)
RESOLVEFUNC(EVP_PKEY_CTX_free) RESOLVEFUNC(EVP_PKEY_CTX_free)
RESOLVEFUNC(EVP_PKEY_base_id)
RESOLVEFUNC(RSA_bits) RESOLVEFUNC(RSA_bits)
RESOLVEFUNC(OPENSSL_sk_new_null) RESOLVEFUNC(OPENSSL_sk_new_null)
RESOLVEFUNC(OPENSSL_sk_push) RESOLVEFUNC(OPENSSL_sk_push)
@ -1077,7 +1081,15 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_version) RESOLVEFUNC(SSL_version)
RESOLVEFUNC(SSL_get_error) RESOLVEFUNC(SSL_get_error)
RESOLVEFUNC(SSL_get_peer_cert_chain) RESOLVEFUNC(SSL_get_peer_cert_chain)
#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
RESOLVEFUNC(SSL_get1_peer_certificate)
RESOLVEFUNC(EVP_PKEY_get_base_id)
#else
RESOLVEFUNC(SSL_get_peer_certificate) RESOLVEFUNC(SSL_get_peer_certificate)
RESOLVEFUNC(EVP_PKEY_base_id)
#endif // OPENSSL_VERSION_MAJOR >= 3
RESOLVEFUNC(SSL_get_verify_result) RESOLVEFUNC(SSL_get_verify_result)
RESOLVEFUNC(SSL_new) RESOLVEFUNC(SSL_new)
RESOLVEFUNC(SSL_get_SSL_CTX) RESOLVEFUNC(SSL_get_SSL_CTX)
@ -1176,9 +1188,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(DH_free) RESOLVEFUNC(DH_free)
RESOLVEFUNC(d2i_DHparams) RESOLVEFUNC(d2i_DHparams)
RESOLVEFUNC(i2d_DHparams) RESOLVEFUNC(i2d_DHparams)
#ifndef OPENSSL_NO_DEPRECATED_3_0
RESOLVEFUNC(DH_check) RESOLVEFUNC(DH_check)
#endif // OPENSSL_NO_DEPRECATED_3_0
RESOLVEFUNC(BN_bin2bn) RESOLVEFUNC(BN_bin2bn)
#ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_EC

View File

@ -236,7 +236,6 @@ Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx); int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
int q_EVP_PKEY_base_id(EVP_PKEY *a);
int q_RSA_bits(RSA *a); int q_RSA_bits(RSA *a);
Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a); Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *)); Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
@ -509,7 +508,6 @@ const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a);
int q_SSL_version(const SSL *a); int q_SSL_version(const SSL *a);
int q_SSL_get_error(SSL *a, int b); int q_SSL_get_error(SSL *a, int b);
STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a); STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a);
X509 *q_SSL_get_peer_certificate(SSL *a);
long q_SSL_get_verify_result(const SSL *a); long q_SSL_get_verify_result(const SSL *a);
SSL *q_SSL_new(SSL_CTX *a); SSL *q_SSL_new(SSL_CTX *a);
SSL_CTX *q_SSL_get_SSL_CTX(SSL *a); SSL_CTX *q_SSL_get_SSL_CTX(SSL *a);
@ -581,10 +579,7 @@ DH *q_DH_new();
void q_DH_free(DH *dh); void q_DH_free(DH *dh);
DH *q_d2i_DHparams(DH **a, const unsigned char **pp, long length); DH *q_d2i_DHparams(DH **a, const unsigned char **pp, long length);
int q_i2d_DHparams(DH *a, unsigned char **p); int q_i2d_DHparams(DH *a, unsigned char **p);
#ifndef OPENSSL_NO_DEPRECATED_3_0
int q_DH_check(DH *dh, int *codes); int q_DH_check(DH *dh, int *codes);
#endif // OPENSSL_NO_DEPRECATED_3_0
BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
#define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh) #define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh)
@ -751,6 +746,17 @@ void *q_CRYPTO_malloc(size_t num, const char *file, int line);
int q_SSL_CTX_get_security_level(const SSL_CTX *ctx); int q_SSL_CTX_get_security_level(const SSL_CTX *ctx);
void q_SSL_CTX_set_security_level(SSL_CTX *ctx, int level); void q_SSL_CTX_set_security_level(SSL_CTX *ctx, int level);
// Here we have the ones that make difference between OpenSSL pre/post v3:
#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3
X509 *q_SSL_get1_peer_certificate(SSL *a);
#define q_SSL_get_peer_certificate q_SSL_get1_peer_certificate
int q_EVP_PKEY_get_base_id(const EVP_PKEY *pkey);
#define q_EVP_PKEY_base_id q_EVP_PKEY_get_base_id
#else
X509 *q_SSL_get_peer_certificate(SSL *a);
int q_EVP_PKEY_base_id(EVP_PKEY *a);
#endif // OPENSSL_VERSION_MAJOR >= 3
QT_END_NAMESPACE QT_END_NAMESPACE
#endif #endif

View File

@ -835,6 +835,8 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb
alloc_error = buf.size() != nbytes+1; alloc_error = buf.size() != nbytes+1;
} }
QElapsedTimer timer;
timer.start();
for (;;) { for (;;) {
connection()->flush(); connection()->flush();
xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_PROPERTY_NOTIFY); xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_PROPERTY_NOTIFY);
@ -870,9 +872,11 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb
tmp_buf.resize(0); tmp_buf.resize(0);
offset += length; offset += length;
} }
} else {
break;
} }
const auto elapsed = timer.elapsed();
if (elapsed > clipboard_timeout)
break;
} }
// timed out ... create a new requestor window, otherwise the requestor // timed out ... create a new requestor window, otherwise the requestor

View File

@ -52,7 +52,7 @@
"headers": "ibase.h", "headers": "ibase.h",
"sources": [ "sources": [
{ "libs": "-lgds32_ms", "condition": "config.win32" }, { "libs": "-lgds32_ms", "condition": "config.win32" },
{ "libs": "-lgds", "condition": "!config.win32" } { "libs": "-lfbclient", "condition": "!config.win32" }
] ]
}, },
"mysql": { "mysql": {
@ -67,6 +67,7 @@
}, },
"headers": "mysql.h", "headers": "mysql.h",
"sources": [ "sources": [
{ "type": "pkgConfig", "args": "mysqlclient" },
{ "type": "mysqlConfig", "query": "--libs_r", "cleanlibs": true }, { "type": "mysqlConfig", "query": "--libs_r", "cleanlibs": true },
{ "type": "mysqlConfig", "query": "--libs", "cleanlibs": true }, { "type": "mysqlConfig", "query": "--libs", "cleanlibs": true },
{ "type": "mysqlConfig", "query": "--libs_r", "cleanlibs": false }, { "type": "mysqlConfig", "query": "--libs_r", "cleanlibs": false },

View File

@ -158,6 +158,20 @@ static inline QVariant qDateTimeFromString(QString &val)
#endif #endif
} }
// check if this client and server version of MySQL/MariaDB support prepared statements
static inline bool checkPreparedQueries(MYSQL *mysql)
{
std::unique_ptr<MYSQL_STMT, decltype(&mysql_stmt_close)> stmt(mysql_stmt_init(mysql), &mysql_stmt_close);
if (!stmt)
return false;
static const char dummyQuery[] = "SELECT ? + ?";
if (mysql_stmt_prepare(stmt.get(), dummyQuery, sizeof(dummyQuery) - 1))
return false;
return mysql_stmt_param_count(stmt.get()) == 2;
}
class QMYSQLResultPrivate; class QMYSQLResultPrivate;
class QMYSQLResult : public QSqlResult class QMYSQLResult : public QSqlResult
@ -209,7 +223,7 @@ public:
struct QMyField struct QMyField
{ {
char *outField = nullptr; char *outField = nullptr;
MYSQL_FIELD *myField = nullptr; const MYSQL_FIELD *myField = nullptr;
QMetaType::Type type = QMetaType::UnknownType; QMetaType::Type type = QMetaType::UnknownType;
my_bool nullIndicator = false; my_bool nullIndicator = false;
ulong bufLength = 0ul; ulong bufLength = 0ul;
@ -347,11 +361,10 @@ static bool qIsInteger(int t)
void QMYSQLResultPrivate::bindBlobs() void QMYSQLResultPrivate::bindBlobs()
{ {
int i; int i;
MYSQL_FIELD *fieldInfo;
MYSQL_BIND *bind; MYSQL_BIND *bind;
for(i = 0; i < fields.count(); ++i) { for(i = 0; i < fields.count(); ++i) {
fieldInfo = fields.at(i).myField; const MYSQL_FIELD *fieldInfo = fields.at(i).myField;
if (qIsBlob(inBinds[i].buffer_type) && meta && fieldInfo) { if (qIsBlob(inBinds[i].buffer_type) && meta && fieldInfo) {
bind = &inBinds[i]; bind = &inBinds[i];
bind->buffer_length = fieldInfo->max_length; bind->buffer_length = fieldInfo->max_length;
@ -378,35 +391,34 @@ bool QMYSQLResultPrivate::bindInValues()
inBinds = new MYSQL_BIND[fields.size()]; inBinds = new MYSQL_BIND[fields.size()];
memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND)); memset(inBinds, 0, fields.size() * sizeof(MYSQL_BIND));
MYSQL_FIELD *fieldInfo; const MYSQL_FIELD *fieldInfo;
while((fieldInfo = mysql_fetch_field(meta))) { while((fieldInfo = mysql_fetch_field(meta))) {
MYSQL_BIND *bind = &inBinds[i];
QMyField &f = fields[i]; QMyField &f = fields[i];
f.myField = fieldInfo; f.myField = fieldInfo;
bind->buffer_length = f.bufLength = fieldInfo->length + 1;
bind->buffer_type = fieldInfo->type;
f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags); f.type = qDecodeMYSQLType(fieldInfo->type, fieldInfo->flags);
if (qIsBlob(fieldInfo->type)) { if (qIsBlob(fieldInfo->type)) {
// the size of a blob-field is available as soon as we call // the size of a blob-field is available as soon as we call
// mysql_stmt_store_result() // mysql_stmt_store_result()
// after mysql_stmt_exec() in QMYSQLResult::exec() // after mysql_stmt_exec() in QMYSQLResult::exec()
fieldInfo->length = 0; bind->buffer_length = f.bufLength = 0;
hasBlobs = true; hasBlobs = true;
} else if (qIsInteger(f.type)) { } else if (qIsInteger(f.type)) {
fieldInfo->length = 8; bind->buffer_length = f.bufLength = 8;
} else { } else {
fieldInfo->type = MYSQL_TYPE_STRING; bind->buffer_type = MYSQL_TYPE_STRING;
} }
bind = &inBinds[i];
field = new char[fieldInfo->length + 1];
memset(field, 0, fieldInfo->length + 1);
bind->buffer_type = fieldInfo->type;
bind->buffer = field;
bind->buffer_length = f.bufLength = fieldInfo->length + 1;
bind->is_null = &f.nullIndicator; bind->is_null = &f.nullIndicator;
bind->length = &f.bufLength; bind->length = &f.bufLength;
bind->is_unsigned = fieldInfo->flags & UNSIGNED_FLAG ? 1 : 0; bind->is_unsigned = fieldInfo->flags & UNSIGNED_FLAG ? 1 : 0;
f.outField=field;
char *field = new char[bind->buffer_length + 1]{};
bind->buffer = f.outField = field;
++i; ++i;
} }
@ -1371,8 +1383,7 @@ bool QMYSQLDriver::open(const QString& db,
} }
#endif // MYSQL_VERSION_ID >= 50007 #endif // MYSQL_VERSION_ID >= 50007
d->preparedQuerysEnabled = mysql_get_client_version() >= 40108 d->preparedQuerysEnabled = checkPreparedQueries(d->mysql);
&& mysql_get_server_version(d->mysql) >= 40100;
#if QT_CONFIG(thread) #if QT_CONFIG(thread)
mysql_thread_init(); mysql_thread_init();

View File

@ -305,10 +305,9 @@ bool Moc::parseEnum(EnumDef *def)
return IncludeState::NoInclude; return IncludeState::NoInclude;
}; };
do { do {
handleInclude();
if (lookup() == RBRACE) // accept trailing comma if (lookup() == RBRACE) // accept trailing comma
break; break;
if ( handleInclude() == IncludeState::IncludeEnd)
continue;
next(IDENTIFIER); next(IDENTIFIER);
def->values += lexem(); def->values += lexem();
handleInclude(); handleInclude();

View File

@ -149,14 +149,14 @@ public:
QRect cellRect(int row, int col) const; QRect cellRect(int row, int col) const;
inline QLayoutItem *itemAt(int index) const { inline QLayoutItem *itemAt(int index) const {
if (index < things.count()) if (index >= 0 && index < things.count())
return things.at(index)->item(); return things.at(index)->item();
else else
return nullptr; return nullptr;
} }
inline QLayoutItem *takeAt(int index) { inline QLayoutItem *takeAt(int index) {
Q_Q(QGridLayout); Q_Q(QGridLayout);
if (index < things.count()) { if (index >= 0 && index < things.count()) {
if (QGridBox *b = things.takeAt(index)) { if (QGridBox *b = things.takeAt(index)) {
QLayoutItem *item = b->takeItem(); QLayoutItem *item = b->takeItem();
if (QLayout *l = item->layout()) { if (QLayout *l = item->layout()) {
@ -184,7 +184,7 @@ public:
} }
void getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan) const { void getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan) const {
if (index < things.count()) { if (index >= 0 && index < things.count()) {
const QGridBox *b = things.at(index); const QGridBox *b = things.at(index);
int toRow = b->toRow(rr); int toRow = b->toRow(rr);
int toCol = b->toCol(cc); int toCol = b->toCol(cc);

View File

@ -1772,14 +1772,6 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget); proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
} }
break; break;
case CE_PushButtonLabel:
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
QStyleOptionButton b(*button);
// no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
b.state &= ~(State_On | State_Sunken);
QCommonStyle::drawControl(element, &b, painter, widget);
}
break;
case CE_MenuBarEmptyArea: case CE_MenuBarEmptyArea:
painter->save(); painter->save();
{ {

View File

@ -2640,6 +2640,9 @@ void QStyleSheetStyle::setProperties(QWidget *w)
default: v = decl.d->values.at(0).variant; break; default: v = decl.d->values.at(0).variant; break;
} }
if (propertyL1 == QByteArray("styleSheet") && value == v)
continue;
w->setProperty(propertyL1, v); w->setProperty(propertyL1, v);
} }
} }

View File

@ -407,8 +407,9 @@ void QLineEditIconButton::setHideWithText(bool hide)
void QLineEditIconButton::onAnimationFinished() void QLineEditIconButton::onAnimationFinished()
{ {
if (shouldHideWithText() && isVisible() && !m_wasHidden) { if (shouldHideWithText() && isVisible() && m_fadingOut) {
hide(); hide();
m_fadingOut = false;
// Invalidate previous geometry to take into account new size of side widgets // Invalidate previous geometry to take into account new size of side widgets
if (auto le = lineEditPrivate()) if (auto le = lineEditPrivate())
@ -418,7 +419,7 @@ void QLineEditIconButton::onAnimationFinished()
void QLineEditIconButton::animateShow(bool visible) void QLineEditIconButton::animateShow(bool visible)
{ {
m_wasHidden = visible; m_fadingOut = !visible;
if (shouldHideWithText() && !isVisible()) { if (shouldHideWithText() && !isVisible()) {
show(); show();
@ -664,10 +665,18 @@ static int effectiveTextMargin(int defaultMargin, const QLineEditPrivate::SideWi
if (widgets.empty()) if (widgets.empty())
return defaultMargin; return defaultMargin;
return defaultMargin + (parameters.margin + parameters.widgetWidth) * const auto visibleSideWidgetCount = std::count_if(widgets.begin(), widgets.end(),
int(std::count_if(widgets.begin(), widgets.end(),
[](const QLineEditPrivate::SideWidgetEntry &e) { [](const QLineEditPrivate::SideWidgetEntry &e) {
return e.widget->isVisibleTo(e.widget->parentWidget()); })); #if QT_CONFIG(animation)
// a button that's fading out doesn't get any space
if (auto* iconButton = qobject_cast<QLineEditIconButton*>(e.widget))
return iconButton->needsSpace();
#endif
return e.widget->isVisibleTo(e.widget->parentWidget());
});
return defaultMargin + (parameters.margin + parameters.widgetWidth) * visibleSideWidgetCount;
} }
QMargins QLineEditPrivate::effectiveTextMargins() const QMargins QLineEditPrivate::effectiveTextMargins() const

View File

@ -95,6 +95,11 @@ public:
bool shouldHideWithText() const; bool shouldHideWithText() const;
void setHideWithText(bool hide); void setHideWithText(bool hide);
bool needsSpace() const {
if (m_fadingOut)
return false;
return isVisibleTo(parentWidget());
}
#endif #endif
protected: protected:
@ -118,7 +123,7 @@ private:
#if QT_CONFIG(animation) #if QT_CONFIG(animation)
bool m_hideWithText = false; bool m_hideWithText = false;
bool m_wasHidden = false; bool m_fadingOut = false;
#endif #endif
}; };

View File

@ -34,6 +34,11 @@ class Foo : public QObject {
enum en { enum en {
#include <enum_inc.h> #include <enum_inc.h>
}; };
enum class en2 {
#include <enum_inc.h>
reference = 42
};
Q_OBJECT Q_OBJECT
}; };
#endif #endif

View File

@ -1493,7 +1493,7 @@ void tst_QApplication::desktopSettingsAware()
{ {
#if QT_CONFIG(process) #if QT_CONFIG(process)
QProcess testProcess; QProcess testProcess;
testProcess.start("desktopsettingsaware_helper"); testProcess.start("./desktopsettingsaware_helper");
QVERIFY2(testProcess.waitForStarted(), QVERIFY2(testProcess.waitForStarted(),
qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString()))); qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
QVERIFY(testProcess.waitForFinished(10000)); QVERIFY(testProcess.waitForFinished(10000));
@ -2447,7 +2447,7 @@ void tst_QApplication::qtbug_12673()
#if QT_CONFIG(process) #if QT_CONFIG(process)
QProcess testProcess; QProcess testProcess;
QStringList arguments; QStringList arguments;
testProcess.start("modal_helper", arguments); testProcess.start("./modal_helper", arguments);
QVERIFY2(testProcess.waitForStarted(), QVERIFY2(testProcess.waitForStarted(),
qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString()))); qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
QVERIFY(testProcess.waitForFinished(20000)); QVERIFY(testProcess.waitForFinished(20000));

View File

@ -75,6 +75,7 @@ private slots:
void taskQTBUG_40609_addingWidgetToItsOwnLayout(); void taskQTBUG_40609_addingWidgetToItsOwnLayout();
void taskQTBUG_40609_addingLayoutToItself(); void taskQTBUG_40609_addingLayoutToItself();
void taskQTBUG_52357_spacingWhenItemIsHidden(); void taskQTBUG_52357_spacingWhenItemIsHidden();
void taskQTBUG_91261_itemIndexRange();
void replaceWidget(); void replaceWidget();
void dontCrashWhenExtendsToEnd(); void dontCrashWhenExtendsToEnd();
}; };
@ -1666,6 +1667,56 @@ void tst_QGridLayout::taskQTBUG_52357_spacingWhenItemIsHidden()
QTRY_COMPARE_WITH_TIMEOUT(tempWidth, button1.width() + button3.width() + layout.spacing(), 1000); QTRY_COMPARE_WITH_TIMEOUT(tempWidth, button1.width() + button3.width() + layout.spacing(), 1000);
} }
void tst_QGridLayout::taskQTBUG_91261_itemIndexRange()
{
QWidget widget;
QGridLayout lay(&widget);
QPushButton *btn = new QPushButton(&widget);
lay.addWidget(btn, 0, 0);
{
auto ptr = lay.itemAt(-1);
QCOMPARE(ptr, nullptr);
ptr = lay.itemAt(0);
QCOMPARE(ptr->widget(), btn);
ptr = lay.itemAt(1);
QCOMPARE(ptr, nullptr);
}
{
int row = -1;
int column = -1;
int rowSpan;
int columnSpan;
lay.getItemPosition(-1, &row, &column, &rowSpan, &columnSpan);
QCOMPARE(row, -1);
QCOMPARE(column, -1);
lay.getItemPosition(1, &row, &column, &rowSpan, &columnSpan);
QCOMPARE(row, -1);
QCOMPARE(column, -1);
lay.getItemPosition(0, &row, &column, &rowSpan, &columnSpan);
QCOMPARE(row, 0);
QCOMPARE(column, 0);
}
{
auto ptr = lay.takeAt(-1);
QCOMPARE(ptr, nullptr);
ptr = lay.takeAt(1);
QCOMPARE(ptr, nullptr);
ptr = lay.takeAt(0);
QCOMPARE(ptr->widget(), btn);
delete ptr;
}
}
void tst_QGridLayout::replaceWidget() void tst_QGridLayout::replaceWidget()
{ {
QWidget wdg; QWidget wdg;

View File

@ -94,6 +94,7 @@ private slots:
void layoutSpacing(); void layoutSpacing();
#endif #endif
void qproperty(); void qproperty();
void qproperty_styleSheet();
void palettePropagation_data(); void palettePropagation_data();
void palettePropagation(); void palettePropagation();
void fontPropagation_data(); void fontPropagation_data();
@ -678,6 +679,23 @@ void tst_QStyleSheetStyle::qproperty()
QCOMPARE(pb.isChecked(), false); QCOMPARE(pb.isChecked(), false);
} }
void tst_QStyleSheetStyle::qproperty_styleSheet()
{
QWidget w;
auto checkBox = new QCheckBox("check", &w);
QString sheet = R"(QCheckBox { qproperty-styleSheet: "QCheckBox { qproperty-text: foobar; }"; })";
QVERIFY(w.property("styleSheet").toString().isEmpty());
w.setStyleSheet(sheet);
QCOMPARE(checkBox->text(), "check");
//recursion crash
w.ensurePolished();
QCOMPARE(w.property("styleSheet").toString(), sheet);
QCOMPARE(checkBox->text(), "foobar");
}
namespace ns { namespace ns {
class PushButton1 : public QPushButton { class PushButton1 : public QPushButton {
Q_OBJECT Q_OBJECT

View File

@ -292,6 +292,7 @@ private slots:
void clearButtonVisibleAfterSettingText_QTBUG_45518(); void clearButtonVisibleAfterSettingText_QTBUG_45518();
void sideWidgets(); void sideWidgets();
void sideWidgetsActionEvents(); void sideWidgetsActionEvents();
void sideWidgetsEffectiveMargins();
void shouldShowPlaceholderText_data(); void shouldShowPlaceholderText_data();
void shouldShowPlaceholderText(); void shouldShowPlaceholderText();
@ -4646,6 +4647,71 @@ void tst_QLineEdit::sideWidgetsActionEvents()
QCOMPARE(toolButton2->x(), toolButton1X); QCOMPARE(toolButton2->x(), toolButton1X);
} }
/*!
Verify that side widgets are positioned correctly and result in
correct effective text margins.
*/
void tst_QLineEdit::sideWidgetsEffectiveMargins()
{
#ifndef QT_BUILD_INTERNAL
QSKIP("This test requires a developer build.");
#else
QLineEdit edit;
edit.setPlaceholderText("placeholder");
edit.setClearButtonEnabled(true);
edit.show();
QLineEditPrivate *priv = QLineEditPrivate::get(&edit);
const auto sideWidgetParameters = priv->sideWidgetParameters();
const int sideWidgetWidth = sideWidgetParameters.widgetWidth + sideWidgetParameters.margin;
QVERIFY(QTest::qWaitForWindowExposed(&edit));
QCOMPARE(priv->effectiveTextMargins().left(), 0);
QCOMPARE(priv->effectiveTextMargins().right(), 0);
edit.setText("Left to right"); // clear button fades in on the right
QCOMPARE(priv->effectiveTextMargins().left(), 0);
QCOMPARE(priv->effectiveTextMargins().right(), sideWidgetWidth);
edit.clear();
QCOMPARE(priv->effectiveTextMargins().left(), 0);
QCOMPARE(priv->effectiveTextMargins().right(), 0);
edit.setLayoutDirection(Qt::RightToLeft);
edit.setText("ئۇيغۇر تىلى"); // clear button fades in on the left
QCOMPARE(priv->effectiveTextMargins().left(), sideWidgetWidth);
QCOMPARE(priv->effectiveTextMargins().right(), 0);
edit.clear();
QCOMPARE(priv->effectiveTextMargins().left(), 0);
QCOMPARE(priv->effectiveTextMargins().right(), 0);
edit.setLayoutDirection(Qt::LeftToRight);
const QIcon leftIcon = edit.style()->standardIcon(QStyle::SP_FileIcon);
const QIcon rightIcon = edit.style()->standardIcon(QStyle::SP_DirIcon);
edit.addAction(leftIcon, QLineEdit::ActionPosition::LeadingPosition);
QCOMPARE(priv->effectiveTextMargins().left(), sideWidgetWidth);
QCOMPARE(priv->effectiveTextMargins().right(), 0);
edit.addAction(rightIcon, QLineEdit::ActionPosition::TrailingPosition);
QCOMPARE(priv->effectiveTextMargins().left(), sideWidgetWidth);
QCOMPARE(priv->effectiveTextMargins().right(), sideWidgetWidth);
edit.setText("Left to right"); // clear button on the right
QCOMPARE(priv->effectiveTextMargins().left(), sideWidgetWidth);
QCOMPARE(priv->effectiveTextMargins().right(), 2 * sideWidgetWidth);
edit.clear();
QCOMPARE(priv->effectiveTextMargins().left(), sideWidgetWidth);
QCOMPARE(priv->effectiveTextMargins().right(), sideWidgetWidth);
edit.setLayoutDirection(Qt::RightToLeft);
edit.setText("ئۇيغۇر تىلى"); // clear button fades in on the left
QCOMPARE(priv->effectiveTextMargins().left(), 2 * sideWidgetWidth);
QCOMPARE(priv->effectiveTextMargins().right(), sideWidgetWidth);
edit.clear();
QCOMPARE(priv->effectiveTextMargins().left(), sideWidgetWidth);
QCOMPARE(priv->effectiveTextMargins().right(), sideWidgetWidth);
#endif
}
Q_DECLARE_METATYPE(Qt::AlignmentFlag) Q_DECLARE_METATYPE(Qt::AlignmentFlag)
void tst_QLineEdit::shouldShowPlaceholderText_data() void tst_QLineEdit::shouldShowPlaceholderText_data()
{ {