Merge remote-tracking branch 'origin/5.12' into 5.13

Conflicts:
	src/corelib/tools/qlocale_data_p.h
        (Regenerated by running the scripts in util/local_database/)
	src/gui/opengl/qopengltextureuploader.cpp

Done-With: Edward Welbourne <edward.welbourne@qt.io>
Done-With: Allan Sandfeld Jensen <allan.jensen@qt.io>
Change-Id: I12df7f066ed0a25eb109f61c4b8d8dea63b683e2
This commit is contained in:
Qt Forward Merge Bot 2019-05-09 01:00:49 +02:00 committed by Liang Qi
commit e56d3b03ed
55 changed files with 4506 additions and 3881 deletions

View File

@ -0,0 +1,52 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
//! [using qt module]
\section1 Using the Module
Using a Qt module requires linking against the module library, either
directly or through other dependencies. Several build tools have dedicated
support for this, including \l{CMake Documentation}{CMake} and
\l{qmake}.
\section2 Building with CMake
Use the \c{find_package()} command to locate the needed module components in
the \c{Qt5} package:
//! [using qt module]
//! [building with qmake]
\section2 Building with qmake
To configure the module for building with qmake, add the module as a value
of the \c QT variable in the project's .pro file:
//! [building with qmake]

View File

@ -18,6 +18,8 @@ HTML.extraimages += template/images/ico_out.png \
template/images/bullet_sq.png \
template/images/bgrContent.png
sourcedirs += includes
#specify which files in the output directory should be packed into the qch file.
qhp.extraFiles += style/offline.css \
images/ico_out.png \

View File

@ -9,4 +9,5 @@ defines += onlinedocs
#uncomment if navigation bar is not wanted
#HTML.nonavigationbar = "true"
sourcedirs += includes-online
sourcedirs += includes-online \
includes

View File

@ -69,6 +69,7 @@ QMAKE_LIBDIR_OPENGL =
QMAKE_LINK_SHLIB = $$QMAKE_LINK
QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
equals(ANDROID_TARGET_ARCH, x86_64) QMAKE_LFLAGS += -L$$ANDROID_PLATFORM_ROOT_PATH/usr/lib64
QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB

View File

@ -1163,6 +1163,10 @@
\snippet code/doc_src_qmake-manual.pro 30
\note The list of supported characters can depend on
the used build tool. In particular, parentheses do not
work with \c{make}.
\target DISTFILES
\section1 DISTFILES

View File

@ -837,7 +837,9 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
if(inc) {
if(!includes)
includes = new SourceFiles;
SourceFile *dep = includes->lookupFile(inc);
/* QTBUG-72383: Local includes "foo.h" must first be resolved relative to the
* sourceDir, only global includes <bar.h> are unique. */
SourceFile *dep = try_local ? nullptr : includes->lookupFile(inc);
if(!dep) {
bool exists = false;
QMakeLocalFileName lfn(inc);
@ -876,7 +878,11 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
dep->file = lfn;
dep->type = QMakeSourceFileInfo::TYPE_C;
files->addFile(dep);
includes->addFile(dep, inc, false);
/* QTBUG-72383: Local includes "foo.h" are keyed by the resolved
* path (stored in dep itself), only global includes <bar.h> are
* unique keys immediately. */
const char *key = try_local ? nullptr : inc;
includes->addFile(dep, key, false);
}
dep->exists = exists;
}

View File

@ -1,53 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, 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$
**
****************************************************************************/
//! [0]
#include <QtCore>
//! [0]

View File

