Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts: mkspecs/features/qml_module.prf mkspecs/features/qt_common.prf src/gui/text/qzip.cpp src/plugins/platforms/cocoa/qnsview.mm src/plugins/platforms/windows/array.h src/testlib/qtestcase.cpp src/widgets/dialogs/qfilesystemmodel.h Change-Id: Ie41c5868415b81f7693c80e045497035504bb210
This commit is contained in:
commit
b894a8def5
8
configure
vendored
8
configure
vendored
@ -692,7 +692,7 @@ CFG_EGLFS_EGLDEVICE=no
|
||||
CFG_EGLFS_MALI=no
|
||||
CFG_EGLFS_VIV=no
|
||||
CFG_EGLFS_VIV_WL=no
|
||||
CFG_DIRECTFB=auto
|
||||
CFG_DIRECTFB=no
|
||||
CFG_GBM=auto
|
||||
CFG_LINUXFB=auto
|
||||
CFG_INTEGRITYFB=no
|
||||
@ -2706,8 +2706,8 @@ Additional options:
|
||||
-no-gbm ............ Do not compile backends for GBM.
|
||||
* -gbm ............... Compile backends for GBM.
|
||||
|
||||
-no-directfb ....... Do not compile DirectFB support.
|
||||
* -directfb .......... Compile DirectFB support.
|
||||
* -no-directfb ....... Do not compile DirectFB support.
|
||||
-directfb .......... Compile DirectFB support.
|
||||
|
||||
-no-linuxfb ........ Do not compile Linux Framebuffer support.
|
||||
* -linuxfb ........... Compile Linux Framebuffer support.
|
||||
@ -3931,7 +3931,7 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ];
|
||||
setBootstrapVariable QMAKE_CXXFLAGS_RELEASE
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS \$(QMAKE_CFLAGS_RELEASE)"
|
||||
EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS \$(QMAKE_CXXFLAGS_RELEASE)"
|
||||
elif [ "$CFG_DEBUG" = "yes" ]; then
|
||||
else
|
||||
setBootstrapVariable QMAKE_CFLAGS_DEBUG
|
||||
setBootstrapVariable QMAKE_CXXFLAGS_DEBUG
|
||||
EXTRA_CFLAGS="$EXTRA_CFLAGS \$(QMAKE_CFLAGS_DEBUG)"
|
||||
|
@ -120,12 +120,12 @@ void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
|
||||
QPointF intersectPoint;
|
||||
QLineF polyLine;
|
||||
for (int i = 1; i < endPolygon.count(); ++i) {
|
||||
p2 = endPolygon.at(i) + myEndItem->pos();
|
||||
polyLine = QLineF(p1, p2);
|
||||
QLineF::IntersectType intersectType =
|
||||
polyLine.intersect(centerLine, &intersectPoint);
|
||||
if (intersectType == QLineF::BoundedIntersection)
|
||||
break;
|
||||
p2 = endPolygon.at(i) + myEndItem->pos();
|
||||
polyLine = QLineF(p1, p2);
|
||||
QLineF::IntersectType intersectType =
|
||||
polyLine.intersect(centerLine, &intersectPoint);
|
||||
if (intersectType == QLineF::BoundedIntersection)
|
||||
break;
|
||||
p1 = p2;
|
||||
}
|
||||
|
||||
@ -136,18 +136,18 @@ void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
|
||||
if (line().dy() >= 0)
|
||||
angle = (Pi * 2) - angle;
|
||||
|
||||
QPointF arrowP1 = line().p1() + QPointF(sin(angle + Pi / 3) * arrowSize,
|
||||
cos(angle + Pi / 3) * arrowSize);
|
||||
QPointF arrowP2 = line().p1() + QPointF(sin(angle + Pi - Pi / 3) * arrowSize,
|
||||
cos(angle + Pi - Pi / 3) * arrowSize);
|
||||
QPointF arrowP1 = line().p1() + QPointF(sin(angle + Pi / 3) * arrowSize,
|
||||
cos(angle + Pi / 3) * arrowSize);
|
||||
QPointF arrowP2 = line().p1() + QPointF(sin(angle + Pi - Pi / 3) * arrowSize,
|
||||
cos(angle + Pi - Pi / 3) * arrowSize);
|
||||
|
||||
arrowHead.clear();
|
||||
arrowHead << line().p1() << arrowP1 << arrowP2;
|
||||
arrowHead.clear();
|
||||
arrowHead << line().p1() << arrowP1 << arrowP2;
|
||||
//! [6] //! [7]
|
||||
painter->drawLine(line());
|
||||
painter->drawPolygon(arrowHead);
|
||||
if (isSelected()) {
|
||||
painter->setPen(QPen(myColor, 1, Qt::DashLine));
|
||||
painter->drawLine(line());
|
||||
painter->drawPolygon(arrowHead);
|
||||
if (isSelected()) {
|
||||
painter->setPen(QPen(myColor, 1, Qt::DashLine));
|
||||
QLineF myLine = line();
|
||||
myLine.translate(0, 4.0);
|
||||
painter->drawLine(myLine);
|
||||
|
41
mkspecs/features/file_copies.prf
Normal file
41
mkspecs/features/file_copies.prf
Normal file
@ -0,0 +1,41 @@
|
||||
isEmpty(COPIES): return()
|
||||
contains(TEMPLATE, .*subdirs): error("COPIES does not work with TEMPLATE=subdirs")
|
||||
|
||||
build_pass:build_all: \
|
||||
debug_and_release:debug {
|
||||
# Avoid that multiple build passes race with each other.
|
||||
# This will fail to copy anything if the user explicitly invokes
|
||||
# only the non-primary build. This is unfixable, as at qmake time
|
||||
# we cannot possibly know how make will be invoked, yet we must
|
||||
# predict it here.
|
||||
return()
|
||||
}
|
||||
|
||||
defineReplace(qtStripProPwd) {
|
||||
return($$relative_path($$1, $$_PRO_FILE_PWD_))
|
||||
}
|
||||
|
||||
for (cp, COPIES) {
|
||||
isEmpty($${cp}.files): next()
|
||||
pfx = copy_$${cp}
|
||||
for (f, $${cp}.files): \
|
||||
$${pfx}.files += $$absolute_path($$f, $$_PRO_FILE_PWD_)
|
||||
path = $$eval($${cp}.path)
|
||||
isEmpty(path): error("COPY $cp defines no .path")
|
||||
base = $$eval($${cp}.base)
|
||||
isEmpty(base) {
|
||||
$${pfx}.output = $$path/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
|
||||
} else: isEqual(base, $$_PRO_FILE_PWD_) {
|
||||
$${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripProPwd}
|
||||
} else {
|
||||
eval(defineReplace(qtStripSrcDir_$$cp) { \
|
||||
return(\$\$relative_path(\$\$1, $$val_escape(base))) \
|
||||
})
|
||||
$${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripSrcDir_$$cp}
|
||||
}
|
||||
$${pfx}.input = $${pfx}.files
|
||||
$${pfx}.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
|
||||
$${pfx}.name = COPY ${QMAKE_FILE_IN}
|
||||
$${pfx}.CONFIG = no_link no_clean target_predeps
|
||||
QMAKE_EXTRA_COMPILERS += $${pfx}
|
||||
}
|
@ -28,24 +28,6 @@ else: \
|
||||
|
||||
!qml1_target:static: CONFIG += builtin_resources
|
||||
|
||||
!force_independent:if(!debug_and_release|!build_all|CONFIG(release, debug|release)) {
|
||||
# These bizarre rules copy the files to the qtbase build directory
|
||||
|
||||
defineReplace(qmlModStripSrcDir) {
|
||||
return($$relative_path($$1, $$_PRO_FILE_PWD_))
|
||||
}
|
||||
|
||||
!builtin_resources: qmlfiles2build.input = fq_qml_files
|
||||
else: qmlfiles2build.input = qmldir_file
|
||||
qmlfiles2build.output = $$instbase/$$TARGETPATH/${QMAKE_FUNC_FILE_IN_qmlModStripSrcDir}
|
||||
!contains(TEMPLATE, vc.*): qmlfiles2build.variable_out = PRE_TARGETDEPS
|
||||
qmlfiles2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
|
||||
qmlfiles2build.name = COPY ${QMAKE_FILE_IN}
|
||||
qmlfiles2build.CONFIG = no_link no_clean
|
||||
|
||||
QMAKE_EXTRA_COMPILERS += qmlfiles2build
|
||||
}
|
||||
|
||||
builtin_resources {
|
||||
URITARGET = $$replace(URI, "\\.", "_")
|
||||
# Ensure the qml files are included in the resources
|
||||
@ -61,3 +43,5 @@ qmldir.base = $$_PRO_FILE_PWD_
|
||||
else: qmldir.files = $$qmldir_file
|
||||
qmldir.path = $$instbase/$$TARGETPATH
|
||||
INSTALLS += qmldir
|
||||
|
||||
!prefix_build: COPIES += qmldir
|
||||
|
@ -44,6 +44,10 @@ contains(TEMPLATE, .*lib) {
|
||||
QMAKE_PRL_INSTALL_REPLACE += lib_replace
|
||||
}
|
||||
|
||||
# The remainder of this file must not apply to bootstrapped tools,
|
||||
# as the host compiler's version and capabilities are not checked.
|
||||
host_build:force_bootstrap: return()
|
||||
|
||||
# Extra warnings for Qt non-example code, to ensure cleanliness of the sources.
|
||||
# The block below may turn these warnings into errors for some Qt targets.
|
||||
# -Wdate-time: warn if we use __DATE__ or __TIME__ (we want to be able to reproduce the exact same binary)
|
||||
|
@ -51,5 +51,5 @@ equals(QMAKE_HOST.os, Windows) {
|
||||
QMAKE_SH = sh
|
||||
}
|
||||
|
||||
CONFIG = qt warn_on release link_prl
|
||||
CONFIG = file_copies qt warn_on release link_prl
|
||||
QT = core gui
|
||||
|
@ -405,9 +405,9 @@ static bool matchWhileUnsplitting(const char *buffer, int buffer_len, int start,
|
||||
int *matchlen, int *lines)
|
||||
{
|
||||
int x = start;
|
||||
for (int n = 0; n < needle_len && x < buffer_len;
|
||||
for (int n = 0; n < needle_len;
|
||||
n++, x = skipEscapedLineEnds(buffer, buffer_len, x + 1, lines)) {
|
||||
if (buffer[x] != needle[n])
|
||||
if (x >= buffer_len || buffer[x] != needle[n])
|
||||
return false;
|
||||
}
|
||||
// That also skipped any remaining BSNLs immediately after the match.
|
||||
@ -568,24 +568,29 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
|
||||
++x;
|
||||
if (buffer_len >= x + 12 && !strncmp(buffer + x, "includehint", 11) &&
|
||||
(buffer[x + 11] == ' ' || buffer[x + 11] == '>')) {
|
||||
for (x += 11; buffer[x] != '>'; ++x) {} // skip
|
||||
for (x += 11; x < buffer_len && buffer[x] != '>'; ++x) {} // skip
|
||||
int inc_len = 0;
|
||||
for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip
|
||||
buffer[x + inc_len] = '\0';
|
||||
inc = buffer + x;
|
||||
for (++x; x + inc_len < buffer_len && buffer[x + inc_len] != '<'; ++inc_len) {} // skip
|
||||
if (x + inc_len < buffer_len) {
|
||||
buffer[x + inc_len] = '\0';
|
||||
inc = buffer + x;
|
||||
}
|
||||
} else if (buffer_len >= x + 13 && !strncmp(buffer + x, "customwidget", 12) &&
|
||||
(buffer[x + 12] == ' ' || buffer[x + 12] == '>')) {
|
||||
for (x += 13; buffer[x] != '>'; ++x) {} // skip up to >
|
||||
for (x += 13; x < buffer_len && buffer[x] != '>'; ++x) {} // skip up to >
|
||||
while(x < buffer_len) {
|
||||
for (x++; buffer[x] != '<'; ++x) {} // skip up to <
|
||||
while (++x < buffer_len && buffer[x] != '<') {} // skip up to <
|
||||
x++;
|
||||
if(buffer_len >= x + 7 && !strncmp(buffer+x, "header", 6) &&
|
||||
(buffer[x + 6] == ' ' || buffer[x + 6] == '>')) {
|
||||
for (x += 7; buffer[x] != '>'; ++x) {} // skip up to >
|
||||
for (x += 7; x < buffer_len && buffer[x] != '>'; ++x) {} // skip up to >
|
||||
int inc_len = 0;
|
||||
for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip
|
||||
buffer[x + inc_len] = '\0';
|
||||
inc = buffer + x;
|
||||
for (++x; x + inc_len < buffer_len && buffer[x + inc_len] != '<';
|
||||
++inc_len) {} // skip
|
||||
if (x + inc_len < buffer_len) {
|
||||
buffer[x + inc_len] = '\0';
|
||||
inc = buffer + x;
|
||||
}
|
||||
break;
|
||||
} else if(buffer_len >= x + 14 && !strncmp(buffer+x, "/customwidget", 13) &&
|
||||
(buffer[x + 13] == ' ' || buffer[x + 13] == '>')) {
|
||||
@ -595,20 +600,18 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
|
||||
}
|
||||
} else if(buffer_len >= x + 8 && !strncmp(buffer + x, "include", 7) &&
|
||||
(buffer[x + 7] == ' ' || buffer[x + 7] == '>')) {
|
||||
for (x += 8; buffer[x] != '>'; ++x) {
|
||||
for (x += 8; x < buffer_len && buffer[x] != '>'; ++x) {
|
||||
if (buffer_len >= x + 9 && buffer[x] == 'i' &&
|
||||
!strncmp(buffer + x, "impldecl", 8)) {
|
||||
for (x += 8; buffer[x] != '='; ++x) {} // skip
|
||||
if (buffer[x] != '=')
|
||||
continue;
|
||||
for (++x; buffer[x] == '\t' || buffer[x] == ' '; ++x) {} // skip
|
||||
for (x += 8; x < buffer_len && buffer[x] != '='; ++x) {} // skip
|
||||
while (++x < buffer_len && (buffer[x] == '\t' || buffer[x] == ' ')) {} // skip
|
||||
char quote = 0;
|
||||
if (buffer[x] == '\'' || buffer[x] == '"') {
|
||||
if (x < buffer_len && (buffer[x] == '\'' || buffer[x] == '"')) {
|
||||
quote = buffer[x];
|
||||
++x;
|
||||
}
|
||||
int val_len;
|
||||
for(val_len = 0; true; ++val_len) {
|
||||
for (val_len = 0; x + val_len < buffer_len; ++val_len) {
|
||||
if(quote) {
|
||||
if (buffer[x + val_len] == quote)
|
||||
break;
|
||||
@ -618,16 +621,22 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
|
||||
}
|
||||
}
|
||||
//? char saved = buffer[x + val_len];
|
||||
buffer[x + val_len] = '\0';
|
||||
if(!strcmp(buffer+x, "in implementation")) {
|
||||
//### do this
|
||||
if (x + val_len < buffer_len) {
|
||||
buffer[x + val_len] = '\0';
|
||||
if (!strcmp(buffer + x, "in implementation")) {
|
||||
//### do this
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int inc_len = 0;
|
||||
for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip
|
||||
buffer[x + inc_len] = '\0';
|
||||
inc = buffer + x;
|
||||
for (++x; x + inc_len < buffer_len && buffer[x + inc_len] != '<';
|
||||
++inc_len) {} // skip
|
||||
|
||||
if (x + inc_len < buffer_len) {
|
||||
buffer[x + inc_len] = '\0';
|
||||
inc = buffer + x;
|
||||
}
|
||||
}
|
||||
}
|
||||
//read past new line now..
|
||||
@ -641,14 +650,16 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
|
||||
#define SKIP_BSNL(pos) skipEscapedLineEnds(buffer, buffer_len, (pos), &line_count)
|
||||
|
||||
// Seek code or directive, skipping comments and space:
|
||||
for(; x < buffer_len; ++x) {
|
||||
x = SKIP_BSNL(x);
|
||||
for (; (x = SKIP_BSNL(x)) < buffer_len; ++x) {
|
||||
if (buffer[x] == ' ' || buffer[x] == '\t') {
|
||||
// keep going
|
||||
} else if (buffer[x] == '/') {
|
||||
int extralines = 0;
|
||||
int y = skipEscapedLineEnds(buffer, buffer_len, x + 1, &extralines);
|
||||
if (buffer[y] == '/') { // C++-style comment
|
||||
if (y >= buffer_len) {
|
||||
x = y;
|
||||
break;
|
||||
} else if (buffer[y] == '/') { // C++-style comment
|
||||
line_count += extralines;
|
||||
x = SKIP_BSNL(y + 1);
|
||||
while (x < buffer_len && !qmake_endOfLine(buffer[x]))
|
||||
@ -659,8 +670,7 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
|
||||
} else if (buffer[y] == '*') { // C-style comment
|
||||
line_count += extralines;
|
||||
x = y;
|
||||
while (++x < buffer_len) {
|
||||
x = SKIP_BSNL(x);
|
||||
while ((x = SKIP_BSNL(++x)) < buffer_len) {
|
||||
if (buffer[x] == '*') {
|
||||
extralines = 0;
|
||||
y = skipEscapedLineEnds(buffer, buffer_len,
|
||||
|
@ -225,10 +225,8 @@ MakefileGenerator
|
||||
build_proj->setExtraVars(basevars);
|
||||
build_proj->setExtraConfigs(basecfgs);
|
||||
|
||||
build_proj->read(project->projectFile());
|
||||
|
||||
//done
|
||||
return createMakefileGenerator(build_proj);
|
||||
if (build_proj->read(project->projectFile()))
|
||||
return createMakefileGenerator(build_proj);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,6 +105,12 @@
|
||||
# endif
|
||||
# define Q_DECL_EXPORT __declspec(dllexport)
|
||||
# define Q_DECL_IMPORT __declspec(dllimport)
|
||||
# if _MSC_VER >= 1800
|
||||
# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) stdext::make_unchecked_array_iterator(x)
|
||||
# endif
|
||||
# if _MSC_VER >= 1500
|
||||
# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) stdext::make_checked_array_iterator(x, size_t(N))
|
||||
# endif
|
||||
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
|
||||
# if defined(__INTEL_COMPILER)
|
||||
# define Q_DECL_VARIABLE_DEPRECATED
|
||||
@ -1106,6 +1112,11 @@
|
||||
# define Q_ALIGNOF(x) alignof(x)
|
||||
#endif
|
||||
|
||||
#if defined(Q_COMPILER_ALIGNAS)
|
||||
# undef Q_DECL_ALIGN
|
||||
# define Q_DECL_ALIGN(n) alignas(n)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fallback macros to certain compiler features
|
||||
*/
|
||||
@ -1174,6 +1185,12 @@
|
||||
#ifndef Q_DECL_CONST_FUNCTION
|
||||
# define Q_DECL_CONST_FUNCTION Q_DECL_PURE_FUNCTION
|
||||
#endif
|
||||
#ifndef QT_MAKE_UNCHECKED_ARRAY_ITERATOR
|
||||
# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) (x)
|
||||
#endif
|
||||
#ifndef QT_MAKE_CHECKED_ARRAY_ITERATOR
|
||||
# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) (x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SG10's SD-6 feature detection and some useful extensions from Clang and GCC
|
||||
|
@ -62,6 +62,7 @@ public:
|
||||
QModelIndex mapFromSource(const QModelIndex& sourceIndex) const Q_DECL_OVERRIDE;
|
||||
QModelIndex mapToSource(const QModelIndex& proxyIndex) const Q_DECL_OVERRIDE;
|
||||
QModelIndex parent(const QModelIndex& child) const Q_DECL_OVERRIDE;
|
||||
using QObject::parent;
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||
bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) Q_DECL_OVERRIDE;
|
||||
|
@ -419,7 +419,7 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
|
||||
if (!isArgvModified(argc, argv)) {
|
||||
origArgc = argc;
|
||||
origArgv = new char *[argc];
|
||||
std::copy(argv, argv + argc, origArgv);
|
||||
std::copy(argv, argv + argc, QT_MAKE_CHECKED_ARRAY_ITERATOR(origArgv, argc));
|
||||
}
|
||||
#endif // Q_OS_WIN && !Q_OS_WINRT
|
||||
|
||||
|
@ -1189,6 +1189,7 @@ public:
|
||||
public:
|
||||
template<class T> QAssociativeIterableImpl(const T*p)
|
||||
: _iterable(p)
|
||||
, _iterator(Q_NULLPTR)
|
||||
, _metaType_id_key(qMetaTypeId<typename T::key_type>())
|
||||
, _metaType_flags_key(QTypeInfo<typename T::key_type>::isPointer)
|
||||
, _metaType_id_value(qMetaTypeId<typename T::mapped_type>())
|
||||
@ -1208,6 +1209,7 @@ public:
|
||||
|
||||
QAssociativeIterableImpl()
|
||||
: _iterable(Q_NULLPTR)
|
||||
, _iterator(Q_NULLPTR)
|
||||
, _metaType_id_key(QMetaType::UnknownType)
|
||||
, _metaType_flags_key(0)
|
||||
, _metaType_id_value(QMetaType::UnknownType)
|
||||
|
@ -2151,8 +2151,8 @@ void QObject::deleteLater()
|
||||
|
||||
Returns a translated version of \a sourceText, optionally based on a
|
||||
\a disambiguation string and value of \a n for strings containing plurals;
|
||||
otherwise returns \a sourceText itself if no appropriate translated string
|
||||
is available.
|
||||
otherwise returns QString::fromUtf8(\a sourceText) if no appropriate
|
||||
translated string is available.
|
||||
|
||||
Example:
|
||||
\snippet ../widgets/mainwindows/sdi/mainwindow.cpp implicit tr context
|
||||
@ -2178,7 +2178,7 @@ void QObject::deleteLater()
|
||||
translators while performing translations is not supported. Doing
|
||||
so will probably result in crashes or other undesirable behavior.
|
||||
|
||||
\sa trUtf8(), QCoreApplication::translate(), {Internationalization with Qt}
|
||||
\sa QCoreApplication::translate(), {Internationalization with Qt}
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -38,6 +38,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/qarraydata.h>
|
||||
#include <QtCore/private/qnumeric_p.h>
|
||||
#include <QtCore/private/qtools_p.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -93,16 +94,22 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment,
|
||||
if (capacity > std::numeric_limits<size_t>::max() / objectSize)
|
||||
return 0;
|
||||
|
||||
size_t alloc = objectSize * capacity;
|
||||
size_t alloc;
|
||||
if (mul_overflow(objectSize, capacity, &alloc))
|
||||
return 0;
|
||||
|
||||
// Make sure qAllocMore won't overflow.
|
||||
// Make sure qAllocMore won't overflow qAllocMore.
|
||||
if (headerSize > size_t(MaxAllocSize) || alloc > size_t(MaxAllocSize) - headerSize)
|
||||
return 0;
|
||||
|
||||
capacity = qAllocMore(int(alloc), int(headerSize)) / int(objectSize);
|
||||
}
|
||||
|
||||
size_t allocSize = headerSize + objectSize * capacity;
|
||||
size_t allocSize;
|
||||
if (mul_overflow(objectSize, capacity, &allocSize))
|
||||
return 0;
|
||||
if (add_overflow(allocSize, headerSize, &allocSize))
|
||||
return 0;
|
||||
|
||||
QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize));
|
||||
if (header) {
|
||||
|
@ -852,7 +852,7 @@ inline bool QList<T>::op_eq_impl(const QList &l, QListData::ArrayCompatibleLayou
|
||||
const T *lb = reinterpret_cast<const T*>(l.p.begin());
|
||||
const T *b = reinterpret_cast<const T*>(p.begin());
|
||||
const T *e = reinterpret_cast<const T*>(p.end());
|
||||
return std::equal(b, e, lb);
|
||||
return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(lb, l.p.size()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -712,8 +712,8 @@ static int findChar(const QChar *str, int len, QChar ch, int from,
|
||||
}
|
||||
|
||||
#define REHASH(a) \
|
||||
if (sl_minus_1 < (int)sizeof(int) * CHAR_BIT) \
|
||||
hashHaystack -= (a) << sl_minus_1; \
|
||||
if (sl_minus_1 < sizeof(uint) * CHAR_BIT) \
|
||||
hashHaystack -= uint(a) << sl_minus_1; \
|
||||
hashHaystack <<= 1
|
||||
|
||||
inline bool qIsUpper(char ch)
|
||||
@ -3096,8 +3096,9 @@ int qFindString(
|
||||
const ushort *needle = (const ushort *)needle0;
|
||||
const ushort *haystack = (const ushort *)haystack0 + from;
|
||||
const ushort *end = (const ushort *)haystack0 + (l-sl);
|
||||
const int sl_minus_1 = sl-1;
|
||||
int hashNeedle = 0, hashHaystack = 0, idx;
|
||||
const uint sl_minus_1 = sl - 1;
|
||||
uint hashNeedle = 0, hashHaystack = 0;
|
||||
int idx;
|
||||
|
||||
if (cs == Qt::CaseSensitive) {
|
||||
for (idx = 0; idx < sl; ++idx) {
|
||||
@ -3172,10 +3173,11 @@ static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *nee
|
||||
|
||||
const ushort *end = haystack;
|
||||
haystack += from;
|
||||
const int sl_minus_1 = sl-1;
|
||||
const uint sl_minus_1 = sl - 1;
|
||||
const ushort *n = needle+sl_minus_1;
|
||||
const ushort *h = haystack+sl_minus_1;
|
||||
int hashNeedle = 0, hashHaystack = 0, idx;
|
||||
uint hashNeedle = 0, hashHaystack = 0;
|
||||
int idx;
|
||||
|
||||
if (cs == Qt::CaseSensitive) {
|
||||
for (idx = 0; idx < sl; ++idx) {
|
||||
|
@ -102,7 +102,8 @@ public:
|
||||
QVarLengthArray<T, Prealloc> &operator=(std::initializer_list<T> list)
|
||||
{
|
||||
resize(list.size());
|
||||
std::copy(list.begin(), list.end(), this->begin());
|
||||
std::copy(list.begin(), list.end(),
|
||||
QT_MAKE_CHECKED_ARRAY_ITERATOR(this->begin(), this->size()));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
@ -473,7 +474,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA
|
||||
int l = int(aend - ptr);
|
||||
int n = l - f;
|
||||
if (QTypeInfo<T>::isComplex) {
|
||||
std::copy(ptr + l, ptr + s, ptr + f);
|
||||
std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f));
|
||||
T *i = ptr + s;
|
||||
T *b = ptr + s - n;
|
||||
while (i != b) {
|
||||
@ -495,7 +496,7 @@ bool operator==(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T,
|
||||
const T *rb = r.begin();
|
||||
const T *b = l.begin();
|
||||
const T *e = l.end();
|
||||
return std::equal(b, e, rb);
|
||||
return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(rb, r.size()));
|
||||
}
|
||||
|
||||
template <typename T, int Prealloc1, int Prealloc2>
|
||||
|
@ -773,7 +773,7 @@ bool QVector<T>::operator==(const QVector<T> &v) const
|
||||
const T *vb = v.d->begin();
|
||||
const T *b = d->begin();
|
||||
const T *e = d->end();
|
||||
return std::equal(b, e, vb);
|
||||
return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(vb, v.d->size));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -105,9 +105,11 @@ typedef dbus_uint32_t dbus_bool_t;
|
||||
/* dbus-shared.h */
|
||||
#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
|
||||
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
||||
#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local"
|
||||
#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
|
||||
#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable"
|
||||
#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
|
||||
#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local"
|
||||
|
||||
#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
|
||||
#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */
|
||||
|
@ -265,6 +265,8 @@ private:
|
||||
|
||||
QString getNameOwnerNoCache(const QString &service);
|
||||
|
||||
void watchForDBusDisconnection();
|
||||
|
||||
void _q_newConnection(QDBusConnectionPrivate *newConnection);
|
||||
|
||||
protected:
|
||||
@ -284,6 +286,7 @@ private slots:
|
||||
void serviceOwnerChangedNoLock(const QString &name, const QString &oldOwner, const QString &newOwner);
|
||||
void registerServiceNoLock(const QString &serviceName);
|
||||
void unregisterServiceNoLock(const QString &serviceName);
|
||||
void handleDBusDisconnection();
|
||||
|
||||
signals:
|
||||
void dispatchStatusChanged();
|
||||
|
@ -1126,6 +1126,12 @@ void QDBusConnectionPrivate::closeConnection()
|
||||
rootNode.children.clear(); // free resources
|
||||
}
|
||||
|
||||
void QDBusConnectionPrivate::handleDBusDisconnection()
|
||||
{
|
||||
while (!pendingCalls.isEmpty())
|
||||
processFinishedCall(pendingCalls.first());
|
||||
}
|
||||
|
||||
void QDBusConnectionPrivate::checkThread()
|
||||
{
|
||||
Q_ASSERT(thread() == QDBusConnectionManager::instance());
|
||||
@ -1651,6 +1657,19 @@ void QDBusConnectionPrivate::handleSignal(const QDBusMessage& msg)
|
||||
handleSignal(key, msg); // third try
|
||||
}
|
||||
|
||||
void QDBusConnectionPrivate::watchForDBusDisconnection()
|
||||
{
|
||||
SignalHook hook;
|
||||
// Initialize the hook for Disconnected signal
|
||||
hook.service.clear(); // org.freedesktop.DBus.Local.Disconnected uses empty service name
|
||||
hook.path = QDBusUtil::dbusPathLocal();
|
||||
hook.obj = this;
|
||||
hook.params << QMetaType::Void;
|
||||
hook.midx = staticMetaObject.indexOfSlot("handleDBusDisconnection()");
|
||||
Q_ASSERT(hook.midx != -1);
|
||||
signalHooks.insert(QLatin1String("Disconnected:" DBUS_INTERFACE_LOCAL), hook);
|
||||
}
|
||||
|
||||
void QDBusConnectionPrivate::setServer(QDBusServer *object, DBusServer *s, const QDBusErrorInternal &error)
|
||||
{
|
||||
mode = ServerMode;
|
||||
@ -1716,6 +1735,8 @@ void QDBusConnectionPrivate::setPeer(DBusConnection *c, const QDBusErrorInternal
|
||||
qDBusSignalFilter,
|
||||
this, 0);
|
||||
|
||||
watchForDBusDisconnection();
|
||||
|
||||
QMetaObject::invokeMethod(this, "doDispatch", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
@ -1792,6 +1813,8 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError
|
||||
Q_ASSERT(hook.midx != -1);
|
||||
signalHooks.insert(QLatin1String("NameOwnerChanged:" DBUS_INTERFACE_DBUS), hook);
|
||||
|
||||
watchForDBusDisconnection();
|
||||
|
||||
qDBusDebug() << this << ": connected successfully";
|
||||
|
||||
// schedule a dispatch:
|
||||
@ -1818,10 +1841,16 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
|
||||
|
||||
QDBusMessage &msg = call->replyMessage;
|
||||
if (call->pending) {
|
||||
// decode the message
|
||||
DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
|
||||
msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities);
|
||||
q_dbus_message_unref(reply);
|
||||
// when processFinishedCall is called and pending call is not completed,
|
||||
// it means we received disconnected signal from libdbus
|
||||
if (q_dbus_pending_call_get_completed(call->pending)) {
|
||||
// decode the message
|
||||
DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending);
|
||||
msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities);
|
||||
q_dbus_message_unref(reply);
|
||||
} else {
|
||||
msg = QDBusMessage::createError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage());
|
||||
}
|
||||
}
|
||||
qDBusDebug() << connection << "got message reply:" << msg;
|
||||
|
||||
@ -2121,8 +2150,8 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void *
|
||||
pcall->pending = pending;
|
||||
q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0);
|
||||
|
||||
// DBus won't notify us when a peer disconnects so we need to track these ourselves
|
||||
if (mode == QDBusConnectionPrivate::PeerMode)
|
||||
// DBus won't notify us when a peer disconnects or server terminates so we need to track these ourselves
|
||||
if (mode == QDBusConnectionPrivate::PeerMode || mode == QDBusConnectionPrivate::ClientMode)
|
||||
pendingCalls.append(pcall);
|
||||
|
||||
return;
|
||||
|
@ -164,6 +164,8 @@ namespace QDBusUtil
|
||||
{ return QStringLiteral(DBUS_SERVICE_DBUS); }
|
||||
inline QString dbusPath()
|
||||
{ return QStringLiteral(DBUS_PATH_DBUS); }
|
||||
inline QString dbusPathLocal()
|
||||
{ return QStringLiteral(DBUS_PATH_LOCAL); }
|
||||
inline QString dbusInterface()
|
||||
{
|
||||
// it's the same string, but just be sure
|
||||
|
@ -1643,7 +1643,7 @@ QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence)
|
||||
s >> keys[i];
|
||||
}
|
||||
qAtomicDetach(keysequence.d);
|
||||
std::copy(keys, keys + MaxKeys, keysequence.d->key);
|
||||
std::copy(keys, keys + MaxKeys, QT_MAKE_CHECKED_ARRAY_ITERATOR(keysequence.d->key, MaxKeys));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,8 @@ public:
|
||||
}
|
||||
inline QKeySequencePrivate(const QKeySequencePrivate ©) : ref(1)
|
||||
{
|
||||
std::copy(copy.key, copy.key + MaxKeyCount, key);
|
||||
std::copy(copy.key, copy.key + MaxKeyCount,
|
||||
QT_MAKE_CHECKED_ARRAY_ITERATOR(key, MaxKeyCount));
|
||||
}
|
||||
QAtomicInt ref;
|
||||
int key[MaxKeyCount];
|
||||
|
@ -6183,7 +6183,8 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
|
||||
|
||||
QString key = QLatin1String("WaveUnderline-")
|
||||
% pen.color().name()
|
||||
% HexString<qreal>(radiusBase);
|
||||
% HexString<qreal>(radiusBase)
|
||||
% HexString<qreal>(pen.widthF());
|
||||
|
||||
QPixmap pixmap;
|
||||
if (QPixmapCache::find(key, pixmap))
|
||||
@ -6191,7 +6192,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
|
||||
|
||||
const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
|
||||
const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod);
|
||||
const int radius = qFloor(radiusBase);
|
||||
const qreal radius = qFloor(radiusBase * 2) / 2.;
|
||||
|
||||
QPainterPath path;
|
||||
|
||||
@ -6214,7 +6215,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
|
||||
// due to it having a rather thick width for the regular underline.
|
||||
const qreal maxPenWidth = .8 * radius;
|
||||
if (wavePen.widthF() > maxPenWidth)
|
||||
wavePen.setWidth(maxPenWidth);
|
||||
wavePen.setWidthF(maxPenWidth);
|
||||
|
||||
QPainter imgPainter(&pixmap);
|
||||
imgPainter.setPen(wavePen);
|
||||
@ -6267,14 +6268,15 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
|
||||
if (underlineStyle == QTextCharFormat::WaveUnderline) {
|
||||
painter->save();
|
||||
painter->translate(0, pos.y() + 1);
|
||||
qreal maxHeight = fe->descent().toReal() - qreal(1);
|
||||
|
||||
QColor uc = charFormat.underlineColor();
|
||||
if (uc.isValid())
|
||||
pen.setColor(uc);
|
||||
|
||||
// Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms
|
||||
const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen);
|
||||
const int descent = (int) fe->descent().toReal();
|
||||
const QPixmap wave = generateWavyPixmap(qMin(qMax(underlineOffset, pen.widthF()), maxHeight / 2.), pen);
|
||||
const int descent = qFloor(maxHeight);
|
||||
|
||||
painter->setBrushOrigin(painter->brushOrigin().x(), 0);
|
||||
painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
|
||||
|
@ -1202,7 +1202,7 @@ void QPdfEngine::setPen()
|
||||
switch(d->pen.joinStyle()) {
|
||||
case Qt::MiterJoin:
|
||||
case Qt::SvgMiterJoin:
|
||||
*d->currentPage << d->pen.miterLimit() << "M ";
|
||||
*d->currentPage << qMax(qreal(1.0), d->pen.miterLimit()) << "M ";
|
||||
pdfJoinStyle = 0;
|
||||
break;
|
||||
case Qt::BevelJoin:
|
||||
|
@ -822,12 +822,12 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const
|
||||
QZipReader::QZipReader(const QString &archive, QIODevice::OpenMode mode)
|
||||
{
|
||||
QScopedPointer<QFile> f(new QFile(archive));
|
||||
f->open(mode);
|
||||
const bool result = f->open(mode);
|
||||
QZipReader::Status status;
|
||||
const QFileDevice::FileError error = f->error();
|
||||
if (error == QFile::NoError)
|
||||
if (result && error == QFile::NoError) {
|
||||
status = NoError;
|
||||
else {
|
||||
} else {
|
||||
if (error == QFile::ReadError)
|
||||
status = FileReadError;
|
||||
else if (error == QFile::OpenError)
|
||||
@ -1119,9 +1119,8 @@ void QZipReader::close()
|
||||
QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode)
|
||||
{
|
||||
QScopedPointer<QFile> f(new QFile(fileName));
|
||||
f->open(mode);
|
||||
QZipWriter::Status status;
|
||||
if (f->error() == QFile::NoError)
|
||||
if (f->open(mode) && f->error() == QFile::NoError)
|
||||
status = QZipWriter::NoError;
|
||||
else {
|
||||
if (f->error() == QFile::WriteError)
|
||||
|
@ -287,7 +287,6 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx)
|
||||
qCDebug(lcSsl) << QSslCertificatePrivate::QSslCertificate_from_X509(q_X509_STORE_CTX_get_current_cert(ctx)).toPem();
|
||||
qCDebug(lcSsl) << "dumping chain";
|
||||
foreach (QSslCertificate cert, QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(q_X509_STORE_CTX_get_chain(ctx))) {
|
||||
QString certFormat(QStringLiteral("O=%1 CN=%2 L=%3 OU=%4 C=%5 ST=%6"));
|
||||
qCDebug(lcSsl) << "Issuer:" << "O=" << cert.issuerInfo(QSslCertificate::Organization)
|
||||
<< "CN=" << cert.issuerInfo(QSslCertificate::CommonName)
|
||||
<< "L=" << cert.issuerInfo(QSslCertificate::LocalityName)
|
||||
|
@ -69,12 +69,6 @@ static inline int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper,
|
||||
return qtLower + ((fcweight - fcLower) * (qtUpper - qtLower)) / (fcUpper - fcLower);
|
||||
}
|
||||
|
||||
static inline bool requiresOpenType(int writingSystem)
|
||||
{
|
||||
return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
|
||||
|| writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
|
||||
}
|
||||
|
||||
static inline int weightFromFcWeight(int fcweight)
|
||||
{
|
||||
// Font Config uses weights from 0 to 215 (the highest enum value) while QFont ranges from
|
||||
@ -300,10 +294,10 @@ static const char *languageForWritingSystem[] = {
|
||||
Q_STATIC_ASSERT(sizeof(languageForWritingSystem) / sizeof(const char *) == QFontDatabase::WritingSystemsCount);
|
||||
|
||||
#if FC_VERSION >= 20297
|
||||
// Newer FontConfig let's us sort out fonts that contain certain glyphs, but no
|
||||
// open type tables for is directly. Do this so we don't pick some strange
|
||||
// pseudo unicode font
|
||||
static const char *openType[] = {
|
||||
// Newer FontConfig let's us sort out fonts that report certain scripts support,
|
||||
// but no open type tables for handling them correctly.
|
||||
// Check the reported script presence in the FC_CAPABILITY's "otlayout:" section.
|
||||
static const char *capabilityForWritingSystem[] = {
|
||||
0, // Any
|
||||
0, // Latin
|
||||
0, // Greek
|
||||
@ -339,7 +333,7 @@ static const char *openType[] = {
|
||||
0, // Runic
|
||||
"nko " // N'Ko
|
||||
};
|
||||
Q_STATIC_ASSERT(sizeof(openType) / sizeof(const char *) == QFontDatabase::WritingSystemsCount);
|
||||
Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount);
|
||||
#endif
|
||||
|
||||
static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
|
||||
@ -422,11 +416,23 @@ static void populateFromPattern(FcPattern *pattern)
|
||||
FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
|
||||
if (res == FcResultMatch) {
|
||||
bool hasLang = false;
|
||||
#if FC_VERSION >= 20297
|
||||
FcChar8 *cap = Q_NULLPTR;
|
||||
FcResult capRes = FcResultNoMatch;
|
||||
#endif
|
||||
for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
|
||||
const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
|
||||
if (lang) {
|
||||
FcLangResult langRes = FcLangSetHasLang(langset, lang);
|
||||
if (langRes != FcLangDifferentLang) {
|
||||
#if FC_VERSION >= 20297
|
||||
if (capabilityForWritingSystem[j] != Q_NULLPTR) {
|
||||
if (cap == Q_NULLPTR)
|
||||
capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap);
|
||||
if (capRes == FcResultMatch && strstr(reinterpret_cast<const char *>(cap), capabilityForWritingSystem[j]) == 0)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
writingSystems.setSupported(QFontDatabase::WritingSystem(j));
|
||||
hasLang = true;
|
||||
}
|
||||
@ -442,18 +448,6 @@ static void populateFromPattern(FcPattern *pattern)
|
||||
writingSystems.setSupported(QFontDatabase::Other);
|
||||
}
|
||||
|
||||
#if FC_VERSION >= 20297
|
||||
for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
|
||||
if (writingSystems.supported(QFontDatabase::WritingSystem(j))
|
||||
&& requiresOpenType(j) && openType[j]) {
|
||||
FcChar8 *cap;
|
||||
res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap);
|
||||
if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
|
||||
writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
FontFile *fontFile = new FontFile;
|
||||
fontFile->fileName = QString::fromLocal8Bit((const char *)file_value);
|
||||
fontFile->indexValue = indexValue;
|
||||
|
@ -105,7 +105,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
|
||||
- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
|
||||
{
|
||||
Q_ASSERT(m_menu->nsMenu() == menu);
|
||||
return m_menu->items().count();
|
||||
return menu.numberOfItems;
|
||||
}
|
||||
|
||||
- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
|
||||
|
@ -747,8 +747,7 @@ QT_WARNING_POP
|
||||
|
||||
- (void)handleMouseEvent:(NSEvent *)theEvent
|
||||
{
|
||||
if ([self handleTabletEvent: theEvent])
|
||||
return;
|
||||
bool isTabletEvent = [self handleTabletEvent: theEvent];
|
||||
|
||||
QPointF qtWindowPoint;
|
||||
QPointF qtScreenPoint;
|
||||
@ -777,7 +776,8 @@ QT_WARNING_POP
|
||||
nativeDrag->setLastMouseEvent(theEvent, self);
|
||||
|
||||
Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
|
||||
QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers);
|
||||
QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers,
|
||||
isTabletEvent ? Qt::MouseEventSynthesizedByQt : Qt::MouseEventNotSynthesized);
|
||||
}
|
||||
|
||||
- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <QtGui/qaccessible.h>
|
||||
#include <QtGui/qclipboard.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include <algorithm>
|
||||
@ -607,7 +608,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_keyBinding(long actionIndex
|
||||
// The IDL documents that the client must free with CoTaskMemFree
|
||||
arrayOfBindingsToReturn = coTaskMemAllocArray<BSTR>(numBindings);
|
||||
std::transform(keyBindings.constBegin(), keyBindings.constEnd(),
|
||||
arrayOfBindingsToReturn, QStringToBSTR);
|
||||
QT_MAKE_CHECKED_ARRAY_ITERATOR(arrayOfBindingsToReturn, numBindings),
|
||||
QStringToBSTR);
|
||||
}
|
||||
}
|
||||
*keyBindings = arrayOfBindingsToReturn;
|
||||
@ -666,9 +668,11 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locationInParent(long *x, l
|
||||
QAccessibleInterface *parentIface = accessible->parent();
|
||||
if (parentIface && parentIface->isValid())
|
||||
topLeft -= parentIface->rect().topLeft();
|
||||
const QPoint nativeTopLeft = QHighDpi::toNativeLocalPosition(topLeft, accessible->window());
|
||||
|
||||
*x = topLeft.x();
|
||||
*y = topLeft.y();
|
||||
|
||||
*x = nativeTopLeft.x();
|
||||
*y = nativeTopLeft.y();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -989,7 +993,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedColumns(long **sele
|
||||
*selectedColumns = Q_NULLPTR;
|
||||
if (count) {
|
||||
*selectedColumns = coTaskMemAllocArray<long>(count);
|
||||
std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedColumns);
|
||||
std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(),
|
||||
QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedColumns, count));
|
||||
}
|
||||
return count ? S_OK : S_FALSE;
|
||||
}
|
||||
@ -1011,7 +1016,8 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedRows(long **selecte
|
||||
*selectedRows = Q_NULLPTR;
|
||||
if (count) {
|
||||
*selectedRows = coTaskMemAllocArray<long>(count);
|
||||
std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(), *selectedRows);
|
||||
std::copy(selectedIndices.constBegin(), selectedIndices.constEnd(),
|
||||
QT_MAKE_CHECKED_ARRAY_ITERATOR(*selectedRows, count));
|
||||
}
|
||||
return count ? S_OK : S_FALSE;
|
||||
}
|
||||
@ -1680,7 +1686,8 @@ HRESULT QWindowsIA2Accessible::wrapListOfCells(const QList<QAccessibleInterface*
|
||||
if (count) {
|
||||
*outputAccessibles = coTaskMemAllocArray<IUnknown *>(count);
|
||||
std::transform(inputCells.constBegin(), inputCells.constEnd(),
|
||||
*outputAccessibles, QWindowsAccessibility::wrap);
|
||||
QT_MAKE_CHECKED_ARRAY_ITERATOR(*outputAccessibles, count),
|
||||
QWindowsAccessibility::wrap);
|
||||
}
|
||||
return count > 0 ? S_OK : S_FALSE;
|
||||
}
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
|
||||
//#include <uiautomationcoreapi.h>
|
||||
#ifndef UiaRootObjectId
|
||||
@ -503,7 +504,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accHitTest(long xLeft, long yT
|
||||
if (!accessible)
|
||||
return E_FAIL;
|
||||
|
||||
QAccessibleInterface *child = accessible->childAt(xLeft, yTop);
|
||||
const QPoint pos = QHighDpi::fromNativeLocalPosition(QPoint(xLeft, yTop), accessible->window());
|
||||
QAccessibleInterface *child = accessible->childAt(pos.x(), pos.y());
|
||||
if (child == 0) {
|
||||
// no child found, return this item if it contains the coordinates
|
||||
if (accessible->rect().contains(xLeft, yTop)) {
|
||||
@ -545,7 +547,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accLocation(long *pxLeft, long
|
||||
QAccessibleInterface *acc = childPointer(accessible, varID);
|
||||
if (!acc || !acc->isValid())
|
||||
return E_FAIL;
|
||||
const QRect rect = acc->rect();
|
||||
const QRect rect = QHighDpi::toNativePixels(acc->rect(), accessible->window());
|
||||
|
||||
*pxLeft = rect.x();
|
||||
*pyTop = rect.y();
|
||||
|
@ -654,7 +654,7 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
|
||||
reconv->dwTargetStrOffset = reconv->dwCompStrOffset;
|
||||
ushort *pastReconv = reinterpret_cast<ushort *>(reconv + 1);
|
||||
std::copy(surroundingText.utf16(), surroundingText.utf16() + surroundingText.size(),
|
||||
pastReconv);
|
||||
QT_MAKE_UNCHECKED_ARRAY_ITERATOR(pastReconv));
|
||||
return memSize;
|
||||
}
|
||||
|
||||
|
@ -466,14 +466,20 @@ qint64 QWinRTFileEngine::read(char *data, qint64 maxlen)
|
||||
hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &op);
|
||||
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
|
||||
|
||||
hr = QWinRTFunctions::await(op, buffer.GetAddressOf());
|
||||
// Quoting MSDN IInputStream::ReadAsync() documentation:
|
||||
// "Depending on the implementation, the data that's read might be placed
|
||||
// into the input buffer, or it might be returned in a different buffer."
|
||||
// Using GetAddressOf can cause ref counting errors leaking the original
|
||||
// buffer.
|
||||
ComPtr<IBuffer> effectiveBuffer;
|
||||
hr = QWinRTFunctions::await(op, effectiveBuffer.GetAddressOf());
|
||||
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
|
||||
|
||||
hr = buffer->get_Length(&length);
|
||||
hr = effectiveBuffer->get_Length(&length);
|
||||
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
|
||||
|
||||
ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
|
||||
hr = buffer.As(&byteArrayAccess);
|
||||
hr = effectiveBuffer.As(&byteArrayAccess);
|
||||
RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
|
||||
|
||||
byte *bytes;
|
||||
|
@ -955,8 +955,20 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *)
|
||||
HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args)
|
||||
{
|
||||
Q_D(QWinRTScreen);
|
||||
|
||||
ComPtr<IPointerPoint> pointerPoint;
|
||||
if (FAILED(args->get_CurrentPoint(&pointerPoint)))
|
||||
return E_INVALIDARG;
|
||||
|
||||
quint32 id;
|
||||
if (FAILED(pointerPoint->get_PointerId(&id)))
|
||||
return E_INVALIDARG;
|
||||
|
||||
d->touchPoints.remove(id);
|
||||
|
||||
QWindowSystemInterface::handleLeaveEvent(0);
|
||||
return S_OK;
|
||||
}
|
||||
@ -1040,6 +1052,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
|
||||
|
||||
break;
|
||||
}
|
||||
case PointerDeviceType_Pen:
|
||||
case PointerDeviceType_Touch: {
|
||||
if (!d->touchDevice) {
|
||||
d->touchDevice = new QTouchDevice;
|
||||
@ -1058,51 +1071,45 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
|
||||
float pressure;
|
||||
properties->get_Pressure(&pressure);
|
||||
|
||||
QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id);
|
||||
if (it != d->touchPoints.end()) {
|
||||
boolean isPressed;
|
||||
boolean isPressed;
|
||||
#ifndef Q_OS_WINPHONE
|
||||
pointerPoint->get_IsInContact(&isPressed);
|
||||
pointerPoint->get_IsInContact(&isPressed);
|
||||
#else
|
||||
properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone
|
||||
properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone
|
||||
#endif
|
||||
it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased;
|
||||
} else {
|
||||
|
||||
const QRectF areaRect(area.X * d->scaleFactor, area.Y * d->scaleFactor,
|
||||
area.Width * d->scaleFactor, area.Height * d->scaleFactor);
|
||||
|
||||
QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = d->touchPoints.find(id);
|
||||
if (it == d->touchPoints.end()) {
|
||||
it = d->touchPoints.insert(id, QWindowSystemInterface::TouchPoint());
|
||||
it.value().state = Qt::TouchPointPressed;
|
||||
it.value().id = id;
|
||||
}
|
||||
it.value().area = QRectF(area.X * d->scaleFactor, area.Y * d->scaleFactor,
|
||||
area.Width * d->scaleFactor, area.Height * d->scaleFactor);
|
||||
|
||||
if (isPressed && it.value().pressure == 0.)
|
||||
it.value().state = Qt::TouchPointPressed;
|
||||
else if (!isPressed && it.value().pressure > 0.)
|
||||
it.value().state = Qt::TouchPointReleased;
|
||||
else if (it.value().area == areaRect)
|
||||
it.value().state = Qt::TouchPointStationary;
|
||||
else
|
||||
it.value().state = Qt::TouchPointMoved;
|
||||
|
||||
it.value().area = areaRect;
|
||||
it.value().normalPosition = QPointF(point.X/d->logicalRect.width(), point.Y/d->logicalRect.height());
|
||||
it.value().pressure = pressure;
|
||||
|
||||
QWindowSystemInterface::handleTouchEvent(topWindow(), d->touchDevice, d->touchPoints.values(), mods);
|
||||
|
||||
// Remove released points, station others
|
||||
for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = d->touchPoints.begin(); i != d->touchPoints.end();) {
|
||||
if (i.value().state == Qt::TouchPointReleased)
|
||||
i = d->touchPoints.erase(i);
|
||||
else
|
||||
(i++).value().state = Qt::TouchPointStationary;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case PointerDeviceType_Pen: {
|
||||
quint32 id;
|
||||
pointerPoint->get_PointerId(&id);
|
||||
|
||||
boolean isPressed;
|
||||
pointerPoint->get_IsInContact(&isPressed);
|
||||
// Fall-through for pen to generate tablet event
|
||||
if (pointerDeviceType != PointerDeviceType_Pen)
|
||||
break;
|
||||
|
||||
boolean isEraser;
|
||||
properties->get_IsEraser(&isEraser);
|
||||
int pointerType = isEraser ? 3 : 1;
|
||||
|
||||
float pressure;
|
||||
properties->get_Pressure(&pressure);
|
||||
|
||||
float xTilt;
|
||||
properties->get_XTilt(&xTilt);
|
||||
|
||||
|
@ -1078,6 +1078,40 @@ void QXcbDrag::cancel()
|
||||
send_leave();
|
||||
}
|
||||
|
||||
// find an ancestor with XdndAware on it
|
||||
static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window)
|
||||
{
|
||||
xcb_window_t target = 0;
|
||||
forever {
|
||||
// check if window has XdndAware
|
||||
xcb_get_property_cookie_t gpCookie = Q_XCB_CALL(
|
||||
xcb_get_property(c->xcb_connection(), false, window,
|
||||
c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0));
|
||||
xcb_get_property_reply_t *gpReply = xcb_get_property_reply(
|
||||
c->xcb_connection(), gpCookie, 0);
|
||||
bool aware = gpReply && gpReply->type != XCB_NONE;
|
||||
free(gpReply);
|
||||
if (aware) {
|
||||
target = window;
|
||||
break;
|
||||
}
|
||||
|
||||
// try window's parent
|
||||
xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL(
|
||||
xcb_query_tree_unchecked(c->xcb_connection(), window));
|
||||
xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply(
|
||||
c->xcb_connection(), qtCookie, NULL);
|
||||
if (!qtReply)
|
||||
break;
|
||||
xcb_window_t root = qtReply->root;
|
||||
xcb_window_t parent = qtReply->parent;
|
||||
free(qtReply);
|
||||
if (window == root)
|
||||
break;
|
||||
window = parent;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event)
|
||||
{
|
||||
@ -1105,17 +1139,16 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
|
||||
// xcb_convert_selection() that we sent the XdndDrop event to.
|
||||
at = findTransactionByWindow(event->requestor);
|
||||
}
|
||||
// if (at == -1 && event->time == XCB_CURRENT_TIME) {
|
||||
// // previous Qt versions always requested the data on a child of the target window
|
||||
// // using CurrentTime... but it could be asking for either drop data or the current drag's data
|
||||
// Window target = findXdndAwareParent(event->requestor);
|
||||
// if (target) {
|
||||
// if (current_target && current_target == target)
|
||||
// at = -2;
|
||||
// else
|
||||
// at = findXdndDropTransactionByWindow(target);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (at == -1 && event->time == XCB_CURRENT_TIME) {
|
||||
xcb_window_t target = findXdndAwareParent(connection(), event->requestor);
|
||||
if (target) {
|
||||
if (current_target == target)
|
||||
at = -2;
|
||||
else
|
||||
at = findTransactionByWindow(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QDrag *transactionDrag = 0;
|
||||
|
@ -239,6 +239,7 @@ namespace QTest
|
||||
static int keyDelay = -1;
|
||||
static int mouseDelay = -1;
|
||||
static int eventDelay = -1;
|
||||
static int timeout = -1;
|
||||
static bool noCrashHandler = false;
|
||||
|
||||
/*! \internal
|
||||
@ -290,6 +291,18 @@ int Q_TESTLIB_EXPORT defaultKeyDelay()
|
||||
return keyDelay;
|
||||
}
|
||||
|
||||
static int defaultTimeout()
|
||||
{
|
||||
if (timeout == -1) {
|
||||
bool ok = false;
|
||||
timeout = qEnvironmentVariableIntValue("QTEST_FUNCTION_TIMEOUT", &ok);
|
||||
|
||||
if (!ok || timeout <= 0)
|
||||
timeout = 5*60*1000;
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
|
||||
Q_TESTLIB_EXPORT QStringList testFunctions;
|
||||
Q_TESTLIB_EXPORT QStringList testTags;
|
||||
@ -867,7 +880,7 @@ public:
|
||||
|
||||
void beginTest() {
|
||||
QMutexLocker locker(&mutex);
|
||||
timeout.store(5*60*1000);
|
||||
timeout.store(defaultTimeout());
|
||||
waitCondition.wakeAll();
|
||||
}
|
||||
|
||||
|
@ -3596,7 +3596,7 @@ void QFileDialogPrivate::_q_enterDirectory(const QModelIndex &index)
|
||||
}
|
||||
} else {
|
||||
// Do not accept when shift-clicking to multi-select a file in environments with single-click-activation (KDE)
|
||||
if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)
|
||||
if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, Q_NULLPTR, qFileDialogUi->treeView)
|
||||
|| q->fileMode() != QFileDialog::ExistingFiles || !(QGuiApplication::keyboardModifiers() & Qt::CTRL)) {
|
||||
q->accept();
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
QModelIndex index(const QString &path, int column = 0) const;
|
||||
QModelIndex parent(const QModelIndex &child) const Q_DECL_OVERRIDE;
|
||||
using QObject::parent;
|
||||
QModelIndex sibling(int row, int column, const QModelIndex &idx) const Q_DECL_OVERRIDE;
|
||||
bool hasChildren(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
bool canFetchMore(const QModelIndex &parent) const Q_DECL_OVERRIDE;
|
||||
|
@ -157,10 +157,10 @@ static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::C
|
||||
|
||||
Qt's built-in widgets use QStyle to perform nearly all of their
|
||||
drawing, ensuring that they look exactly like the equivalent
|
||||
native widgets. The diagram below shows a QComboBox in eight
|
||||
native widgets. The diagram below shows a QComboBox in nine
|
||||
different styles.
|
||||
|
||||
\image qstyle-comboboxes.png Eight combo boxes
|
||||
\image qstyle-comboboxes.png Nine combo boxes
|
||||
|
||||
Topics:
|
||||
|
||||
|
@ -310,7 +310,7 @@ void QAbstractScrollAreaPrivate::init()
|
||||
viewportFilter.reset(new QAbstractScrollAreaFilter(this));
|
||||
viewport->installEventFilter(viewportFilter.data());
|
||||
viewport->setFocusProxy(q);
|
||||
q->setFocusPolicy(Qt::WheelFocus);
|
||||
q->setFocusPolicy(Qt::StrongFocus);
|
||||
q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
|
||||
q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
layoutChildren();
|
||||
|
@ -734,9 +734,10 @@ bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::Keyb
|
||||
if (stepsToScroll == 0) {
|
||||
// We moved less than a line, but might still have accumulated partial scroll,
|
||||
// unless we already are at one of the ends.
|
||||
if (offset_accumulated > 0.f && value < maximum)
|
||||
const float effective_offset = invertedControls ? -offset_accumulated : offset_accumulated;
|
||||
if (effective_offset > 0.f && value < maximum)
|
||||
return true;
|
||||
if (offset_accumulated < 0.f && value > minimum)
|
||||
if (effective_offset < 0.f && value > minimum)
|
||||
return true;
|
||||
offset_accumulated = 0;
|
||||
return false;
|
||||
|
@ -78,15 +78,14 @@ public:
|
||||
void init(const QVariant &var);
|
||||
void readLocaleSettings();
|
||||
|
||||
void emitSignals(EmitPolicy ep, const QVariant &old);
|
||||
QString textFromValue(const QVariant &f) const;
|
||||
QVariant valueFromText(const QString &f) const;
|
||||
|
||||
QDateTime validateAndInterpret(QString &input, int &, QValidator::State &state,
|
||||
bool fixup = false) const;
|
||||
void clearSection(int index);
|
||||
|
||||
// Override QAbstractSpinBoxPrivate:
|
||||
void emitSignals(EmitPolicy ep, const QVariant &old) Q_DECL_OVERRIDE;
|
||||
QString textFromValue(const QVariant &f) const Q_DECL_OVERRIDE;
|
||||
QVariant valueFromText(const QString &f) const Q_DECL_OVERRIDE;
|
||||
void _q_editorCursorPositionChanged(int oldpos, int newpos) Q_DECL_OVERRIDE;
|
||||
void interpret(EmitPolicy ep) Q_DECL_OVERRIDE;
|
||||
void clearCache() const Q_DECL_OVERRIDE;
|
||||
@ -94,16 +93,18 @@ public:
|
||||
void updateEditFieldGeometry() Q_DECL_OVERRIDE;
|
||||
QVariant getZeroVariant() const Q_DECL_OVERRIDE;
|
||||
void setRange(const QVariant &min, const QVariant &max) Q_DECL_OVERRIDE;
|
||||
void updateEdit() Q_DECL_OVERRIDE;
|
||||
|
||||
// Override QDateTimePraser:
|
||||
// Override QDateTimeParser:
|
||||
QString displayText() const Q_DECL_OVERRIDE { return edit->text(); }
|
||||
QDateTime getMinimum() const Q_DECL_OVERRIDE { return minimum.toDateTime(); }
|
||||
QDateTime getMaximum() const Q_DECL_OVERRIDE { return maximum.toDateTime(); }
|
||||
QLocale locale() const Q_DECL_OVERRIDE { return q_func()->locale(); }
|
||||
QString getAmPmText(AmPm ap, Case cs) const Q_DECL_OVERRIDE;
|
||||
int cursorPosition() const Q_DECL_OVERRIDE { return edit ? edit->cursorPosition() : -1; }
|
||||
|
||||
int absoluteIndex(QDateTimeEdit::Section s, int index) const;
|
||||
int absoluteIndex(const SectionNode &s) const;
|
||||
void updateEdit();
|
||||
QDateTime stepBy(int index, int steps, bool test = false) const;
|
||||
int sectionAt(int pos) const;
|
||||
int closestSection(int index, bool forward) const;
|
||||
@ -114,8 +115,6 @@ public:
|
||||
|
||||
void updateTimeSpec();
|
||||
QString valueToText(const QVariant &var) const { return textFromValue(var); }
|
||||
QString getAmPmText(AmPm ap, Case cs) const;
|
||||
int cursorPosition() const { return edit ? edit->cursorPosition() : -1; }
|
||||
|
||||
void _q_resetButton();
|
||||
void updateArrow(QStyle::StateFlag state);
|
||||
|
@ -802,7 +802,7 @@ void QPlainTextEditPrivate::init(const QString &txt)
|
||||
|
||||
viewport->setBackgroundRole(QPalette::Base);
|
||||
q->setAcceptDrops(true);
|
||||
q->setFocusPolicy(Qt::WheelFocus);
|
||||
q->setFocusPolicy(Qt::StrongFocus);
|
||||
q->setAttribute(Qt::WA_KeyCompression);
|
||||
q->setAttribute(Qt::WA_InputMethodEnabled);
|
||||
q->setInputMethodHints(Qt::ImhMultiLine);
|
||||
|
@ -177,7 +177,7 @@ void QTextEditPrivate::init(const QString &html)
|
||||
|
||||
viewport->setBackgroundRole(QPalette::Base);
|
||||
q->setAcceptDrops(true);
|
||||
q->setFocusPolicy(Qt::WheelFocus);
|
||||
q->setFocusPolicy(Qt::StrongFocus);
|
||||
q->setAttribute(Qt::WA_KeyCompression);
|
||||
q->setAttribute(Qt::WA_InputMethodEnabled);
|
||||
q->setInputMethodHints(Qt::ImhMultiLine);
|
||||
|
@ -1,2 +0,0 @@
|
||||
[tzTest]
|
||||
opensuse-13.1
|
@ -762,16 +762,22 @@ void tst_QTimeZone::tzTest()
|
||||
// Warning: This could vary depending on age of TZ file!
|
||||
|
||||
// Test low date uses first rule found
|
||||
// Note: Depending on the OS in question, the database may be carrying the
|
||||
// Local Mean Time. which for Berlin is 0:53:28
|
||||
QTimeZonePrivate::Data dat = tzp.data(-9999999999999);
|
||||
QCOMPARE(dat.atMSecsSinceEpoch, (qint64)-9999999999999);
|
||||
QCOMPARE(dat.standardTimeOffset, 3600);
|
||||
QCOMPARE(dat.daylightTimeOffset, 0);
|
||||
if (dat.abbreviation == "LMT") {
|
||||
QCOMPARE(dat.standardTimeOffset, 3208);
|
||||
} else {
|
||||
QCOMPARE(dat.standardTimeOffset, 3600);
|
||||
|
||||
// Test previous to low value is invalid
|
||||
dat = tzp.previousTransition(-9999999999999);
|
||||
QCOMPARE(dat.atMSecsSinceEpoch, std::numeric_limits<qint64>::min());
|
||||
QCOMPARE(dat.standardTimeOffset, std::numeric_limits<int>::min());
|
||||
QCOMPARE(dat.daylightTimeOffset, std::numeric_limits<int>::min());
|
||||
// Test previous to low value is invalid
|
||||
dat = tzp.previousTransition(-9999999999999);
|
||||
QCOMPARE(dat.atMSecsSinceEpoch, std::numeric_limits<qint64>::min());
|
||||
QCOMPARE(dat.standardTimeOffset, std::numeric_limits<int>::min());
|
||||
QCOMPARE(dat.daylightTimeOffset, std::numeric_limits<int>::min());
|
||||
}
|
||||
|
||||
dat = tzp.nextTransition(-9999999999999);
|
||||
QCOMPARE(dat.atMSecsSinceEpoch, (qint64)-2422054408000);
|
||||
|
@ -1213,6 +1213,27 @@ void tst_QDBusConnection::callVirtualObjectLocal()
|
||||
QCOMPARE(obj.replyArguments, subPathReply.arguments());
|
||||
}
|
||||
|
||||
void tst_QDBusConnection::pendingCallWhenDisconnected()
|
||||
{
|
||||
if (!QCoreApplication::instance())
|
||||
QSKIP("Test requires a QCoreApplication");
|
||||
|
||||
QDBusServer *server = new QDBusServer;
|
||||
QDBusConnection con = QDBusConnection::connectToPeer(server->address(), "disconnect");
|
||||
QTestEventLoop::instance().enterLoop(2);
|
||||
QVERIFY(con.isConnected());
|
||||
QDBusMessage message = QDBusMessage::createMethodCall("", "/", QString(), "method");
|
||||
QDBusPendingCall reply = con.asyncCall(message);
|
||||
|
||||
delete server;
|
||||
|
||||
QTestEventLoop::instance().enterLoop(2);
|
||||
QVERIFY(!con.isConnected());
|
||||
QVERIFY(reply.isFinished());
|
||||
QVERIFY(reply.isError());
|
||||
QVERIFY(reply.error().type() == QDBusError::Disconnected);
|
||||
}
|
||||
|
||||
QString MyObject::path;
|
||||
QString MyObjectWithoutInterface::path;
|
||||
QString MyObjectWithoutInterface::interface;
|
||||
|
@ -116,6 +116,7 @@ private slots:
|
||||
void registerVirtualObject();
|
||||
void callVirtualObject();
|
||||
void callVirtualObjectLocal();
|
||||
void pendingCallWhenDisconnected();
|
||||
|
||||
public:
|
||||
QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; }
|
||||
|
@ -679,25 +679,105 @@ void tst_Compiler::cxx11_atomics()
|
||||
#endif
|
||||
}
|
||||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_CLANG("-Wignored-attributes")
|
||||
QT_WARNING_DISABLE_CLANG("-Wunused-local-typedefs")
|
||||
QT_WARNING_DISABLE_GCC("-Wattributes")
|
||||
QT_WARNING_DISABLE_GCC("-Wunused-local-typedefs")
|
||||
|
||||
#ifndef __has_cpp_attribute
|
||||
# define __has_cpp_attribute(x) 0
|
||||
#endif
|
||||
#ifdef Q_COMPILER_ATTRIBUTES
|
||||
[[noreturn]] void attribute_f1();
|
||||
void attribute_f2 [[noreturn]] ();
|
||||
# if (defined(__cpp_namespace_attributes) && __cpp_namespace_attributes >= 201411) && __has_cpp_attribute(deprecated)
|
||||
namespace NS [[deprecated]] { }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
void tst_Compiler::cxx11_attributes()
|
||||
{
|
||||
#ifndef Q_COMPILER_ATTRIBUTES
|
||||
QSKIP("Compiler does not support C++11 feature");
|
||||
#else
|
||||
struct [[deprecated]] C {};
|
||||
// Attributes in function parameters and using clauses cause MSVC 2015 to crash
|
||||
// https://connect.microsoft.com/VisualStudio/feedback/details/2011594
|
||||
# if (!defined(Q_CC_MSVC) || _MSC_FULL_VER >= 190023811) && !defined(Q_CC_INTEL)
|
||||
void f([[ ]] int);
|
||||
[[ ]] using namespace QtPrivate;
|
||||
[[ ]] try {
|
||||
} catch ([[]] int) {
|
||||
}
|
||||
# endif
|
||||
|
||||
struct [[ ]] A { };
|
||||
struct B : A {
|
||||
[[ ]] int m_i : 32;
|
||||
[[noreturn]] void f() const { ::exit(0); }
|
||||
|
||||
# ifdef Q_COMPILER_DEFAULT_DELETE_MEMBERS
|
||||
[[ ]] ~B() = default;
|
||||
[[ ]] B(const B &) = delete;
|
||||
# endif
|
||||
};
|
||||
# if __has_cpp_attribute(deprecated)
|
||||
struct [[deprecated]] C { };
|
||||
# endif
|
||||
enum [[ ]] E { };
|
||||
[[ ]] void [[ ]] * [[ ]] * [[ ]] ptr = 0;
|
||||
int B::* [[ ]] pmm = 0;
|
||||
|
||||
# if __has_cpp_attribute(deprecated)
|
||||
enum [[deprecated]] E2 {
|
||||
# if defined(__cpp_enumerator_attributes) && __cpp_enumerator_attributes >= 201411
|
||||
value [[deprecated]] = 0
|
||||
# endif
|
||||
};
|
||||
# endif
|
||||
# ifdef Q_COMPILER_LAMBDA
|
||||
[]()[[ ]] {}();
|
||||
# endif
|
||||
# ifdef Q_COMPILER_TEMPLATE_ALIAS
|
||||
using B2 [[ ]] = B;
|
||||
# endif
|
||||
|
||||
[[ ]] goto end;
|
||||
# ifdef Q_CC_GNU
|
||||
// Attributes in gnu:: namespace
|
||||
[[gnu::unused]] end:
|
||||
;
|
||||
[[gnu::unused]] struct D {} d;
|
||||
[[noreturn]] void f();
|
||||
struct D e [[gnu::used, gnu::unused]];
|
||||
[[gnu::aligned(8)]] int i;
|
||||
[[gnu::aligned(8)]] int i [[ ]];
|
||||
int array[][[]] = { 1 };
|
||||
# else
|
||||
// Non GNU, so use an empty attribute
|
||||
[[ ]] end:
|
||||
;
|
||||
[[ ]] struct D {} d;
|
||||
struct D e [[ ]];
|
||||
[[ ]] int i [[ ]];
|
||||
int array[][[]] = { 1 };
|
||||
# endif
|
||||
|
||||
[[gnu::unused]] end:
|
||||
;
|
||||
int & [[ ]] lref = i;
|
||||
int && [[ ]] rref = 1;
|
||||
[[ ]] (void)1;
|
||||
[[ ]] for (i = 0; i < 2; ++i)
|
||||
;
|
||||
|
||||
Q_UNUSED(ptr);
|
||||
Q_UNUSED(pmm);
|
||||
Q_UNUSED(d);
|
||||
Q_UNUSED(e);
|
||||
Q_UNUSED(i);
|
||||
Q_UNUSED(array);
|
||||
Q_UNUSED(lref);
|
||||
Q_UNUSED(rref);
|
||||
#endif
|
||||
}
|
||||
QT_WARNING_POP
|
||||
|
||||
#ifdef Q_COMPILER_AUTO_FUNCTION
|
||||
auto autoFunction() -> unsigned
|
||||
|
@ -465,6 +465,7 @@ private:
|
||||
const QString m_platform;
|
||||
QSize m_testWidgetSize;
|
||||
QPoint m_availableTopLeft;
|
||||
QPoint m_safeCursorPos;
|
||||
const bool m_windowsAnimationsEnabled;
|
||||
};
|
||||
|
||||
@ -622,6 +623,7 @@ void tst_QWidget::getSetCheck()
|
||||
|
||||
tst_QWidget::tst_QWidget()
|
||||
: m_platform(QGuiApplication::platformName().toLower())
|
||||
, m_safeCursorPos(0, 0)
|
||||
, m_windowsAnimationsEnabled(windowsAnimationsEnabled())
|
||||
{
|
||||
if (m_windowsAnimationsEnabled) // Disable animations which can interfere with screen grabbing in moveChild(), showAndMoveChild()
|
||||
@ -664,7 +666,13 @@ void tst_QWidget::initTestCase()
|
||||
// to avoid Windows warnings about minimum size for decorated windows.
|
||||
int width = 200;
|
||||
const QScreen *screen = QGuiApplication::primaryScreen();
|
||||
m_availableTopLeft = screen->availableGeometry().topLeft();
|
||||
const QRect availableGeometry = screen->availableGeometry();
|
||||
m_availableTopLeft = availableGeometry.topLeft();
|
||||
// XCB: Determine "safe" cursor position at bottom/right corner of screen.
|
||||
// Pushing the mouse rapidly to the top left corner can trigger KDE / KWin's
|
||||
// "Present all Windows" (Ctrl+F9) feature also programmatically.
|
||||
if (m_platform == QLatin1String("xcb"))
|
||||
m_safeCursorPos = availableGeometry.bottomRight() - QPoint(40, 40);
|
||||
const int screenWidth = screen->geometry().width();
|
||||
if (screenWidth > 2000)
|
||||
width = 100 * ((screenWidth + 500) / 1000);
|
||||
@ -5664,7 +5672,7 @@ void tst_QWidget::setToolTip()
|
||||
// Mouse over doesn't work on Windows mobile, so skip the rest of the test for that platform.
|
||||
#ifndef Q_OS_WINCE_WM
|
||||
for (int pass = 0; pass < 2; ++pass) {
|
||||
QCursor::setPos(0, 0);
|
||||
QCursor::setPos(m_safeCursorPos);
|
||||
QScopedPointer<QWidget> popup(new QWidget(0, Qt::Popup));
|
||||
popup->setObjectName(QLatin1String("tst_qwidget setToolTip #") + QString::number(pass));
|
||||
popup->setWindowTitle(popup->objectName());
|
||||
@ -6015,7 +6023,7 @@ void tst_QWidget::childEvents()
|
||||
|
||||
// Move away the cursor; otherwise it might result in an enter event if it's
|
||||
// inside the widget when the widget is shown.
|
||||
QCursor::setPos(qApp->desktop()->availableGeometry().bottomRight());
|
||||
QCursor::setPos(m_safeCursorPos);
|
||||
QTest::qWait(100);
|
||||
|
||||
{
|
||||
@ -8878,7 +8886,7 @@ void tst_QWidget::syntheticEnterLeave()
|
||||
int numLeaveEvents;
|
||||
};
|
||||
|
||||
QCursor::setPos(QPoint(0,0));
|
||||
QCursor::setPos(m_safeCursorPos);
|
||||
|
||||
MyWidget window;
|
||||
window.setWindowFlags(Qt::WindowStaysOnTopHint);
|
||||
@ -8998,7 +9006,7 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave()
|
||||
int numEnterEvents, numMouseMoveEvents;
|
||||
};
|
||||
|
||||
QCursor::setPos(QPoint(0,0));
|
||||
QCursor::setPos(m_safeCursorPos);
|
||||
|
||||
SELParent parent;
|
||||
parent.move(200, 200);
|
||||
@ -10174,7 +10182,7 @@ void tst_QWidget::destroyedSignal()
|
||||
void tst_QWidget::underMouse()
|
||||
{
|
||||
// Move the mouse cursor to a safe location
|
||||
QCursor::setPos(0,0);
|
||||
QCursor::setPos(m_safeCursorPos);
|
||||
|
||||
ColorWidget topLevelWidget(0, Qt::FramelessWindowHint, Qt::blue);
|
||||
ColorWidget childWidget1(&topLevelWidget, Qt::Widget, Qt::yellow);
|
||||
@ -10430,7 +10438,7 @@ public:
|
||||
void tst_QWidget::taskQTBUG_27643_enterEvents()
|
||||
{
|
||||
// Move the mouse cursor to a safe location so it won't interfere
|
||||
QCursor::setPos(0,0);
|
||||
QCursor::setPos(m_safeCursorPos);
|
||||
|
||||
EnterTestMainDialog dialog;
|
||||
QPushButton button(&dialog);
|
||||
|
@ -77,6 +77,8 @@ private slots:
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
void wheelEvent_data();
|
||||
void wheelEvent();
|
||||
void fineGrainedWheelEvent_data();
|
||||
void fineGrainedWheelEvent();
|
||||
#endif
|
||||
void sliderPressedReleased_data();
|
||||
void sliderPressedReleased();
|
||||
@ -892,6 +894,55 @@ void tst_QAbstractSlider::wheelEvent()
|
||||
if (expectedSignalCount)
|
||||
QVERIFY(actionTriggeredTimeStamp < valueChangedTimeStamp);
|
||||
}
|
||||
|
||||
void tst_QAbstractSlider::fineGrainedWheelEvent_data()
|
||||
{
|
||||
QTest::addColumn<bool>("invertedControls");
|
||||
QTest::newRow("invertedControls=false") << false;
|
||||
QTest::newRow("invertedControls=true") << true;
|
||||
}
|
||||
|
||||
void tst_QAbstractSlider::fineGrainedWheelEvent()
|
||||
{
|
||||
QFETCH(bool, invertedControls);
|
||||
|
||||
QCoreApplication *applicationInstance = QCoreApplication::instance();
|
||||
QVERIFY(applicationInstance != 0);
|
||||
QApplication::setWheelScrollLines(3);
|
||||
|
||||
slider->setRange(0, 10);
|
||||
slider->setSingleStep(1);
|
||||
slider->setPageStep(10);
|
||||
slider->setInvertedControls(invertedControls);
|
||||
slider->setOrientation(Qt::Vertical);
|
||||
slider->setSliderPosition(0);
|
||||
|
||||
const int singleStepDelta = invertedControls ? (-WHEEL_DELTA / 3) : (WHEEL_DELTA / 3);
|
||||
|
||||
QWheelEvent eventDown(slider->rect().bottomRight(), singleStepDelta / 2,
|
||||
Qt::NoButton, Qt::NoModifier, Qt::Vertical);
|
||||
QVERIFY(applicationInstance->sendEvent(slider,&eventDown));
|
||||
QCOMPARE(slider->sliderPosition(), 0);
|
||||
QVERIFY(applicationInstance->sendEvent(slider,&eventDown));
|
||||
QCOMPARE(slider->sliderPosition(), 1);
|
||||
|
||||
QWheelEvent eventUp(slider->rect().bottomRight(), -singleStepDelta / 2,
|
||||
Qt::NoButton, Qt::NoModifier, Qt::Vertical);
|
||||
QVERIFY(applicationInstance->sendEvent(slider,&eventUp));
|
||||
QCOMPARE(slider->sliderPosition(), 1);
|
||||
QVERIFY(applicationInstance->sendEvent(slider,&eventUp));
|
||||
QCOMPARE(slider->sliderPosition(), 0);
|
||||
QVERIFY(applicationInstance->sendEvent(slider,&eventUp));
|
||||
QCOMPARE(slider->sliderPosition(), 0);
|
||||
QVERIFY(applicationInstance->sendEvent(slider,&eventUp));
|
||||
QCOMPARE(slider->sliderPosition(), 0);
|
||||
|
||||
QVERIFY(applicationInstance->sendEvent(slider,&eventDown));
|
||||
QCOMPARE(slider->sliderPosition(), 0);
|
||||
QVERIFY(applicationInstance->sendEvent(slider,&eventDown));
|
||||
QCOMPARE(slider->sliderPosition(), 1);
|
||||
}
|
||||
|
||||
#endif // !QT_NO_WHEELEVENT
|
||||
|
||||
void tst_QAbstractSlider::sliderPressedReleased_data()
|
||||
|
@ -492,6 +492,7 @@ void tst_QMdiArea::subWindowActivated2()
|
||||
spy.clear();
|
||||
|
||||
mdiArea.show();
|
||||
mdiArea.activateWindow();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&mdiArea));
|
||||
QTRY_COMPARE(spy.count(), 1);
|
||||
QVERIFY(mdiArea.currentSubWindow());
|
||||
|
@ -31,6 +31,7 @@ qsysinfo \
|
||||
qtabletevent \
|
||||
qtexteditlist \
|
||||
qtbug-8933 \
|
||||
qtbug-52641 \
|
||||
qtouchevent \
|
||||
touch \
|
||||
qwidget_zorder \
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <QMetaObject>
|
||||
#include <QMetaEnum>
|
||||
|
||||
TabletWidget::TabletWidget(bool mouseToo) : mMouseToo(mouseToo)
|
||||
TabletWidget::TabletWidget(bool mouseToo) : mMouseToo(mouseToo), mWheelEventCount(0)
|
||||
{
|
||||
QPalette newPalette = palette();
|
||||
newPalette.setColor(QPalette::Window, Qt::white);
|
||||
@ -82,6 +82,10 @@ bool TabletWidget::eventFilter(QObject *, QEvent *ev)
|
||||
mGPos = event->globalPos();
|
||||
mTimestamp = event->timestamp();
|
||||
}
|
||||
break;
|
||||
case QEvent::Wheel:
|
||||
++mWheelEventCount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -176,6 +180,8 @@ void TabletWidget::paintEvent(QPaintEvent *)
|
||||
eventInfo << QString("z: %1").arg(QString::number(mZ));
|
||||
|
||||
eventInfo << QString("Unique Id: %1").arg(QString::number(mUnique));
|
||||
|
||||
eventInfo << QString("Total wheel events: %1").arg(QString::number(mWheelEventCount));
|
||||
}
|
||||
|
||||
QString text = eventInfo.join("\n");
|
||||
|
@ -61,6 +61,7 @@ private:
|
||||
qint64 mUnique;
|
||||
bool mMouseToo;
|
||||
ulong mTimestamp;
|
||||
int mWheelEventCount;
|
||||
};
|
||||
|
||||
#endif // TABLETWIDGET_H
|
||||
|
87
tests/manual/qtbug-52641/main.cpp
Normal file
87
tests/manual/qtbug-52641/main.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 Kai Pastor
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QPainter>
|
||||
#include <QPdfWriter>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
|
||||
QString filepath = QFileDialog::getSaveFileName(nullptr, "Save File", "",
|
||||
"PDF files (*.pdf)");
|
||||
if (filepath.isEmpty())
|
||||
return 1;
|
||||
QPdfWriter writer(filepath);
|
||||
writer.setPageSize(QPageSize(QPageSize::A4));
|
||||
writer.setResolution(300);
|
||||
|
||||
QPainterPath path;
|
||||
path.moveTo(0,0);
|
||||
path.lineTo(1000,0);
|
||||
path.lineTo(1000,1000);
|
||||
path.lineTo(0,800);
|
||||
path.lineTo(500,100);
|
||||
path.lineTo(800,900);
|
||||
path.lineTo(300,600);
|
||||
|
||||
QPen pen;
|
||||
pen.setWidth(30);
|
||||
pen.setJoinStyle(Qt::MiterJoin);
|
||||
|
||||
// The black path on the first page must always be visible in the PDF viewer.
|
||||
QPainter p(&writer);
|
||||
pen.setMiterLimit(6.0);
|
||||
p.setPen(pen);
|
||||
p.drawPath(path);
|
||||
|
||||
// If a miter limit below 1.0 is written to the PDF,
|
||||
// broken PDF viewers may not show the red path on the second page.
|
||||
writer.newPage();
|
||||
pen.setMiterLimit(0.6);
|
||||
pen.setColor(Qt::red);
|
||||
p.setPen(pen);
|
||||
p.drawPath(path);
|
||||
|
||||
p.end();
|
||||
return 0;
|
||||
}
|
5
tests/manual/qtbug-52641/qtbug-52641.pro
Normal file
5
tests/manual/qtbug-52641/qtbug-52641.pro
Normal file
@ -0,0 +1,5 @@
|
||||
TARGET = qtbug-52641
|
||||
TEMPLATE = app
|
||||
QT = core gui widgets
|
||||
SOURCES = main.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user