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/bullet_sq.png \
|
||||||
template/images/bgrContent.png
|
template/images/bgrContent.png
|
||||||
|
|
||||||
|
sourcedirs += includes
|
||||||
|
|
||||||
#specify which files in the output directory should be packed into the qch file.
|
#specify which files in the output directory should be packed into the qch file.
|
||||||
qhp.extraFiles += style/offline.css \
|
qhp.extraFiles += style/offline.css \
|
||||||
images/ico_out.png \
|
images/ico_out.png \
|
||||||
|
@ -9,4 +9,5 @@ defines += onlinedocs
|
|||||||
#uncomment if navigation bar is not wanted
|
#uncomment if navigation bar is not wanted
|
||||||
#HTML.nonavigationbar = "true"
|
#HTML.nonavigationbar = "true"
|
||||||
|
|
||||||
sourcedirs += includes-online
|
sourcedirs += includes-online \
|
||||||
|
includes
|
||||||
|
@ -69,6 +69,7 @@ QMAKE_LIBDIR_OPENGL =
|
|||||||
|
|
||||||
QMAKE_LINK_SHLIB = $$QMAKE_LINK
|
QMAKE_LINK_SHLIB = $$QMAKE_LINK
|
||||||
QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
|
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_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared
|
||||||
QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
|
QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
|
||||||
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
|
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
|
||||||
|
@ -1163,6 +1163,10 @@
|
|||||||
|
|
||||||
\snippet code/doc_src_qmake-manual.pro 30
|
\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
|
\target DISTFILES
|
||||||
\section1 DISTFILES
|
\section1 DISTFILES
|
||||||
|
|
||||||
|
@ -837,7 +837,9 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
|
|||||||
if(inc) {
|
if(inc) {
|
||||||
if(!includes)
|
if(!includes)
|
||||||
includes = new SourceFiles;
|
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) {
|
if(!dep) {
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
QMakeLocalFileName lfn(inc);
|
QMakeLocalFileName lfn(inc);
|
||||||
@ -876,7 +878,11 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
|
|||||||
dep->file = lfn;
|
dep->file = lfn;
|
||||||
dep->type = QMakeSourceFileInfo::TYPE_C;
|
dep->type = QMakeSourceFileInfo::TYPE_C;
|
||||||
files->addFile(dep);
|
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;
|
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/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the documentation of the Qt Toolkit.
|
** 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.
|
\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
|
\section1 Core Functionalities
|
||||||
|
|
||||||
Qt adds these features to C++:
|
Qt Core adds these features to C++:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
\li a very powerful mechanism for seamless object communication called
|
\li a very powerful mechanism for seamless object communication called
|
||||||
@ -61,6 +53,15 @@
|
|||||||
\li \l{Signals & Slots}
|
\li \l{Signals & Slots}
|
||||||
\endlist
|
\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
|
\section1 Threading and Concurrent Programming
|
||||||
|
|
||||||
Qt provides thread support in the form of platform-independent \l{Threading
|
Qt provides thread support in the form of platform-independent \l{Threading
|
||||||
|
@ -33,12 +33,5 @@
|
|||||||
|
|
||||||
\brief Provides core non-GUI functionality.
|
\brief Provides core non-GUI functionality.
|
||||||
|
|
||||||
All other Qt modules rely on this module. To include the
|
All other Qt modules rely on this module.
|
||||||
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.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -1425,6 +1425,13 @@ bool qSharedBuild() Q_DECL_NOTHROW
|
|||||||
\l Q_OS_WIN32, \l Q_OS_WIN64, or \l Q_OS_WINRT is defined.
|
\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
|
\macro Q_OS_WIN32
|
||||||
\relates <QtGlobal>
|
\relates <QtGlobal>
|
||||||
|
@ -176,6 +176,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT)
|
#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT)
|
||||||
|
# define Q_OS_WINDOWS
|
||||||
# define Q_OS_WIN
|
# define Q_OS_WIN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "qmutex.h"
|
#include "qmutex.h"
|
||||||
#include <private/qthread_p.h>
|
#include <private/qthread_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "qtextstream.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <qt_windows.h>
|
#include <qt_windows.h>
|
||||||
|
|
||||||
@ -480,6 +481,7 @@ static const char *findWMstr(uint msg)
|
|||||||
{ 0x02DD, "WM_TABLET_FIRST + 29" },
|
{ 0x02DD, "WM_TABLET_FIRST + 29" },
|
||||||
{ 0x02DE, "WM_TABLET_FIRST + 30" },
|
{ 0x02DE, "WM_TABLET_FIRST + 30" },
|
||||||
{ 0x02DF, "WM_TABLET_LAST" },
|
{ 0x02DF, "WM_TABLET_LAST" },
|
||||||
|
{ 0x02E0, "WM_DPICHANGED" },
|
||||||
{ 0x0300, "WM_CUT" },
|
{ 0x0300, "WM_CUT" },
|
||||||
{ 0x0301, "WM_COPY" },
|
{ 0x0301, "WM_COPY" },
|
||||||
{ 0x0302, "WM_PASTE" },
|
{ 0x0302, "WM_PASTE" },
|
||||||
@ -765,6 +767,13 @@ QString decodeMSG(const MSG& msg)
|
|||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
parameters = QLatin1String("Destroy hwnd ") + hwndS;
|
parameters = QLatin1String("Destroy hwnd ") + hwndS;
|
||||||
break;
|
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:
|
case WM_IME_NOTIFY:
|
||||||
{
|
{
|
||||||
parameters = QLatin1String("Command(");
|
parameters = QLatin1String("Command(");
|
||||||
|
@ -39,18 +39,294 @@
|
|||||||
|
|
||||||
#include "qdeadlinetimer.h"
|
#include "qdeadlinetimer.h"
|
||||||
#include "qdeadlinetimer_p.h"
|
#include "qdeadlinetimer_p.h"
|
||||||
|
#include "private/qnumeric_p.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
Q_DECL_CONST_FUNCTION static inline QPair<qint64, qint64> toSecsAndNSecs(qint64 nsecs)
|
namespace {
|
||||||
|
class TimeReference
|
||||||
{
|
{
|
||||||
qint64 secs = nsecs / (1000*1000*1000);
|
enum : unsigned {
|
||||||
if (nsecs < 0)
|
umega = 1000 * 1000,
|
||||||
--secs;
|
ugiga = umega * 1000
|
||||||
nsecs -= secs * 1000*1000*1000;
|
};
|
||||||
return qMakePair(secs, nsecs);
|
|
||||||
|
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
|
\class QDeadlineTimer
|
||||||
\inmodule QtCore
|
\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
|
void QDeadlineTimer::setRemainingTime(qint64 msecs, Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
if (msecs == -1)
|
if (msecs == -1) {
|
||||||
*this = QDeadlineTimer(Forever, timerType);
|
*this = QDeadlineTimer(Forever, timerType);
|
||||||
else
|
return;
|
||||||
setPreciseRemainingTime(0, msecs * 1000 * 1000, timerType);
|
}
|
||||||
|
|
||||||
|
*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);
|
*this = current(timerType);
|
||||||
if (QDeadlineTimerNanosecondsInT2) {
|
TimeReference ref(t1, t2);
|
||||||
t1 += secs + toSecsAndNSecs(nsecs).first;
|
if (!ref.addSecsAndNSecs(secs, nsecs))
|
||||||
t2 += toSecsAndNSecs(nsecs).second;
|
ref.saturate(TimeReference::sign(secs, nsecs));
|
||||||
if (t2 > 1000*1000*1000) {
|
ref.updateTimer(t1, t2);
|
||||||
t2 -= 1000*1000*1000;
|
|
||||||
++t1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t1 += secs * 1000 * 1000 * 1000 + nsecs;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -391,8 +668,22 @@ void QDeadlineTimer::setTimerType(Qt::TimerType timerType)
|
|||||||
*/
|
*/
|
||||||
qint64 QDeadlineTimer::remainingTime() const Q_DECL_NOTHROW
|
qint64 QDeadlineTimer::remainingTime() const Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
qint64 ns = remainingTimeNSecs();
|
if (isForever())
|
||||||
return ns <= 0 ? ns : (ns + 999999) / (1000 * 1000);
|
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
|
\internal
|
||||||
Same as remainingTimeNSecs, but may return negative remaining times. Does
|
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
|
qint64 QDeadlineTimer::rawRemainingTimeNSecs() const Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
QDeadlineTimer now = current(timerType());
|
QDeadlineTimer now = current(timerType());
|
||||||
if (QDeadlineTimerNanosecondsInT2)
|
TimeReference ref(t1, t2);
|
||||||
return (t1 - now.t1) * (1000*1000*1000) + t2 - now.t2;
|
|
||||||
return t1 - now.t1;
|
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
|
qint64 QDeadlineTimer::deadline() const Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
if (isForever())
|
if (isForever())
|
||||||
return t1;
|
return TimeReference::Max;
|
||||||
return deadlineNSecs() / (1000 * 1000);
|
|
||||||
|
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
|
same as QElapsedTimer::msecsSinceReference(). The value will be in the past
|
||||||
if this QDeadlineTimer has expired.
|
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()}.
|
\c{std::numeric_limits<qint64>::max()}.
|
||||||
|
|
||||||
This function can be used to calculate the amount of time a timer is
|
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
|
qint64 QDeadlineTimer::deadlineNSecs() const Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
if (isForever())
|
if (isForever())
|
||||||
return t1;
|
return TimeReference::Max;
|
||||||
if (QDeadlineTimerNanosecondsInT2)
|
|
||||||
return t1 * 1000 * 1000 * 1000 + t2;
|
qint64 result;
|
||||||
return t1;
|
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
|
timerType. If the value is in the past, this QDeadlineTimer will be marked
|
||||||
as expired.
|
as expired.
|
||||||
|
|
||||||
If \a msecs is \c{std::numeric_limits<qint64>::max()}, this QDeadlineTimer
|
If \a msecs is \c{std::numeric_limits<qint64>::max()} or the deadline is
|
||||||
will be set to never expire.
|
beyond a representable point in the future, this QDeadlineTimer will be set
|
||||||
|
to never expire.
|
||||||
|
|
||||||
\sa setPreciseDeadline(), deadline(), deadlineNSecs(), setRemainingTime()
|
\sa setPreciseDeadline(), deadline(), deadlineNSecs(), setRemainingTime()
|
||||||
*/
|
*/
|
||||||
void QDeadlineTimer::setDeadline(qint64 msecs, Qt::TimerType timerType) Q_DECL_NOTHROW
|
void QDeadlineTimer::setDeadline(qint64 msecs, Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
if (msecs == (std::numeric_limits<qint64>::max)()) {
|
if (msecs == TimeReference::Max) {
|
||||||
setPreciseDeadline(msecs, 0, timerType); // msecs == MAX implies Forever
|
*this = QDeadlineTimer(Forever, timerType);
|
||||||
} else {
|
return;
|
||||||
setPreciseDeadline(msecs / 1000, msecs % 1000 * 1000 * 1000, timerType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
void QDeadlineTimer::setPreciseDeadline(qint64 secs, qint64 nsecs, Qt::TimerType timerType) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
type = timerType;
|
type = timerType;
|
||||||
if (secs == (std::numeric_limits<qint64>::max)() || nsecs == (std::numeric_limits<qint64>::max)()) {
|
|
||||||
*this = QDeadlineTimer(Forever, timerType);
|
// We don't pass the seconds to the constructor, because we don't know
|
||||||
} else if (QDeadlineTimerNanosecondsInT2) {
|
// at this point if t1 holds the seconds or nanoseconds; it's platform specific.
|
||||||
t1 = secs + toSecsAndNSecs(nsecs).first;
|
TimeReference ref;
|
||||||
t2 = toSecsAndNSecs(nsecs).second;
|
if (!ref.addSecsAndNSecs(secs, nsecs))
|
||||||
} else {
|
ref.saturate(TimeReference::sign(secs, nsecs));
|
||||||
t1 = secs * (1000*1000*1000) + 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
|
QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
if (dt.isForever() || nsecs == (std::numeric_limits<qint64>::max)()) {
|
if (dt.isForever())
|
||||||
dt = QDeadlineTimer(Forever, dt.timerType());
|
return dt;
|
||||||
} else if (QDeadlineTimerNanosecondsInT2) {
|
|
||||||
dt.t1 += toSecsAndNSecs(nsecs).first;
|
TimeReference ref(dt.t1, dt.t2);
|
||||||
dt.t2 += toSecsAndNSecs(nsecs).second;
|
if (!ref.addNanoseconds(nsecs))
|
||||||
if (dt.t2 > 1000*1000*1000) {
|
ref.saturate(nsecs > 0);
|
||||||
dt.t2 -= 1000*1000*1000;
|
ref.updateTimer(dt.t1, dt.t2);
|
||||||
++dt.t1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dt.t1 += nsecs;
|
|
||||||
}
|
|
||||||
return dt;
|
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().
|
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)
|
\fn QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt)
|
||||||
\relates QDeadlineTimer
|
\relates QDeadlineTimer
|
||||||
|
@ -108,8 +108,7 @@ public:
|
|||||||
friend bool operator>=(QDeadlineTimer d1, QDeadlineTimer d2) Q_DECL_NOTHROW
|
friend bool operator>=(QDeadlineTimer d1, QDeadlineTimer d2) Q_DECL_NOTHROW
|
||||||
{ return !(d1 < d2); }
|
{ return !(d1 < d2); }
|
||||||
|
|
||||||
friend QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs)
|
friend Q_CORE_EXPORT QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs);
|
||||||
{ return QDeadlineTimer::addNSecs(dt, msecs * 1000 * 1000); }
|
|
||||||
friend QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt)
|
friend QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt)
|
||||||
{ return dt + msecs; }
|
{ return dt + msecs; }
|
||||||
friend QDeadlineTimer operator-(QDeadlineTimer dt, qint64 msecs)
|
friend QDeadlineTimer operator-(QDeadlineTimer dt, qint64 msecs)
|
||||||
|
@ -92,7 +92,7 @@
|
|||||||
\note For the current keyboard input locale take a look at
|
\note For the current keyboard input locale take a look at
|
||||||
QInputMethod::locale().
|
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(),
|
\sa QString::arg(), QString::toInt(), QString::toDouble(),
|
||||||
QInputMethod::locale()
|
QInputMethod::locale()
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,3 @@
|
|||||||
#! [0]
|
|
||||||
#include <QtGui>
|
|
||||||
#! [0]
|
|
||||||
|
|
||||||
#! [1]
|
#! [1]
|
||||||
QT -= gui
|
QT -= gui
|
||||||
#! [1]
|
#! [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
|
These classes are used internally by Qt's user interface technologies
|
||||||
and can also be used directly, for instance to write applications using
|
and can also be used directly, for instance to write applications using
|
||||||
low-level OpenGL ES graphics APIs.
|
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
|
higher level API's, like Qt Quick, that are much more suitable
|
||||||
than the enablers found in the Qt GUI module.
|
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)
|
\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
|
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:
|
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
|
#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GL_TEXTURE_SWIZZLE_RGBA
|
#ifndef GL_TEXTURE_SWIZZLE_R
|
||||||
#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef GL_SRGB
|
#ifndef GL_SRGB
|
||||||
@ -128,11 +140,13 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
|
|||||||
#endif
|
#endif
|
||||||
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
|
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
|
||||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||||
GLint swizzle[4] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
|
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
|
||||||
funcs->glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
|
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
|
||||||
#else
|
#else
|
||||||
GLint swizzle[4] = { GL_GREEN, GL_BLUE, GL_ALPHA, GL_RED };
|
funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_GREEN);
|
||||||
funcs->glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
|
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
|
#endif
|
||||||
externalFormat = internalFormat = GL_RGBA;
|
externalFormat = internalFormat = GL_RGBA;
|
||||||
pixelType = GL_UNSIGNED_BYTE;
|
pixelType = GL_UNSIGNED_BYTE;
|
||||||
@ -164,12 +178,12 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
|
|||||||
externalFormat = GL_BGRA;
|
externalFormat = GL_BGRA;
|
||||||
internalFormat = GL_RGB10_A2;
|
internalFormat = GL_RGB10_A2;
|
||||||
targetFormat = image.format();
|
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;
|
pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||||
externalFormat = GL_RGBA;
|
externalFormat = GL_RGBA;
|
||||||
internalFormat = GL_RGB10_A2;
|
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();
|
targetFormat = image.format();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -227,8 +241,10 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
|
|||||||
pixelType = GL_UNSIGNED_BYTE;
|
pixelType = GL_UNSIGNED_BYTE;
|
||||||
targetFormat = image.format();
|
targetFormat = image.format();
|
||||||
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
|
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
|
||||||
GLint swizzle[4] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED };
|
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ALPHA);
|
||||||
funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
|
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;
|
externalFormat = internalFormat = GL_RED;
|
||||||
pixelType = GL_UNSIGNED_BYTE;
|
pixelType = GL_UNSIGNED_BYTE;
|
||||||
targetFormat = image.format();
|
targetFormat = image.format();
|
||||||
@ -247,8 +263,10 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
|
|||||||
pixelType = GL_UNSIGNED_BYTE;
|
pixelType = GL_UNSIGNED_BYTE;
|
||||||
targetFormat = image.format();
|
targetFormat = image.format();
|
||||||
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
|
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
|
||||||
GLint swizzle[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
|
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
|
||||||
funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
|
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;
|
externalFormat = internalFormat = GL_RED;
|
||||||
pixelType = GL_UNSIGNED_BYTE;
|
pixelType = GL_UNSIGNED_BYTE;
|
||||||
targetFormat = image.format();
|
targetFormat = image.format();
|
||||||
@ -267,8 +285,10 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
|
|||||||
pixelType = GL_UNSIGNED_SHORT;
|
pixelType = GL_UNSIGNED_SHORT;
|
||||||
targetFormat = image.format();
|
targetFormat = image.format();
|
||||||
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
|
} else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
|
||||||
GLint swizzle[4] = { GL_RED, GL_RED, GL_RED, GL_ONE };
|
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
|
||||||
funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
|
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;
|
externalFormat = internalFormat = GL_RED;
|
||||||
pixelType = GL_UNSIGNED_SHORT;
|
pixelType = GL_UNSIGNED_SHORT;
|
||||||
targetFormat = image.format();
|
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)
|
static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qreal threshold)
|
||||||
{
|
{
|
||||||
int map[4];
|
int map[4];
|
||||||
bool p1_p2_equal = (orig->x1 == orig->x2 && orig->y1 == orig->y2);
|
bool p1_p2_equal = qFuzzyCompare(orig->x1, orig->x2) && qFuzzyCompare(orig->y1, orig->y2);
|
||||||
bool p2_p3_equal = (orig->x2 == orig->x3 && orig->y2 == orig->y3);
|
bool p2_p3_equal = qFuzzyCompare(orig->x2, orig->x3) && qFuzzyCompare(orig->y2, orig->y3);
|
||||||
bool p3_p4_equal = (orig->x3 == orig->x4 && orig->y3 == orig->y4);
|
bool p3_p4_equal = qFuzzyCompare(orig->x3, orig->x4) && qFuzzyCompare(orig->y3, orig->y4);
|
||||||
|
|
||||||
QPointF points[4];
|
QPointF points[4];
|
||||||
int np = 0;
|
int np = 0;
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qfontdatabase.h"
|
#include "qfontdatabase.h"
|
||||||
#include "qdebug.h"
|
#include "qloggingcategory.h"
|
||||||
#include "qalgorithms.h"
|
#include "qalgorithms.h"
|
||||||
#include "qguiapplication.h"
|
#include "qguiapplication.h"
|
||||||
#include "qvarlengtharray.h" // here or earlier - workaround for VC++6
|
#include "qvarlengtharray.h" // here or earlier - workaround for VC++6
|
||||||
@ -59,25 +59,13 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <algorithm>
|
#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>
|
#include <qtgui_tracepoints_p.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(lcFontDb, "qt.text.font.db")
|
||||||
|
Q_LOGGING_CATEGORY(lcFontMatch, "qt.text.font.match")
|
||||||
|
|
||||||
#define SMOOTH_SCALABLE 0xffff
|
#define SMOOTH_SCALABLE 0xffff
|
||||||
|
|
||||||
#if defined(QT_BUILD_INTERNAL)
|
#if defined(QT_BUILD_INTERNAL)
|
||||||
@ -744,7 +732,7 @@ void qt_registerFont(const QString &familyName, const QString &stylename,
|
|||||||
const QSupportedWritingSystems &writingSystems, void *handle)
|
const QSupportedWritingSystems &writingSystems, void *handle)
|
||||||
{
|
{
|
||||||
QFontDatabasePrivate *d = privateDb();
|
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;
|
QtFontStyle::Key styleKey;
|
||||||
styleKey.style = style;
|
styleKey.style = style;
|
||||||
styleKey.weight = weight;
|
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];
|
return foundry->styles[best];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1098,20 +1086,20 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
|
|||||||
desc->size = 0;
|
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) {
|
for (int x = 0; x < family->count; ++x) {
|
||||||
QtFontFoundry *foundry = family->foundries[x];
|
QtFontFoundry *foundry = family->foundries[x];
|
||||||
if (!foundry_name.isEmpty() && foundry->name.compare(foundry_name, Qt::CaseInsensitive) != 0)
|
if (!foundry_name.isEmpty() && foundry->name.compare(foundry_name, Qt::CaseInsensitive) != 0)
|
||||||
continue;
|
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);
|
foundry->name.isEmpty() ? "-- none --" : foundry->name.toLatin1().constData(), foundry->count);
|
||||||
|
|
||||||
QtFontStyle *style = bestStyle(foundry, styleKey, styleName);
|
QtFontStyle *style = bestStyle(foundry, styleKey, styleName);
|
||||||
|
|
||||||
if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) {
|
if (!style->smoothScalable && (styleStrategy & QFont::ForceOutline)) {
|
||||||
FM_DEBUG(" ForceOutline set, but not smoothly scalable");
|
qCDebug(lcFontMatch, " ForceOutline set, but not smoothly scalable");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1122,7 +1110,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
|
|||||||
if (!(styleStrategy & QFont::ForceOutline)) {
|
if (!(styleStrategy & QFont::ForceOutline)) {
|
||||||
size = style->pixelSize(pixelSize);
|
size = style->pixelSize(pixelSize);
|
||||||
if (size) {
|
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;
|
px = size->pixelSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1131,7 +1119,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
|
|||||||
if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
|
if (!size && style->smoothScalable && ! (styleStrategy & QFont::PreferBitmap)) {
|
||||||
size = style->pixelSize(SMOOTH_SCALABLE);
|
size = style->pixelSize(SMOOTH_SCALABLE);
|
||||||
if (size) {
|
if (size) {
|
||||||
FM_DEBUG(" found smoothly scalable font (%d pixels)", pixelSize);
|
qCDebug(lcFontMatch, " found smoothly scalable font (%d pixels)", pixelSize);
|
||||||
px = pixelSize;
|
px = pixelSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1140,7 +1128,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
|
|||||||
if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
|
if (!size && style->bitmapScalable && (styleStrategy & QFont::PreferMatch)) {
|
||||||
size = style->pixelSize(0);
|
size = style->pixelSize(0);
|
||||||
if (size) {
|
if (size) {
|
||||||
FM_DEBUG(" found bitmap scalable font (%d pixels)", pixelSize);
|
qCDebug(lcFontMatch, " found bitmap scalable font (%d pixels)", pixelSize);
|
||||||
px = pixelSize;
|
px = pixelSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1164,12 +1152,12 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
|
|||||||
if (d < distance) {
|
if (d < distance) {
|
||||||
distance = d;
|
distance = d;
|
||||||
size = style->pixelSizes + x;
|
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) {
|
if (!size) {
|
||||||
FM_DEBUG(" no size supports the script we want");
|
qCDebug(lcFontMatch, " no size supports the script we want");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1204,7 +1192,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
|
|||||||
this_score += qAbs(px - pixelSize);
|
this_score += qAbs(px - pixelSize);
|
||||||
|
|
||||||
if (this_score < score) {
|
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);
|
this_score, score);
|
||||||
|
|
||||||
score = this_score;
|
score = this_score;
|
||||||
@ -1212,7 +1200,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
|
|||||||
desc->style = style;
|
desc->style = style;
|
||||||
desc->size = size;
|
desc->size = size;
|
||||||
} else {
|
} 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';
|
char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';
|
||||||
|
|
||||||
|
|
||||||
FM_DEBUG("QFontDatabase::match\n"
|
qCDebug(lcFontMatch, "QFontDatabase::match\n"
|
||||||
" request:\n"
|
" request:\n"
|
||||||
" family: %s [%s], script: %d\n"
|
" family: %s [%s], script: %d\n"
|
||||||
" weight: %d, style: %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);
|
QFontCache::Key key(request, script, multi ? 1 : 0);
|
||||||
engine = fontCache->findEngine(key);
|
engine = fontCache->findEngine(key);
|
||||||
if (engine) {
|
if (engine) {
|
||||||
FM_DEBUG("Cache hit level 1");
|
qCDebug(lcFontMatch, "Cache hit level 1");
|
||||||
return engine;
|
return engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2712,7 +2700,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
|
|||||||
else
|
else
|
||||||
blackListed.append(index);
|
blackListed.append(index);
|
||||||
} else {
|
} else {
|
||||||
FM_DEBUG(" NO MATCH FOUND\n");
|
qCDebug(lcFontMatch, " NO MATCH FOUND\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!engine) {
|
if (!engine) {
|
||||||
@ -2756,7 +2744,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
|
|||||||
if (!engine)
|
if (!engine)
|
||||||
engine = new QFontEngineBox(request.pixelSize);
|
engine = new QFontEngineBox(request.pixelSize);
|
||||||
|
|
||||||
FM_DEBUG("returning box engine");
|
qCDebug(lcFontMatch, "returning box engine");
|
||||||
}
|
}
|
||||||
|
|
||||||
return engine;
|
return engine;
|
||||||
|
@ -1383,11 +1383,12 @@ void QTextEngine::shapeText(int item) const
|
|||||||
if (QChar::isHighSurrogate(ucs4) && i + 1 < itemLength) {
|
if (QChar::isHighSurrogate(ucs4) && i + 1 < itemLength) {
|
||||||
uint low = string[i + 1];
|
uint low = string[i + 1];
|
||||||
if (QChar::isLowSurrogate(low)) {
|
if (QChar::isLowSurrogate(low)) {
|
||||||
|
// high part never changes in simple casing
|
||||||
|
uc[i] = ucs4;
|
||||||
++i;
|
++i;
|
||||||
ucs4 = QChar::surrogateToUcs4(ucs4, low);
|
ucs4 = QChar::surrogateToUcs4(ucs4, low);
|
||||||
ucs4 = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
|
ucs4 = si.analysis.flags == QScriptAnalysis::Lowercase ? QChar::toLower(ucs4)
|
||||||
: QChar::toUpper(ucs4);
|
: QChar::toUpper(ucs4);
|
||||||
// high part never changes in simple casing
|
|
||||||
uc[i] = QChar::lowSurrogate(ucs4);
|
uc[i] = QChar::lowSurrogate(ucs4);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -875,8 +875,14 @@ void QNativeSocketEngine::close()
|
|||||||
if (d->closingDown)
|
if (d->closingDown)
|
||||||
return;
|
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();
|
processReadReady();
|
||||||
|
if (alive.isNull())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
d->closingDown = true;
|
d->closingDown = true;
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ quint64 spiStatesFromQState(QAccessible::State state)
|
|||||||
if (state.checkStateMixed)
|
if (state.checkStateMixed)
|
||||||
setSpiStateBit(&spiState, ATSPI_STATE_INDETERMINATE);
|
setSpiStateBit(&spiState, ATSPI_STATE_INDETERMINATE);
|
||||||
if (state.readOnly)
|
if (state.readOnly)
|
||||||
unsetSpiStateBit(&spiState, ATSPI_STATE_EDITABLE);
|
setSpiStateBit(&spiState, ATSPI_STATE_READ_ONLY);
|
||||||
// if (state.HotTracked)
|
// if (state.HotTracked)
|
||||||
if (state.defaultButton)
|
if (state.defaultButton)
|
||||||
setSpiStateBit(&spiState, ATSPI_STATE_IS_DEFAULT);
|
setSpiStateBit(&spiState, ATSPI_STATE_IS_DEFAULT);
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(qLcTray)
|
Q_DECLARE_LOGGING_CATEGORY(qLcTray)
|
||||||
|
Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
|
||||||
|
|
||||||
ResourceHelper::ResourceHelper()
|
ResourceHelper::ResourceHelper()
|
||||||
{
|
{
|
||||||
@ -96,6 +97,7 @@ const char *QGenericUnixTheme::name = "generic";
|
|||||||
// Default system font, corresponding to the value returned by 4.8 for
|
// Default system font, corresponding to the value returned by 4.8 for
|
||||||
// XRender/FontConfig which we can now assume as default.
|
// XRender/FontConfig which we can now assume as default.
|
||||||
static const char defaultSystemFontNameC[] = "Sans Serif";
|
static const char defaultSystemFontNameC[] = "Sans Serif";
|
||||||
|
static const char defaultFixedFontNameC[] = "monospace";
|
||||||
enum { defaultSystemFontSize = 9 };
|
enum { defaultSystemFontSize = 9 };
|
||||||
|
|
||||||
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
|
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
|
||||||
@ -136,9 +138,10 @@ public:
|
|||||||
QGenericUnixThemePrivate()
|
QGenericUnixThemePrivate()
|
||||||
: QPlatformThemePrivate()
|
: QPlatformThemePrivate()
|
||||||
, systemFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize)
|
, systemFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize)
|
||||||
, fixedFont(QStringLiteral("monospace"), systemFont.pointSize())
|
, fixedFont(QLatin1String(defaultFixedFontNameC), systemFont.pointSize())
|
||||||
{
|
{
|
||||||
fixedFont.setStyleHint(QFont::TypeWriter);
|
fixedFont.setStyleHint(QFont::TypeWriter);
|
||||||
|
qCDebug(lcQpaFonts) << "default fonts: system" << systemFont << "fixed" << fixedFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QFont systemFont;
|
const QFont systemFont;
|
||||||
@ -390,7 +393,7 @@ void QKdeThemePrivate::refresh()
|
|||||||
if (QFont *fixedFont = kdeFont(readKdeSetting(QStringLiteral("fixed"), kdeDirs, kdeVersion, kdeSettings))) {
|
if (QFont *fixedFont = kdeFont(readKdeSetting(QStringLiteral("fixed"), kdeDirs, kdeVersion, kdeSettings))) {
|
||||||
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
|
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
|
||||||
} else {
|
} else {
|
||||||
fixedFont = new QFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize);
|
fixedFont = new QFont(QLatin1String(defaultFixedFontNameC), defaultSystemFontSize);
|
||||||
fixedFont->setStyleHint(QFont::TypeWriter);
|
fixedFont->setStyleHint(QFont::TypeWriter);
|
||||||
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
|
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
|
||||||
}
|
}
|
||||||
@ -403,6 +406,8 @@ void QKdeThemePrivate::refresh()
|
|||||||
if (QFont *toolBarFont = kdeFont(readKdeSetting(QStringLiteral("toolBarFont"), kdeDirs, kdeVersion, kdeSettings)))
|
if (QFont *toolBarFont = kdeFont(readKdeSetting(QStringLiteral("toolBarFont"), kdeDirs, kdeVersion, kdeSettings)))
|
||||||
resources.fonts[QPlatformTheme::ToolButtonFont] = toolBarFont;
|
resources.fonts[QPlatformTheme::ToolButtonFont] = toolBarFont;
|
||||||
|
|
||||||
|
qCDebug(lcQpaFonts) << "default fonts: system" << resources.fonts[QPlatformTheme::SystemFont]
|
||||||
|
<< "fixed" << resources.fonts[QPlatformTheme::FixedFont];
|
||||||
qDeleteAll(kdeSettings);
|
qDeleteAll(kdeSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,8 +721,9 @@ public:
|
|||||||
QString fontName = gtkFontName.left(split);
|
QString fontName = gtkFontName.left(split);
|
||||||
|
|
||||||
systemFont = new QFont(fontName, size);
|
systemFont = new QFont(fontName, size);
|
||||||
fixedFont = new QFont(QLatin1String("monospace"), systemFont->pointSize());
|
fixedFont = new QFont(QLatin1String(defaultFixedFontNameC), systemFont->pointSize());
|
||||||
fixedFont->setStyleHint(QFont::TypeWriter);
|
fixedFont->setStyleHint(QFont::TypeWriter);
|
||||||
|
qCDebug(lcQpaFonts) << "default fonts: system" << systemFont << "fixed" << fixedFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutable QFont *systemFont;
|
mutable QFont *systemFont;
|
||||||
|
@ -76,8 +76,10 @@ public:
|
|||||||
void endPaint() override;
|
void endPaint() override;
|
||||||
|
|
||||||
void flush(QWindow *, const QRegion &, const QPoint &) override;
|
void flush(QWindow *, const QRegion &, const QPoint &) override;
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
void composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
void composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
||||||
QPlatformTextureList *textures, bool translucentBackground) override;
|
QPlatformTextureList *textures, bool translucentBackground) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
QPlatformGraphicsBuffer *graphicsBuffer() const override;
|
QPlatformGraphicsBuffer *graphicsBuffer() const override;
|
||||||
|
|
||||||
|
@ -523,6 +523,7 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion,
|
|||||||
// the window server.
|
// the window server.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_OPENGL
|
||||||
void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset,
|
||||||
QPlatformTextureList *textures, bool translucentBackground)
|
QPlatformTextureList *textures, bool translucentBackground)
|
||||||
{
|
{
|
||||||
@ -531,6 +532,7 @@ void QCALayerBackingStore::composeAndFlush(QWindow *window, const QRegion ®io
|
|||||||
|
|
||||||
QPlatformBackingStore::composeAndFlush(window, region, offset, textures, translucentBackground);
|
QPlatformBackingStore::composeAndFlush(window, region, offset, textures, translucentBackground);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QPlatformGraphicsBuffer *QCALayerBackingStore::graphicsBuffer() const
|
QPlatformGraphicsBuffer *QCALayerBackingStore::graphicsBuffer() const
|
||||||
{
|
{
|
||||||
|
@ -1208,23 +1208,34 @@ void QCocoaWindow::windowDidChangeScreen()
|
|||||||
if (!window())
|
if (!window())
|
||||||
return;
|
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)) {
|
Q_ASSERT_X(!m_view.window.screen || currentScreen,
|
||||||
if (newScreen == screen()) {
|
"QCocoaWindow", "Failed to get QCocoaScreen for NSScreen");
|
||||||
// Screen properties have changed. Will be handled by
|
|
||||||
// NSApplicationDidChangeScreenParametersNotification
|
|
||||||
// in QCocoaIntegration::updateScreens().
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(lcQpaWindow) << window() << "moved to" << newScreen;
|
// Note: The previous screen may be the same as the current screen, either because
|
||||||
QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
|
// 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)
|
qCDebug(lcQpaWindow) << "Screen changed for" << window() << "from" << previousScreen << "to" << currentScreen;
|
||||||
requestUpdate(); // Restart display-link on new screen
|
QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(
|
||||||
} else {
|
window(), currentScreen ? currentScreen->screen() : nullptr);
|
||||||
qCWarning(lcQpaWindow) << "Failed to get QCocoaScreen for" << m_view.window.screen;
|
|
||||||
|
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;
|
ulong timestamp = [theEvent timestamp] * 1000;
|
||||||
|
|
||||||
auto eventType = cocoaEvent2QtMouseEvent(theEvent);
|
const auto button = cocoaButton2QtButton(theEvent);
|
||||||
qCInfo(lcQpaMouse) << "Frame-strut" << eventType << "at" << qtWindowPoint << "with" << m_frameStrutButtons << "in" << self.window;
|
auto eventType = [&]() {
|
||||||
QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(), timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons);
|
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
|
@end
|
||||||
|
|
||||||
@ -472,12 +497,15 @@
|
|||||||
// uses the legacy cursorRect API, so the cursor is reset to the arrow
|
// uses the legacy cursorRect API, so the cursor is reset to the arrow
|
||||||
// cursor. See rdar://34183708
|
// cursor. See rdar://34183708
|
||||||
|
|
||||||
if (self.cursor && self.cursor != NSCursor.currentCursor) {
|
auto previousCursor = NSCursor.currentCursor;
|
||||||
qCInfo(lcQpaMouse) << "Updating cursor for" << self << "to" << self.cursor;
|
|
||||||
|
if (self.cursor)
|
||||||
[self.cursor set];
|
[self.cursor set];
|
||||||
} else {
|
else
|
||||||
[super cursorUpdate:theEvent];
|
[super cursorUpdate:theEvent];
|
||||||
}
|
|
||||||
|
if (NSCursor.currentCursor != previousCursor)
|
||||||
|
qCInfo(lcQpaMouse) << "Cursor update for" << self << "resulted in new cursor" << NSCursor.currentCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseMovedImpl:(NSEvent *)theEvent
|
- (void)mouseMovedImpl:(NSEvent *)theEvent
|
||||||
|
@ -51,7 +51,9 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*"));
|
|||||||
|
|
||||||
static QCocoaWindow *toPlatformWindow(NSWindow *window)
|
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
|
@implementation QNSWindowDelegate
|
||||||
|
@ -614,6 +614,9 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
|||||||
if (m_needsEnterOnPointerUpdate) {
|
if (m_needsEnterOnPointerUpdate) {
|
||||||
m_needsEnterOnPointerUpdate = false;
|
m_needsEnterOnPointerUpdate = false;
|
||||||
if (window != m_currentWindow) {
|
if (window != m_currentWindow) {
|
||||||
|
// make sure we subscribe to leave events for this window
|
||||||
|
trackLeave(hwnd);
|
||||||
|
|
||||||
QWindowSystemInterface::handleEnterEvent(window, localPos, globalPos);
|
QWindowSystemInterface::handleEnterEvent(window, localPos, globalPos);
|
||||||
m_currentWindow = window;
|
m_currentWindow = window;
|
||||||
if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(target))
|
if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(target))
|
||||||
|
@ -1876,6 +1876,9 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
|
|||||||
{
|
{
|
||||||
if (message == WM_ERASEBKGND) // Backing store - ignored.
|
if (message == WM_ERASEBKGND) // Backing store - ignored.
|
||||||
return true;
|
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
|
// Ignore invalid update bounding rectangles
|
||||||
RECT updateRect;
|
RECT updateRect;
|
||||||
if (!GetUpdateRect(m_data.hwnd, &updateRect, FALSE))
|
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) {
|
} else if (name.contains("uc-logic") && isTablet) {
|
||||||
tabletData.pointerType = QTabletEvent::Pen;
|
tabletData.pointerType = QTabletEvent::Pen;
|
||||||
dbgType = QLatin1String("pen");
|
dbgType = QLatin1String("pen");
|
||||||
|
} else if (name.contains("ugee")) {
|
||||||
|
isTablet = true;
|
||||||
|
tabletData.pointerType = QTabletEvent::Pen;
|
||||||
|
dbgType = QLatin1String("pen");
|
||||||
} else {
|
} else {
|
||||||
isTablet = false;
|
isTablet = false;
|
||||||
}
|
}
|
||||||
|
@ -454,6 +454,13 @@ QAccessible::Role QAccessibleDisplay::role() const
|
|||||||
return QAccessibleWidget::role();
|
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 QAccessibleDisplay::text(QAccessible::Text t) const
|
||||||
{
|
{
|
||||||
QString str;
|
QString str;
|
||||||
@ -732,10 +739,9 @@ QAccessible::State QAccessibleLineEdit::state() const
|
|||||||
QAccessible::State state = QAccessibleWidget::state();
|
QAccessible::State state = QAccessibleWidget::state();
|
||||||
|
|
||||||
QLineEdit *l = lineEdit();
|
QLineEdit *l = lineEdit();
|
||||||
|
state.editable = true;
|
||||||
if (l->isReadOnly())
|
if (l->isReadOnly())
|
||||||
state.readOnly = true;
|
state.readOnly = true;
|
||||||
else
|
|
||||||
state.editable = true;
|
|
||||||
|
|
||||||
if (l->echoMode() != QLineEdit::Normal)
|
if (l->echoMode() != QLineEdit::Normal)
|
||||||
state.passwordEdit = true;
|
state.passwordEdit = true;
|
||||||
|
@ -116,6 +116,7 @@ public:
|
|||||||
|
|
||||||
QString text(QAccessible::Text t) const override;
|
QString text(QAccessible::Text t) const override;
|
||||||
QAccessible::Role role() 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;
|
QVector<QPair<QAccessibleInterface*, QAccessible::Relation> >relations(QAccessible::Relation match = QAccessible::AllRelations) const override;
|
||||||
void *interface_cast(QAccessible::InterfaceType t) override;
|
void *interface_cast(QAccessible::InterfaceType t) override;
|
||||||
|
@ -1369,6 +1369,12 @@ void QLineEdit::setReadOnly(bool enable)
|
|||||||
QEvent event(QEvent::ReadOnlyChange);
|
QEvent event(QEvent::ReadOnlyChange);
|
||||||
QCoreApplication::sendEvent(this, &event);
|
QCoreApplication::sendEvent(this, &event);
|
||||||
update();
|
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->preeditString() != cursor.block().layout()->preeditAreaText()
|
||||||
|| e->replacementLength() > 0;
|
|| e->replacementLength() > 0;
|
||||||
|
|
||||||
|
int oldCursorPos = cursor.position();
|
||||||
|
|
||||||
cursor.beginEditBlock();
|
cursor.beginEditBlock();
|
||||||
if (isGettingInput) {
|
if (isGettingInput) {
|
||||||
cursor.removeSelectedText();
|
cursor.removeSelectedText();
|
||||||
@ -2076,6 +2078,8 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
|
|||||||
|
|
||||||
if (cursor.d)
|
if (cursor.d)
|
||||||
cursor.d->setX();
|
cursor.d->setX();
|
||||||
|
if (oldCursorPos != cursor.position())
|
||||||
|
emit q->cursorPositionChanged();
|
||||||
if (oldPreeditCursor != preeditCursor)
|
if (oldPreeditCursor != preeditCursor)
|
||||||
emit q->microFocusChanged();
|
emit q->microFocusChanged();
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtCore/QTime>
|
#include <QtCore/QTime>
|
||||||
#include <QtCore/QDeadlineTimer>
|
#include <QtCore/QDeadlineTimer>
|
||||||
|
#include <QtCore/QElapsedTimer>
|
||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
#if QT_HAS_INCLUDE(<chrono>)
|
#if QT_HAS_INCLUDE(<chrono>)
|
||||||
@ -50,6 +51,7 @@ private Q_SLOTS:
|
|||||||
void current();
|
void current();
|
||||||
void deadlines();
|
void deadlines();
|
||||||
void setDeadline();
|
void setDeadline();
|
||||||
|
void overflow();
|
||||||
void expire();
|
void expire();
|
||||||
void stdchrono();
|
void stdchrono();
|
||||||
};
|
};
|
||||||
@ -417,6 +419,83 @@ void tst_QDeadlineTimer::setDeadline()
|
|||||||
QCOMPARE(deadline.deadlineNSecs(), nsec);
|
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()
|
void tst_QDeadlineTimer::expire()
|
||||||
{
|
{
|
||||||
QFETCH_GLOBAL(Qt::TimerType, timerType);
|
QFETCH_GLOBAL(Qt::TimerType, timerType);
|
||||||
|
@ -2458,9 +2458,9 @@ void tst_QLocale::timeFormat()
|
|||||||
QCOMPARE(c.timeFormat(QLocale::NarrowFormat), c.timeFormat(QLocale::ShortFormat));
|
QCOMPARE(c.timeFormat(QLocale::NarrowFormat), c.timeFormat(QLocale::ShortFormat));
|
||||||
|
|
||||||
const QLocale no("no_NO");
|
const QLocale no("no_NO");
|
||||||
QCOMPARE(no.timeFormat(QLocale::NarrowFormat), QLatin1String("HH:mm"));
|
QCOMPARE(no.timeFormat(QLocale::NarrowFormat), QLatin1String("HH.mm"));
|
||||||
QCOMPARE(no.timeFormat(QLocale::ShortFormat), 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::LongFormat), QLatin1String("HH.mm.ss t"));
|
||||||
|
|
||||||
const QLocale id("id_ID");
|
const QLocale id("id_ID");
|
||||||
QCOMPARE(id.timeFormat(QLocale::ShortFormat), QLatin1String("HH.mm"));
|
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));
|
QCOMPARE(c.dateTimeFormat(QLocale::NarrowFormat), c.dateTimeFormat(QLocale::ShortFormat));
|
||||||
|
|
||||||
const QLocale no("no_NO");
|
const QLocale no("no_NO");
|
||||||
QCOMPARE(no.dateTimeFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy HH:mm"));
|
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::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::LongFormat), QLatin1String("dddd d. MMMM yyyy HH.mm.ss t"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QLocale::monthName()
|
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 <private/qrawfont_p.h>
|
||||||
#include <qpa/qplatformfontdatabase.h>
|
#include <qpa/qplatformfontdatabase.h>
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(lcTests, "qt.text.tests")
|
||||||
|
|
||||||
class tst_QFontDatabase : public QObject
|
class tst_QFontDatabase : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -49,6 +51,7 @@ private slots:
|
|||||||
|
|
||||||
void fixedPitch_data();
|
void fixedPitch_data();
|
||||||
void fixedPitch();
|
void fixedPitch();
|
||||||
|
void systemFixedFont();
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
void trickyFonts_data();
|
void trickyFonts_data();
|
||||||
@ -156,6 +159,16 @@ void tst_QFontDatabase::fixedPitch()
|
|||||||
QCOMPARE(fi.fixedPitch(), 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
|
#ifdef Q_OS_MAC
|
||||||
void tst_QFontDatabase::trickyFonts_data()
|
void tst_QFontDatabase::trickyFonts_data()
|
||||||
{
|
{
|
||||||
|
@ -2045,6 +2045,15 @@ void tst_QAccessibility::lineEditTest()
|
|||||||
QVERIFY(!iface->state().selectable);
|
QVERIFY(!iface->state().selectable);
|
||||||
QVERIFY(iface->state().selectableText);
|
QVERIFY(iface->state().selectableText);
|
||||||
QVERIFY(!iface->state().hasPopup);
|
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());
|
QCOMPARE(bool(iface->state().focused), le->hasFocus());
|
||||||
|
|
||||||
QString secret(QLatin1String("secret"));
|
QString secret(QLatin1String("secret"));
|
||||||
@ -3640,6 +3649,12 @@ void tst_QAccessibility::labelTest()
|
|||||||
QVERIFY(acc_label);
|
QVERIFY(acc_label);
|
||||||
|
|
||||||
QCOMPARE(acc_label->text(QAccessible::Name), text);
|
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();
|
QVector<QPair<QAccessibleInterface *, QAccessible::Relation> > rels = acc_label->relations();
|
||||||
QCOMPARE(rels.count(), 1);
|
QCOMPARE(rels.count(), 1);
|
||||||
|
@ -5,3 +5,4 @@ SOURCES += tst_qaccessibilitylinux.cpp
|
|||||||
|
|
||||||
QT += gui-private widgets dbus testlib accessibility_support-private linuxaccessibility_support-private
|
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 <QDBusInterface>
|
||||||
#include <QDBusReply>
|
#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 "bus_interface.h"
|
||||||
|
|
||||||
#include "dbusconnection_p.h"
|
|
||||||
#include "struct_marshallers_p.h"
|
|
||||||
|
|
||||||
#define COMPARE3(v1, v2, v3) QCOMPARE(v1, v3); QCOMPARE(v2, v3);
|
#define COMPARE3(v1, v2, v3) QCOMPARE(v1, v3); QCOMPARE(v2, v3);
|
||||||
|
|
||||||
class AccessibleTestWindow : public QWidget
|
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, "GetRoleName").arguments().first().toString(), QLatin1String("label"));
|
||||||
QCOMPARE(labelInterface->call(QDBus::Block, "GetRole").arguments().first().toUInt(), 29u);
|
QCOMPARE(labelInterface->call(QDBus::Block, "GetRole").arguments().first().toUInt(), 29u);
|
||||||
QCOMPARE(getParent(labelInterface), mainWindow->path());
|
QCOMPARE(getParent(labelInterface), mainWindow->path());
|
||||||
|
QVERIFY(!hasState(labelInterface, ATSPI_STATE_EDITABLE));
|
||||||
|
QVERIFY(hasState(labelInterface, ATSPI_STATE_READ_ONLY));
|
||||||
|
|
||||||
l->setText("New text");
|
l->setText("New text");
|
||||||
QCOMPARE(labelInterface->property("Name").toString(), l->text());
|
QCOMPARE(labelInterface->property("Name").toString(), l->text());
|
||||||
@ -303,6 +304,12 @@ void tst_QAccessibilityLinux::testLineEdit()
|
|||||||
QCOMPARE(lineEdit->selectionStart(), -1);
|
QCOMPARE(lineEdit->selectionStart(), -1);
|
||||||
QCOMPARE(textInterface->call(QDBus::Block, "GetNSelections").arguments().first().toInt(), 0);
|
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();
|
m_window->clearChildren();
|
||||||
delete accessibleInterface;
|
delete accessibleInterface;
|
||||||
delete textInterface;
|
delete textInterface;
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
<Incident type="pass" file="" line="0" />
|
<Incident type="pass" file="" line="0" />
|
||||||
<Duration msecs="0"/>
|
<Duration msecs="0"/>
|
||||||
</TestFunction>
|
</TestFunction>
|
||||||
|
<TestFunction name="wait">
|
||||||
|
<Incident type="pass" file="" line="0" />
|
||||||
|
<Duration msecs="0"/>
|
||||||
|
</TestFunction>
|
||||||
<TestFunction name="cleanupTestCase">
|
<TestFunction name="cleanupTestCase">
|
||||||
<Incident type="pass" file="" line="0" />
|
<Incident type="pass" file="" line="0" />
|
||||||
<Duration msecs="0"/>
|
<Duration msecs="0"/>
|
||||||
|
@ -2,8 +2,9 @@ TAP version 13
|
|||||||
# tst_Sleep
|
# tst_Sleep
|
||||||
ok 1 - initTestCase()
|
ok 1 - initTestCase()
|
||||||
ok 2 - sleep()
|
ok 2 - sleep()
|
||||||
ok 3 - cleanupTestCase()
|
ok 3 - wait()
|
||||||
1..3
|
ok 4 - cleanupTestCase()
|
||||||
# tests 3
|
1..4
|
||||||
# pass 3
|
# tests 4
|
||||||
|
# pass 4
|
||||||
# fail 0
|
# fail 0
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
##teamcity[testFinished name='initTestCase()' flowId='tst_Sleep']
|
##teamcity[testFinished name='initTestCase()' flowId='tst_Sleep']
|
||||||
##teamcity[testStarted name='sleep()' flowId='tst_Sleep']
|
##teamcity[testStarted name='sleep()' flowId='tst_Sleep']
|
||||||
##teamcity[testFinished 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[testStarted name='cleanupTestCase()' flowId='tst_Sleep']
|
||||||
##teamcity[testFinished name='cleanupTestCase()' flowId='tst_Sleep']
|
##teamcity[testFinished name='cleanupTestCase()' flowId='tst_Sleep']
|
||||||
##teamcity[testSuiteFinished name='tst_Sleep' flowId='tst_Sleep']
|
##teamcity[testSuiteFinished name='tst_Sleep' flowId='tst_Sleep']
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
Config: Using QtTest library
|
Config: Using QtTest library
|
||||||
PASS : tst_Sleep::initTestCase()
|
PASS : tst_Sleep::initTestCase()
|
||||||
PASS : tst_Sleep::sleep()
|
PASS : tst_Sleep::sleep()
|
||||||
|
PASS : tst_Sleep::wait()
|
||||||
PASS : tst_Sleep::cleanupTestCase()
|
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 *********
|
********* Finished testing of tst_Sleep *********
|
||||||
|
@ -13,6 +13,10 @@
|
|||||||
<Incident type="pass" file="" line="0" />
|
<Incident type="pass" file="" line="0" />
|
||||||
<Duration msecs="0"/>
|
<Duration msecs="0"/>
|
||||||
</TestFunction>
|
</TestFunction>
|
||||||
|
<TestFunction name="wait">
|
||||||
|
<Incident type="pass" file="" line="0" />
|
||||||
|
<Duration msecs="0"/>
|
||||||
|
</TestFunction>
|
||||||
<TestFunction name="cleanupTestCase">
|
<TestFunction name="cleanupTestCase">
|
||||||
<Incident type="pass" file="" line="0" />
|
<Incident type="pass" file="" line="0" />
|
||||||
<Duration msecs="0"/>
|
<Duration msecs="0"/>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?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>
|
<properties>
|
||||||
<property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
|
<property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
|
||||||
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
|
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
|
||||||
@ -7,6 +7,7 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<testcase result="pass" name="initTestCase"/>
|
<testcase result="pass" name="initTestCase"/>
|
||||||
<testcase result="pass" name="sleep"/>
|
<testcase result="pass" name="sleep"/>
|
||||||
|
<testcase result="pass" name="wait"/>
|
||||||
<testcase result="pass" name="cleanupTestCase"/>
|
<testcase result="pass" name="cleanupTestCase"/>
|
||||||
<system-err/>
|
<system-err/>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
@ -36,6 +36,7 @@ class tst_Sleep: public QObject
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void sleep();
|
void sleep();
|
||||||
|
void wait();
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_Sleep::sleep()
|
void tst_Sleep::sleep()
|
||||||
@ -53,6 +54,24 @@ void tst_Sleep::sleep()
|
|||||||
QVERIFY(t.elapsed() > 1000 * 10);
|
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)
|
QTEST_MAIN(tst_Sleep)
|
||||||
|
|
||||||
#include "tst_sleep.moc"
|
#include "tst_sleep.moc"
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
The CLDR data can be downloaded from CLDR_, which has a sub-directory
|
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
|
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
|
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:
|
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
|
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
|
command-line argument. Save its standard output (but not error) to a
|
||||||
|
@ -53,7 +53,21 @@ def ordStr(c):
|
|||||||
def fixOrdStr(c, d):
|
def fixOrdStr(c, d):
|
||||||
return str(ord(c if len(c) == 1 else 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):
|
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 = ""
|
result = ""
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(format):
|
while i < len(format):
|
||||||
@ -68,20 +82,30 @@ def convertFormat(format):
|
|||||||
i += 1
|
i += 1
|
||||||
else:
|
else:
|
||||||
s = format[i:]
|
s = format[i:]
|
||||||
if s.startswith("EEEE"):
|
if s.startswith('E'): # week-day
|
||||||
result += "dddd"
|
n = startCount('E', s)
|
||||||
i += 4
|
if n < 3:
|
||||||
elif s.startswith("EEE"):
|
result += 'ddd'
|
||||||
result += "ddd"
|
elif n == 4:
|
||||||
i += 3
|
result += 'dddd'
|
||||||
elif s.startswith("a"):
|
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"
|
result += "AP"
|
||||||
i += 1
|
i += startCount('ab', s)
|
||||||
elif s.startswith("z"):
|
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"
|
result += "t"
|
||||||
i += 1
|
i += startCount('zv', s)
|
||||||
elif s.startswith("v"):
|
|
||||||
i += 1
|
|
||||||
else:
|
else:
|
||||||
result += format[i]
|
result += format[i]
|
||||||
i += 1
|
i += 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user