@ -0,0 +1,2 @@
find_package(Qt5 COMPONENTS Core REQUIRED)
target_link_libraries(mytarget Qt5::Core)

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@ -31,17 +31,9 @@
\brief The Qt Core module is part of Qt's essential modules.
\section1 Getting Started
All other Qt modules rely on this module. To include the
definitions of the module's classes, use the following directive:
\snippet code/doc_src_qtcore.cpp 0
If you use \l qmake to build your projects, Qt Core is included by default.
\section1 Core Functionalities
Qt adds these features to C++:
Qt Core adds these features to C++:
\list
\li a very powerful mechanism for seamless object communication called
@ -61,6 +53,15 @@
\li \l{Signals & Slots}
\endlist
\include module-use.qdocinc using qt module
\quotefile overview/using-qt-core.cmake
See also the \l[QtDoc]{Building with CMake} overview.
\section2 Building with qmake
If you use \l qmake to build your projects, Qt5Core is linked by default.
\section1 Threading and Concurrent Programming
Qt provides thread support in the form of platform-independent \l{Threading

View File

@ -33,12 +33,5 @@
\brief Provides core non-GUI functionality.
All other Qt modules rely on this module. To include the
definitions of the module's classes, use the following directive:
\snippet code/doc_src_qtcore.cpp 0
If you use \l qmake to build your projects, \l{Qt Core} is included by
default.
All other Qt modules rely on this module.
*/

View File

@ -1425,6 +1425,13 @@ bool qSharedBuild() Q_DECL_NOTHROW
\l Q_OS_WIN32, \l Q_OS_WIN64, or \l Q_OS_WINRT is defined.
*/
/*!
\macro Q_OS_WINDOWS
\relates <QtGlobal>
This is a synonym for Q_OS_WIN.
*/
/*!
\macro Q_OS_WIN32
\relates <QtGlobal>

View File

@ -176,6 +176,7 @@
#endif
#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT)
# define Q_OS_WINDOWS
# define Q_OS_WIN
#endif

View File

@ -48,6 +48,7 @@
#include "qmutex.h"
#include <private/qthread_p.h>
#endif
#include "qtextstream.h"
#include <ctype.h>
#include <qt_windows.h>
@ -480,6 +481,7 @@ static const char *findWMstr(uint msg)
{ 0x02DD, "WM_TABLET_FIRST + 29" },
{ 0x02DE, "WM_TABLET_FIRST + 30" },
{ 0x02DF, "WM_TABLET_LAST" },
{ 0x02E0, "WM_DPICHANGED" },
{ 0x0300, "WM_CUT" },
{ 0x0301, "WM_COPY" },
{ 0x0302, "WM_PASTE" },
@ -765,6 +767,13 @@ QString decodeMSG(const MSG& msg)
case WM_DESTROY:
parameters = QLatin1String("Destroy hwnd ") + hwndS;
break;
case 0x02E0u: { // WM_DPICHANGED
auto rect = reinterpret_cast<const RECT *>(lParam);
QTextStream(&parameters) << "DPI: " << HIWORD(wParam) << ','
<< LOWORD(wParam) << ' ' << (rect->right - rect->left) << 'x'
<< (rect->bottom - rect->top) << forcesign << rect->left << rect->top;
}
break;
case WM_IME_NOTIFY:
{
parameters = QLatin1String("Command(");

View File

@ -39,18 +39,294 @@
#include "qdeadlinetimer.h"
#include "qdeadlinetimer_p.h"
#include "private/qnumeric_p.h"
QT_BEGIN_NAMESPACE
Q_DECL_CONST_FUNCTION static inline QPair<qint64, qint64> toSecsAndNSecs(qint64 nsecs)
namespace {
class TimeReference
{
qint64 secs = nsecs / (1000*1000*1000);
if (nsecs < 0)
--secs;
nsecs -= secs * 1000*1000*1000;
return qMakePair(secs, nsecs);
enum : unsigned {
umega = 1000 * 1000,
ugiga = umega * 1000
};
enum : qint64 {
kilo = 1000,
mega = kilo * 1000,
giga = mega * 1000
};
public:
enum RoundingStrategy {
RoundDown,
RoundUp,
RoundDefault = RoundDown
};
static constexpr qint64 Min = std::numeric_limits<qint64>::min();
static constexpr qint64 Max = std::numeric_limits<qint64>::max();
inline TimeReference(qint64 = 0, unsigned = 0);
inline void updateTimer(qint64 &, unsigned &);
inline bool addNanoseconds(qint64);
inline bool addMilliseconds(qint64);
bool addSecsAndNSecs(qint64, qint64);
inline bool subtract(const qint64, const unsigned);
inline bool toMilliseconds(qint64 *, RoundingStrategy = RoundDefault) const;
inline bool toNanoseconds(qint64 *) const;
inline void saturate(bool toMax);
static bool sign(qint64, qint64);
private:
bool adjust(const qint64, const unsigned, qint64 = 0);
private:
qint64 secs;
unsigned nsecs;
};
}
inline TimeReference::TimeReference(qint64 t1, unsigned t2)
: secs(t1), nsecs(t2)
{
}
inline void TimeReference::updateTimer(qint64 &t1, unsigned &t2)
{
t1 = secs;
t2 = nsecs;
}
inline void TimeReference::saturate(bool toMax)
{
secs = toMax ? Max : Min;
}
/*!
* \internal
*
* Determines the sign of a (seconds, nanoseconds) pair
* for differentiating overflow from underflow. It doesn't
* deal with equality as it shouldn't ever be called in that case.
*
* Returns true if the pair represents a positive time offset
* false otherwise.
*/
bool TimeReference::sign(qint64 secs, qint64 nsecs)
{
if (secs > 0) {
if (nsecs > 0)
return true;
} else {
if (nsecs < 0)
return false;
}
// They are different in sign
secs += nsecs / giga;
if (secs > 0)
return true;
else if (secs < 0)
return false;
// We should never get over|underflow out of
// the case: secs * giga == -nsecs
// So the sign of nsecs is the deciding factor
Q_ASSERT(nsecs % giga != 0);
return nsecs > 0;
}
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
inline bool TimeReference::addNanoseconds(qint64 arg)
{
return addSecsAndNSecs(arg / giga, arg % giga);
}
inline bool TimeReference::addMilliseconds(qint64 arg)
{
return addSecsAndNSecs(arg / kilo, (arg % kilo) * mega);
}
/*!
* \internal
*
* Adds \a t1 addSecs seconds and \a addNSecs nanoseconds to the
* time reference. The arguments are normalized to seconds (qint64)
* and nanoseconds (unsigned) before the actual calculation is
* delegated to adjust(). If the nanoseconds are negative the
* owed second used for the normalization is passed on to adjust()
* as third argument.
*
* Returns true if operation was successful, false on over|underflow
*/
bool TimeReference::addSecsAndNSecs(qint64 addSecs, qint64 addNSecs)
{
// Normalize the arguments
if (qAbs(addNSecs) >= giga) {
if (add_overflow<qint64>(addSecs, addNSecs / giga, &addSecs))
return false;
addNSecs %= giga;
}
if (addNSecs < 0)
return adjust(addSecs, ugiga - unsigned(-addNSecs), -1);
return adjust(addSecs, unsigned(addNSecs));
}
/*!
* \internal
*
* Adds \a t1 seconds and \a t2 nanoseconds to the internal members.
* Takes into account the additional \a carrySeconds we may owe or need to carry over.
*
* Returns true if operation was successful, false on over|underflow
*/
bool TimeReference::adjust(const qint64 t1, const unsigned t2, qint64 carrySeconds)
{
Q_STATIC_ASSERT(QDeadlineTimerNanosecondsInT2);
nsecs += t2;
if (nsecs >= ugiga) {
nsecs -= ugiga;
carrySeconds++;
}
// We don't worry about the order of addition, because the result returned by
// callers of this function is unchanged regardless of us over|underflowing.
// If we do, we do so by no more than a second, thus saturating the timer to
// Forever has the same effect as if we did the arithmetic exactly and salvaged
// the overflow.
return !add_overflow<qint64>(secs, t1, &secs) && !add_overflow<qint64>(secs, carrySeconds, &secs);
}
/*!
* \internal
*
* Subtracts \a t1 seconds and \a t2 nanoseconds from the time reference.
* When normalizing the nanoseconds to a positive number the owed seconds is
* passed as third argument to adjust() as the seconds may over|underflow
* if we do the calculation directly. There is little sense to check the
* seconds for over|underflow here in case we are going to need to carry
* over a second _after_ we add the nanoseconds.
*
* Returns true if operation was successful, false on over|underflow
*/
inline bool TimeReference::subtract(const qint64 t1, const unsigned t2)
{
Q_ASSERT(t2 < ugiga);
return adjust(-t1, ugiga - t2, -1);
}
/*!
* \internal
*
* Converts the time reference to milliseconds.
*
* Checks are done without making use of mul_overflow because it may
* not be implemented on some 32bit platforms.
*
* Returns true if operation was successful, false on over|underflow
*/
inline bool TimeReference::toMilliseconds(qint64 *result, RoundingStrategy rounding) const
{
static constexpr qint64 maxSeconds = Max / kilo;
static constexpr qint64 minSeconds = Min / kilo;
if (secs > maxSeconds || secs < minSeconds)
return false;
unsigned ns = rounding == RoundDown ? nsecs : nsecs + umega - 1;
return !add_overflow<qint64>(secs * kilo, ns / umega, result);
}
/*!
* \internal
*
* Converts the time reference to nanoseconds.
*
* Checks are done without making use of mul_overflow because it may
* not be implemented on some 32bit platforms.
*
* Returns true if operation was successful, false on over|underflow
*/
inline bool TimeReference::toNanoseconds(qint64 *result) const
{
static constexpr qint64 maxSeconds = Max / giga;
static constexpr qint64 minSeconds = Min / giga;
if (secs > maxSeconds || secs < minSeconds)
return false;
return !add_overflow<qint64>(secs * giga, nsecs, result);
}
#else
inline bool TimeReference::addNanoseconds(qint64 arg)
{
return adjust(arg, 0);
}
inline bool TimeReference::addMilliseconds(qint64 arg)
{
static constexpr qint64 maxMilliseconds = Max / mega;
if (qAbs(arg) > maxMilliseconds)
return false;
return addNanoseconds(arg * mega);
}
inline bool TimeReference::addSecsAndNSecs(qint64 addSecs, qint64 addNSecs)
{
static constexpr qint64 maxSeconds = Max / giga;
static constexpr qint64 minSeconds = Min / giga;
if (addSecs > maxSeconds || addSecs < minSeconds || add_overflow<qint64>(addSecs * giga, addNSecs, &addNSecs))
return false;
return addNanoseconds(addNSecs);
}
inline bool TimeReference::adjust(const qint64 t1, const unsigned t2, qint64 carrySeconds)
{
Q_STATIC_ASSERT(!QDeadlineTimerNanosecondsInT2);
Q_UNUSED(t2);
Q_UNUSED(carrySeconds);
return !add_overflow<qint64>(secs, t1, &secs);
}
inline bool TimeReference::subtract(const qint64 t1, const unsigned t2)
{
Q_UNUSED(t2);
return addNanoseconds(-t1);
}
inline bool TimeReference::toMilliseconds(qint64 *result, RoundingStrategy rounding) const
{
// Force QDeadlineTimer to treat the border cases as
// over|underflow and saturate the results returned to the user.
// We don't want to get valid milliseconds out of saturated timers.
if (secs == Max || secs == Min)
return false;
*result = secs / mega;
if (rounding == RoundUp && secs > *result * mega)
(*result)++;
return true;
}
inline bool TimeReference::toNanoseconds(qint64 *result) const
{
*result = secs;
return true;
}
#endif
/*!
\class QDeadlineTimer
\inmodule QtCore
@ -262,10 +538,17 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW
*/
void QDeadlineTimer::setRemainingTime(qint64 msecs, Qt::TimerType timerType) Q_DECL_NOTHROW
{
if (msecs == -1)
if (msecs == -1) {
*this = QDeadlineTimer(Forever, timerType);
else
setPreciseRemainingTime(0, msecs * 1000 * 1000, timerType);
return;
}
*this = current(timerType);
TimeReference ref(t1, t2);
if (!ref.addMilliseconds(msecs))
ref.saturate(msecs > 0);
ref.updateTimer(t1, t2);
}
/*!
@ -287,16 +570,10 @@ void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, qint64 nsecs, Qt::Time
}
*this = current(timerType);
if (QDeadlineTimerNanosecondsInT2) {
t1 += secs + toSecsAndNSecs(nsecs).first;
t2 += toSecsAndNSecs(nsecs).second;
if (t2 > 1000*1000*1000) {
t2 -= 1000*1000*1000;
++t1;
}
} else {
t1 += secs * 1000 * 1000 * 1000 + nsecs;
}
TimeReference ref(t1, t2);
if (!ref.addSecsAndNSecs(secs, nsecs))
ref.saturate(TimeReference::sign(secs, nsecs));
ref.updateTimer(t1, t2);
}
/*!
@ -391,8 +668,22 @@ void QDeadlineTimer::setTimerType(Qt::TimerType timerType)
*/
qint64 QDeadlineTimer::remainingTime() const Q_DECL_NOTHROW
{
qint64 ns = remainingTimeNSecs();
return ns <= 0 ? ns : (ns + 999999) / (1000 * 1000);
if (isForever())
return -1;
QDeadlineTimer now = current(timerType());
TimeReference ref(t1, t2);
qint64 msecs;
if (!ref.subtract(now.t1, now.t2))
return 0; // We can only underflow here
// If we fail the conversion, t1 < now.t1 means we underflowed,
// thus the deadline had long expired
if (!ref.toMilliseconds(&msecs, TimeReference::RoundUp))
return t1 < now.t1 ? 0 : -1;
return msecs < 0 ? 0 : msecs;
}
/*!
@ -414,14 +705,23 @@ qint64 QDeadlineTimer::remainingTimeNSecs() const Q_DECL_NOTHROW
/*!
\internal
Same as remainingTimeNSecs, but may return negative remaining times. Does
not deal with Forever.
not deal with Forever. In case of underflow the result is saturated to
the minimum possible value, on overflow - the maximum possible value.
*/
qint64 QDeadlineTimer::rawRemainingTimeNSecs() const Q_DECL_NOTHROW
{
QDeadlineTimer now = current(timerType());
if (QDeadlineTimerNanosecondsInT2)
return (t1 - now.t1) * (1000*1000*1000) + t2 - now.t2;
return t1 - now.t1;
TimeReference ref(t1, t2);
qint64 nsecs;
if (!ref.subtract(now.t1, now.t2))
return TimeReference::Min; // We can only underflow here
// If we fail the conversion, t1 < now.t1 means we underflowed,
// thus the deadline had long expired
if (!ref.toNanoseconds(&nsecs))
return t1 < now.t1 ? TimeReference::Min : TimeReference::Max;
return nsecs;
}
/*!
@ -447,8 +747,13 @@ qint64 QDeadlineTimer::rawRemainingTimeNSecs() const Q_DECL_NOTHROW
qint64 QDeadlineTimer::deadline() const Q_DECL_NOTHROW
{
if (isForever())
return t1;
return deadlineNSecs() / (1000 * 1000);
return TimeReference::Max;
qint64 result;
if (!TimeReference(t1, t2).toMilliseconds(&result))
return t1 < 0 ? TimeReference::Min : TimeReference::Max;
return result;
}
/*!
@ -457,7 +762,8 @@ qint64 QDeadlineTimer::deadline() const Q_DECL_NOTHROW
same as QElapsedTimer::msecsSinceReference(). The value will be in the past
if this QDeadlineTimer has expired.
If this QDeadlineTimer never expires, this function returns
If this QDeadlineTimer never expires or the number of nanoseconds until the
deadline can't be accommodated in the return type, this function returns
\c{std::numeric_limits<qint64>::max()}.
This function can be used to calculate the amount of time a timer is
@ -474,10 +780,13 @@ qint64 QDeadlineTimer::deadline() const Q_DECL_NOTHROW
qint64 QDeadlineTimer::deadlineNSecs() const Q_DECL_NOTHROW
{
if (isForever())
return t1;
if (QDeadlineTimerNanosecondsInT2)
return t1 * 1000 * 1000 * 1000 + t2;
return t1;
return TimeReference::Max;
qint64 result;
if (!TimeReference(t1, t2).toNanoseconds(&result))
return t1 < 0 ? TimeReference::Min : TimeReference::Max;
return result;
}
/*!
@ -487,18 +796,25 @@ qint64 QDeadlineTimer::deadlineNSecs() const Q_DECL_NOTHROW
timerType. If the value is in the past, this QDeadlineTimer will be marked
as expired.
If \a msecs is \c{std::numeric_limits<qint64>::max()}, this QDeadlineTimer
will be set to never expire.
If \a msecs is \c{std::numeric_limits<qint64>::max()} or the deadline is
beyond a representable point in the future, this QDeadlineTimer will be set
to never expire.
\sa setPreciseDeadline(), deadline(), deadlineNSecs(), setRemainingTime()
*/
void QDeadlineTimer::setDeadline(qint64 msecs, Qt::TimerType timerType) Q_DECL_NOTHROW
{
if (msecs == (std::numeric_limits<qint64>::max)()) {
setPreciseDeadline(msecs, 0, timerType); // msecs == MAX implies Forever
} else {
setPreciseDeadline(msecs / 1000, msecs % 1000 * 1000 * 1000, timerType);
if (msecs == TimeReference::Max) {
*this = QDeadlineTimer(Forever, timerType);
return;
}
type = timerType;
TimeReference ref;
if (!ref.addMilliseconds(msecs))
ref.saturate(msecs > 0);
ref.updateTimer(t1, t2);
}
/*!
@ -516,14 +832,13 @@ void QDeadlineTimer::setDeadline(qint64 msecs, Qt::TimerType timerType) Q_DECL_N
void QDeadlineTimer::setPreciseDeadline(qint64 secs, qint64 nsecs, Qt::TimerType timerType) Q_DECL_NOTHROW
{
type = timerType;
if (secs == (std::numeric_limits<qint64>::max)() || nsecs == (std::numeric_limits<qint64>::max)()) {
*this = QDeadlineTimer(Forever, timerType);
} else if (QDeadlineTimerNanosecondsInT2) {
t1 = secs + toSecsAndNSecs(nsecs).first;
t2 = toSecsAndNSecs(nsecs).second;
} else {
t1 = secs * (1000*1000*1000) + nsecs;
}
// We don't pass the seconds to the constructor, because we don't know
// at this point if t1 holds the seconds or nanoseconds; it's platform specific.
TimeReference ref;
if (!ref.addSecsAndNSecs(secs, nsecs))
ref.saturate(TimeReference::sign(secs, nsecs));
ref.updateTimer(t1, t2);
}
/*!
@ -536,18 +851,14 @@ void QDeadlineTimer::setPreciseDeadline(qint64 secs, qint64 nsecs, Qt::TimerType
*/
QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_NOTHROW
{
if (dt.isForever() || nsecs == (std::numeric_limits<qint64>::max)()) {
dt = QDeadlineTimer(Forever, dt.timerType());
} else if (QDeadlineTimerNanosecondsInT2) {
dt.t1 += toSecsAndNSecs(nsecs).first;
dt.t2 += toSecsAndNSecs(nsecs).second;
if (dt.t2 > 1000*1000*1000) {
dt.t2 -= 1000*1000*1000;
++dt.t1;
}
} else {
dt.t1 += nsecs;
}
if (dt.isForever())
return dt;
TimeReference ref(dt.t1, dt.t2);
if (!ref.addNanoseconds(nsecs))
ref.saturate(nsecs > 0);
ref.updateTimer(dt.t1, dt.t2);
return dt;
}
@ -656,6 +967,19 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_
To add times of precision greater than 1 millisecond, use addNSecs().
*/
QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs)
{
if (dt.isForever())
return dt;
TimeReference ref(dt.t1, dt.t2);
if (!ref.addMilliseconds(msecs))
ref.saturate(msecs > 0);
ref.updateTimer(dt.t1, dt.t2);
return dt;
}
/*!
\fn QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt)
\relates QDeadlineTimer

View File

@ -108,8 +108,7 @@ public:
friend bool operator>=(QDeadlineTimer d1, QDeadlineTimer d2) Q_DECL_NOTHROW
{ return !(d1 < d2); }
friend QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs)
{ return QDeadlineTimer::addNSecs(dt, msecs * 1000 * 1000); }
friend Q_CORE_EXPORT QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs);
friend QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt)
{ return dt + msecs; }
friend QDeadlineTimer operator-(QDeadlineTimer dt, qint64 msecs)

View File

@ -92,7 +92,7 @@
\note For the current keyboard input locale take a look at
QInputMethod::locale().
QLocale's data is based on Common Locale Data Repository v34.
QLocale's data is based on Common Locale Data Repository v35.1.
\sa QString::arg(), QString::toInt(), QString::toDouble(),
QInputMethod::locale()

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,3 @@
#! [0]
#include <QtGui>
#! [0]
#! [1]
QT -= gui
#! [1]

View File

@ -0,0 +1,2 @@
find_package(Qt5 COMPONENTS Gui REQUIRED)
target_link_libraries(mytarget Qt5::Gui)

View File

@ -40,18 +40,6 @@
These classes are used internally by Qt's user interface technologies
and can also be used directly, for instance to write applications using
low-level OpenGL ES graphics APIs.
To include the definitions of the module's classes, use the
following directive:
\snippet code/doc_src_qtgui.pro 0
\if !defined(qtforpython)
If you use \l qmake to build your projects, \l{Qt GUI} is included by
default. To disable Qt GUI, add the following line to your \c .pro file:
\snippet code/doc_src_qtgui.pro 1
\endif
*/
/*!
@ -69,14 +57,15 @@
higher level API's, like Qt Quick, that are much more suitable
than the enablers found in the Qt GUI module.
\section1 Getting Started
To include the definitions of the module's classes, use the
following directive:
\snippet code/doc_src_qtgui.pro 0
\if !defined(qtforpython)
\include module-use.qdocinc using qt module
\quotefile overview/using-qt-gui.cmake
See also the \l[QtDoc]{Building with CMake} overview.
\section2 Building with qmake
If you use \l qmake to build your projects, Qt GUI is included by
default. To disable Qt GUI, add the following line to your \c .pro file:

View File

@ -77,8 +77,20 @@
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
#endif
#ifndef GL_TEXTURE_SWIZZLE_RGBA
#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
#ifndef GL_TEXTURE_SWIZZLE_R
#define GL_TEXTURE_SWIZZLE_R 0x8E42
#endif
#ifndef GL_TEXTURE_SWIZZLE_G
#define GL_TEXTURE_SWIZZLE_G 0x8E43
#endif
#ifndef GL_TEXTURE_SWIZZLE_B
#define GL_TEXTURE_SWIZZLE_B 0x8E44
#endif
#ifndef GL_TEXTURE_SWIZZLE_A
#define GL_TEXTURE_SWIZZLE_A 0x8E45
#endif
#ifndef GL_SRGB
@ -128,11 +140,13 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
#endif
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
GLint swizzle[4] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
funcs->glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
#else
GLint swizzle[4] = { GL_GREEN, GL_BLUE, GL_ALPHA, GL_RED };
funcs->glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_GREEN);
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_ALPHA);
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_RED);
#endif
externalFormat = internalFormat = GL_RGBA;
pixelType = GL_UNSIGNED_BYTE;
@ -164,12 +178,12 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
externalFormat = GL_BGRA;
internalFormat = GL_RGB10_A2;
targetFormat = image.format();
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle) && (isOpenGL12orBetter || isOpenGLES3orBetter)) {
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
externalFormat = GL_RGBA;
internalFormat = GL_RGB10_A2;
GLint swizzle[4] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
targetFormat = image.format();
}
break;
@ -227,8 +241,10 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
pixelType = GL_UNSIGNED_BYTE;
targetFormat = image.format();
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
GLint swizzle[4] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED };
funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ALPHA);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ZERO);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ZERO);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ZERO);
externalFormat = internalFormat = GL_RED;
pixelType = GL_UNSIGNED_BYTE;
targetFormat = image.format();
@ -247,8 +263,10 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
pixelType = GL_UNSIGNED_BYTE;
targetFormat = image.format();
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
GLint swizzle[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
externalFormat = internalFormat = GL_RED;
pixelType = GL_UNSIGNED_BYTE;
targetFormat = image.format();
@ -267,8 +285,10 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
pixelType = GL_UNSIGNED_SHORT;
targetFormat = image.format();
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
GLint swizzle[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE);
externalFormat = internalFormat = GL_RED;
pixelType = GL_UNSIGNED_SHORT;
targetFormat = image.format();

View File

@ -261,9 +261,9 @@ static ShiftResult good_offset(const QBezier *b1, const QBezier *b2, qreal offse
static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qreal threshold)
{
int map[4];
bool p1_p2_equal = (orig->x1 == orig->x2 && orig->y1 == orig->y2);
bool p2_p3_equal = (orig->x2 == orig->x3 && orig->y2 == orig->y3);
bool p3_p4_equal = (orig->x3 == orig->x4 && orig->y3 == orig->y4);
bool p1_p2_equal = qFuzzyCompare(orig->x1, orig->x2) && qFuzzyCompare(orig->y1, orig->y2);
bool p2_p3_equal = qFuzzyCompare(orig->x2, orig->x3) && qFuzzyCompare(orig->y2, orig->y3);
bool p3_p4_equal = qFuzzyCompare(orig->x3, orig->x4) && qFuzzyCompare(orig->y3, orig->y4);
QPointF points[4];
int np = 0;

View File

@ -38,7 +38,7 @@
****************************************************************************/
#include "qfontdatabase.h"
#include "qdebug.h"
#include "qloggingcategory.h"
#include "qalgorithms.h"
#include "qguiapplication.h"
#include "qvarlengtharray.h" // here or earlier - workaround for VC++6
@ -59,25 +59,13 @@
#include <stdlib.h>
#include <algorithm>
// #define QFONTDATABASE_DEBUG
#ifdef QFONTDATABASE_DEBUG
# define FD_DEBUG qDebug
#else
# define FD_DEBUG if (false) qDebug
#endif
// #define FONT_MATCH_DEBUG
#ifdef FONT_MATCH_DEBUG
# define FM_DEBUG qDebug
#else
# define FM_DEBUG if (false) qDebug
#endif
#include <qtgui_tracepoints_p.h>
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcFontDb, "qt.text.font.db")
Q_LOGGING_CATEGORY(lcFontMatch, "qt.text.font.match")
#define SMOOTH_SCALABLE 0xffff
#if defined(QT_BUILD_INTERNAL)
@ -744,7 +732,7 @@ void qt_registerFont(const QString &familyName, const QString &stylename,
const QSupportedWritingSystems &writingSystems, void *handle)
{
QFontDatabasePrivate *d = privateDb();
// qDebug() << "Adding font" << familyName << weight << style << pixelSize << antialiased;
qCDebug(lcFontDb) << "Adding font" << familyName << weight << style << pixelSize << "aa" << antialiased << "fixed" << fixedPitch;
QtFontStyle::Key styleKey;
styleKey.style = style;
styleKey.weight = weight;
@ -1079,7 +1067,7 @@ static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &st
}
}
FM_DEBUG( " best style has distance 0x%x", dist );
qCDebug(lcFontMatch, " best style has distance 0x%x", dist );
return foundry->styles[best];
}
@ -1098,20 +1086,20 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
desc->size = 0;
FM_DEBUG(" REMARK: looking for best foundry for family '%s' [%d]", family->name.toLatin1().constData(), family->count);
qCDebug(lcFontMatch, " REMARK: looking for best foundry for family '%s' [%d]", family->name.toLatin1().constData(), family->count);
for (int x = 0; x < family->count; ++x) {
QtFontFoundry *foundry = family->foundries[x];
if (!foundry_name.isEmpty() && foundry->name.compare(foundry_name, Qt::CaseInsensitive) != 0)
continue;
FM_DEBUG(" looking for matching style in foundry '%s' %d",
qCDebug(lcFontMatch, " looking for matching style in foundry '%s' %d",
foundry->name.isEmpty() ? "-- none --" : foundry->name.toLatin1().constData(), foundry->count);
QtFontStyle *style = bestStyle(foundry, styleKey, styleName);
if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) {
FM_DEBUG(" ForceOutline set, but not smoothly scalable");
qCDebug(lcFontMatch, " ForceOutline set, but not smoothly scalable");
continue;
}
@ -1122,7 +1110,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
if (!(styleStrategy & QFont::ForceOutline)) {
size = style->pixelSize(pixelSize);
if (size) {
FM_DEBUG(" found exact size match (%d pixels)", size->pixelSize);
qCDebug(lcFontMatch, " found exact size match (%d pixels)", size->pixelSize);
px = size->pixelSize;
}
}
@ -1131,7 +1119,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
size = style->pixelSize(SMOOTH_SCALABLE);
if (size) {
FM_DEBUG(" found smoothly scalable font (%d pixels)", pixelSize);
qCDebug(lcFontMatch, " found smoothly scalable font (%d pixels)", pixelSize);
px = pixelSize;
}
}
@ -1140,7 +1128,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
size = style->pixelSize(0);
if (size) {
FM_DEBUG(" found bitmap scalable font (%d pixels)", pixelSize);
qCDebug(lcFontMatch, " found bitmap scalable font (%d pixels)", pixelSize);
px = pixelSize;
}
}
@ -1164,12 +1152,12 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
if (d < distance) {
distance = d;
size = style->pixelSizes + x;
FM_DEBUG(" best size so far: %3d (%d)", size->pixelSize, pixelSize);
qCDebug(lcFontMatch, " best size so far: %3d (%d)", size->pixelSize, pixelSize);
}
}
if (!size) {
FM_DEBUG(" no size supports the script we want");
qCDebug(lcFontMatch, " no size supports the script we want");
continue;
}
@ -1204,7 +1192,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
this_score += qAbs(px - pixelSize);
if (this_score < score) {
FM_DEBUG(" found a match: score %x best score so far %x",
qCDebug(lcFontMatch, " found a match: score %x best score so far %x",
this_score, score);
score = this_score;
@ -1212,7 +1200,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
desc->style = style;
desc->size = size;
} else {
FM_DEBUG(" score %x no better than best %x", this_score, score);
qCDebug(lcFontMatch, " score %x no better than best %x", this_score, score);
}
}
@ -1245,7 +1233,7 @@ static int match(int script, const QFontDef &request,
char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';
FM_DEBUG("QFontDatabase::match\n"
qCDebug(lcFontMatch, "QFontDatabase::match\n"
" request:\n"
" family: %s [%s], script: %d\n"
" weight: %d, style: %d\n"
@ -2683,7 +2671,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
QFontCache::Key key(request, script, multi ? 1 : 0);
engine = fontCache->findEngine(key);
if (engine) {
FM_DEBUG("Cache hit level 1");
qCDebug(lcFontMatch, "Cache hit level 1");
return engine;
}
@ -2712,7 +2700,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
else
blackListed.append(index);
} else {
FM_DEBUG(" NO MATCH FOUND\n");
qCDebug(lcFontMatch, " NO MATCH FOUND\n");
}
if (!engine) {
@ -2756,7 +2744,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
if (!engine)
engine = new QFontEngineBox(request.pixelSize);
FM_DEBUG("returning box engine");
qCDebug(lcFontMatch, "returning box engine");
}
return engine;

View File

@ -1383,11 +1383,12 @@ void QTextEngine::shapeText(int item) const
if (QChar::isHighSurrogate(ucs4) && i + 1 < itemLength) {
uint low = string[i + 1];
if (QChar::isLowSurrogate(low)) {
// high part never changes in simple casing
uc[i] = ucs4;
++i;
ucs4 = QChar::surrogateToUcs4(ucs4, low);
ucs4 = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
: QChar::toUpper(ucs4);
// high part never changes in simple casing
uc[i] = QChar::lowSurrogate(ucs4);
}
} else {

View File

@ -875,8 +875,14 @@ void QNativeSocketEngine::close()
if (d->closingDown)
return;
if (d->pendingReadNotification)
if (d->pendingReadNotification) {
// We use QPointer here to see if this QNativeSocketEngine was deleted as a result of
// finishing and cleaning up a network request when calling "processReadReady".
QPointer<QNativeSocketEngine> alive(this);
processReadReady();
if (alive.isNull())
return;
}
d->closingDown = true;

View File

@ -79,7 +79,7 @@ quint64 spiStatesFromQState(QAccessible::State state)
if (state.checkStateMixed)
setSpiStateBit(&spiState, ATSPI_STATE_INDETERMINATE);
if (state.readOnly)
unsetSpiStateBit(&spiState, ATSPI_STATE_EDITABLE);
setSpiStateBit(&spiState, ATSPI_STATE_READ_ONLY);
// if (state.HotTracked)
if (state.defaultButton)
setSpiStateBit(&spiState, ATSPI_STATE_IS_DEFAULT);

View File

@ -76,6 +76,7 @@
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(qLcTray)
Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
ResourceHelper::ResourceHelper()
{
@ -96,6 +97,7 @@ const char *QGenericUnixTheme::name = "generic";
// Default system font, corresponding to the value returned by 4.8 for
// XRender/FontConfig which we can now assume as default.
static const char defaultSystemFontNameC[] = "Sans Serif";
static const char defaultFixedFontNameC[] = "monospace";
enum { defaultSystemFontSize = 9 };
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
@ -136,9 +138,10 @@ public:
QGenericUnixThemePrivate()
: QPlatformThemePrivate()
, systemFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize)
, fixedFont(QStringLiteral("monospace"), systemFont.pointSize())
, fixedFont(QLatin1String(defaultFixedFontNameC), systemFont.pointSize())
{
fixedFont.setStyleHint(QFont::TypeWriter);
qCDebug(lcQpaFonts) << "default fonts: system" << systemFont << "fixed" << fixedFont;
}
const QFont systemFont;
@ -390,7 +393,7 @@ void QKdeThemePrivate::refresh()
if (QFont *fixedFont = kdeFont(readKdeSetting(QStringLiteral("fixed"), kdeDirs, kdeVersion, kdeSettings))) {
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
} else {
fixedFont = new QFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize);
fixedFont = new QFont(QLatin1String(defaultFixedFontNameC), defaultSystemFontSize);
fixedFont->setStyleHint(QFont::TypeWriter);
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
}
@ -403,6 +406,8 @@ void QKdeThemePrivate::refresh()
if (QFont *toolBarFont = kdeFont(readKdeSetting(QStringLiteral("toolBarFont"), kdeDirs, kdeVersion, kdeSettings)))
resources.fonts[QPlatformTheme::ToolButtonFont] = toolBarFont;
qCDebug(lcQpaFonts) << "default fonts: system" << resources.fonts[QPlatformTheme::SystemFont]
<< "fixed" << resources.fonts[QPlatformTheme::FixedFont];
qDeleteAll(kdeSettings);
}
@ -716,8 +721,9 @@ public:
QString fontName = gtkFontName.left(split);
systemFont = new QFont(fontName, size);
fixedFont = new QFont(QLatin1String("monospace"), systemFont->pointSize());
fixedFont = new QFont(QLatin1String(defaultFixedFontNameC), systemFont->pointSize());
fixedFont->setStyleHint(QFont::TypeWriter);
qCDebug(lcQpaFonts) << "default fonts: system" << systemFont << "fixed" << fixedFont;
}
mutable QFont *systemFont;

