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:
commit
e56d3b03ed
52
doc/global/includes/module-use.qdocinc
Normal file
52
doc/global/includes/module-use.qdocinc
Normal 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]
|
@ -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 \
|
||||
|
@ -9,4 +9,5 @@ defines += onlinedocs
|
||||
#uncomment if navigation bar is not wanted
|
||||
#HTML.nonavigationbar = "true"
|
||||
|
||||
sourcedirs += includes-online
|
||||
sourcedirs += includes-online \
|
||||
includes
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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]
|
2
src/corelib/doc/snippets/overview/using-qt-core.cmake
Normal file
2
src/corelib/doc/snippets/overview/using-qt-core.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
find_package(Qt5 COMPONENTS Core REQUIRED)
|
||||
target_link_libraries(mytarget Qt5::Core)
|
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
||||
|
@ -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(¶meters) << "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(");
|
||||
|
@ -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)
|
||||
{
|
||||
qint64 secs = nsecs / (1000*1000*1000);
|
||||
if (nsecs < 0)
|
||||
--secs;
|
||||
nsecs -= secs * 1000*1000*1000;
|
||||
return qMakePair(secs, nsecs);
|
||||
namespace {
|
||||
class TimeReference
|
||||
{
|
||||
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
|
||||
|
@ -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)
|
||||
|
@ -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
@ -1,7 +1,3 @@
|
||||
#! [0]
|
||||
#include <QtGui>
|
||||
#! [0]
|
||||
|
||||
#! [1]
|
||||
QT -= gui
|
||||
#! [1]
|
||||
|
2
src/gui/doc/snippets/overview/using-qt-gui.cmake
Normal file
2
src/gui/doc/snippets/overview/using-qt-gui.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
find_package(Qt5 COMPONENTS Gui REQUIRED)
|
||||
target_link_libraries(mytarget Qt5::Gui)
|
@ -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:
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 ®ion, const QPoint &offset,
|
||||
QPlatformTextureList *textures, bool translucentBackground) override;
|
||||
#endif
|
||||
|
||||
QPlatformGraphicsBuffer *graphicsBuffer() const override;
|
||||
|
||||
|
@ -523,6 +523,7 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
||||
// the window server.
|
||||
}
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
||||
QPlatformTextureList *textures, bool translucentBackground)
|
||||
{
|
||||
@ -531,6 +532,7 @@ void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®io
|
||||
|
||||
QPlatformBackingStore::composeAndFlush(window, region, offset, textures, translucentBackground);
|
||||
}
|
||||
#endif
|
||||
|
||||
QPlatformGraphicsBuffer *QCALayerBackingStore::graphicsBuffer() const
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
3
tests/auto/gui/text/qfontdatabase/BLACKLIST
Normal file
3
tests/auto/gui/text/qfontdatabase/BLACKLIST
Normal file
@ -0,0 +1,3 @@
|
||||
[systemFixedFont] # QTBUG-54623
|
||||
winrt
|
||||
b2qt
|
@ -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()
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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"/>
|
||||
|
@ -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
|
||||
|
@ -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']
|
||||
|
@ -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 *********
|
||||
|
@ -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"/>
|
||||
|
@ -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>
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user