View File

@ -76,8 +76,10 @@ public:
void endPaint() override;
void flush(QWindow *, const QRegion &, const QPoint &) override;
#ifndef QT_NO_OPENGL
void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
QPlatformTextureList *textures, bool translucentBackground) override;
#endif
QPlatformGraphicsBuffer *graphicsBuffer() const override;

View File

@ -523,6 +523,7 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion &region,
// the window server.
}
#ifndef QT_NO_OPENGL
void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
QPlatformTextureList *textures, bool translucentBackground)
{
@ -531,6 +532,7 @@ void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion &regio
QPlatformBackingStore::composeAndFlush(window, region, offset, textures, translucentBackground);
}
#endif
QPlatformGraphicsBuffer *QCALayerBackingStore::graphicsBuffer() const
{

View File

@ -1208,23 +1208,34 @@ void QCocoaWindow::windowDidChangeScreen()
if (!window())
return;
const bool wasRunningDisplayLink = static_cast<QCocoaScreen *>(screen())->isRunningDisplayLink();
// Note: When a window is resized to 0x0 Cocoa will report the window's screen as nil
auto *currentScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen);
auto *previousScreen = static_cast<QCocoaScreen*>(screen());
if (QCocoaScreen *newScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen)) {
if (newScreen == screen()) {
// Screen properties have changed. Will be handled by
// NSApplicationDidChangeScreenParametersNotification
// in QCocoaIntegration::updateScreens().
return;
}
Q_ASSERT_X(!m_view.window.screen || currentScreen,
"QCocoaWindow", "Failed to get QCocoaScreen for NSScreen");
qCDebug(lcQpaWindow) << window() << "moved to" << newScreen;
QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
// Note: The previous screen may be the same as the current screen, either because
// the screen was just reconfigured, which still results in AppKit sending an
// NSWindowDidChangeScreenNotification, because the previous screen was removed,
// and we ended up calling QWindow::setScreen to move the window, which doesn't
// actually move the window to the new screen, or because we've delivered the
// screen change to the top level window, which will make all the child windows
// of that window report the new screen when requested via QWindow::screen().
// We still need to deliver the screen change in all these cases, as the
// device-pixel ratio may have changed, and needs to be delivered to all
// windows, both top level and child windows.
if (hasPendingUpdateRequest() && wasRunningDisplayLink)
requestUpdate(); // Restart display-link on new screen
} else {
qCWarning(lcQpaWindow) << "Failed to get QCocoaScreen for" << m_view.window.screen;
qCDebug(lcQpaWindow) << "Screen changed for" << window() << "from" << previousScreen << "to" << currentScreen;
QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(
window(), currentScreen ? currentScreen->screen() : nullptr);
if (currentScreen && hasPendingUpdateRequest()) {
// Restart display-link on new screen. We need to do this unconditionally,
// since we can't rely on the previousScreen reflecting whether or not the
// window actually moved from one screen to another, or just stayed on the
// same screen.
currentScreen->requestUpdate();
}
}

View File

@ -147,9 +147,34 @@
ulong timestamp = [theEvent timestamp] * 1000;
auto eventType = cocoaEvent2QtMouseEvent(theEvent);
qCInfo(lcQpaMouse) << "Frame-strut" << eventType << "at" << qtWindowPoint << "with" << m_frameStrutButtons << "in" << self.window;
QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons);
const auto button = cocoaButton2QtButton(theEvent);
auto eventType = [&]() {
switch (theEvent.type) {
case NSEventTypeLeftMouseDown:
case NSEventTypeRightMouseDown:
case NSEventTypeOtherMouseDown:
return QEvent::NonClientAreaMouseButtonPress;
case NSEventTypeLeftMouseUp:
case NSEventTypeRightMouseUp:
case NSEventTypeOtherMouseUp:
return QEvent::NonClientAreaMouseButtonRelease;
case NSEventTypeLeftMouseDragged:
case NSEventTypeRightMouseDragged:
case NSEventTypeOtherMouseDragged:
return QEvent::NonClientAreaMouseMove;
default:
break;
}
return QEvent::None;
}();
qCInfo(lcQpaMouse) << eventType << "at" << qtWindowPoint << "with" << m_frameStrutButtons << "in" << self.window;
QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(),
timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons, button, eventType);
}
@end
@ -472,12 +497,15 @@
// uses the legacy cursorRect API, so the cursor is reset to the arrow
// cursor. See rdar://34183708
if (self.cursor && self.cursor != NSCursor.currentCursor) {
qCInfo(lcQpaMouse) << "Updating cursor for" << self << "to" << self.cursor;
auto previousCursor = NSCursor.currentCursor;
if (self.cursor)
[self.cursor set];
} else {
else
[super cursorUpdate:theEvent];
}
if (NSCursor.currentCursor != previousCursor)
qCInfo(lcQpaMouse) << "Cursor update for" << self << "resulted in new cursor" << NSCursor.currentCursor;
}
- (void)mouseMovedImpl:(NSEvent *)theEvent

View File

@ -51,7 +51,9 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*"));
static QCocoaWindow *toPlatformWindow(NSWindow *window)
{
return qnsview_cast(window.contentView).platformWindow;
if ([window conformsToProtocol:@protocol(QNSWindowProtocol)])
return static_cast<QCocoaNSWindow *>(window).platformWindow;
return nullptr;
}
@implementation QNSWindowDelegate

View File

@ -614,6 +614,9 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
if (m_needsEnterOnPointerUpdate) {
m_needsEnterOnPointerUpdate = false;
if (window != m_currentWindow) {
// make sure we subscribe to leave events for this window
trackLeave(hwnd);
QWindowSystemInterface::handleEnterEvent(window, localPos, globalPos);
m_currentWindow = window;
if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(target))

View File

@ -1876,6 +1876,9 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
{
if (message == WM_ERASEBKGND) // Backing store - ignored.
return true;
// QTBUG-75455: Suppress WM_PAINT sent to invisible windows when setting WS_EX_LAYERED
if (!window()->isVisible() && (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) != 0)
return false;
// Ignore invalid update bounding rectangles
RECT updateRect;
if (!GetUpdateRect(m_data.hwnd, &updateRect, FALSE))

View File

@ -240,6 +240,10 @@ void QXcbConnection::xi2SetupDevice(void *info, bool removeExisting)
} else if (name.contains("uc-logic") && isTablet) {
tabletData.pointerType = QTabletEvent::Pen;
dbgType = QLatin1String("pen");
} else if (name.contains("ugee")) {
isTablet = true;
tabletData.pointerType = QTabletEvent::Pen;
dbgType = QLatin1String("pen");
} else {
isTablet = false;
}

View File

@ -454,6 +454,13 @@ QAccessible::Role QAccessibleDisplay::role() const
return QAccessibleWidget::role();
}
QAccessible::State QAccessibleDisplay::state() const
{
QAccessible::State s = QAccessibleWidget::state();
s.readOnly = true;
return s;
}
QString QAccessibleDisplay::text(QAccessible::Text t) const
{
QString str;
@ -732,10 +739,9 @@ QAccessible::State QAccessibleLineEdit::state() const
QAccessible::State state = QAccessibleWidget::state();
QLineEdit *l = lineEdit();
state.editable = true;
if (l->isReadOnly())
state.readOnly = true;
else
state.editable = true;
if (l->echoMode() != QLineEdit::Normal)
state.passwordEdit = true;

View File

@ -116,6 +116,7 @@ public:
QString text(QAccessible::Text t) const override;
QAccessible::Role role() const override;
QAccessible::State state() const override;
QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >relations(QAccessible::Relation match = QAccessible::AllRelations) const override;
void *interface_cast(QAccessible::InterfaceType t) override;

View File

@ -1369,6 +1369,12 @@ void QLineEdit::setReadOnly(bool enable)
QEvent event(QEvent::ReadOnlyChange);
QCoreApplication::sendEvent(this, &event);
update();
#ifndef QT_NO_ACCESSIBILITY
QAccessible::State changedState;
changedState.readOnly = true;
QAccessibleStateChangeEvent ev(this, changedState);
QAccessible::updateAccessibility(&ev);
#endif
}
}

View File

@ -1972,6 +1972,8 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
|| e->preeditString() != cursor.block().layout()->preeditAreaText()
|| e->replacementLength() > 0;
int oldCursorPos = cursor.position();
cursor.beginEditBlock();
if (isGettingInput) {
cursor.removeSelectedText();
@ -2076,6 +2078,8 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
if (cursor.d)
cursor.d->setX();
if (oldCursorPos != cursor.position())
emit q->cursorPositionChanged();
if (oldPreeditCursor != preeditCursor)
emit q->microFocusChanged();
}

View File

@ -29,6 +29,7 @@
#include <QtCore/QString>
#include <QtCore/QTime>
#include <QtCore/QDeadlineTimer>
#include <QtCore/QElapsedTimer>
#include <QtTest/QtTest>
#if QT_HAS_INCLUDE(<chrono>)
@ -50,6 +51,7 @@ private Q_SLOTS:
void current();
void deadlines();
void setDeadline();
void overflow();
void expire();
void stdchrono();
};
@ -417,6 +419,83 @@ void tst_QDeadlineTimer::setDeadline()
QCOMPARE(deadline.deadlineNSecs(), nsec);
}
void tst_QDeadlineTimer::overflow()
{
QFETCH_GLOBAL(Qt::TimerType, timerType);
// Check the constructor for overflows (should also cover saturating the result of the deadline() method if overflowing)
QDeadlineTimer now = QDeadlineTimer::current(timerType), deadline(std::numeric_limits<qint64>::max() - 1, timerType);
QVERIFY(deadline.isForever() || deadline.deadline() >= now.deadline());
// Check the setDeadline with milliseconds (should also cover implicitly setting the nanoseconds as qint64 max)
deadline.setDeadline(std::numeric_limits<qint64>::max() - 1, timerType);
QVERIFY(deadline.isForever() || deadline.deadline() >= now.deadline());
// Check the setRemainingTime with milliseconds (should also cover implicitly setting the nanoseconds as qint64 max)
deadline.setRemainingTime(std::numeric_limits<qint64>::max() - 1, timerType);
QVERIFY(deadline.isForever() || deadline.deadline() >= now.deadline());
// Check that the deadline gets saturated when the arguments of setPreciseDeadline are large
deadline.setPreciseDeadline(std::numeric_limits<qint64>::max() - 1, std::numeric_limits<qint64>::max() - 1, timerType);
QCOMPARE(deadline.deadline(), std::numeric_limits<qint64>::max());
QVERIFY(deadline.isForever());
// Check that remainingTime gets saturated if we overflow
deadline.setPreciseRemainingTime(std::numeric_limits<qint64>::max() - 1, std::numeric_limits<qint64>::max() - 1, timerType);
QCOMPARE(deadline.remainingTime(), qint64(-1));
QVERIFY(deadline.isForever());
// Check that we saturate the getter for nanoseconds
deadline.setPreciseDeadline(std::numeric_limits<qint64>::max() - 1, 0, timerType);
QCOMPARE(deadline.deadlineNSecs(), std::numeric_limits<qint64>::max());
// Check that adding nanoseconds and overflowing is consistent and saturates the timer
deadline = QDeadlineTimer::addNSecs(deadline, std::numeric_limits<qint64>::max() - 1);
QVERIFY(deadline.isForever());
// Make sure forever is forever, regardless of us subtracting time from it
deadline = QDeadlineTimer(QDeadlineTimer::Forever, timerType);
deadline = QDeadlineTimer::addNSecs(deadline, -10000);
QVERIFY(deadline.isForever());
// Make sure we get the correct result when moving the deadline back and forth in time
QDeadlineTimer current = QDeadlineTimer::current(timerType);
QDeadlineTimer takenNSecs = QDeadlineTimer::addNSecs(current, -1000);
QVERIFY(takenNSecs.deadlineNSecs() - current.deadlineNSecs() == -1000);
QDeadlineTimer addedNSecs = QDeadlineTimer::addNSecs(current, 1000);
QVERIFY(addedNSecs.deadlineNSecs() - current.deadlineNSecs() == 1000);
// Make sure the calculation goes as expected when we need to subtract nanoseconds
// We make use of an additional timer to be certain that
// even when the environment is under load we can track the
// time needed to do the calls
static constexpr qint64 nsExpected = 1000 * 1000 * 1000 - 1000; // 1s - 1000ns, what we pass to setPreciseRemainingTime() later
QElapsedTimer callTimer;
callTimer.start();
deadline = QDeadlineTimer::current(timerType);
qint64 nsDeadline = deadline.deadlineNSecs();
// We adjust in relation to current() here, so we expect the difference to be a tad over the exact number.
// However we are tracking the elapsed time, so it shouldn't be a problem.
deadline.setPreciseRemainingTime(1, -1000, timerType);
qint64 difference = (deadline.deadlineNSecs() - nsDeadline) - nsExpected;
QVERIFY(difference >= 0); // Should always be true, but just in case
QVERIFY(difference <= callTimer.nsecsElapsed()); // Ideally difference should be 0 exactly
// Make sure setRemainingTime underflows gracefully
deadline.setPreciseRemainingTime(std::numeric_limits<qint64>::min() / 10, 0, timerType);
QVERIFY(!deadline.isForever()); // On Win/macOS the above underflows, make sure we don't saturate to Forever
QVERIFY(deadline.remainingTime() == 0);
// If the timer is saturated we don't want to get a valid number of milliseconds
QVERIFY(deadline.deadline() == std::numeric_limits<qint64>::min());
// Check that the conversion to milliseconds and nanoseconds underflows gracefully
deadline.setPreciseDeadline(std::numeric_limits<qint64>::min() / 10, 0, timerType);
QVERIFY(!deadline.isForever()); // On Win/macOS the above underflows, make sure we don't saturate to Forever
QVERIFY(deadline.deadline() == std::numeric_limits<qint64>::min());
QVERIFY(deadline.deadlineNSecs() == std::numeric_limits<qint64>::min());
}
void tst_QDeadlineTimer::expire()
{
QFETCH_GLOBAL(Qt::TimerType, timerType);

View File

@ -2458,9 +2458,9 @@ void tst_QLocale::timeFormat()
QCOMPARE(c.timeFormat(QLocale::NarrowFormat), c.timeFormat(QLocale::ShortFormat));
const QLocale no("no_NO");
QCOMPARE(no.timeFormat(QLocale::NarrowFormat), QLatin1String("HH:mm"));
QCOMPARE(no.timeFormat(QLocale::ShortFormat), QLatin1String("HH:mm"));
QCOMPARE(no.timeFormat(QLocale::LongFormat), QLatin1String("HH:mm:ss t"));
QCOMPARE(no.timeFormat(QLocale::NarrowFormat), QLatin1String("HH.mm"));
QCOMPARE(no.timeFormat(QLocale::ShortFormat), QLatin1String("HH.mm"));
QCOMPARE(no.timeFormat(QLocale::LongFormat), QLatin1String("HH.mm.ss t"));
const QLocale id("id_ID");
QCOMPARE(id.timeFormat(QLocale::ShortFormat), QLatin1String("HH.mm"));
@ -2482,9 +2482,9 @@ void tst_QLocale::dateTimeFormat()
QCOMPARE(c.dateTimeFormat(QLocale::NarrowFormat), c.dateTimeFormat(QLocale::ShortFormat));
const QLocale no("no_NO");
QCOMPARE(no.dateTimeFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy HH:mm"));
QCOMPARE(no.dateTimeFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yyyy HH:mm"));
QCOMPARE(no.dateTimeFormat(QLocale::LongFormat), QLatin1String("dddd d. MMMM yyyy HH:mm:ss t"));
QCOMPARE(no.dateTimeFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy HH.mm"));
QCOMPARE(no.dateTimeFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yyyy HH.mm"));
QCOMPARE(no.dateTimeFormat(QLocale::LongFormat), QLatin1String("dddd d. MMMM yyyy HH.mm.ss t"));
}
void tst_QLocale::monthName()

View File

@ -0,0 +1,3 @@
[systemFixedFont] # QTBUG-54623
winrt
b2qt

View File

@ -35,6 +35,8 @@
#include <private/qrawfont_p.h>
#include <qpa/qplatformfontdatabase.h>
Q_LOGGING_CATEGORY(lcTests, "qt.text.tests")
class tst_QFontDatabase : public QObject
{
Q_OBJECT
@ -49,6 +51,7 @@ private slots:
void fixedPitch_data();
void fixedPitch();
void systemFixedFont();
#ifdef Q_OS_MAC
void trickyFonts_data();
@ -156,6 +159,16 @@ void tst_QFontDatabase::fixedPitch()
QCOMPARE(fi.fixedPitch(), fixedPitch);
}
void tst_QFontDatabase::systemFixedFont() // QTBUG-54623
{
QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
QFontInfo fontInfo(font);
bool fdbSaysFixed = QFontDatabase().isFixedPitch(fontInfo.family(), fontInfo.styleName());
qCDebug(lcTests) << "system fixed font is" << font << "really fixed?" << fdbSaysFixed << fontInfo.fixedPitch();
QVERIFY(fdbSaysFixed);
QVERIFY(fontInfo.fixedPitch());
}
#ifdef Q_OS_MAC
void tst_QFontDatabase::trickyFonts_data()
{

View File

@ -2045,6 +2045,15 @@ void tst_QAccessibility::lineEditTest()
QVERIFY(!iface->state().selectable);
QVERIFY(iface->state().selectableText);
QVERIFY(!iface->state().hasPopup);
QVERIFY(!iface->state().readOnly);
QVERIFY(iface->state().editable);
le->setReadOnly(true);
QVERIFY(iface->state().editable);
QVERIFY(iface->state().readOnly);
le->setReadOnly(false);
QVERIFY(!iface->state().readOnly);
QCOMPARE(bool(iface->state().focused), le->hasFocus());
QString secret(QLatin1String("secret"));
@ -3640,6 +3649,12 @@ void tst_QAccessibility::labelTest()
QVERIFY(acc_label);
QCOMPARE(acc_label->text(QAccessible::Name), text);
QCOMPARE(acc_label->state().editable, false);
QCOMPARE(acc_label->state().passwordEdit, false);
QCOMPARE(acc_label->state().disabled, false);
QCOMPARE(acc_label->state().focused, false);
QCOMPARE(acc_label->state().focusable, false);
QCOMPARE(acc_label->state().readOnly, true);
QVector<QPair<QAccessibleInterface *, QAccessible::Relation> > rels = acc_label->relations();
QCOMPARE(rels.count(), 1);

View File

@ -5,3 +5,4 @@ SOURCES += tst_qaccessibilitylinux.cpp
QT += gui-private widgets dbus testlib accessibility_support-private linuxaccessibility_support-private
DBUS_INTERFACES = $$PWD/../../../../src/platformsupport/linuxaccessibility/dbusxml/Bus.xml

View File

@ -42,12 +42,11 @@
#include <QDBusInterface>
#include <QDBusReply>
#include "atspi/atspi-constants.h"
#include <atspi/atspi-constants.h>
#include <private/dbusconnection_p.h>
#include <private/struct_marshallers_p.h>
#include "bus_interface.h"
#include "dbusconnection_p.h"
#include "struct_marshallers_p.h"
#define COMPARE3(v1, v2, v3) QCOMPARE(v1, v3); QCOMPARE(v2, v3);
class AccessibleTestWindow : public QWidget
@ -251,6 +250,8 @@ void tst_QAccessibilityLinux::testLabel()
QCOMPARE(labelInterface->call(QDBus::Block, "GetRoleName").arguments().first().toString(), QLatin1String("label"));
QCOMPARE(labelInterface->call(QDBus::Block, "GetRole").arguments().first().toUInt(), 29u);
QCOMPARE(getParent(labelInterface), mainWindow->path());
QVERIFY(!hasState(labelInterface, ATSPI_STATE_EDITABLE));
QVERIFY(hasState(labelInterface, ATSPI_STATE_READ_ONLY));
l->setText("New text");
QCOMPARE(labelInterface->property("Name").toString(), l->text());
@ -303,6 +304,12 @@ void tst_QAccessibilityLinux::testLineEdit()
QCOMPARE(lineEdit->selectionStart(), -1);
QCOMPARE(textInterface->call(QDBus::Block, "GetNSelections").arguments().first().toInt(), 0);
QVERIFY(hasState(accessibleInterface, ATSPI_STATE_EDITABLE));
QVERIFY(!hasState(accessibleInterface, ATSPI_STATE_READ_ONLY));
lineEdit->setReadOnly(true);
QVERIFY(hasState(accessibleInterface, ATSPI_STATE_EDITABLE));
QVERIFY(hasState(accessibleInterface, ATSPI_STATE_READ_ONLY));
m_window->clearChildren();
delete accessibleInterface;
delete textInterface;

View File

@ -11,6 +11,10 @@
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="wait">
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>

View File

@ -2,8 +2,9 @@ TAP version 13
# tst_Sleep
ok 1 - initTestCase()
ok 2 - sleep()
ok 3 - cleanupTestCase()
1..3
# tests 3
# pass 3
ok 3 - wait()
ok 4 - cleanupTestCase()
1..4
# tests 4
# pass 4
# fail 0

View File

@ -3,6 +3,8 @@
##teamcity[testFinished name='initTestCase()' flowId='tst_Sleep']
##teamcity[testStarted name='sleep()' flowId='tst_Sleep']
##teamcity[testFinished name='sleep()' flowId='tst_Sleep']
##teamcity[testStarted name='wait()' flowId='tst_Sleep']
##teamcity[testFinished name='wait()' flowId='tst_Sleep']
##teamcity[testStarted name='cleanupTestCase()' flowId='tst_Sleep']
##teamcity[testFinished name='cleanupTestCase()' flowId='tst_Sleep']
##teamcity[testSuiteFinished name='tst_Sleep' flowId='tst_Sleep']

View File

@ -2,6 +2,7 @@
Config: Using QtTest library
PASS : tst_Sleep::initTestCase()
PASS : tst_Sleep::sleep()
PASS : tst_Sleep::wait()
PASS : tst_Sleep::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
Totals: 4 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms
********* Finished testing of tst_Sleep *********

View File

@ -13,6 +13,10 @@
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="wait">
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
<Duration msecs="0"/>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<testsuite errors="0" failures="0" tests="3" name="tst_Sleep">
<testsuite errors="0" failures="0" tests="4" name="tst_Sleep">
<properties>
<property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
@ -7,6 +7,7 @@
</properties>
<testcase result="pass" name="initTestCase"/>
<testcase result="pass" name="sleep"/>
<testcase result="pass" name="wait"/>
<testcase result="pass" name="cleanupTestCase"/>
<system-err/>
</testsuite>

View File

@ -36,6 +36,7 @@ class tst_Sleep: public QObject
private slots:
void sleep();
void wait();
};
void tst_Sleep::sleep()
@ -53,6 +54,24 @@ void tst_Sleep::sleep()
QVERIFY(t.elapsed() > 1000 * 10);
}
void tst_Sleep::wait()
{
QElapsedTimer t;
t.start();
QTest::qWait(1);
QVERIFY(t.elapsed() >= 1);
QTest::qWait(10);
QVERIFY(t.elapsed() >= 11);
QTest::qWait(100);
QVERIFY(t.elapsed() >= 111);
QTest::qWait(1000);
QVERIFY(t.elapsed() >= 1111);
}
QTEST_MAIN(tst_Sleep)
#include "tst_sleep.moc"

View File

@ -31,7 +31,7 @@
The CLDR data can be downloaded from CLDR_, which has a sub-directory
for each version; you need the ``core.zip`` file for your version of
choice (typically the latest). This script has had updates to cope up
to v29; for later versions, we may need adaptations. Unpack the
to v35; for later versions, we may need adaptations. Unpack the
downloaded ``core.zip`` and check it has a common/main/ sub-directory:
pass the path of that sub-directory to this script as its single
command-line argument. Save its standard output (but not error) to a

View File

@ -53,7 +53,21 @@ def ordStr(c):
def fixOrdStr(c, d):
return str(ord(c if len(c) == 1 else d))
def startCount(c, text): # strspn
"""First index in text where it doesn't have a character in c"""
assert text and text[0] in c
try:
return (j for j, d in enumerate(text) if d not in c).next()
except StopIteration:
return len(text)
def convertFormat(format):
"""Convert date/time format-specier from CLDR to Qt
Match up (as best we can) the differences between:
* https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
* QDateTimeParser::parseFormat() and QLocalePrivate::dateTimeToString()
"""
result = ""
i = 0
while i < len(format):
@ -68,20 +82,30 @@ def convertFormat(format):
i += 1
else:
s = format[i:]
if s.startswith("EEEE"):
result += "dddd"
i += 4
elif s.startswith("EEE"):
result += "ddd"
i += 3
elif s.startswith("a"):
if s.startswith('E'): # week-day
n = startCount('E', s)
if n < 3:
result += 'ddd'
elif n == 4:
result += 'dddd'
else: # 5: narrow, 6 short; but should be name, not number :-(
result += 'd' if n < 6 else 'dd'
i += n
elif s[0] in 'ab': # am/pm
# 'b' should distinguish noon/midnight, too :-(
result += "AP"
i += 1
elif s.startswith("z"):
i += startCount('ab', s)
elif s.startswith('S'): # fractions of seconds: count('S') == number of decimals to show
result += 'z'
i += startCount('S', s)
elif s.startswith('V'): # long time zone specifiers (and a deprecated short ID)
result += 't'
i += startCount('V', s)
elif s[0] in 'zv': # zone
# Should use full name, e.g. "Central European Time", if 'zzzz' :-(
# 'v' should get generic non-location format, e.g. PT for "Pacific Time", no DST indicator
result += "t"
i += 1
elif s.startswith("v"):
i += 1
i += startCount('zv', s)
else:
result += format[i]
i += 1