Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp Change-Id: I6b82507bf9a80a374c40393e72f4843f1557de89
This commit is contained in:
commit
a4a7c1bcf7
@ -29,16 +29,18 @@
|
||||
\example widgets/shapedclock
|
||||
\title Shaped Clock Example
|
||||
\ingroup examples-widgets
|
||||
\brief The Shaped Clock example shows how to apply a widget mask to a top-level
|
||||
widget to produce a shaped window.
|
||||
\brief The Shaped Clock example shows how to apply a translucent background
|
||||
and a widget mask to a top-level widget to produce a shaped window.
|
||||
|
||||
\borderedimage shapedclock-example.png
|
||||
|
||||
Widget masks are used to customize the shapes of top-level widgets by restricting
|
||||
the available area for painting. On some window systems, setting certain window flags
|
||||
will cause the window decoration (title bar, window frame, buttons) to be disabled,
|
||||
allowing specially-shaped windows to be created. In this example, we use this feature
|
||||
to create a circular window containing an analog clock.
|
||||
Widget masks are used to customize the shapes of top-level widgets by
|
||||
restricting the area available for painting and mouse input. Using a
|
||||
translucent background facilitates partially transparent windows and smooth
|
||||
edges. On most window systems, setting certain window flags will cause the
|
||||
window decoration (title bar, window frame, buttons) to be disabled,
|
||||
allowing specially-shaped windows to be created. In this example, we use
|
||||
this feature to create a circular window containing an analog clock.
|
||||
|
||||
Since this example's window does not provide a \uicontrol File menu or a close
|
||||
button, we provide a context menu with an \uicontrol Exit entry so that the example
|
||||
@ -52,8 +54,10 @@
|
||||
|
||||
\snippet widgets/shapedclock/shapedclock.h 0
|
||||
|
||||
The \l{QWidget::paintEvent()}{paintEvent()} implementation is the same as that found
|
||||
in the \c AnalogClock class. We implement \l{QWidget::sizeHint()}{sizeHint()}
|
||||
The \l{QWidget::paintEvent()}{paintEvent()} implementation is the same as
|
||||
that found in the \c AnalogClock class, with one important exception: we
|
||||
now must also draw background (the clock face) ourselves, since the widget
|
||||
background is just transparent. We implement \l{QWidget::sizeHint()}{sizeHint()}
|
||||
so that we don't have to resize the widget explicitly. We also provide an event
|
||||
handler for resize events. This allows us to update the mask if the clock is resized.
|
||||
|
||||
@ -70,9 +74,11 @@
|
||||
|
||||
\snippet widgets/shapedclock/shapedclock.cpp 0
|
||||
|
||||
We inform the window manager that the widget is not to be decorated with a window
|
||||
frame by setting the Qt::FramelessWindowHint flag on the widget. As a result, we need
|
||||
to provide a way for the user to move the clock around the screen.
|
||||
We request a transparent window by setting the Qt::WA_TranslucentBackground
|
||||
widget attribute. We inform the window manager that the widget is not to be
|
||||
decorated with a window frame by setting the Qt::FramelessWindowHint flag
|
||||
on the widget. As a result, we need to provide a way for the user to move
|
||||
the clock around the screen.
|
||||
|
||||
Mouse button events are delivered to the \c mousePressEvent() handler:
|
||||
|
||||
@ -94,14 +100,20 @@
|
||||
widget is moved to the point given by subtracting the \c dragPosition from the current
|
||||
cursor position in global coordinates. If we drag the widget, we also accept the event.
|
||||
|
||||
The \c paintEvent() function is given for completeness. See the
|
||||
\l{Analog Clock Example}{Analog Clock} example for a description of the process used
|
||||
to render the clock.
|
||||
The \c paintEvent() function is mainly the same as described in the
|
||||
\l{Analog Clock Example}{Analog Clock} example. The one addition is that we
|
||||
use QPainter::drawEllipse() to draw a round clock face with the current
|
||||
palette's default background color. We make the clock face a bit smaller
|
||||
than the widget mask, so that the anti-aliased, semi-transparent pixels on
|
||||
the edge are not clipped away by the widget mask. This gives the shaped
|
||||
window smooth edges on the screen.
|
||||
|
||||
\snippet widgets/shapedclock/shapedclock.cpp 3
|
||||
|
||||
In the \c resizeEvent() handler, we re-use some of the code from the \c paintEvent()
|
||||
to determine the region of the widget that is visible to the user:
|
||||
In the \c resizeEvent() handler, we re-use some of the code from the \c
|
||||
paintEvent() to determine the region of the widget that is visible to the
|
||||
user. This tells the system the area where mouse clicks should go to us,
|
||||
and not to whatever window is behind us:
|
||||
|
||||
\snippet widgets/shapedclock/shapedclock.cpp 4
|
||||
|
||||
@ -121,6 +133,12 @@
|
||||
|
||||
\section1 Notes on Widget Masks
|
||||
|
||||
Widget masks are used to hint to the window system that the application
|
||||
does not want mouse events for areas outside the mask. On most systems,
|
||||
they also result in coarse visual clipping. To get smooth window edges, one
|
||||
should use translucent background and anti-aliased painting, as shown in
|
||||
this example.
|
||||
|
||||
Since QRegion allows arbitrarily complex regions to be created, widget masks can be
|
||||
made to suit the most unconventionally-shaped windows, and even allow widgets to be
|
||||
displayed with holes in them.
|
||||
|
@ -61,6 +61,7 @@
|
||||
ShapedClock::ShapedClock(QWidget *parent)
|
||||
: QWidget(parent, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint)
|
||||
{
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
QTimer *timer = new QTimer(this);
|
||||
connect(timer, &QTimer::timeout, this, QOverload<>::of(&ShapedClock::update));
|
||||
timer->start(1000);
|
||||
@ -122,6 +123,10 @@ void ShapedClock::paintEvent(QPaintEvent *)
|
||||
painter.translate(width() / 2, height() / 2);
|
||||
painter.scale(side / 200.0, side / 200.0);
|
||||
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(palette().window());
|
||||
painter.drawEllipse(QPoint(0, 0), 98, 98);
|
||||
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(hourColor);
|
||||
|
||||
@ -168,6 +173,6 @@ void ShapedClock::resizeEvent(QResizeEvent * /* event */)
|
||||
//! [5]
|
||||
QSize ShapedClock::sizeHint() const
|
||||
{
|
||||
return QSize(100, 100);
|
||||
return QSize(200, 200);
|
||||
}
|
||||
//! [5]
|
||||
|
@ -71,7 +71,7 @@ contains(TEMPLATE, .*app) {
|
||||
# replacing the app name placeholder with the actual app name.
|
||||
apphtml.name = application main html file
|
||||
apphtml.output = $$DESTDIR/$$TARGET_HTML
|
||||
apphtml.commands = sed -e s/@APPNAME@/$$TARGET_BASE/g $$WASM_PLUGIN_PATH/wasm_shell.html > $$DESTDIR/$$TARGET_HTML
|
||||
apphtml.commands = $$QMAKE_STREAM_EDITOR -e s/@APPNAME@/$$TARGET_BASE/g $$WASM_PLUGIN_PATH/wasm_shell.html > $$DESTDIR/$$TARGET_HTML
|
||||
apphtml.input = $$WASM_PLUGIN_PATH/wasm_shell.html
|
||||
apphtml.depends = $$apphtml.input
|
||||
QMAKE_EXTRA_COMPILERS += apphtml
|
||||
|
@ -25,7 +25,7 @@ EMTERP_FLAGS = \
|
||||
-s ASSERTIONS=1 \
|
||||
--profiling-funcs
|
||||
|
||||
EMCC_COMMON_LFLAGS = \
|
||||
EMCC_COMMON_LFLAGS += \
|
||||
-s WASM=1 \
|
||||
-s FULL_ES2=1 \
|
||||
-s FULL_ES3=1 \
|
||||
|
@ -154,7 +154,7 @@ static int doSed(int argc, char **argv)
|
||||
FILE *f;
|
||||
if (!strcmp(inFile, "-")) {
|
||||
f = stdin;
|
||||
} else if (!(f = fopen(inFile, "r"))) {
|
||||
} else if (!(f = fopen(inFile, "rb"))) {
|
||||
perror(inFile);
|
||||
return 1;
|
||||
}
|
||||
|
@ -492,6 +492,39 @@
|
||||
# error "Qt has not been tested with this compiler - see http://www.qt-project.org/"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SG10's SD-6 feature detection and some useful extensions from Clang and GCC
|
||||
* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
|
||||
* http://clang.llvm.org/docs/LanguageExtensions.html#feature-checking-macros
|
||||
* Not using wrapper macros, per http://eel.is/c++draft/cpp.cond#7.sentence-2
|
||||
*/
|
||||
#ifndef __has_builtin
|
||||
# define __has_builtin(x) 0
|
||||
#endif
|
||||
#ifndef __has_feature
|
||||
# define __has_feature(x) 0
|
||||
#endif
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0
|
||||
#endif
|
||||
#ifndef __has_cpp_attribute
|
||||
# define __has_cpp_attribute(x) 0
|
||||
#endif
|
||||
#ifndef __has_include
|
||||
# define __has_include(x) 0
|
||||
#endif
|
||||
#ifndef __has_include_next
|
||||
# define __has_include_next(x) 0
|
||||
#endif
|
||||
|
||||
// Kept around until all submodules have transitioned
|
||||
#define QT_HAS_BUILTIN(x) __has_builtin(x)
|
||||
#define QT_HAS_FEATURE(x) __has_feature(x)
|
||||
#define QT_HAS_ATTRIBUTE(x) __has_attribute(x)
|
||||
#define QT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
||||
#define QT_HAS_INCLUDE(x) __has_include(x)
|
||||
#define QT_HAS_INCLUDE_NEXT(x) __has_include_next(x)
|
||||
|
||||
/*
|
||||
* C++11 support
|
||||
*
|
||||
@ -1018,37 +1051,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SG10's SD-6 feature detection and some useful extensions from Clang and GCC
|
||||
* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
|
||||
* http://clang.llvm.org/docs/LanguageExtensions.html#feature-checking-macros
|
||||
*/
|
||||
#ifdef __has_builtin
|
||||
# define QT_HAS_BUILTIN(x) __has_builtin(x)
|
||||
#else
|
||||
# define QT_HAS_BUILTIN(x) 0
|
||||
#endif
|
||||
#ifdef __has_attribute
|
||||
# define QT_HAS_ATTRIBUTE(x) __has_attribute(x)
|
||||
#else
|
||||
# define QT_HAS_ATTRIBUTE(x) 0
|
||||
#endif
|
||||
#ifdef __has_cpp_attribute
|
||||
# define QT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
||||
#else
|
||||
# define QT_HAS_CPP_ATTRIBUTE(x) 0
|
||||
#endif
|
||||
#ifdef __has_include
|
||||
# define QT_HAS_INCLUDE(x) __has_include(x)
|
||||
#else
|
||||
# define QT_HAS_INCLUDE(x) 0
|
||||
#endif
|
||||
#ifdef __has_include_next
|
||||
# define QT_HAS_INCLUDE_NEXT(x) __has_include_next(x)
|
||||
#else
|
||||
# define QT_HAS_INCLUDE_NEXT(x) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* C++11 keywords and expressions
|
||||
*/
|
||||
@ -1123,7 +1125,7 @@
|
||||
# define Q_DECL_ALIGN(n) alignas(n)
|
||||
#endif
|
||||
|
||||
#if QT_HAS_CPP_ATTRIBUTE(nodiscard) && !defined(Q_CC_CLANG) // P0188R1
|
||||
#if __has_cpp_attribute(nodiscard) && !defined(Q_CC_CLANG) // P0188R1
|
||||
// Can't use [[nodiscard]] with Clang, see https://bugs.llvm.org/show_bug.cgi?id=33518
|
||||
# undef Q_REQUIRED_RESULT
|
||||
# define Q_REQUIRED_RESULT [[nodiscard]]
|
||||
@ -1225,11 +1227,6 @@
|
||||
#ifndef QT_MAKE_CHECKED_ARRAY_ITERATOR
|
||||
# define QT_MAKE_CHECKED_ARRAY_ITERATOR(x, N) (x)
|
||||
#endif
|
||||
#ifdef __has_feature
|
||||
# define QT_HAS_FEATURE(x) __has_feature(x)
|
||||
#else
|
||||
# define QT_HAS_FEATURE(x) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Warning/diagnostic handling
|
||||
@ -1320,11 +1317,11 @@
|
||||
} while (false)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#if QT_HAS_CPP_ATTRIBUTE(clang::fallthrough)
|
||||
#if __has_cpp_attribute(clang::fallthrough)
|
||||
# define Q_FALLTHROUGH() [[clang::fallthrough]]
|
||||
#elif QT_HAS_CPP_ATTRIBUTE(gnu::fallthrough)
|
||||
#elif __has_cpp_attribute(gnu::fallthrough)
|
||||
# define Q_FALLTHROUGH() [[gnu::fallthrough]]
|
||||
#elif QT_HAS_CPP_ATTRIBUTE(fallthrough)
|
||||
#elif __has_cpp_attribute(fallthrough)
|
||||
# define Q_FALLTHROUGH() [[fallthrough]]
|
||||
#endif
|
||||
#endif
|
||||
|
@ -77,13 +77,13 @@
|
||||
#define QT_FEATURE_binaryjson -1
|
||||
#define QT_FEATURE_cborstream -1
|
||||
#define QT_CRYPTOGRAPHICHASH_ONLY_SHA1
|
||||
#define QT_FEATURE_cxx11_random (QT_HAS_INCLUDE(<random>) ? 1 : -1)
|
||||
#define QT_FEATURE_cxx11_random (__has_include(<random>) ? 1 : -1)
|
||||
#define QT_NO_DATASTREAM
|
||||
#define QT_FEATURE_datestring 1
|
||||
#define QT_FEATURE_datetimeparser -1
|
||||
#define QT_FEATURE_easingcurve -1
|
||||
#define QT_FEATURE_etw -1
|
||||
#define QT_FEATURE_getauxval (QT_HAS_INCLUDE(<sys/auxv.h>) ? 1 : -1)
|
||||
#define QT_FEATURE_getauxval (__has_include(<sys/auxv.h>) ? 1 : -1)
|
||||
#define QT_FEATURE_getentropy -1
|
||||
#define QT_NO_GEOM_VARIANT
|
||||
#define QT_FEATURE_hijricalendar -1
|
||||
|
@ -66,7 +66,7 @@ template <typename T> Q_ALWAYS_INLINE void qToUnaligned(const T src, void *dest)
|
||||
// Using sizeof(T) inside memcpy function produces internal compiler error with
|
||||
// MSVC2008/ARM in tst_endian -> use extra indirection to resolve size of T.
|
||||
const size_t size = sizeof(T);
|
||||
#if QT_HAS_BUILTIN(__builtin_memcpy)
|
||||
#if __has_builtin(__builtin_memcpy)
|
||||
__builtin_memcpy
|
||||
#else
|
||||
memcpy
|
||||
@ -78,7 +78,7 @@ template <typename T> Q_ALWAYS_INLINE T qFromUnaligned(const void *src)
|
||||
{
|
||||
T dest;
|
||||
const size_t size = sizeof(T);
|
||||
#if QT_HAS_BUILTIN(__builtin_memcpy)
|
||||
#if __has_builtin(__builtin_memcpy)
|
||||
__builtin_memcpy
|
||||
#else
|
||||
memcpy
|
||||
|
@ -92,7 +92,7 @@
|
||||
# include <sys/systeminfo.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_DARWIN) && QT_HAS_INCLUDE(<IOKit/IOKitLib.h>)
|
||||
#if defined(Q_OS_DARWIN) && __has_include(<IOKit/IOKitLib.h>)
|
||||
# include <IOKit/IOKitLib.h>
|
||||
# include <private/qcore_mac_p.h>
|
||||
#endif
|
||||
@ -3067,7 +3067,7 @@ enum {
|
||||
*/
|
||||
QByteArray QSysInfo::machineUniqueId()
|
||||
{
|
||||
#if defined(Q_OS_DARWIN) && QT_HAS_INCLUDE(<IOKit/IOKitLib.h>)
|
||||
#if defined(Q_OS_DARWIN) && __has_include(<IOKit/IOKitLib.h>)
|
||||
char uuid[UuidStringLen + 1];
|
||||
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
|
||||
QCFString stringRef = (CFStringRef)IORegistryEntryCreateCFProperty(service, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
|
||||
|
@ -717,7 +717,7 @@ inline void qt_noop(void) {}
|
||||
|
||||
#if !defined(QT_NO_EXCEPTIONS)
|
||||
# if !defined(Q_MOC_RUN)
|
||||
# if (defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !QT_HAS_FEATURE(cxx_exceptions)) || \
|
||||
# if (defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !__has_feature(cxx_exceptions)) || \
|
||||
(defined(Q_CC_GNU) && !defined(__EXCEPTIONS))
|
||||
# define QT_NO_EXCEPTIONS
|
||||
# endif
|
||||
|
@ -74,7 +74,7 @@ Q_CORE_EXPORT time_t qMkTime(struct tm *when);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#if !QT_HAS_BUILTIN(__builtin_available)
|
||||
#if !__has_builtin(__builtin_available)
|
||||
#include <initializer_list>
|
||||
#include <QtCore/qoperatingsystemversion.h>
|
||||
#include <QtCore/qversionnumber.h>
|
||||
@ -142,7 +142,7 @@ QT_END_NAMESPACE
|
||||
QT_BUILTIN_AVAILABLE1, \
|
||||
QT_BUILTIN_AVAILABLE0, )
|
||||
#define __builtin_available(...) QT_BUILTIN_AVAILABLE_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
|
||||
#endif // !QT_HAS_BUILTIN(__builtin_available)
|
||||
#endif // !__has_builtin(__builtin_available)
|
||||
#endif // defined(__cplusplus)
|
||||
|
||||
#endif // QGLOBAL_P_H
|
||||
|
@ -70,7 +70,7 @@
|
||||
#if QT_CONFIG(slog2)
|
||||
#include <sys/slog2.h>
|
||||
#endif
|
||||
#if QT_HAS_INCLUDE(<paths.h>)
|
||||
#if __has_include(<paths.h>)
|
||||
#include <paths.h>
|
||||
#endif
|
||||
|
||||
@ -106,7 +106,7 @@
|
||||
# if __UCLIBC_HAS_BACKTRACE__
|
||||
# define QLOGGING_HAVE_BACKTRACE
|
||||
# endif
|
||||
# elif (defined(__GLIBC__) && defined(__GLIBCXX__)) || (QT_HAS_INCLUDE(<cxxabi.h>) && QT_HAS_INCLUDE(<execinfo.h>))
|
||||
# elif (defined(__GLIBC__) && defined(__GLIBCXX__)) || (__has_include(<cxxabi.h>) && __has_include(<execinfo.h>))
|
||||
# define QLOGGING_HAVE_BACKTRACE
|
||||
# endif
|
||||
#endif
|
||||
@ -116,7 +116,7 @@ extern char *__progname;
|
||||
#endif
|
||||
|
||||
#ifndef QT_BOOTSTRAPPED
|
||||
#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || QT_HAS_INCLUDE(<sys/syscall.h>))
|
||||
#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || __has_include(<sys/syscall.h>))
|
||||
# include <sys/syscall.h>
|
||||
|
||||
# if defined(Q_OS_ANDROID) && !defined(SYS_gettid)
|
||||
@ -1276,7 +1276,7 @@ void QMessagePattern::setPattern(const QString &pattern)
|
||||
#if defined(QLOGGING_HAVE_BACKTRACE) && !defined(QT_BOOTSTRAPPED)
|
||||
// make sure the function has "Message" in the name so the function is removed
|
||||
|
||||
#if ((defined(Q_CC_GNU) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) || QT_HAS_ATTRIBUTE(optimize)) \
|
||||
#if ((defined(Q_CC_GNU) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) || __has_attribute(optimize)) \
|
||||
&& !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
|
||||
// force skipping the frame pointer, to save the backtrace() function some work
|
||||
__attribute__((optimize("omit-frame-pointer")))
|
||||
|
@ -253,7 +253,7 @@ QT_WARNING_POP
|
||||
// size_t. Implementations for 8- and 16-bit types will work but may not be as
|
||||
// efficient. Implementations for 64-bit may be missing on 32-bit platforms.
|
||||
|
||||
#if (defined(Q_CC_GNU) && (Q_CC_GNU >= 500) || (defined(Q_CC_INTEL) && !defined(Q_OS_WIN))) || QT_HAS_BUILTIN(__builtin_add_overflow)
|
||||
#if (defined(Q_CC_GNU) && (Q_CC_GNU >= 500) || (defined(Q_CC_INTEL) && !defined(Q_OS_WIN))) || __has_builtin(__builtin_add_overflow)
|
||||
// GCC 5, ICC 18, and Clang 3.8 have builtins to detect overflows
|
||||
|
||||
template <typename T> inline
|
||||
|
@ -55,7 +55,7 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if QT_HAS_INCLUDE(<paths.h>)
|
||||
#if __has_include(<paths.h>)
|
||||
# include <paths.h>
|
||||
#endif
|
||||
#ifndef _PATH_TMP // from <paths.h>
|
||||
|
@ -100,7 +100,7 @@ QT_END_NAMESPACE
|
||||
#include <private/qcore_unix_p.h>
|
||||
#endif
|
||||
|
||||
#if QT_HAS_INCLUDE(<paths.h>)
|
||||
#if __has_include(<paths.h>)
|
||||
#include <paths.h>
|
||||
#endif
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
||||
#include <qcoreapplication.h>
|
||||
#endif
|
||||
|
||||
#if QT_HAS_INCLUDE(<paths.h>)
|
||||
#if __has_include(<paths.h>)
|
||||
#include <paths.h>
|
||||
#endif
|
||||
|
||||
|
@ -108,7 +108,7 @@
|
||||
# endif // QT_LARGEFILE_SUPPORT
|
||||
#endif // Q_OS_BSD4
|
||||
|
||||
#if QT_HAS_INCLUDE(<paths.h>)
|
||||
#if __has_include(<paths.h>)
|
||||
# include <paths.h>
|
||||
#endif
|
||||
#ifndef _PATH_MOUNTED
|
||||
|
@ -52,7 +52,7 @@
|
||||
|
||||
#include <limits>
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
# include <chrono>
|
||||
#endif
|
||||
|
||||
@ -120,7 +120,7 @@ public:
|
||||
QDeadlineTimer &operator-=(qint64 msecs)
|
||||
{ *this = *this + (-msecs); return *this; }
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>) || defined(Q_CLANG_QDOC)
|
||||
#if __has_include(<chrono>) || defined(Q_CLANG_QDOC)
|
||||
template <class Clock, class Duration>
|
||||
QDeadlineTimer(std::chrono::time_point<Clock, Duration> deadline_,
|
||||
Qt::TimerType type_ = Qt::CoarseTimer) : t2(0)
|
||||
|
@ -55,7 +55,7 @@
|
||||
|
||||
#include <QtCore/qobject_impl.h>
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
# include <chrono>
|
||||
#endif
|
||||
|
||||
@ -154,7 +154,7 @@ public:
|
||||
void moveToThread(QThread *thread);
|
||||
|
||||
int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
Q_ALWAYS_INLINE
|
||||
int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer)
|
||||
{
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include <QtCore/qbasictimer.h> // conceptual inheritance
|
||||
#include <QtCore/qobject.h>
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
# include <chrono>
|
||||
#endif
|
||||
|
||||
@ -177,7 +177,7 @@ Q_SIGNALS:
|
||||
void timeout(QPrivateSignal);
|
||||
|
||||
public:
|
||||
#if QT_HAS_INCLUDE(<chrono>) || defined(Q_QDOC)
|
||||
#if __has_include(<chrono>) || defined(Q_QDOC)
|
||||
void setInterval(std::chrono::milliseconds value)
|
||||
{
|
||||
setInterval(int(value.count()));
|
||||
@ -223,7 +223,7 @@ private:
|
||||
static void singleShotImpl(int msec, Qt::TimerType timerType,
|
||||
const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj);
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
static Qt::TimerType defaultTypeFor(std::chrono::milliseconds interval)
|
||||
{ return defaultTypeFor(int(interval.count())); }
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
||||
#include <QtCore/qbytearraylist.h>
|
||||
#endif
|
||||
|
||||
#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
|
||||
#if __has_include(<variant>) && __cplusplus >= 201703L
|
||||
#include <variant>
|
||||
#elif defined(Q_CLANG_QDOC)
|
||||
namespace std { template<typename...> struct variant; }
|
||||
@ -372,7 +372,7 @@ class Q_CORE_EXPORT QVariant
|
||||
static inline QVariant fromValue(const T &value)
|
||||
{ return QVariant(qMetaTypeId<T>(), &value, QTypeInfo<T>::isPointer); }
|
||||
|
||||
#if (QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L) || defined(Q_CLANG_QDOC)
|
||||
#if (__has_include(<variant>) && __cplusplus >= 201703L) || defined(Q_CLANG_QDOC)
|
||||
template<typename... Types>
|
||||
static inline QVariant fromStdVariant(const std::variant<Types...> &value)
|
||||
{
|
||||
@ -538,7 +538,7 @@ inline QVariant QVariant::fromValue(const QVariant &value)
|
||||
return value;
|
||||
}
|
||||
|
||||
#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
|
||||
#if __has_include(<variant>) && __cplusplus >= 201703L
|
||||
template<>
|
||||
inline QVariant QVariant::fromValue(const std::monostate &)
|
||||
{
|
||||
|
@ -214,7 +214,7 @@ public:
|
||||
bool contains(const QCborValue &value) const;
|
||||
|
||||
int compare(const QCborArray &other) const noexcept Q_DECL_PURE_FUNCTION;
|
||||
#if 0 && QT_HAS_INCLUDE(<compare>)
|
||||
#if 0 && __has_include(<compare>)
|
||||
std::strong_ordering operator<=>(const QCborArray &other) const
|
||||
{
|
||||
int c = compare(other);
|
||||
|
@ -245,7 +245,7 @@ public:
|
||||
{ const_iterator it = find(key); return it != end(); }
|
||||
|
||||
int compare(const QCborMap &other) const noexcept Q_DECL_PURE_FUNCTION;
|
||||
#if 0 && QT_HAS_INCLUDE(<compare>)
|
||||
#if 0 && __has_include(<compare>)
|
||||
std::strong_ordering operator<=>(const QCborMap &other) const
|
||||
{
|
||||
int c = compare(other);
|
||||
|
@ -59,7 +59,7 @@
|
||||
# undef False
|
||||
#endif
|
||||
|
||||
#if 0 && QT_HAS_INCLUDE(<compare>)
|
||||
#if 0 && __has_include(<compare>)
|
||||
# include <compare>
|
||||
#endif
|
||||
|
||||
@ -265,7 +265,7 @@ public:
|
||||
QCborValueRef operator[](const QString & key);
|
||||
|
||||
int compare(const QCborValue &other) const;
|
||||
#if 0 && QT_HAS_INCLUDE(<compare>)
|
||||
#if 0 && __has_include(<compare>)
|
||||
std::strong_ordering operator<=>(const QCborValue &other) const
|
||||
{
|
||||
int c = compare(other);
|
||||
@ -421,7 +421,7 @@ public:
|
||||
|
||||
int compare(const QCborValue &other) const
|
||||
{ return concrete().compare(other); }
|
||||
#if 0 && QT_HAS_INCLUDE(<compare>)
|
||||
#if 0 && __has_include(<compare>)
|
||||
std::strong_ordering operator<=>(const QCborValue &other) const
|
||||
{
|
||||
int c = compare(other);
|
||||
|
@ -196,8 +196,7 @@ public:
|
||||
if (value.container)
|
||||
return replaceAt_complex(e, value, disp);
|
||||
|
||||
e.value = value.value_helper();
|
||||
e.type = value.type();
|
||||
e = { value.value_helper(), value.type() };
|
||||
if (value.isContainer())
|
||||
e.container = nullptr;
|
||||
}
|
||||
|
@ -334,7 +334,7 @@ int qstricmp(const char *str1, const char *str2)
|
||||
return int(Incomplete);
|
||||
};
|
||||
|
||||
#if defined(__SSE4_1__) && !(defined(__SANITIZE_ADDRESS__) || QT_HAS_FEATURE(address_sanitizer))
|
||||
#if defined(__SSE4_1__) && !(defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer))
|
||||
enum { PageSize = 4096, PageMask = PageSize - 1 };
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
forever {
|
||||
|
@ -243,7 +243,7 @@ public:
|
||||
void chop(int n);
|
||||
|
||||
#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP) && !defined(Q_CLANG_QDOC)
|
||||
# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !QT_HAS_CPP_ATTRIBUTE(nodiscard)
|
||||
# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !__has_cpp_attribute(nodiscard)
|
||||
// required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941
|
||||
# pragma push_macro("Q_REQUIRED_RESULT")
|
||||
# undef Q_REQUIRED_RESULT
|
||||
|
@ -146,6 +146,9 @@ qsizetype qFindStringBoyerMoore(QStringView haystack, qsizetype from, QStringVie
|
||||
static inline qsizetype qFindChar(QStringView str, QChar ch, qsizetype from, Qt::CaseSensitivity cs) noexcept;
|
||||
template <typename Haystack>
|
||||
static inline qsizetype qLastIndexOf(Haystack haystack, QChar needle, qsizetype from, Qt::CaseSensitivity cs) noexcept;
|
||||
template <>
|
||||
inline qsizetype qLastIndexOf(QString haystack, QChar needle,
|
||||
qsizetype from, Qt::CaseSensitivity cs) noexcept = delete; // unwanted, would detach
|
||||
static inline qsizetype qt_string_count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs);
|
||||
static inline qsizetype qt_string_count(QStringView haystack, QChar needle, Qt::CaseSensitivity cs);
|
||||
|
||||
@ -3813,7 +3816,7 @@ int QString::indexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs) co
|
||||
int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) const
|
||||
{
|
||||
// ### Qt6: qsizetype
|
||||
return int(QtPrivate::lastIndexOf(*this, from, str, cs));
|
||||
return int(QtPrivate::lastIndexOf(QStringView(*this), from, str, cs));
|
||||
}
|
||||
|
||||
#endif // QT_STRINGVIEW_LEVEL < 2
|
||||
@ -3852,7 +3855,7 @@ int QString::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) co
|
||||
int QString::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
|
||||
{
|
||||
// ### Qt6: qsizetype
|
||||
return int(qLastIndexOf(*this, ch, from, cs));
|
||||
return int(qLastIndexOf(QStringView(*this), ch, from, cs));
|
||||
}
|
||||
|
||||
#if QT_STRINGVIEW_LEVEL < 2
|
||||
|
@ -485,7 +485,7 @@ public:
|
||||
Q_REQUIRED_RESULT QString rightJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const;
|
||||
|
||||
#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP) && !defined(Q_CLANG_QDOC)
|
||||
# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !QT_HAS_CPP_ATTRIBUTE(nodiscard)
|
||||
# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !__has_cpp_attribute(nodiscard)
|
||||
// required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941
|
||||
# pragma push_macro("Q_REQUIRED_RESULT")
|
||||
# undef Q_REQUIRED_RESULT
|
||||
|
@ -81,7 +81,7 @@ QT_END_NAMESPACE
|
||||
// if not defined in linux/futex.h
|
||||
# define FUTEX_PRIVATE_FLAG 128 // added in v2.6.22
|
||||
|
||||
# if QT_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__)
|
||||
# if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)
|
||||
# include <sanitizer/tsan_interface.h>
|
||||
inline void _q_tsan_acquire(void *addr, void *addr2)
|
||||
{
|
||||
@ -98,7 +98,7 @@ inline void _q_tsan_release(void *addr, void *addr2)
|
||||
# else
|
||||
inline void _q_tsan_acquire(void *, void *) {}
|
||||
inline void _q_tsan_release(void *, void *) {}
|
||||
# endif // QT_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__)
|
||||
# endif // __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace QtLinuxFutex {
|
||||
|
@ -44,7 +44,7 @@
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <new>
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
# include <chrono>
|
||||
# include <limits>
|
||||
#endif
|
||||
@ -147,7 +147,7 @@ public:
|
||||
// Lockable concept
|
||||
bool try_lock() QT_MUTEX_LOCK_NOEXCEPT { return tryLock(); }
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>) || defined(Q_CLANG_QDOC)
|
||||
#if __has_include(<chrono>) || defined(Q_CLANG_QDOC)
|
||||
// TimedLockable concept
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_for(std::chrono::duration<Rep, Period> duration)
|
||||
@ -175,7 +175,7 @@ private:
|
||||
friend class QRecursiveMutex;
|
||||
friend class ::tst_QMutex;
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
template<class Rep, class Period>
|
||||
static int convertToMilliseconds(std::chrono::duration<Rep, Period> duration)
|
||||
{
|
||||
@ -213,7 +213,7 @@ public:
|
||||
using QMutex::tryLock;
|
||||
using QMutex::unlock;
|
||||
using QMutex::try_lock;
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
using QMutex::try_lock_for;
|
||||
using QMutex::try_lock_until;
|
||||
#endif
|
||||
@ -295,7 +295,7 @@ public:
|
||||
inline void unlock() noexcept {}
|
||||
inline bool isRecursive() const noexcept { return true; }
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
template <class Rep, class Period>
|
||||
inline bool try_lock_for(std::chrono::duration<Rep, Period> duration) noexcept
|
||||
{
|
||||
|
@ -127,7 +127,7 @@ static const char qt_shortMonthNames[][4] = {
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
static int qt_monthNumberFromShortName(QStringRef shortName)
|
||||
static int qt_monthNumberFromShortName(QStringView shortName)
|
||||
{
|
||||
for (unsigned int i = 0; i < sizeof(qt_shortMonthNames) / sizeof(qt_shortMonthNames[0]); ++i) {
|
||||
if (shortName == QLatin1String(qt_shortMonthNames[i], 3))
|
||||
@ -136,9 +136,9 @@ static int qt_monthNumberFromShortName(QStringRef shortName)
|
||||
return -1;
|
||||
}
|
||||
static int qt_monthNumberFromShortName(const QString &shortName)
|
||||
{ return qt_monthNumberFromShortName(QStringRef(&shortName)); }
|
||||
{ return qt_monthNumberFromShortName(QStringView(shortName)); }
|
||||
|
||||
static int fromShortMonthName(const QStringRef &monthName, int year)
|
||||
static int fromShortMonthName(QStringView monthName, int year)
|
||||
{
|
||||
// Assume that English monthnames are the default
|
||||
int month = qt_monthNumberFromShortName(monthName);
|
||||
@ -207,7 +207,7 @@ static QString toOffsetString(Qt::DateFormat format, int offset)
|
||||
|
||||
#if QT_CONFIG(datestring)
|
||||
// Parse offset in [+-]HH[[:]mm] format
|
||||
static int fromOffsetString(const QStringRef &offsetString, bool *valid) noexcept
|
||||
static int fromOffsetString(QStringView offsetString, bool *valid) noexcept
|
||||
{
|
||||
*valid = false;
|
||||
|
||||
@ -228,22 +228,23 @@ static int fromOffsetString(const QStringRef &offsetString, bool *valid) noexcep
|
||||
return 0;
|
||||
|
||||
// Split the hour and minute parts
|
||||
const QStringRef time = offsetString.mid(1);
|
||||
int hhLen = time.indexOf(QLatin1Char(':'));
|
||||
int mmIndex;
|
||||
const QStringView time = offsetString.mid(1);
|
||||
qsizetype hhLen = time.indexOf(QLatin1Char(':'));
|
||||
qsizetype mmIndex;
|
||||
if (hhLen == -1)
|
||||
mmIndex = hhLen = 2; // [+-]HHmm or [+-]HH format
|
||||
else
|
||||
mmIndex = hhLen + 1;
|
||||
|
||||
const QStringRef hhRef = time.left(hhLen);
|
||||
const QLocale C = QLocale::c();
|
||||
const QStringView hhRef = time.left(qMin(hhLen, time.size()));
|
||||
bool ok = false;
|
||||
const int hour = hhRef.toInt(&ok);
|
||||
const int hour = C.toInt(hhRef, &ok);
|
||||
if (!ok)
|
||||
return 0;
|
||||
|
||||
const QStringRef mmRef = time.mid(mmIndex);
|
||||
const int minute = mmRef.isEmpty() ? 0 : mmRef.toInt(&ok);
|
||||
const QStringView mmRef = time.mid(qMin(mmIndex, time.size()));
|
||||
const int minute = mmRef.isEmpty() ? 0 : C.toInt(mmRef, &ok);
|
||||
if (!ok || minute < 0 || minute > 59)
|
||||
return 0;
|
||||
|
||||
@ -2324,7 +2325,7 @@ int QTime::msecsTo(const QTime &t) const
|
||||
|
||||
#if QT_CONFIG(datestring)
|
||||
|
||||
static QTime fromIsoTimeString(const QStringRef &string, Qt::DateFormat format, bool *isMidnight24)
|
||||
static QTime fromIsoTimeString(QStringView string, Qt::DateFormat format, bool *isMidnight24)
|
||||
{
|
||||
if (isMidnight24)
|
||||
*isMidnight24 = false;
|
||||
@ -2333,11 +2334,12 @@ static QTime fromIsoTimeString(const QStringRef &string, Qt::DateFormat format,
|
||||
if (size < 5)
|
||||
return QTime();
|
||||
|
||||
const QLocale C(QLocale::c());
|
||||
bool ok = false;
|
||||
int hour = string.mid(0, 2).toInt(&ok);
|
||||
int hour = C.toInt(string.mid(0, 2), &ok);
|
||||
if (!ok)
|
||||
return QTime();
|
||||
const int minute = string.mid(3, 2).toInt(&ok);
|
||||
const int minute = C.toInt(string.mid(3, 2), &ok);
|
||||
if (!ok)
|
||||
return QTime();
|
||||
int second = 0;
|
||||
@ -2358,11 +2360,11 @@ static QTime fromIsoTimeString(const QStringRef &string, Qt::DateFormat format,
|
||||
// seconds is 4. E.g. 12:34,99999 will expand to 12:34:59.9994. The milliseconds
|
||||
// will then be rounded up AND clamped to 999.
|
||||
|
||||
const QStringRef minuteFractionStr = string.mid(6, 5);
|
||||
const long minuteFractionInt = minuteFractionStr.toLong(&ok);
|
||||
const QStringView minuteFractionStr = string.mid(6, qMin(qsizetype(5), string.size() - 6));
|
||||
const long minuteFractionInt = C.toLong(minuteFractionStr, &ok);
|
||||
if (!ok)
|
||||
return QTime();
|
||||
const float minuteFraction = double(minuteFractionInt) / (std::pow(double(10), minuteFractionStr.count()));
|
||||
const float minuteFraction = double(minuteFractionInt) / (std::pow(double(10), minuteFractionStr.size()));
|
||||
|
||||
const float secondWithMs = minuteFraction * 60;
|
||||
const float secondNoMs = std::floor(secondWithMs);
|
||||
@ -2371,15 +2373,20 @@ static QTime fromIsoTimeString(const QStringRef &string, Qt::DateFormat format,
|
||||
msec = qMin(qRound(secondFraction * 1000.0), 999);
|
||||
} else {
|
||||
// HH:mm:ss or HH:mm:ss.zzz
|
||||
second = string.mid(6, 2).toInt(&ok);
|
||||
second = C.toInt(string.mid(6, qMin(qsizetype(2), string.size() - 6)), &ok);
|
||||
if (!ok)
|
||||
return QTime();
|
||||
if (size > 8 && (string.at(8) == QLatin1Char(',') || string.at(8) == QLatin1Char('.'))) {
|
||||
const QStringRef msecStr(string.mid(9, 4));
|
||||
int msecInt = msecStr.isEmpty() ? 0 : msecStr.toInt(&ok);
|
||||
QStringView msecStr(string.mid(9, qMin(qsizetype(4), string.size() - 9)));
|
||||
// toInt() ignores leading spaces, so catch them before calling it
|
||||
if (!msecStr.isEmpty() && !msecStr.at(0).isDigit())
|
||||
return QTime();
|
||||
// We do, however, want to ignore *trailing* spaces.
|
||||
msecStr = msecStr.trimmed();
|
||||
int msecInt = msecStr.isEmpty() ? 0 : C.toInt(msecStr, &ok);
|
||||
if (!ok)
|
||||
return QTime();
|
||||
const double secondFraction(msecInt / (std::pow(double(10), msecStr.count())));
|
||||
const double secondFraction(msecInt / (std::pow(double(10), msecStr.size())));
|
||||
msec = qMin(qRound(secondFraction * 1000.0), 999);
|
||||
}
|
||||
}
|
||||
@ -2428,7 +2435,7 @@ QTime QTime::fromString(const QString &string, Qt::DateFormat format)
|
||||
case Qt::ISODateWithMs:
|
||||
case Qt::TextDate:
|
||||
default:
|
||||
return fromIsoTimeString(QStringRef(&string), format, nullptr);
|
||||
return fromIsoTimeString(QStringView(string), format, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3410,6 +3417,7 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
|
||||
DaylightStatus hint,
|
||||
QDate *zoneDate, QTime *zoneTime)
|
||||
{
|
||||
Q_ASSERT(zone.isValid());
|
||||
// Get the effective data from QTimeZone
|
||||
QTimeZonePrivate::Data data = zone.d->dataForLocalTime(zoneMSecs, int(hint));
|
||||
// Docs state any time before 1970-01-01 will *not* have any DST applied
|
||||
@ -3799,8 +3807,9 @@ QTimeZone QDateTime::timeZone() const
|
||||
case Qt::OffsetFromUTC:
|
||||
return QTimeZone(d->m_offsetFromUtc);
|
||||
case Qt::TimeZone:
|
||||
Q_ASSERT(d->m_timeZone.isValid());
|
||||
return d->m_timeZone;
|
||||
if (d->m_timeZone.isValid())
|
||||
return d->m_timeZone;
|
||||
break;
|
||||
case Qt::LocalTime:
|
||||
return QTimeZone::systemTimeZone();
|
||||
}
|
||||
@ -3884,6 +3893,7 @@ QString QDateTime::timeZoneAbbreviation() const
|
||||
#if !QT_CONFIG(timezone)
|
||||
break;
|
||||
#else
|
||||
Q_ASSERT(d->m_timeZone.isValid());
|
||||
return d->m_timeZone.d->abbreviation(toMSecsSinceEpoch());
|
||||
#endif // timezone
|
||||
case Qt::LocalTime: {
|
||||
@ -3920,6 +3930,7 @@ bool QDateTime::isDaylightTime() const
|
||||
#if !QT_CONFIG(timezone)
|
||||
break;
|
||||
#else
|
||||
Q_ASSERT(d->m_timeZone.isValid());
|
||||
return d->m_timeZone.d->isDaylightTime(toMSecsSinceEpoch());
|
||||
#endif // timezone
|
||||
case Qt::LocalTime: {
|
||||
@ -4044,6 +4055,10 @@ void QDateTime::setTimeZone(const QTimeZone &toZone)
|
||||
*/
|
||||
qint64 QDateTime::toMSecsSinceEpoch() const
|
||||
{
|
||||
// Note: QDateTimeParser relies on this producing a useful result, even when
|
||||
// !isValid(), at least when the invalidity is a time in a fall-back (that
|
||||
// we'll have adjusted to lie outside it, but marked invalid because it's
|
||||
// not what was asked for). Other things may be doing similar.
|
||||
switch (getSpec(d)) {
|
||||
case Qt::UTC:
|
||||
return getMSecs(d);
|
||||
@ -4058,12 +4073,13 @@ qint64 QDateTime::toMSecsSinceEpoch() const
|
||||
}
|
||||
|
||||
case Qt::TimeZone:
|
||||
#if !QT_CONFIG(timezone)
|
||||
return 0;
|
||||
#else
|
||||
return QDateTimePrivate::zoneMSecsToEpochMSecs(d->m_msecs, d->m_timeZone,
|
||||
extractDaylightStatus(getStatus(d)));
|
||||
#if QT_CONFIG(timezone)
|
||||
if (d->m_timeZone.isValid()) {
|
||||
return QDateTimePrivate::zoneMSecsToEpochMSecs(d->m_msecs, d->m_timeZone,
|
||||
extractDaylightStatus(getStatus(d)));
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
Q_UNREACHABLE();
|
||||
return 0;
|
||||
@ -4158,9 +4174,11 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs)
|
||||
case Qt::TimeZone:
|
||||
Q_ASSERT(!d.isShort());
|
||||
#if QT_CONFIG(timezone)
|
||||
d.detach();
|
||||
if (!d->m_timeZone.isValid())
|
||||
break;
|
||||
// Docs state any LocalTime before 1970-01-01 will *not* have any DST applied
|
||||
// but all affected times afterwards will have DST applied.
|
||||
d.detach();
|
||||
if (msecs >= 0) {
|
||||
status = mergeDaylightStatus(status,
|
||||
d->m_timeZone.d->isDaylightTime(msecs)
|
||||
@ -4433,7 +4451,7 @@ static inline void massageAdjustedDateTime(const QDateTimeData &d, QDate *date,
|
||||
QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime;
|
||||
localMSecsToEpochMSecs(timeToMSecs(*date, *time), &status, date, time);
|
||||
#if QT_CONFIG(timezone)
|
||||
} else if (spec == Qt::TimeZone) {
|
||||
} else if (spec == Qt::TimeZone && d->m_timeZone.isValid()) {
|
||||
QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(*date, *time),
|
||||
d->m_timeZone,
|
||||
QDateTimePrivate::UnknownDaylightTime,
|
||||
@ -5094,7 +5112,8 @@ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone
|
||||
{
|
||||
QDateTime dt;
|
||||
dt.setTimeZone(timeZone);
|
||||
dt.setMSecsSinceEpoch(msecs);
|
||||
if (timeZone.isValid())
|
||||
dt.setMSecsSinceEpoch(msecs);
|
||||
return dt;
|
||||
}
|
||||
|
||||
@ -5197,16 +5216,17 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
|
||||
if (!date.isValid())
|
||||
return QDateTime();
|
||||
if (size == 10)
|
||||
return QDateTime(date);
|
||||
return date.startOfDay();
|
||||
|
||||
Qt::TimeSpec spec = Qt::LocalTime;
|
||||
QStringRef isoString(&string);
|
||||
isoString = isoString.mid(10); // trim "yyyy-MM-dd"
|
||||
QStringView isoString = QStringView(string).mid(10); // trim "yyyy-MM-dd"
|
||||
|
||||
// Must be left with T and at least one digit for the hour:
|
||||
// Must be left with T (or space) and at least one digit for the hour:
|
||||
if (isoString.size() < 2
|
||||
|| !(isoString.startsWith(QLatin1Char('T'))
|
||||
// FIXME: QSql relies on QVariant::toDateTime() accepting a space here:
|
||||
|| !(isoString.startsWith(QLatin1Char('T'), Qt::CaseInsensitive)
|
||||
// RFC 3339 (section 5.6) allows a space here. (It actually
|
||||
// allows any separator one considers more readable, merely
|
||||
// giving space as an example - but let's not go wild !)
|
||||
|| isoString.startsWith(QLatin1Char(' ')))) {
|
||||
return QDateTime();
|
||||
}
|
||||
@ -5214,7 +5234,7 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
|
||||
|
||||
int offset = 0;
|
||||
// Check end of string for Time Zone definition, either Z for UTC or [+-]HH:mm for Offset
|
||||
if (isoString.endsWith(QLatin1Char('Z'))) {
|
||||
if (isoString.endsWith(QLatin1Char('Z'), Qt::CaseInsensitive)) {
|
||||
spec = Qt::UTC;
|
||||
isoString.chop(1); // trim 'Z'
|
||||
} else {
|
||||
@ -5345,7 +5365,7 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
|
||||
if (parts.count() == 5)
|
||||
return QDateTime(date, time, Qt::LocalTime);
|
||||
|
||||
QStringRef tz = parts.at(5);
|
||||
QStringView tz = parts.at(5);
|
||||
if (!tz.startsWith(QLatin1String("GMT"), Qt::CaseInsensitive))
|
||||
return QDateTime();
|
||||
tz = tz.mid(3);
|
||||
|
@ -1363,7 +1363,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
|
||||
// given date (which might be a spring-forward, skipping an hour).
|
||||
if (parserType == QVariant::DateTime && !(isSet & HourSectionMask) && !when.isValid()) {
|
||||
qint64 msecs = when.toMSecsSinceEpoch();
|
||||
// Fortunately, that gets a useful answer ...
|
||||
// Fortunately, that gets a useful answer, even though when is invalid ...
|
||||
const QDateTime replace =
|
||||
#if QT_CONFIG(timezone)
|
||||
tspec == Qt::TimeZone
|
||||
|
@ -381,18 +381,15 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
|
||||
On the first pass, the case we consider is what hint told us to expect
|
||||
(except when hint was -1 and didn't actually tell us what to expect),
|
||||
so it's likely right. We only get a second pass if the first failed,
|
||||
by which time the second case, that we're trying, is likely right. If
|
||||
an overwhelming majority of calls have hint == -1, the Q_LIKELY here
|
||||
shall be wrong half the time; otherwise, its errors shall be rarer
|
||||
than that.
|
||||
by which time the second case, that we're trying, is likely right.
|
||||
*/
|
||||
if (nextFirst ? i == 0 : i) {
|
||||
Q_ASSERT(nextStart != invalidMSecs());
|
||||
if (Q_LIKELY(nextStart <= nextTran.atMSecsSinceEpoch))
|
||||
if (nextStart <= nextTran.atMSecsSinceEpoch)
|
||||
return nextTran;
|
||||
} else {
|
||||
// If next is invalid, nextFirst is false, to route us here first:
|
||||
if (nextStart == invalidMSecs() || Q_LIKELY(nextStart > tran.atMSecsSinceEpoch))
|
||||
if (nextStart == invalidMSecs() || nextStart > tran.atMSecsSinceEpoch)
|
||||
return tran;
|
||||
}
|
||||
}
|
||||
@ -421,7 +418,7 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
|
||||
|
||||
int early = offsetFromUtc(recent);
|
||||
int late = offsetFromUtc(imminent);
|
||||
if (Q_LIKELY(early == late)) { // > 99% of the time
|
||||
if (early == late) { // > 99% of the time
|
||||
utcEpochMSecs = forLocalMSecs - early * 1000;
|
||||
} else {
|
||||
// Close to a DST transition: early > late is near a fall-back,
|
||||
@ -433,7 +430,7 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
|
||||
const qint64 forStd = forLocalMSecs - offsetInStd * 1000;
|
||||
// Best guess at the answer:
|
||||
const qint64 hinted = hint > 0 ? forDst : forStd;
|
||||
if (Q_LIKELY(offsetFromUtc(hinted) == (hint > 0 ? offsetInDst : offsetInStd))) {
|
||||
if (offsetFromUtc(hinted) == (hint > 0 ? offsetInDst : offsetInStd)) {
|
||||
utcEpochMSecs = hinted;
|
||||
} else if (hint <= 0 && offsetFromUtc(forDst) == offsetInDst) {
|
||||
utcEpochMSecs = forDst;
|
||||
|
@ -535,7 +535,7 @@ QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessItera
|
||||
# define QT_HAS_BUILTIN_CTZS
|
||||
Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) noexcept
|
||||
{
|
||||
# if QT_HAS_BUILTIN(__builtin_ctzs)
|
||||
# if __has_builtin(__builtin_ctzs)
|
||||
return __builtin_ctzs(v);
|
||||
# else
|
||||
return __builtin_ctz(v);
|
||||
@ -544,7 +544,7 @@ Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) noexcept
|
||||
#define QT_HAS_BUILTIN_CLZS
|
||||
Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) noexcept
|
||||
{
|
||||
# if QT_HAS_BUILTIN(__builtin_clzs)
|
||||
# if __has_builtin(__builtin_clzs)
|
||||
return __builtin_clzs(v);
|
||||
# else
|
||||
return __builtin_clz(v) - 16U;
|
||||
|
@ -51,7 +51,7 @@ template <typename F> QScopeGuard<F> qScopeGuard(F f);
|
||||
|
||||
template <typename F>
|
||||
class
|
||||
#if QT_HAS_CPP_ATTRIBUTE(nodiscard)
|
||||
#if __has_cpp_attribute(nodiscard)
|
||||
// Q_REQUIRED_RESULT can be defined as __warn_unused_result__ or as [[nodiscard]]
|
||||
// but the 1st one has some limitations for example can be placed only on functions.
|
||||
Q_REQUIRED_RESULT
|
||||
@ -91,7 +91,7 @@ private:
|
||||
|
||||
|
||||
template <typename F>
|
||||
#if QT_HAS_CPP_ATTRIBUTE(nodiscard)
|
||||
#if __has_cpp_attribute(nodiscard)
|
||||
Q_REQUIRED_RESULT
|
||||
#endif
|
||||
QScopeGuard<F> qScopeGuard(F f)
|
||||
|
@ -131,6 +131,14 @@ void QPlatformCursor::setPos(const QPoint &pos)
|
||||
QWindowSystemInterface::handleMouseEvent(nullptr, pos, pos, Qt::NoButton, Qt::NoButton, QEvent::MouseMove);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the size of the cursor, in native pixels.
|
||||
*/
|
||||
QSize QPlatformCursor::size() const
|
||||
{
|
||||
return QSize(16, 16);
|
||||
}
|
||||
|
||||
// End of display and pointer event handling code
|
||||
// Beginning of built-in cursor graphics
|
||||
// from src/gui/embedded/QGraphicsSystemCursorImage_qws.cpp
|
||||
|
@ -96,6 +96,7 @@ public:
|
||||
#endif // QT_NO_CURSOR
|
||||
virtual QPoint pos() const;
|
||||
virtual void setPos(const QPoint &pos);
|
||||
virtual QSize size() const;
|
||||
|
||||
static Capabilities capabilities() { return m_capabilities; }
|
||||
static void setCapabilities(Capabilities c) { m_capabilities = c; }
|
||||
|
@ -784,10 +784,12 @@ QDebug operator<<(QDebug dbg, const QColorSpace &colorSpace)
|
||||
QDebugStateSaver saver(dbg);
|
||||
dbg.nospace();
|
||||
dbg << "QColorSpace(";
|
||||
if (colorSpace.d_ptr->namedColorSpace)
|
||||
dbg << colorSpace.d_ptr->namedColorSpace << ", ";
|
||||
dbg << colorSpace.primaries() << ", " << colorSpace.transferFunction();
|
||||
dbg << ", gamma=" << colorSpace.gamma();
|
||||
if (colorSpace.d_ptr) {
|
||||
if (colorSpace.d_ptr->namedColorSpace)
|
||||
dbg << colorSpace.d_ptr->namedColorSpace << ", ";
|
||||
dbg << colorSpace.primaries() << ", " << colorSpace.transferFunction();
|
||||
dbg << ", gamma=" << colorSpace.gamma();
|
||||
}
|
||||
dbg << ')';
|
||||
return dbg;
|
||||
}
|
||||
|
@ -2428,7 +2428,15 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
|
||||
f->glUniformMatrix2fv(uniform.glslLocation, 1, GL_FALSE, reinterpret_cast<const float *>(src));
|
||||
break;
|
||||
case QShaderDescription::Mat3:
|
||||
f->glUniformMatrix3fv(uniform.glslLocation, 1, GL_FALSE, reinterpret_cast<const float *>(src));
|
||||
{
|
||||
// 4 floats per column (or row, if row-major)
|
||||
float mat[9];
|
||||
const float *srcMat = reinterpret_cast<const float *>(src);
|
||||
memcpy(mat, srcMat, 3 * sizeof(float));
|
||||
memcpy(mat + 3, srcMat + 4, 3 * sizeof(float));
|
||||
memcpy(mat + 6, srcMat + 8, 3 * sizeof(float));
|
||||
f->glUniformMatrix3fv(uniform.glslLocation, 1, GL_FALSE, mat);
|
||||
}
|
||||
break;
|
||||
case QShaderDescription::Mat4:
|
||||
f->glUniformMatrix4fv(uniform.glslLocation, 1, GL_FALSE, reinterpret_cast<const float *>(src));
|
||||
@ -2919,21 +2927,64 @@ bool QRhiGles2::linkProgram(GLuint program)
|
||||
return true;
|
||||
}
|
||||
|
||||
void QRhiGles2::gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub,
|
||||
void QRhiGles2::registerUniformIfActive(const QShaderDescription::BlockVariable &var,
|
||||
const QByteArray &namePrefix,
|
||||
int binding,
|
||||
int baseOffset,
|
||||
GLuint program,
|
||||
QVector<QGles2UniformDescription> *dst)
|
||||
{
|
||||
if (var.type == QShaderDescription::Struct) {
|
||||
qWarning("Nested structs are not supported at the moment. '%s' ignored.",
|
||||
qPrintable(var.name));
|
||||
return;
|
||||
}
|
||||
QGles2UniformDescription uniform;
|
||||
uniform.type = var.type;
|
||||
const QByteArray name = namePrefix + var.name.toUtf8();
|
||||
uniform.glslLocation = f->glGetUniformLocation(program, name.constData());
|
||||
if (uniform.glslLocation >= 0) {
|
||||
uniform.binding = binding;
|
||||
uniform.offset = uint(baseOffset + var.offset);
|
||||
uniform.size = var.size;
|
||||
dst->append(uniform);
|
||||
}
|
||||
}
|
||||
|
||||
void QRhiGles2::gatherUniforms(GLuint program,
|
||||
const QShaderDescription::UniformBlock &ub,
|
||||
QVector<QGles2UniformDescription> *dst)
|
||||
{
|
||||
const QByteArray prefix = ub.structName.toUtf8() + '.';
|
||||
QByteArray prefix = ub.structName.toUtf8() + '.';
|
||||
for (const QShaderDescription::BlockVariable &blockMember : ub.members) {
|
||||
// ### no array support for now
|
||||
QGles2UniformDescription uniform;
|
||||
uniform.type = blockMember.type;
|
||||
const QByteArray name = prefix + blockMember.name.toUtf8();
|
||||
uniform.glslLocation = f->glGetUniformLocation(program, name.constData());
|
||||
if (uniform.glslLocation >= 0) {
|
||||
uniform.binding = ub.binding;
|
||||
uniform.offset = uint(blockMember.offset);
|
||||
uniform.size = blockMember.size;
|
||||
dst->append(uniform);
|
||||
if (blockMember.type == QShaderDescription::Struct) {
|
||||
prefix += blockMember.name.toUtf8();
|
||||
const int baseOffset = blockMember.offset;
|
||||
if (blockMember.arrayDims.isEmpty()) {
|
||||
for (const QShaderDescription::BlockVariable &structMember : blockMember.structMembers)
|
||||
registerUniformIfActive(structMember, prefix, ub.binding, baseOffset, program, dst);
|
||||
} else {
|
||||
if (blockMember.arrayDims.count() > 1) {
|
||||
qWarning("Array of struct '%s' has more than one dimension. Only the first dimension is used.",
|
||||
qPrintable(blockMember.name));
|
||||
}
|
||||
const int dim = blockMember.arrayDims.first();
|
||||
const int elemSize = blockMember.size / dim;
|
||||
int elemOffset = baseOffset;
|
||||
for (int di = 0; di < dim; ++di) {
|
||||
const QByteArray arrayPrefix = prefix + '[' + QByteArray::number(di) + ']' + '.';
|
||||
for (const QShaderDescription::BlockVariable &structMember : blockMember.structMembers)
|
||||
registerUniformIfActive(structMember, arrayPrefix, ub.binding, elemOffset, program, dst);
|
||||
elemOffset += elemSize;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!blockMember.arrayDims.isEmpty()) {
|
||||
qWarning("Arrays are only supported for structs at the moment. '%s' ignored.",
|
||||
qPrintable(blockMember.name));
|
||||
continue;
|
||||
}
|
||||
registerUniformIfActive(blockMember, prefix, ub.binding, 0, program, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -706,7 +706,14 @@ public:
|
||||
QByteArray shaderSource(const QRhiShaderStage &shaderStage, int *glslVersion);
|
||||
bool compileShader(GLuint program, const QRhiShaderStage &shaderStage, int *glslVersion);
|
||||
bool linkProgram(GLuint program);
|
||||
void gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub,
|
||||
void registerUniformIfActive(const QShaderDescription::BlockVariable &var,
|
||||
const QByteArray &namePrefix,
|
||||
int binding,
|
||||
int baseOffset,
|
||||
GLuint program,
|
||||
QVector<QGles2UniformDescription> *dst);
|
||||
void gatherUniforms(GLuint program,
|
||||
const QShaderDescription::UniformBlock &ub,
|
||||
QVector<QGles2UniformDescription> *dst);
|
||||
void gatherSamplers(GLuint program, const QShaderDescription::InOutVariable &v,
|
||||
QVector<QGles2SamplerDescription> *dst);
|
||||
|
@ -3215,7 +3215,10 @@ id<MTLLibrary> QRhiMetalData::createMetalLib(const QShader &shader, QShader::Var
|
||||
[opts release];
|
||||
// src is autoreleased
|
||||
|
||||
if (err) {
|
||||
// if lib is null and err is non-null, we had errors (fail)
|
||||
// if lib is non-null and err is non-null, we had warnings (success)
|
||||
// if lib is non-null and err is null, there were no errors or warnings (success)
|
||||
if (!lib) {
|
||||
const QString msg = QString::fromNSString(err.localizedDescription);
|
||||
*error = msg;
|
||||
return nil;
|
||||
|
@ -2261,6 +2261,7 @@ void QTextCursor::insertFragment(const QTextDocumentFragment &fragment)
|
||||
d->remove();
|
||||
fragment.d->insert(*this);
|
||||
d->priv->endEditBlock();
|
||||
d->setX();
|
||||
|
||||
if (fragment.d && fragment.d->doc)
|
||||
d->priv->mergeCachedResources(fragment.d->doc->docHandle());
|
||||
|
@ -347,7 +347,19 @@ QTextDocument *QTextDocument::clone(QObject *parent) const
|
||||
{
|
||||
Q_D(const QTextDocument);
|
||||
QTextDocument *doc = new QTextDocument(parent);
|
||||
QTextCursor(doc).insertFragment(QTextDocumentFragment(this));
|
||||
if (isEmpty()) {
|
||||
const QTextCursor thisCursor(const_cast<QTextDocument *>(this));
|
||||
|
||||
const auto blockFormat = thisCursor.blockFormat();
|
||||
if (blockFormat.isValid() && !blockFormat.isEmpty())
|
||||
QTextCursor(doc).setBlockFormat(blockFormat);
|
||||
|
||||
const auto blockCharFormat = thisCursor.blockCharFormat();
|
||||
if (blockCharFormat.isValid() && !blockCharFormat.isEmpty())
|
||||
QTextCursor(doc).setBlockCharFormat(blockCharFormat);
|
||||
} else {
|
||||
QTextCursor(doc).insertFragment(QTextDocumentFragment(this));
|
||||
}
|
||||
doc->rootFrame()->setFrameFormat(rootFrame()->frameFormat());
|
||||
QTextDocumentPrivate *priv = doc->d_func();
|
||||
priv->title = d->title;
|
||||
|
@ -67,7 +67,7 @@ void QCocoaClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
|
||||
}
|
||||
|
||||
pasteBoard->sync();
|
||||
pasteBoard->setMimeData(data);
|
||||
pasteBoard->setMimeData(data, QMacPasteboard::LazyRequest);
|
||||
emitChanged(mode);
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,9 @@ public:
|
||||
void changeCursor(QCursor *cursor, QWindow *window) override;
|
||||
QPoint pos() const override;
|
||||
void setPos(const QPoint &position) override;
|
||||
|
||||
QSize size() const override;
|
||||
|
||||
private:
|
||||
QHash<Qt::CursorShape, NSCursor *> m_cursors;
|
||||
NSCursor *convertCursor(QCursor *cursor);
|
||||
|
@ -85,6 +85,31 @@ void QCocoaCursor::setPos(const QPoint &position)
|
||||
CFRelease(e);
|
||||
}
|
||||
|
||||
|
||||
QSize QCocoaCursor::size() const
|
||||
{
|
||||
NSCursor *cocoaCursor = NSCursor.currentSystemCursor;
|
||||
if (!cocoaCursor)
|
||||
return QPlatformCursor::size();
|
||||
NSImage *cursorImage = cocoaCursor.image;
|
||||
if (!cursorImage)
|
||||
return QPlatformCursor::size();
|
||||
|
||||
QSizeF size = QSizeF::fromCGSize(cursorImage.size);
|
||||
NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults;
|
||||
NSDictionary *accessSettings = [defaults persistentDomainForName:@"com.apple.universalaccess"];
|
||||
if (accessSettings == nil)
|
||||
return size.toSize();
|
||||
|
||||
float sizeScale = [accessSettings[@"mouseDriverCursorSize"] floatValue];
|
||||
if (sizeScale > 0) {
|
||||
size.rwidth() *= sizeScale;
|
||||
size.rheight() *= sizeScale;
|
||||
}
|
||||
|
||||
return size.toSize();
|
||||
}
|
||||
|
||||
NSCursor *QCocoaCursor::convertCursor(QCursor *cursor)
|
||||
{
|
||||
if (!cursor)
|
||||
|
@ -186,6 +186,7 @@ public:
|
||||
QAtomicInt serialNumber;
|
||||
int lastSerial;
|
||||
bool interrupt;
|
||||
bool propagateInterrupt = false;
|
||||
|
||||
static void postedEventsSourceCallback(void *info);
|
||||
static void waitingObserverCallback(CFRunLoopObserverRef observer,
|
||||
|
@ -84,13 +84,12 @@
|
||||
#include "private/qthread_p.h"
|
||||
#include "private/qguiapplication_p.h"
|
||||
#include <qdebug.h>
|
||||
#include <qscopeguard.h>
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
static inline CFRunLoopRef mainRunLoop()
|
||||
{
|
||||
return CFRunLoopGetMain();
|
||||
@ -348,6 +347,16 @@ static inline void qt_mac_waitForMoreEvents(NSString *runLoopMode = NSDefaultRun
|
||||
bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
{
|
||||
Q_D(QCocoaEventDispatcher);
|
||||
|
||||
// In rare rather corner cases a user's application messes with
|
||||
// QEventLoop::exec()/exit() and QCoreApplication::processEvents(),
|
||||
// we have to undo what bool blocker normally does.
|
||||
d->propagateInterrupt = false;
|
||||
const auto boolBlockerUndo = qScopeGuard([d](){
|
||||
if (d->propagateInterrupt)
|
||||
d->interrupt = true;
|
||||
d->propagateInterrupt = false;
|
||||
});
|
||||
QBoolBlocker interruptBlocker(d->interrupt, false);
|
||||
|
||||
bool interruptLater = false;
|
||||
@ -496,7 +505,16 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
|
||||
if ((d->processEventsFlags & QEventLoop::EventLoopExec) == 0) {
|
||||
// When called "manually", always process posted events and timers
|
||||
bool oldInterrupt = d->interrupt;
|
||||
d->processPostedEvents();
|
||||
if (!oldInterrupt && d->interrupt && !d->currentModalSession()) {
|
||||
// We had direct processEvent call, coming not from QEventLoop::exec().
|
||||
// One of the posted events triggered an application to interrupt the loop.
|
||||
// But bool blocker will reset d->interrupt to false, so the real event
|
||||
// loop will never notice it was interrupted. Now we'll have to fix it by
|
||||
// enforcing the value of d->interrupt.
|
||||
d->propagateInterrupt = true;
|
||||
}
|
||||
retVal = d->processTimers() || retVal;
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,10 @@ private:
|
||||
QSurfaceFormat m_format;
|
||||
QVarLengthArray<QMacNotificationObserver, 3> m_updateObservers;
|
||||
QAtomicInt m_needsUpdate = false;
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
friend QDebug operator<<(QDebug debug, const QCocoaGLContext *screen);
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -158,6 +158,8 @@ void QCocoaGLContext::initialize()
|
||||
[m_context setValues:&order forParameter:NSOpenGLCPSurfaceOrder];
|
||||
|
||||
updateSurfaceFormat();
|
||||
|
||||
qCDebug(lcQpaOpenGLContext).verbosity(3) << "Created" << this << "based on requested" << context()->format();
|
||||
}
|
||||
|
||||
NSOpenGLPixelFormat *QCocoaGLContext::pixelFormatForSurfaceFormat(const QSurfaceFormat &format)
|
||||
@ -355,7 +357,7 @@ QCocoaGLContext::~QCocoaGLContext()
|
||||
|
||||
bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
|
||||
{
|
||||
qCDebug(lcQpaOpenGLContext) << "Making" << m_context << "current"
|
||||
qCDebug(lcQpaOpenGLContext) << "Making" << this << "current"
|
||||
<< "in" << QThread::currentThread() << "for" << surface;
|
||||
|
||||
Q_ASSERT(surface->surface()->supportsOpenGL());
|
||||
@ -555,4 +557,20 @@ QFunctionPointer QCocoaGLContext::getProcAddress(const char *procName)
|
||||
return (QFunctionPointer)dlsym(RTLD_DEFAULT, procName);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
QDebug operator<<(QDebug debug, const QCocoaGLContext *context)
|
||||
{
|
||||
QDebugStateSaver saver(debug);
|
||||
debug.nospace();
|
||||
debug << "QCocoaGLContext(" << (const void *)context;
|
||||
if (context) {
|
||||
if (debug.verbosity() > QDebug::DefaultVerbosity)
|
||||
debug << ", " << context->format();
|
||||
debug << ", " << context->nativeContext();
|
||||
}
|
||||
debug << ')';
|
||||
return debug;
|
||||
}
|
||||
#endif // !QT_NO_DEBUG_STREAM
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -559,7 +559,10 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
|
||||
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
|
||||
if ((type & Qt::Popup) != Qt::Popup && (type & Qt::Dialog) != Qt::Dialog) {
|
||||
NSWindowCollectionBehavior behavior = m_view.window.collectionBehavior;
|
||||
if ((flags & Qt::WindowFullscreenButtonHint) || m_view.window.qt_fullScreen) {
|
||||
const bool enableFullScreen = m_view.window.qt_fullScreen
|
||||
|| !(flags & Qt::CustomizeWindowHint)
|
||||
|| (flags & Qt::WindowFullscreenButtonHint);
|
||||
if (enableFullScreen) {
|
||||
behavior |= NSWindowCollectionBehaviorFullScreenPrimary;
|
||||
behavior &= ~NSWindowCollectionBehaviorFullScreenAuxiliary;
|
||||
} else {
|
||||
|
@ -138,8 +138,12 @@ QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt)
|
||||
|
||||
QMacPasteboard::~QMacPasteboard()
|
||||
{
|
||||
// commit all promises for paste after exit close
|
||||
resolvingBeforeDestruction = true;
|
||||
/*
|
||||
Commit all promises for paste when shutting down,
|
||||
unless we are the stack-allocated clipboard used by QCocoaDrag.
|
||||
*/
|
||||
if (mime_type == QMacInternalPasteboardMime::MIME_DND)
|
||||
resolvingBeforeDestruction = true;
|
||||
PasteboardResolvePromises(paste);
|
||||
if (paste)
|
||||
CFRelease(paste);
|
||||
|
@ -60,6 +60,18 @@ static const int c_screenCode = _PULSE_CODE_MINAVAIL + 0;
|
||||
static const int c_armCode = _PULSE_CODE_MINAVAIL + 1;
|
||||
static const int c_quitCode = _PULSE_CODE_MINAVAIL + 2;
|
||||
|
||||
#if !defined(screen_register_event)
|
||||
int screen_register_event(screen_context_t, struct sigevent *event)
|
||||
{
|
||||
return MsgRegisterEvent(event, -1);
|
||||
}
|
||||
|
||||
int screen_unregister_event(struct sigevent *event)
|
||||
{
|
||||
return MsgUnregisterEvent(event);
|
||||
}
|
||||
#endif
|
||||
|
||||
QQnxScreenEventThread::QQnxScreenEventThread(screen_context_t context)
|
||||
: QThread()
|
||||
, m_screenContext(context)
|
||||
@ -75,10 +87,14 @@ QQnxScreenEventThread::QQnxScreenEventThread(screen_context_t context)
|
||||
qFatal("QQnxScreenEventThread: Can't continue without a channel connection");
|
||||
}
|
||||
|
||||
struct sigevent screenEvent;
|
||||
SIGEV_PULSE_INIT(&screenEvent, m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_screenCode, 0);
|
||||
SIGEV_PULSE_INIT(&m_screenEvent, m_connectionId, SIGEV_PULSE_PRIO_INHERIT, c_screenCode, 0);
|
||||
if (screen_register_event(m_screenContext, &m_screenEvent) == -1) {
|
||||
ConnectDetach(m_connectionId);
|
||||
ChannelDestroy(m_channelId);
|
||||
qFatal("QQnxScreenEventThread: Can't continue without a registered event");
|
||||
}
|
||||
|
||||
screen_notify(m_screenContext, SCREEN_NOTIFY_EVENT, nullptr, &screenEvent);
|
||||
screen_notify(m_screenContext, SCREEN_NOTIFY_EVENT, nullptr, &m_screenEvent);
|
||||
}
|
||||
|
||||
QQnxScreenEventThread::~QQnxScreenEventThread()
|
||||
@ -86,6 +102,8 @@ QQnxScreenEventThread::~QQnxScreenEventThread()
|
||||
// block until thread terminates
|
||||
shutdown();
|
||||
|
||||
screen_notify(m_screenContext, SCREEN_NOTIFY_EVENT, nullptr, nullptr);
|
||||
screen_unregister_event(&m_screenEvent);
|
||||
ConnectDetach(m_connectionId);
|
||||
ChannelDestroy(m_channelId);
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <QtCore/QMutex>
|
||||
|
||||
#include <screen/screen.h>
|
||||
#include <sys/siginfo.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -73,6 +74,7 @@ private:
|
||||
|
||||
int m_channelId;
|
||||
int m_connectionId;
|
||||
struct sigevent m_screenEvent;
|
||||
screen_context_t m_screenContext;
|
||||
bool m_emitNeededOnNextScreenPulse = true;
|
||||
int m_screenPulsesSinceLastArmPulse = 0;
|
||||
|
@ -54,6 +54,8 @@ QWasmScreen::QWasmScreen(const QString &canvasId)
|
||||
m_compositor = new QWasmCompositor(this);
|
||||
m_eventTranslator = new QWasmEventTranslator(this);
|
||||
updateQScreenAndCanvasRenderSize();
|
||||
emscripten::val canvas = emscripten::val::global(m_canvasId.toUtf8().constData());
|
||||
canvas.call<void>("focus");
|
||||
}
|
||||
|
||||
QWasmScreen::~QWasmScreen()
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <QtGui/qscreen.h>
|
||||
#include <QtGui/private/qguiapplication_p.h> // getPixmapCursor()
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
#include <QtCore/private/qwinregistry_p.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
@ -686,6 +687,30 @@ void QWindowsCursor::setPos(const QPoint &pos)
|
||||
SetCursorPos(pos.x() , pos.y());
|
||||
}
|
||||
|
||||
/*
|
||||
The standard size is 32x32, even though the cursor is actually just
|
||||
16 pixels large. If a large cursor is set in the accessibility settings,
|
||||
then the cursor increases with 8 pixels for each step.
|
||||
*/
|
||||
QSize QWindowsCursor::size() const
|
||||
{
|
||||
const QPair<DWORD,bool> cursorSizeSetting =
|
||||
QWinRegistryKey(HKEY_CURRENT_USER, LR"(Control Panel\Cursors)")
|
||||
.dwordValue(L"CursorBaseSize");
|
||||
const int baseSize = screenCursorSize(m_screen).width() / 2;
|
||||
if (!cursorSizeSetting.second)
|
||||
return QSize(baseSize / 2, baseSize / 2);
|
||||
|
||||
// The registry values are dpi-independent, so we need to scale the result.
|
||||
int cursorSizeValue = cursorSizeSetting.first * m_screen->logicalDpi().first
|
||||
/ m_screen->logicalBaseDpi().first;
|
||||
|
||||
// map from registry value 32-256 to 0-14, and from there to pixels
|
||||
cursorSizeValue = (cursorSizeValue - 2 * baseSize) / baseSize;
|
||||
const int cursorSize = baseSize + cursorSizeValue * (baseSize / 2);
|
||||
return QSize(cursorSize, cursorSize);
|
||||
}
|
||||
|
||||
QPixmap QWindowsCursor::dragDefaultCursor(Qt::DropAction action) const
|
||||
{
|
||||
switch (action) {
|
||||
|
@ -113,6 +113,8 @@ public:
|
||||
QPoint pos() const override;
|
||||
void setPos(const QPoint &pos) override;
|
||||
|
||||
QSize size() const override;
|
||||
|
||||
static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1);
|
||||
static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); }
|
||||
static PixmapCursor customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen = nullptr);
|
||||
|
@ -57,11 +57,13 @@
|
||||
#include "qwindowsmenu.h"
|
||||
#include "qwindowsscreen.h"
|
||||
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtGui/qpixmap.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qrect.h>
|
||||
#include <QtCore/qvector.h>
|
||||
#include <QtCore/qsettings.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
||||
#include <qt_windows.h>
|
||||
#include <commctrl.h>
|
||||
@ -134,9 +136,12 @@ static int indexOfHwnd(HWND hwnd)
|
||||
extern "C" LRESULT QT_WIN_CALLBACK qWindowsTrayIconWndProc(HWND hwnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// QTBUG-79248: Trigger screen update if there are no other windows.
|
||||
if (message == WM_DPICHANGED && QGuiApplication::topLevelWindows().isEmpty())
|
||||
QWindowsContext::instance()->screenManager().handleScreenChanges();
|
||||
if (message == MYWM_TASKBARCREATED || message == MYWM_NOTIFYICON
|
||||
|| message == WM_INITMENU || message == WM_INITMENUPOPUP
|
||||
|| message == WM_COMMAND) {
|
||||
|| message == WM_CLOSE || message == WM_COMMAND) {
|
||||
const int index = indexOfHwnd(hwnd);
|
||||
if (index >= 0) {
|
||||
MSG msg;
|
||||
@ -439,6 +444,9 @@ bool QWindowsSystemTrayIcon::winEvent(const MSG &message, long *result)
|
||||
case WM_INITMENUPOPUP:
|
||||
QWindowsPopupMenu::notifyAboutToShow(reinterpret_cast<HMENU>(message.wParam));
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
QWindowSystemInterface::handleApplicationTermination<QWindowSystemInterface::SynchronousDelivery>();
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
QWindowsPopupMenu::notifyTriggered(LOWORD(message.wParam));
|
||||
break;
|
||||
|
@ -289,7 +289,8 @@ HRESULT QWindowsUiaMainProvider::GetPatternProvider(PATTERNID idPattern, IUnknow
|
||||
break;
|
||||
case UIA_TogglePatternId:
|
||||
// Checkbox controls.
|
||||
if (accessible->role() == QAccessible::CheckBox) {
|
||||
if (accessible->role() == QAccessible::CheckBox
|
||||
|| (accessible->role() == QAccessible::MenuItem && accessible->state().checkable)) {
|
||||
*pRetVal = new QWindowsUiaToggleProvider(id());
|
||||
}
|
||||
break;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "qxcbwindow.h"
|
||||
#include "qxcbcursor.h"
|
||||
#include "qxcbimage.h"
|
||||
#include "qxcbintegration.h"
|
||||
#include "qnamespace.h"
|
||||
#include "qxcbxsettings.h"
|
||||
|
||||
@ -49,6 +50,7 @@
|
||||
#include <QDebug>
|
||||
#include <QtAlgorithms>
|
||||
|
||||
#include <qpa/qplatformservices.h>
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
#include <private/qmath_p.h>
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
@ -356,6 +358,15 @@ static QFontEngine::SubpixelAntialiasingType parseXftRgba(const QByteArray& stri
|
||||
|
||||
void QXcbVirtualDesktop::readXResources()
|
||||
{
|
||||
const QPlatformServices *services = QXcbIntegration::instance()->services();
|
||||
bool useXftConf = false;
|
||||
if (services) {
|
||||
const QList<QByteArray> desktopEnv = services->desktopEnvironment().split(':');
|
||||
useXftConf = desktopEnv.contains("GNOME") || desktopEnv.contains("UNITY") || desktopEnv.contains("XFCE");
|
||||
}
|
||||
if (!useXftConf)
|
||||
return;
|
||||
|
||||
int offset = 0;
|
||||
QByteArray resources;
|
||||
while (true) {
|
||||
|
@ -838,6 +838,7 @@ QSqlRecord QPSQLResult::record() const
|
||||
}
|
||||
int ptype = PQftype(d->result, i);
|
||||
f.setType(qDecodePSQLType(ptype));
|
||||
f.setValue(QVariant(f.type())); // only set in setType() when it's invalid before
|
||||
int len = PQfsize(d->result, i);
|
||||
int precision = PQfmod(d->result, i);
|
||||
|
||||
|
14
src/testlib/doc/snippets/code/doc_src_cmakelists.txt
Normal file
14
src/testlib/doc/snippets/code/doc_src_cmakelists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
project(mytest LANGUAGES CXX)
|
||||
|
||||
find_package(Qt5Test REQUIRED)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
enable_testing(true)
|
||||
|
||||
add_executable(mytest tst_mytest.cpp)
|
||||
add_test(NAME mytest COMMAND mytest)
|
||||
|
||||
target_link_libraries(mytest PRIVATE Qt5::Test)
|
@ -83,6 +83,10 @@
|
||||
\li Custom types can easily be added to the test data and test output.
|
||||
\endtable
|
||||
|
||||
You can use a Qt Creator wizard to create a project that contains Qt tests
|
||||
and build and run them directly from Qt Creator. For more information, see
|
||||
\l {Running Autotests}.
|
||||
|
||||
\section1 Creating a Test
|
||||
|
||||
To create a test, subclass QObject and add one or more private slots to it. Each
|
||||
@ -133,6 +137,41 @@
|
||||
\if !defined(qtforpython)
|
||||
\section1 Building a Test
|
||||
|
||||
You can build an executable that contains one test class that typically
|
||||
tests one class of production code. However, usually you would want to
|
||||
test several classes in a project by running one command.
|
||||
|
||||
See \l {Chapter 1: Writing a Unit Test}{Writing a Unit Test} for a step by
|
||||
step explanation.
|
||||
|
||||
\section2 Building with CMake and CTest
|
||||
|
||||
You can use \l {CMake and CTest} to create a test.
|
||||
\l{https://cmake.org/cmake/help/latest/manual/ctest.1.html}{CTest} enables
|
||||
you to include or exclude tests based on a regular expression that is
|
||||
matched against the test name. You can further apply the \c LABELS property
|
||||
to a test and CTest can then include or exclude tests based on those labels.
|
||||
All labeled targets will be run when \c {test} target is called on the
|
||||
command line.
|
||||
|
||||
There are several other advantages with CMake. For example, the result of
|
||||
a test run can be published on a web server using CDash with virtually no
|
||||
effort.
|
||||
|
||||
CTest scales to very different unit test frameworks, and works out of the
|
||||
box with QTest.
|
||||
|
||||
The following is an example of a CMakeLists.txt file that specifies the
|
||||
project name and the language used (here, \e mytest and C++), the Qt
|
||||
modules required for building the test (Qt5Test), and the files that are
|
||||
included in the test (\e tst_mytest.cpp).
|
||||
|
||||
\quotefile code/doc_src_cmakelists.txt
|
||||
|
||||
For more information about the options you have, see \l {Build with CMake}.
|
||||
|
||||
\section2 Building with qmake
|
||||
|
||||
If you are using \c qmake as your build tool, just add the
|
||||
following to your project file:
|
||||
|
||||
@ -146,14 +185,14 @@
|
||||
See the \l{Building a Testcase}{qmake manual} for
|
||||
more information about \c{make check}.
|
||||
|
||||
\section2 Building with Other Tools
|
||||
|
||||
If you are using other build tools, make sure that you add the location
|
||||
of the Qt Test header files to your include path (usually \c{include/QtTest}
|
||||
under your Qt installation directory). If you are using a release build
|
||||
of Qt, link your test to the \c QtTest library. For debug builds, use
|
||||
\c{QtTest_debug}.
|
||||
|
||||
See \l {Chapter 1: Writing a Unit Test}{Writing a Unit Test} for a step by
|
||||
step explanation.
|
||||
\endif
|
||||
|
||||
\section1 Qt Test Command Line Arguments
|
||||
|
@ -299,6 +299,8 @@ QAccessible::State QAccessibleMenuItem::state() const
|
||||
s.disabled = true;
|
||||
if (m_action->isChecked())
|
||||
s.checked = true;
|
||||
if (m_action->isCheckable())
|
||||
s.checkable = true;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -710,14 +710,17 @@ void QProgressDialog::setValue(int progress)
|
||||
QSize QProgressDialog::sizeHint() const
|
||||
{
|
||||
Q_D(const QProgressDialog);
|
||||
QSize sh = d->label ? d->label->sizeHint() : QSize(0, 0);
|
||||
QSize bh = d->bar->sizeHint();
|
||||
int margin = style()->pixelMetric(QStyle::PM_DefaultTopLevelMargin);
|
||||
int spacing = style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
|
||||
int h = margin * 2 + bh.height() + sh.height() + spacing;
|
||||
QSize labelSize = d->label ? d->label->sizeHint() : QSize(0, 0);
|
||||
QSize barSize = d->bar->sizeHint();
|
||||
int marginBottom = style()->pixelMetric(QStyle::PM_LayoutBottomMargin, 0, this);
|
||||
int spacing = style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing, 0, this);
|
||||
int marginLeft = style()->pixelMetric(QStyle::PM_LayoutLeftMargin, 0, this);
|
||||
int marginRight = style()->pixelMetric(QStyle::PM_LayoutRightMargin, 0, this);
|
||||
|
||||
int height = marginBottom * 2 + barSize.height() + labelSize.height() + spacing;
|
||||
if (d->cancel)
|
||||
h += d->cancel->sizeHint().height() + spacing;
|
||||
return QSize(qMax(200, sh.width() + 2 * margin), h);
|
||||
height += d->cancel->sizeHint().height() + spacing;
|
||||
return QSize(qMax(200, labelSize.width() + marginLeft + marginRight), height);
|
||||
}
|
||||
|
||||
/*!\reimp
|
||||
|
@ -3074,9 +3074,10 @@ void QAbstractItemView::keyboardSearch(const QString &search)
|
||||
QSize QAbstractItemView::sizeHintForIndex(const QModelIndex &index) const
|
||||
{
|
||||
Q_D(const QAbstractItemView);
|
||||
if (!d->isIndexValid(index) || !d->itemDelegate)
|
||||
if (!d->isIndexValid(index))
|
||||
return QSize();
|
||||
return d->delegateForIndex(index)->sizeHint(d->viewOptionsV1(), index);
|
||||
const auto delegate = d->delegateForIndex(index);
|
||||
return delegate ? delegate->sizeHint(d->viewOptionsV1(), index) : QSize();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3318,6 +3319,8 @@ void QAbstractItemView::update(const QModelIndex &index)
|
||||
|
||||
The \a roles which have been changed can either be an empty container (meaning everything
|
||||
has changed), or a non-empty container with the subset of roles which have changed.
|
||||
|
||||
\note: Qt::ToolTipRole is not honored by dataChanged() in the views provided by Qt.
|
||||
*/
|
||||
void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
|
||||
{
|
||||
@ -4451,7 +4454,9 @@ QItemViewPaintPairs QAbstractItemViewPrivate::draggablePaintPairs(const QModelIn
|
||||
rect |= current;
|
||||
}
|
||||
}
|
||||
rect &= viewportRect;
|
||||
QRect clipped = rect & viewportRect;
|
||||
rect.setLeft(clipped.left());
|
||||
rect.setRight(clipped.right());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -664,7 +664,9 @@ QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList
|
||||
rect |= current;
|
||||
}
|
||||
}
|
||||
rect &= viewportRect;
|
||||
QRect clipped = rect & viewportRect;
|
||||
rect.setLeft(clipped.left());
|
||||
rect.setRight(clipped.right());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -53,11 +53,14 @@
|
||||
#endif
|
||||
#include <qtextdocument.h>
|
||||
#include <qdebug.h>
|
||||
#include <qpa/qplatformscreen.h>
|
||||
#include <qpa/qplatformcursor.h>
|
||||
#include <private/qstylesheetstyle_p.h>
|
||||
|
||||
#ifndef QT_NO_TOOLTIP
|
||||
#include <qlabel.h>
|
||||
#include <QtWidgets/private/qlabel_p.h>
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
#include <qtooltip.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -398,24 +401,34 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
|
||||
}
|
||||
#endif //QT_NO_STYLE_STYLESHEET
|
||||
|
||||
|
||||
QRect screen = QDesktopWidgetPrivate::screenGeometry(getTipScreen(pos, w));
|
||||
|
||||
QPoint p = pos;
|
||||
p += QPoint(2, 16);
|
||||
int screenNumber = getTipScreen(pos, w);
|
||||
QScreen *screen = QGuiApplication::screens().at(screenNumber);
|
||||
if (screen) {
|
||||
const QPlatformScreen *platformScreen = screen->handle();
|
||||
const QSize cursorSize = QHighDpi::fromNativePixels(platformScreen->cursor()->size(),
|
||||
platformScreen);
|
||||
QPoint offset(2, cursorSize.height());
|
||||
// assuming an arrow shape, we can just move to the side for very large cursors
|
||||
if (cursorSize.height() > 2 * this->height())
|
||||
offset = QPoint(cursorSize.width() / 2, 0);
|
||||
|
||||
if (p.x() + this->width() > screen.x() + screen.width())
|
||||
p += offset;
|
||||
|
||||
QRect screenRect = screen->geometry();
|
||||
if (p.x() + this->width() > screenRect.x() + screenRect.width())
|
||||
p.rx() -= 4 + this->width();
|
||||
if (p.y() + this->height() > screen.y() + screen.height())
|
||||
if (p.y() + this->height() > screenRect.y() + screenRect.height())
|
||||
p.ry() -= 24 + this->height();
|
||||
if (p.y() < screen.y())
|
||||
p.setY(screen.y());
|
||||
if (p.x() + this->width() > screen.x() + screen.width())
|
||||
p.setX(screen.x() + screen.width() - this->width());
|
||||
if (p.x() < screen.x())
|
||||
p.setX(screen.x());
|
||||
if (p.y() + this->height() > screen.y() + screen.height())
|
||||
p.setY(screen.y() + screen.height() - this->height());
|
||||
if (p.y() < screenRect.y())
|
||||
p.setY(screenRect.y());
|
||||
if (p.x() + this->width() > screenRect.x() + screenRect.width())
|
||||
p.setX(screenRect.x() + screenRect.width() - this->width());
|
||||
if (p.x() < screenRect.x())
|
||||
p.setX(screenRect.x());
|
||||
if (p.y() + this->height() > screenRect.y() + screenRect.height())
|
||||
p.setY(screenRect.y() + screenRect.height() - this->height());
|
||||
}
|
||||
this->move(p);
|
||||
}
|
||||
|
||||
|
@ -8621,6 +8621,23 @@ bool QWidget::event(QEvent *event)
|
||||
}
|
||||
}
|
||||
switch (event->type()) {
|
||||
case QEvent::PlatformSurface: {
|
||||
// Sync up QWidget's view of whether or not the widget has been created
|
||||
switch (static_cast<QPlatformSurfaceEvent*>(event)->surfaceEventType()) {
|
||||
case QPlatformSurfaceEvent::SurfaceCreated:
|
||||
if (!testAttribute(Qt::WA_WState_Created))
|
||||
create();
|
||||
break;
|
||||
case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
|
||||
if (testAttribute(Qt::WA_WState_Created)) {
|
||||
// Child windows have already been destroyed by QWindow,
|
||||
// so we skip them here.
|
||||
destroy(false, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::MouseMove:
|
||||
mouseMoveEvent((QMouseEvent*)event);
|
||||
break;
|
||||
|
@ -1363,7 +1363,6 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
|
||||
|
||||
if (!button->icon.isNull()) {
|
||||
//Center both icon and text
|
||||
QRect iconRect;
|
||||
QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
|
||||
if (mode == QIcon::Normal && button->state & State_HasFocus)
|
||||
mode = QIcon::Active;
|
||||
@ -1372,28 +1371,29 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
|
||||
state = QIcon::On;
|
||||
|
||||
QPixmap pixmap = button->icon.pixmap(qt_getWindow(widget), button->iconSize, mode, state);
|
||||
|
||||
int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio();
|
||||
int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio();
|
||||
int labelWidth = pixmapWidth;
|
||||
int labelHeight = pixmapHeight;
|
||||
int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
|
||||
int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
|
||||
if (!button->text.isEmpty())
|
||||
if (!button->text.isEmpty()) {
|
||||
int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width();
|
||||
labelWidth += (textWidth + iconSpacing);
|
||||
}
|
||||
|
||||
iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
|
||||
textRect.y() + (textRect.height() - labelHeight) / 2,
|
||||
pixmapWidth, pixmapHeight);
|
||||
QRect iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2,
|
||||
textRect.y() + (textRect.height() - labelHeight) / 2,
|
||||
pixmapWidth, pixmapHeight);
|
||||
|
||||
iconRect = visualRect(button->direction, textRect, iconRect);
|
||||
|
||||
tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
|
||||
|
||||
if (button->direction == Qt::RightToLeft)
|
||||
if (button->direction == Qt::RightToLeft) {
|
||||
tf |= Qt::AlignRight;
|
||||
textRect.setRight(iconRect.left() - iconSpacing);
|
||||
else
|
||||
} else {
|
||||
tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead
|
||||
textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing);
|
||||
}
|
||||
|
||||
if (button->state & (State_On | State_Sunken))
|
||||
iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, widget),
|
||||
|
@ -1770,59 +1770,10 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
|
||||
break;
|
||||
case CE_PushButtonLabel:
|
||||
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
|
||||
QRect ir = button->rect;
|
||||
uint tf = Qt::AlignVCenter;
|
||||
if (styleHint(SH_UnderlineShortcut, button, widget))
|
||||
tf |= Qt::TextShowMnemonic;
|
||||
else
|
||||
tf |= Qt::TextHideMnemonic;
|
||||
|
||||
if (!button->icon.isNull()) {
|
||||
//Center both icon and text
|
||||
QPoint point;
|
||||
|
||||
QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal
|
||||
: QIcon::Disabled;
|
||||
if (mode == QIcon::Normal && button->state & State_HasFocus)
|
||||
mode = QIcon::Active;
|
||||
QIcon::State state = QIcon::Off;
|
||||
if (button->state & State_On)
|
||||
state = QIcon::On;
|
||||
|
||||
QPixmap pixmap = button->icon.pixmap(qt_getWindow(widget), button->iconSize, mode, state);
|
||||
int w = pixmap.width() / pixmap.devicePixelRatio();
|
||||
int h = pixmap.height() / pixmap.devicePixelRatio();
|
||||
|
||||
if (!button->text.isEmpty())
|
||||
w += button->fontMetrics.boundingRect(option->rect, tf, button->text).width() + 2;
|
||||
|
||||
point = QPoint(ir.x() + ir.width() / 2 - w / 2,
|
||||
ir.y() + ir.height() / 2 - h / 2);
|
||||
|
||||
w = pixmap.width() / pixmap.devicePixelRatio();
|
||||
|
||||
if (button->direction == Qt::RightToLeft)
|
||||
point.rx() += w;
|
||||
|
||||
painter->drawPixmap(visualPos(button->direction, button->rect, point), pixmap);
|
||||
|
||||
if (button->direction == Qt::RightToLeft)
|
||||
ir.translate(-point.x() - 2, 0);
|
||||
else
|
||||
ir.translate(point.x() + w, 0);
|
||||
|
||||
// left-align text if there is
|
||||
if (!button->text.isEmpty())
|
||||
tf |= Qt::AlignLeft;
|
||||
|
||||
} else {
|
||||
tf |= Qt::AlignHCenter;
|
||||
}
|
||||
|
||||
if (button->features & QStyleOptionButton::HasMenu)
|
||||
ir = ir.adjusted(0, 0, -proxy()->pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
|
||||
proxy()->drawItemText(painter, ir, tf, button->palette, (button->state & State_Enabled),
|
||||
button->text, QPalette::ButtonText);
|
||||
QStyleOptionButton b(*button);
|
||||
// no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
|
||||
b.state &= ~(State_On | State_Sunken);
|
||||
QCommonStyle::drawControl(element, &b, painter, widget);
|
||||
}
|
||||
break;
|
||||
case CE_MenuBarEmptyArea:
|
||||
|
@ -3501,6 +3501,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
|
||||
} else {
|
||||
QWindowsStyle::drawControl(ce, &btnOpt, p, w);
|
||||
}
|
||||
rule.drawImage(p, rule.contentsRect(opt->rect));
|
||||
if (!customMenu)
|
||||
return;
|
||||
} else {
|
||||
@ -3730,6 +3731,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
|
||||
bool dis = !(opt->state & QStyle::State_Enabled),
|
||||
act = opt->state & QStyle::State_Selected;
|
||||
|
||||
int textRectOffset = m->maxIconWidth;
|
||||
if (!mi.icon.isNull()) {
|
||||
QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
|
||||
if (act && !dis)
|
||||
@ -3755,19 +3757,21 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
|
||||
p->drawPixmap(pmr.topLeft(), pixmap);
|
||||
} else if (checkable) {
|
||||
QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark);
|
||||
const QRect cmRect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
|
||||
if (subSubRule.hasDrawable() || checked) {
|
||||
QStyleOptionMenuItem newMi = mi;
|
||||
if (!dis)
|
||||
newMi.state |= State_Enabled;
|
||||
if (act)
|
||||
if (mi.checked)
|
||||
newMi.state |= State_On;
|
||||
newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction);
|
||||
newMi.rect = cmRect;
|
||||
drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w);
|
||||
}
|
||||
textRectOffset = std::max(textRectOffset, cmRect.width());
|
||||
}
|
||||
|
||||
QRect textRect = subRule.contentsRect(opt->rect);
|
||||
textRect.setLeft(textRect.left() + m->maxIconWidth);
|
||||
textRect.setLeft(textRect.left() + textRectOffset);
|
||||
textRect.setWidth(textRect.width() - mi.tabWidth);
|
||||
const QRect vTextRect = visualRect(opt->direction, m->rect, textRect);
|
||||
|
||||
|
@ -90,12 +90,10 @@ QT_BEGIN_NAMESPACE
|
||||
today's date, and restricted the valid date range to today plus or
|
||||
minus 365 days. We've set the order to month, day, year.
|
||||
|
||||
The minimum value for QDateTimeEdit is 14 September 1752. You can
|
||||
change this by calling setMinimumDate(), taking into account that
|
||||
the minimum value for QDate is 2 January 4713BC.
|
||||
|
||||
Other useful functions are setMaximumDate(), setMinimumTime()
|
||||
and setMaximumTime().
|
||||
The range of valid values for a QDateTimeEdit is controlled by the properties
|
||||
\l minimumDateTime, \l maximumDateTime, and their respective date and time
|
||||
components. By default, any date-time from the start of 100 CE to the end of
|
||||
9999 CE is valid.
|
||||
|
||||
\section1 Using a Pop-up Calendar Widget
|
||||
|
||||
@ -223,10 +221,16 @@ QDateTimeEdit::~QDateTimeEdit()
|
||||
When setting this property the timespec of the QDateTimeEdit remains the same
|
||||
and the timespec of the new QDateTime is ignored.
|
||||
|
||||
By default, this property contains a date that refers to January 1,
|
||||
2000 and a time of 00:00:00 and 0 milliseconds.
|
||||
By default, this property is set to the start of 2000 CE. It can only be set
|
||||
to a valid QDateTime value. If any operation causes this property to have an
|
||||
invalid date-time as value, it is reset to the value of the \l minimumDateTime
|
||||
property.
|
||||
|
||||
\sa date, time
|
||||
If the QDateTimeEdit has no date fields, setting this property sets the
|
||||
widget's date-range to start and end on the date of the new value of this
|
||||
property.
|
||||
|
||||
\sa date, time, minimumDateTime, maximumDateTime
|
||||
*/
|
||||
|
||||
QDateTime QDateTimeEdit::dateTime() const
|
||||
@ -329,25 +333,23 @@ void QDateTimeEdit::setCalendar(QCalendar calendar)
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QDateTimeEdit::minimumDateTime
|
||||
\since 4.4
|
||||
\property QDateTimeEdit::minimumDateTime
|
||||
|
||||
\brief the minimum datetime of the date time edit
|
||||
|
||||
When setting this property the \l maximumDateTime() is adjusted if
|
||||
necessary to ensure that the range remains valid. If the datetime is
|
||||
not a valid QDateTime object, this function does nothing.
|
||||
Changing this property implicitly updates the \l minimumDate and \l
|
||||
minimumTime properties to the date and time parts of this property,
|
||||
respectively. When setting this property, the \l maximumDateTime is adjusted,
|
||||
if necessary, to ensure that the range remains valid. Otherwise, changing this
|
||||
property preserves the \l minimumDateTime property.
|
||||
|
||||
The default minimumDateTime can be restored with
|
||||
clearMinimumDateTime()
|
||||
This property can only be set to a valid QDateTime value. The earliest
|
||||
date-time that setMinimumDateTime() accepts is the start of 100 CE. The
|
||||
property's default is the start of September 14, 1752 CE. This default can be
|
||||
restored with clearMinimumDateTime().
|
||||
|
||||
By default, this property contains a date that refers to September 14,
|
||||
1752 and a time of 00:00:00 and 0 milliseconds.
|
||||
|
||||
\sa maximumDateTime(), minimumTime(), maximumTime(), minimumDate(),
|
||||
maximumDate(), setDateTimeRange(), setDateRange(), setTimeRange(),
|
||||
clearMaximumDateTime(), clearMinimumDate(),
|
||||
clearMaximumDate(), clearMinimumTime(), clearMaximumTime()
|
||||
\sa maximumDateTime, minimumTime, minimumDate, setDateTimeRange(), QDateTime::isValid()
|
||||
*/
|
||||
|
||||
QDateTime QDateTimeEdit::minimumDateTime() const
|
||||
@ -372,25 +374,23 @@ void QDateTimeEdit::setMinimumDateTime(const QDateTime &dt)
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QDateTimeEdit::maximumDateTime
|
||||
\since 4.4
|
||||
\property QDateTimeEdit::maximumDateTime
|
||||
|
||||
\brief the maximum datetime of the date time edit
|
||||
|
||||
When setting this property the \l minimumDateTime() is adjusted if
|
||||
necessary to ensure that the range remains valid. If the datetime is
|
||||
not a valid QDateTime object, this function does nothing.
|
||||
Changing this property implicitly updates the \l maximumDate and \l
|
||||
maximumTime properties to the date and time parts of this property,
|
||||
respectively. When setting this property, the \l minimumDateTime is adjusted,
|
||||
if necessary, to ensure that the range remains valid. Otherwise, changing this
|
||||
property preserves the \l minimumDateTime property.
|
||||
|
||||
The default maximumDateTime can be restored with
|
||||
This property can only be set to a valid QDateTime value. The latest
|
||||
date-time that setMaximumDateTime() accepts is the end of 9999 CE. This is the
|
||||
default for this property. This default can be restored with
|
||||
clearMaximumDateTime().
|
||||
|
||||
By default, this property contains a date that refers to 31 December,
|
||||
9999 and a time of 23:59:59 and 999 milliseconds.
|
||||
|
||||
\sa minimumDateTime(), minimumTime(), maximumTime(), minimumDate(),
|
||||
maximumDate(), setDateTimeRange(), setDateRange(), setTimeRange(),
|
||||
clearMinimumDateTime(), clearMinimumDate(),
|
||||
clearMaximumDate(), clearMinimumTime(), clearMaximumTime()
|
||||
\sa minimumDateTime, maximumTime, maximumDate(), setDateTimeRange(), QDateTime::isValid()
|
||||
*/
|
||||
|
||||
QDateTime QDateTimeEdit::maximumDateTime() const
|
||||
@ -414,11 +414,12 @@ void QDateTimeEdit::setMaximumDateTime(const QDateTime &dt)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Convenience function to set minimum and maximum date time with one
|
||||
function call.
|
||||
\since 4.4
|
||||
\brief Set the range of allowed date-times for the date time edit.
|
||||
|
||||
This convenience function sets the \l minimumDateTime and \l maximumDateTime
|
||||
properties.
|
||||
|
||||
\snippet code/src_gui_widgets_qdatetimeedit.cpp 1
|
||||
|
||||
@ -426,21 +427,18 @@ void QDateTimeEdit::setMaximumDateTime(const QDateTime &dt)
|
||||
|
||||
\snippet code/src_gui_widgets_qdatetimeedit.cpp 2
|
||||
|
||||
If either \a min or \a max are not valid, this function does
|
||||
nothing.
|
||||
If either \a min or \a max is invalid, this function does nothing. If \a max
|
||||
is less than \a min, \a min is used also as \a max.
|
||||
|
||||
\sa setMinimumDate(), maximumDate(), setMaximumDate(),
|
||||
clearMinimumDate(), setMinimumTime(), maximumTime(),
|
||||
setMaximumTime(), clearMinimumTime(), QDateTime::isValid()
|
||||
\sa minimumDateTime, maximumDateTime, setDateRange(), setTimeRange(), QDateTime::isValid()
|
||||
*/
|
||||
|
||||
void QDateTimeEdit::setDateTimeRange(const QDateTime &min, const QDateTime &max)
|
||||
{
|
||||
Q_D(QDateTimeEdit);
|
||||
// FIXME: does none of the range checks applied to setMin/setMax methods !
|
||||
const QDateTime minimum = min.toTimeSpec(d->spec);
|
||||
QDateTime maximum = max.toTimeSpec(d->spec);
|
||||
if (min > max)
|
||||
maximum = minimum;
|
||||
const QDateTime maximum = (min > max ? minimum : max.toTimeSpec(d->spec));
|
||||
d->setRange(minimum, maximum);
|
||||
}
|
||||
|
||||
@ -449,15 +447,20 @@ void QDateTimeEdit::setDateTimeRange(const QDateTime &min, const QDateTime &max)
|
||||
|
||||
\brief the minimum date of the date time edit
|
||||
|
||||
When setting this property the \l maximumDate is adjusted if
|
||||
necessary, to ensure that the range remains valid. If the date is
|
||||
not a valid QDate object, this function does nothing.
|
||||
Changing this property updates the date of the \l minimumDateTime property
|
||||
while preserving the \l minimumTime property. When setting this property,
|
||||
the \l maximumDate is adjusted, if necessary, to ensure that the range remains
|
||||
valid. When this happens, the \l maximumTime property is also adjusted if it
|
||||
is less than the \l minimumTime property. Otherwise, changes to this property
|
||||
preserve the \l maximumDateTime property.
|
||||
|
||||
By default, this property contains a date that refers to September 14, 1752.
|
||||
The minimum date must be at least the first day in year 100, otherwise
|
||||
setMinimumDate() has no effect.
|
||||
This property can only be set to a valid QDate object describing a date on
|
||||
which the current \l minimumTime property makes a valid QDateTime object. The
|
||||
earliest date that setMinimumDate() accepts is the start of 100 CE. The
|
||||
default for this property is September 14, 1752 CE. This default can be
|
||||
restored with clearMinimumDateTime().
|
||||
|
||||
\sa minimumTime(), maximumTime(), setDateRange()
|
||||
\sa maximumDate, minimumTime, minimumDateTime, setDateRange(), QDate::isValid()
|
||||
*/
|
||||
|
||||
QDate QDateTimeEdit::minimumDate() const
|
||||
@ -484,13 +487,20 @@ void QDateTimeEdit::clearMinimumDate()
|
||||
|
||||
\brief the maximum date of the date time edit
|
||||
|
||||
When setting this property the \l minimumDate is adjusted if
|
||||
necessary to ensure that the range remains valid. If the date is
|
||||
not a valid QDate object, this function does nothing.
|
||||
Changing this property updates the date of the \l maximumDateTime property
|
||||
while preserving the \l maximumTime property. When setting this property, the
|
||||
\l minimumDate is adjusted, if necessary, to ensure that the range remains
|
||||
valid. When this happens, the \l minimumTime property is also adjusted if it
|
||||
is greater than the \l maximumTime property. Otherwise, changes to this
|
||||
property preserve the \l minimumDateTime property.
|
||||
|
||||
By default, this property contains a date that refers to December 31, 9999.
|
||||
This property can only be set to a valid QDate object describing a date on
|
||||
which the current \l maximumTime property makes a valid QDateTime object. The
|
||||
latest date that setMaximumDate() accepts is the end of 9999 CE. This is the
|
||||
default for this property. This default can be restored with
|
||||
clearMaximumDateTime().
|
||||
|
||||
\sa minimumDate, minimumTime, maximumTime, setDateRange()
|
||||
\sa minimumDate, maximumTime, maximumDateTime, setDateRange(), QDate::isValid()
|
||||
*/
|
||||
|
||||
QDate QDateTimeEdit::maximumDate() const
|
||||
@ -502,9 +512,8 @@ QDate QDateTimeEdit::maximumDate() const
|
||||
void QDateTimeEdit::setMaximumDate(const QDate &max)
|
||||
{
|
||||
Q_D(QDateTimeEdit);
|
||||
if (max.isValid()) {
|
||||
if (max.isValid())
|
||||
setMaximumDateTime(QDateTime(max, d->maximum.toTime(), d->spec));
|
||||
}
|
||||
}
|
||||
|
||||
void QDateTimeEdit::clearMaximumDate()
|
||||
@ -517,13 +526,18 @@ void QDateTimeEdit::clearMaximumDate()
|
||||
|
||||
\brief the minimum time of the date time edit
|
||||
|
||||
When setting this property the \l maximumTime is adjusted if
|
||||
necessary, to ensure that the range remains valid. If the time is
|
||||
not a valid QTime object, this function does nothing.
|
||||
Changing this property updates the time of the \l minimumDateTime property
|
||||
while preserving the \l minimumDate and \l maximumDate properties. If those
|
||||
date properties coincide, when setting this property, the \l maximumTime
|
||||
property is adjusted, if necessary, to ensure that the range remains
|
||||
valid. Otherwise, changing this property preserves the \l maximumDateTime
|
||||
property.
|
||||
|
||||
By default, this property contains a time of 00:00:00 and 0 milliseconds.
|
||||
This property can be set to any valid QTime value. By default, this property
|
||||
contains a time of 00:00:00 and 0 milliseconds. This default can be restored
|
||||
with clearMinimumTime().
|
||||
|
||||
\sa maximumTime, minimumDate, maximumDate, setTimeRange()
|
||||
\sa maximumTime, minimumDate, minimumDateTime, setTimeRange(), QTime::isValid()
|
||||
*/
|
||||
|
||||
QTime QDateTimeEdit::minimumTime() const
|
||||
@ -551,13 +565,18 @@ void QDateTimeEdit::clearMinimumTime()
|
||||
|
||||
\brief the maximum time of the date time edit
|
||||
|
||||
When setting this property, the \l minimumTime is adjusted if
|
||||
necessary to ensure that the range remains valid. If the time is
|
||||
not a valid QTime object, this function does nothing.
|
||||
Changing this property updates the time of the \l maximumDateTime property
|
||||
while preserving the \l minimumDate and \l maximumDate properties. If those
|
||||
date properties coincide, when setting this property, the \l minimumTime
|
||||
property is adjusted, if necessary, to ensure that the range remains
|
||||
valid. Otherwise, changing this property preserves the \l minimumDateTime
|
||||
property.
|
||||
|
||||
By default, this property contains a time of 23:59:59 and 999 milliseconds.
|
||||
This property can be set to any valid QTime value. By default, this property
|
||||
contains a time of 23:59:59 and 999 milliseconds. This default can be restored
|
||||
with clearMaximumTime().
|
||||
|
||||
\sa minimumTime, minimumDate, maximumDate, setTimeRange()
|
||||
\sa minimumTime, maximumDate, maximumDateTime, setTimeRange(), QTime::isValid()
|
||||
*/
|
||||
QTime QDateTimeEdit::maximumTime() const
|
||||
{
|
||||
@ -580,8 +599,10 @@ void QDateTimeEdit::clearMaximumTime()
|
||||
}
|
||||
|
||||
/*!
|
||||
Convenience function to set minimum and maximum date with one
|
||||
function call.
|
||||
\brief Set the range of allowed dates for the date time edit.
|
||||
|
||||
This convenience function sets the \l minimumDate and \l maximumDate
|
||||
properties.
|
||||
|
||||
\snippet code/src_gui_widgets_qdatetimeedit.cpp 3
|
||||
|
||||
@ -589,12 +610,14 @@ void QDateTimeEdit::clearMaximumTime()
|
||||
|
||||
\snippet code/src_gui_widgets_qdatetimeedit.cpp 4
|
||||
|
||||
If either \a min or \a max are not valid, this function does
|
||||
nothing.
|
||||
If either \a min or \a max is invalid, this function does nothing. This
|
||||
function preserves the \l minimumTime property. If \a max is less than \a min,
|
||||
the new maximumDateTime property shall be the new minimumDateTime property. If
|
||||
\a max is equal to \a min and the \l maximumTime property was less then the \l
|
||||
minimumTime property, the \l maximumTime property is set to the \l minimumTime
|
||||
property. Otherwise, this preserves the \l maximumTime property.
|
||||
|
||||
\sa setMinimumDate(), maximumDate(), setMaximumDate(),
|
||||
clearMinimumDate(), setMinimumTime(), maximumTime(),
|
||||
setMaximumTime(), clearMinimumTime(), QDate::isValid()
|
||||
\sa minimumDate, maximumDate, setDateTimeRange(), QDate::isValid()
|
||||
*/
|
||||
|
||||
void QDateTimeEdit::setDateRange(const QDate &min, const QDate &max)
|
||||
@ -607,8 +630,16 @@ void QDateTimeEdit::setDateRange(const QDate &min, const QDate &max)
|
||||
}
|
||||
|
||||
/*!
|
||||
Convenience function to set minimum and maximum time with one
|
||||
function call.
|
||||
\brief Set the range of allowed times for the date time edit.
|
||||
|
||||
This convenience function sets the \l minimumTime and \l maximumTime
|
||||
properties.
|
||||
|
||||
Note that these only constrain the date time edit's value on,
|
||||
respectively, the \l minimumDate and \l maximumDate. When these date
|
||||
properties do not coincide, times after \a maximumTime are allowed on dates
|
||||
before \l maximumDate and times before \a minimumTime are allowed on dates
|
||||
after \l minimumDate.
|
||||
|
||||
\snippet code/src_gui_widgets_qdatetimeedit.cpp 5
|
||||
|
||||
@ -616,12 +647,11 @@ void QDateTimeEdit::setDateRange(const QDate &min, const QDate &max)
|
||||
|
||||
\snippet code/src_gui_widgets_qdatetimeedit.cpp 6
|
||||
|
||||
If either \a min or \a max are not valid, this function does
|
||||
nothing.
|
||||
If either \a min or \a max is invalid, this function does nothing. This
|
||||
function preserves the \l minimumDate and \l maximumDate properties. If those
|
||||
properties coincide and max is \a less than \a min, \a min is used as \a max.
|
||||
|
||||
\sa setMinimumDate(), maximumDate(), setMaximumDate(),
|
||||
clearMinimumDate(), setMinimumTime(), maximumTime(),
|
||||
setMaximumTime(), clearMinimumTime(), QTime::isValid()
|
||||
\sa minimumTime, maximumTime, setDateTimeRange(), QTime::isValid()
|
||||
*/
|
||||
|
||||
void QDateTimeEdit::setTimeRange(const QTime &min, const QTime &max)
|
||||
@ -865,7 +895,7 @@ QString QDateTimeEdit::sectionText(Section section) const
|
||||
|
||||
Note that if you specify a two digit year, it will be interpreted
|
||||
to be in the century in which the date time edit was initialized.
|
||||
The default century is the 21 (2000-2099).
|
||||
The default century is the 21st (2000-2099).
|
||||
|
||||
If you specify an invalid format the format will not be set.
|
||||
|
||||
|
@ -1216,8 +1216,8 @@ QMargins QLineEdit::textMargins() const
|
||||
\row \li \c a \li ASCII alphabetic character permitted but not required.
|
||||
\row \li \c N \li ASCII alphanumeric character required. A-Z, a-z, 0-9.
|
||||
\row \li \c n \li ASCII alphanumeric character permitted but not required.
|
||||
\row \li \c X \li Any character required.
|
||||
\row \li \c x \li Any character permitted but not required.
|
||||
\row \li \c X \li Any non-blank character required.
|
||||
\row \li \c x \li Any non-blank character permitted but not required.
|
||||
\row \li \c 9 \li ASCII digit required. 0-9.
|
||||
\row \li \c 0 \li ASCII digit permitted but not required.
|
||||
\row \li \c D \li ASCII digit required. 1-9.
|
||||
|
@ -792,6 +792,8 @@ void QMenuSloppyState::setSubMenuPopup(const QRect &actionRect, QAction *resetAc
|
||||
m_use_reset_action = true;
|
||||
m_time.stop();
|
||||
m_action_rect = actionRect;
|
||||
if (m_sub_menu)
|
||||
QMenuPrivate::get(m_sub_menu)->sloppyState.m_parent = nullptr;
|
||||
m_sub_menu = subMenu;
|
||||
QMenuPrivate::get(subMenu)->sloppyState.m_parent = this;
|
||||
m_reset_action = resetAction;
|
||||
|
@ -846,7 +846,8 @@ QMenu *QMenuBar::addMenu(const QIcon &icon, const QString &title)
|
||||
}
|
||||
|
||||
/*!
|
||||
Appends \a menu to the menu bar. Returns the menu's menuAction().
|
||||
Appends \a menu to the menu bar. Returns the menu's menuAction(). The menu bar
|
||||
does not take ownership of the menu.
|
||||
|
||||
\note The returned QAction object can be used to hide the corresponding
|
||||
menu.
|
||||
|
@ -2328,6 +2328,7 @@ void QPlainTextEdit::changeEvent(QEvent *e)
|
||||
d->autoScrollTimer.stop();
|
||||
} else if (e->type() == QEvent::EnabledChange) {
|
||||
e->setAccepted(isEnabled());
|
||||
d->control->setPalette(palette());
|
||||
d->sendControlEvent(e);
|
||||
} else if (e->type() == QEvent::PaletteChange) {
|
||||
d->control->setPalette(palette());
|
||||
|
@ -1090,7 +1090,7 @@ bool QWidgetLineControl::isValidInput(QChar key, QChar mask) const
|
||||
return true;
|
||||
break;
|
||||
case 'X':
|
||||
if (key.isPrint())
|
||||
if (key.isPrint() && key != m_blank)
|
||||
return true;
|
||||
break;
|
||||
case 'x':
|
||||
|
@ -1283,6 +1283,8 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
|
||||
} else {
|
||||
QTextCursor localCursor = cursor;
|
||||
localCursor.deletePreviousChar();
|
||||
if (cursor.d)
|
||||
cursor.d->setX();
|
||||
}
|
||||
goto accept;
|
||||
}
|
||||
@ -1322,9 +1324,13 @@ void QWidgetTextControlPrivate::keyPressEvent(QKeyEvent *e)
|
||||
else if (e == QKeySequence::Delete) {
|
||||
QTextCursor localCursor = cursor;
|
||||
localCursor.deleteChar();
|
||||
if (cursor.d)
|
||||
cursor.d->setX();
|
||||
} else if (e == QKeySequence::Backspace) {
|
||||
QTextCursor localCursor = cursor;
|
||||
localCursor.deletePreviousChar();
|
||||
if (cursor.d)
|
||||
cursor.d->setX();
|
||||
}else if (e == QKeySequence::DeleteEndOfWord) {
|
||||
if (!cursor.hasSelection())
|
||||
cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if QT_HAS_INCLUDE(<stdbool.h>) || __STDC_VERSION__ >= 199901L
|
||||
#if __has_include(<stdbool.h>) || __STDC_VERSION__ >= 199901L
|
||||
# include <stdbool.h>
|
||||
#else
|
||||
# undef true
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <QtCore/QElapsedTimer>
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
# include <chrono>
|
||||
#endif
|
||||
|
||||
@ -519,7 +519,7 @@ void tst_QDeadlineTimer::expire()
|
||||
|
||||
void tst_QDeadlineTimer::stdchrono()
|
||||
{
|
||||
#if !QT_HAS_INCLUDE(<chrono>)
|
||||
#if !__has_include(<chrono>)
|
||||
QSKIP("std::chrono not found on this system");
|
||||
#else
|
||||
using namespace std::chrono;
|
||||
|
@ -67,6 +67,7 @@ private slots:
|
||||
void sendPostedEvents_data();
|
||||
void sendPostedEvents();
|
||||
void processEventsOnlySendsQueuedEvents();
|
||||
void eventLoopExit();
|
||||
};
|
||||
|
||||
bool tst_QEventDispatcher::event(QEvent *e)
|
||||
@ -314,5 +315,49 @@ void tst_QEventDispatcher::processEventsOnlySendsQueuedEvents()
|
||||
QCOMPARE(object.eventsReceived, 4);
|
||||
}
|
||||
|
||||
void tst_QEventDispatcher::eventLoopExit()
|
||||
{
|
||||
// This test was inspired by QTBUG-79477. A particular
|
||||
// implementation detail in QCocoaEventDispatcher allowed
|
||||
// QEventLoop::exit() to fail to really exit the event loop.
|
||||
// Thus this test is a part of the dispatcher auto-test.
|
||||
|
||||
// Imitates QApplication::exec():
|
||||
QEventLoop mainLoop;
|
||||
// The test itself is a lambda:
|
||||
QTimer::singleShot(0, [&mainLoop]() {
|
||||
// Two more single shots, both will be posted as events
|
||||
// (zero timeout) and supposed to be processes by the
|
||||
// mainLoop:
|
||||
|
||||
QTimer::singleShot(0, [&mainLoop]() {
|
||||
// wakeUp triggers QCocoaEventDispatcher into incrementing
|
||||
// its 'serialNumber':
|
||||
mainLoop.wakeUp();
|
||||
// QCocoaEventDispatcher::processEvents() will process
|
||||
// posted events and execute the second lambda defined below:
|
||||
QCoreApplication::processEvents();
|
||||
});
|
||||
|
||||
QTimer::singleShot(0, [&mainLoop]() {
|
||||
// With QCocoaEventDispatcher this is executed while in the
|
||||
// processEvents (see above) and would fail to actually
|
||||
// interrupt the loop.
|
||||
mainLoop.exit();
|
||||
});
|
||||
});
|
||||
|
||||
bool timeoutObserved = false;
|
||||
QTimer::singleShot(500, [&timeoutObserved, &mainLoop]() {
|
||||
// In case the QEventLoop::exit above failed, we have to bail out
|
||||
// early, not wasting time:
|
||||
mainLoop.exit();
|
||||
timeoutObserved = true;
|
||||
});
|
||||
|
||||
mainLoop.exec();
|
||||
QVERIFY(!timeoutObserved);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QEventDispatcher)
|
||||
#include "tst_qeventdispatcher.moc"
|
||||
|
@ -223,7 +223,7 @@ void tst_QTimer::remainingTimeDuringActivation()
|
||||
|
||||
namespace {
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
template <typename T>
|
||||
std::chrono::milliseconds to_ms(T t)
|
||||
{ return std::chrono::duration_cast<std::chrono::milliseconds>(t); }
|
||||
@ -233,7 +233,7 @@ namespace {
|
||||
|
||||
void tst_QTimer::basic_chrono()
|
||||
{
|
||||
#if !QT_HAS_INCLUDE(<chrono>)
|
||||
#if !__has_include(<chrono>)
|
||||
QSKIP("This test requires C++11 <chrono> support");
|
||||
#else
|
||||
// duplicates zeroTimer, singleShotTimeout, interval and remainingTime
|
||||
@ -871,7 +871,7 @@ void tst_QTimer::singleShotToFunctors()
|
||||
|
||||
void tst_QTimer::singleShot_chrono()
|
||||
{
|
||||
#if !QT_HAS_INCLUDE(<chrono>)
|
||||
#if !__has_include(<chrono>)
|
||||
QSKIP("This test requires C++11 <chrono> support");
|
||||
#else
|
||||
// duplicates singleShotStaticFunctionZeroTimeout and singleShotToFunctors
|
||||
|
@ -45,7 +45,7 @@
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
#include <cmath>
|
||||
#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
|
||||
#if __has_include(<variant>) && __cplusplus >= 201703L
|
||||
#include <variant>
|
||||
#endif
|
||||
#include <QLinkedList>
|
||||
@ -4568,7 +4568,7 @@ void tst_QVariant::accessSequentialContainerKey()
|
||||
|
||||
void tst_QVariant::fromStdVariant()
|
||||
{
|
||||
#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
|
||||
#if __has_include(<variant>) && __cplusplus >= 201703L
|
||||
{
|
||||
typedef std::variant<int, bool> intorbool_t;
|
||||
intorbool_t stdvar = 5;
|
||||
|
@ -384,7 +384,7 @@ void tst_QCborValue::copyCompare()
|
||||
QCOMPARE(v, other);
|
||||
QVERIFY(!(v != other));
|
||||
QVERIFY(!(v < other));
|
||||
#if 0 && QT_HAS_INCLUDE(<compare>)
|
||||
#if 0 && __has_include(<compare>)
|
||||
QVERIFY(v <= other);
|
||||
QVERIFY(v >= other);
|
||||
QVERIFY(!(v > other));
|
||||
@ -821,9 +821,37 @@ void tst_QCborValue::mapMutation()
|
||||
QVERIFY(v.isUndefined());
|
||||
|
||||
// now mutate the list
|
||||
// simple -> HasByteData
|
||||
const QString strValue = QStringLiteral("value");
|
||||
v = strValue;
|
||||
QVERIFY(v.isString());
|
||||
QCOMPARE(v, QCborValue(strValue));
|
||||
QCOMPARE(m, QCborMap({{42, strValue}}));
|
||||
|
||||
// HasByteData -> HasByteData
|
||||
const QLatin1String otherStrValue("othervalue");
|
||||
v = otherStrValue;
|
||||
QVERIFY(v.isString());
|
||||
QCOMPARE(v, QCborValue(otherStrValue));
|
||||
QCOMPARE(m, QCborMap({{42, otherStrValue}}));
|
||||
|
||||
// HasByteData -> simple
|
||||
v = 42;
|
||||
QVERIFY(v.isInteger());
|
||||
QCOMPARE(v, QCborValue(42));
|
||||
QCOMPARE(m, QCborMap({{42, 42}}));
|
||||
|
||||
// simple -> container
|
||||
v = QCborArray{1, 2, 3};
|
||||
QVERIFY(v.isArray());
|
||||
QCOMPARE(v, QCborArray({1, 2, 3}));
|
||||
QCOMPARE(m, QCborMap({{42, QCborArray{1, 2, 3}}}));
|
||||
|
||||
// container -> simple
|
||||
v = true;
|
||||
QVERIFY(v.isBool());
|
||||
QVERIFY(v.isTrue());
|
||||
QCOMPARE(m, QCborMap({{42, true}}));
|
||||
QVERIFY(m.begin()->isTrue());
|
||||
QVERIFY(m.begin().value() == v);
|
||||
QVERIFY(v == m.begin().value());
|
||||
|
@ -89,7 +89,7 @@ enum {
|
||||
waitTime = 100
|
||||
};
|
||||
|
||||
#if QT_HAS_INCLUDE(<chrono>)
|
||||
#if __has_include(<chrono>)
|
||||
static Q_CONSTEXPR std::chrono::milliseconds waitTimeAsDuration(waitTime);
|
||||
#endif
|
||||
|
||||
@ -100,7 +100,7 @@ void tst_QMutex::convertToMilliseconds_data()
|
||||
QTest::addColumn<qint64>("intValue");
|
||||
QTest::addColumn<qint64>("expected");
|
||||
|
||||
#if !QT_HAS_INCLUDE(<chrono>)
|
||||
#if !__has_include(<chrono>)
|
||||
QSKIP("This test requires <chrono>");
|
||||
#endif
|
||||
|
||||
@ -156,7 +156,7 @@ void tst_QMutex::convertToMilliseconds_data()
|
||||
|
||||
void tst_QMutex::convertToMilliseconds()
|
||||
{
|
||||
#if !QT_HAS_INCLUDE(<chrono>)
|
||||
#if !__has_include(<chrono>)
|
||||
QSKIP("This test requires <chrono>");
|
||||
#else
|
||||
QFETCH(TimeUnit, unit);
|
||||
@ -325,7 +325,7 @@ void tst_QMutex::tryLock_non_recursive()
|
||||
}
|
||||
|
||||
void tst_QMutex::try_lock_for_non_recursive() {
|
||||
#if !QT_HAS_INCLUDE(<chrono>)
|
||||
#if !__has_include(<chrono>)
|
||||
QSKIP("This test requires <chrono>");
|
||||
#else
|
||||
class Thread : public QThread
|
||||
@ -454,7 +454,7 @@ void tst_QMutex::try_lock_for_non_recursive() {
|
||||
|
||||
void tst_QMutex::try_lock_until_non_recursive()
|
||||
{
|
||||
#if !QT_HAS_INCLUDE(<chrono>)
|
||||
#if !__has_include(<chrono>)
|
||||
QSKIP("This test requires <chrono>");
|
||||
#else
|
||||
class Thread : public QThread
|
||||
@ -707,7 +707,7 @@ void tst_QMutex::tryLock_recursive()
|
||||
|
||||
void tst_QMutex::try_lock_for_recursive()
|
||||
{
|
||||
#if !QT_HAS_INCLUDE(<chrono>)
|
||||
#if !__has_include(<chrono>)
|
||||
QSKIP("This test requires <chrono>");
|
||||
#else
|
||||
class Thread : public QThread
|
||||
@ -836,7 +836,7 @@ void tst_QMutex::try_lock_for_recursive()
|
||||
|
||||
void tst_QMutex::try_lock_until_recursive()
|
||||
{
|
||||
#if !QT_HAS_INCLUDE(<chrono>)
|
||||
#if !__has_include(<chrono>)
|
||||
QSKIP("This test requires <chrono>");
|
||||
#else
|
||||
class Thread : public QThread
|
||||
|
@ -150,6 +150,7 @@ private slots:
|
||||
void timeZones() const;
|
||||
void systemTimeZoneChange() const;
|
||||
|
||||
void invalid_data() const;
|
||||
void invalid() const;
|
||||
void range() const;
|
||||
|
||||
@ -2209,6 +2210,13 @@ void tst_QDateTime::fromStringDateFormat_data()
|
||||
<< Qt::TextDate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 3, 456));
|
||||
|
||||
// Test Qt::ISODate format.
|
||||
QTest::newRow("trailing space") // QTBUG-80445
|
||||
<< QString("2000-01-02 03:04:05.678 ")
|
||||
<< Qt::ISODate << QDateTime(QDate(2000, 1, 2), QTime(3, 4, 5, 678));
|
||||
QTest::newRow("space before millis")
|
||||
<< QString("2000-01-02 03:04:05. 678") << Qt::ISODate << QDateTime();
|
||||
|
||||
// Normal usage:
|
||||
QTest::newRow("ISO +01:00") << QString::fromLatin1("1987-02-13T13:24:51+01:00")
|
||||
<< Qt::ISODate << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC);
|
||||
QTest::newRow("ISO +00:01") << QString::fromLatin1("1987-02-13T13:24:51+00:01")
|
||||
@ -2229,11 +2237,17 @@ void tst_QDateTime::fromStringDateFormat_data()
|
||||
<< Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9), Qt::UTC);
|
||||
QTest::newRow("ISO zzz-3") << QString::fromLatin1("2014-12-15T12:37:09.745-3")
|
||||
<< Qt::ISODate << QDateTime(QDate(2014, 12, 15), QTime(15, 37, 9, 745), Qt::UTC);
|
||||
QTest::newRow("ISO lower-case") << QString::fromLatin1("2005-06-28T07:57:30.002z")
|
||||
<< Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2), Qt::UTC);
|
||||
// No time specified - defaults to Qt::LocalTime.
|
||||
QTest::newRow("ISO data3") << QString::fromLatin1("2002-10-01")
|
||||
<< Qt::ISODate << QDateTime(QDate(2002, 10, 1), QTime(0, 0, 0, 0), Qt::LocalTime);
|
||||
// Excess digits in milliseconds, round correctly:
|
||||
QTest::newRow("ISO") << QString::fromLatin1("2005-06-28T07:57:30.0010000000Z")
|
||||
<< Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 1), Qt::UTC);
|
||||
QTest::newRow("ISO rounding") << QString::fromLatin1("2005-06-28T07:57:30.0015Z")
|
||||
<< Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 2), Qt::UTC);
|
||||
// ... and accept comma as separator:
|
||||
QTest::newRow("ISO with comma 1") << QString::fromLatin1("2005-06-28T07:57:30,0040000000Z")
|
||||
<< Qt::ISODate << QDateTime(QDate(2005, 6, 28), QTime(7, 57, 30, 4), Qt::UTC);
|
||||
QTest::newRow("ISO with comma 2") << QString::fromLatin1("2005-06-28T07:57:30,0015Z")
|
||||
@ -2458,6 +2472,7 @@ void tst_QDateTime::fromStringStringFormat_data()
|
||||
if (southBrazil.isValid()) {
|
||||
QTest::newRow("spring-forward-midnight")
|
||||
<< QString("2008-10-19 23:45.678 America/Sao_Paulo") << QString("yyyy-MM-dd mm:ss.zzz t")
|
||||
// That's in the hour skipped - expect the matching time after the spring-forward, in DST:
|
||||
<< QDateTime(QDate(2008, 10, 19), QTime(1, 23, 45, 678), southBrazil);
|
||||
}
|
||||
#endif
|
||||
@ -3359,6 +3374,9 @@ void tst_QDateTime::timeZones() const
|
||||
QCOMPARE(utc.date(), utcDst.date());
|
||||
QCOMPARE(utc.time(), utcDst.time());
|
||||
|
||||
// Crash test, QTBUG-80146:
|
||||
QVERIFY(!nzStd.toTimeZone(QTimeZone()).isValid());
|
||||
|
||||
// Sydney is 2 hours behind New Zealand
|
||||
QTimeZone ausTz = QTimeZone("Australia/Sydney");
|
||||
QDateTime aus = nzStd.toTimeZone(ausTz);
|
||||
@ -3528,23 +3546,42 @@ void tst_QDateTime::systemTimeZoneChange() const
|
||||
QCOMPARE(tzDate.toMSecsSinceEpoch(), tzMsecs);
|
||||
}
|
||||
|
||||
void tst_QDateTime::invalid_data() const
|
||||
{
|
||||
QTest::addColumn<QDateTime>("when");
|
||||
QTest::addColumn<Qt::TimeSpec>("spec");
|
||||
QTest::addColumn<bool>("goodZone");
|
||||
QTest::newRow("default") << QDateTime() << Qt::LocalTime << true;
|
||||
|
||||
QDateTime invalidDate = QDateTime(QDate(0, 0, 0), QTime(-1, -1, -1));
|
||||
QTest::newRow("simple") << invalidDate << Qt::LocalTime << true;
|
||||
QTest::newRow("UTC") << invalidDate.toUTC() << Qt::UTC << true;
|
||||
QTest::newRow("offset")
|
||||
<< invalidDate.toOffsetFromUtc(3600) << Qt::OffsetFromUTC << true;
|
||||
QTest::newRow("CET")
|
||||
<< invalidDate.toTimeZone(QTimeZone("Europe/Oslo")) << Qt::TimeZone << true;
|
||||
|
||||
// Crash tests, QTBUG-80146:
|
||||
QTest::newRow("nozone+construct")
|
||||
<< QDateTime(QDate(1970, 1, 1), QTime(12, 0), QTimeZone()) << Qt::TimeZone << false;
|
||||
QTest::newRow("nozone+fromMSecs")
|
||||
<< QDateTime::fromMSecsSinceEpoch(42, QTimeZone()) << Qt::TimeZone << false;
|
||||
QDateTime valid(QDate(1970, 1, 1), QTime(12, 0), Qt::UTC);
|
||||
QTest::newRow("tonozone") << valid.toTimeZone(QTimeZone()) << Qt::TimeZone << false;
|
||||
}
|
||||
|
||||
void tst_QDateTime::invalid() const
|
||||
{
|
||||
QDateTime invalidDate = QDateTime(QDate(0, 0, 0), QTime(-1, -1, -1));
|
||||
QCOMPARE(invalidDate.isValid(), false);
|
||||
QCOMPARE(invalidDate.timeSpec(), Qt::LocalTime);
|
||||
|
||||
QDateTime utcDate = invalidDate.toUTC();
|
||||
QCOMPARE(utcDate.isValid(), false);
|
||||
QCOMPARE(utcDate.timeSpec(), Qt::UTC);
|
||||
|
||||
QDateTime offsetDate = invalidDate.toOffsetFromUtc(3600);
|
||||
QCOMPARE(offsetDate.isValid(), false);
|
||||
QCOMPARE(offsetDate.timeSpec(), Qt::OffsetFromUTC);
|
||||
|
||||
QDateTime tzDate = invalidDate.toTimeZone(QTimeZone("Europe/Oslo"));
|
||||
QCOMPARE(tzDate.isValid(), false);
|
||||
QCOMPARE(tzDate.timeSpec(), Qt::TimeZone);
|
||||
QFETCH(QDateTime, when);
|
||||
QFETCH(Qt::TimeSpec, spec);
|
||||
QFETCH(bool, goodZone);
|
||||
QVERIFY(!when.isValid());
|
||||
QCOMPARE(when.timeSpec(), spec);
|
||||
QCOMPARE(when.timeZoneAbbreviation(), QString());
|
||||
if (!goodZone)
|
||||
QCOMPARE(when.toMSecsSinceEpoch(), 0);
|
||||
QVERIFY(!when.isDaylightTime());
|
||||
QCOMPARE(when.timeZone().isValid(), goodZone);
|
||||
}
|
||||
|
||||
void tst_QDateTime::range() const
|
||||
|
@ -51,7 +51,7 @@
|
||||
#ifdef Q_CC_MSVC
|
||||
#define COMPILER_HAS_STDLIB_INCLUDE(x) 1
|
||||
#else
|
||||
#define COMPILER_HAS_STDLIB_INCLUDE(x) QT_HAS_INCLUDE(x)
|
||||
#define COMPILER_HAS_STDLIB_INCLUDE(x) __has_include(x)
|
||||
#endif
|
||||
|
||||
#if COMPILER_HAS_STDLIB_INCLUDE(<forward_list>)
|
||||
|
@ -125,6 +125,7 @@ private slots:
|
||||
void clonePreservesResources();
|
||||
void clonePreservesUserStates();
|
||||
void clonePreservesIndentWidth();
|
||||
void clonePreservesFormatsWhenEmpty();
|
||||
void blockCount();
|
||||
void defaultStyleSheet();
|
||||
|
||||
@ -2348,6 +2349,32 @@ void tst_QTextDocument::clonePreservesIndentWidth()
|
||||
delete clone;
|
||||
}
|
||||
|
||||
void tst_QTextDocument::clonePreservesFormatsWhenEmpty()
|
||||
{
|
||||
QTextDocument document;
|
||||
QTextCursor cursor(&document);
|
||||
|
||||
// Change a few char format attributes
|
||||
QTextCharFormat charFormat;
|
||||
charFormat.setFontPointSize(charFormat.fontPointSize() + 1);
|
||||
charFormat.setFontWeight(charFormat.fontWeight() + 1);
|
||||
cursor.setBlockCharFormat(charFormat);
|
||||
|
||||
// Change a few block format attributes
|
||||
QTextBlockFormat blockFormat;
|
||||
blockFormat.setAlignment(Qt::AlignRight); // The default is Qt::AlignLeft
|
||||
blockFormat.setIndent(blockFormat.indent() + 1);
|
||||
cursor.setBlockFormat(blockFormat);
|
||||
|
||||
auto clone = document.clone();
|
||||
QTextCursor cloneCursor(clone);
|
||||
|
||||
QCOMPARE(cloneCursor.blockCharFormat().fontPointSize(), charFormat.fontPointSize());
|
||||
QCOMPARE(cloneCursor.blockCharFormat().fontWeight(), charFormat.fontWeight());
|
||||
QCOMPARE(cloneCursor.blockFormat().alignment(), blockFormat.alignment());
|
||||
QCOMPARE(cloneCursor.blockFormat().indent(), blockFormat.indent());
|
||||
}
|
||||
|
||||
void tst_QTextDocument::blockCount()
|
||||
{
|
||||
QCOMPARE(doc->blockCount(), 1);
|
||||
|
@ -1,3 +0,0 @@
|
||||
# QTBUG-65667
|
||||
[localAddress:linklocal-ipv4]
|
||||
windows ci
|
@ -215,31 +215,45 @@ void tst_QNetworkInterface::loopbackIPv6()
|
||||
}
|
||||
void tst_QNetworkInterface::localAddress_data()
|
||||
{
|
||||
bool ipv6 = isIPv6Working();
|
||||
QTest::addColumn<QHostAddress>("target");
|
||||
|
||||
QTest::newRow("localhost-ipv4") << QHostAddress(QHostAddress::LocalHost);
|
||||
if (isIPv6Working())
|
||||
if (ipv6)
|
||||
QTest::newRow("localhost-ipv6") << QHostAddress(QHostAddress::LocalHostIPv6);
|
||||
|
||||
QTest::newRow("test-server") << QtNetworkSettings::serverIP();
|
||||
|
||||
// Since we don't actually transmit anything, we can list any IPv4 address
|
||||
// and it should work. But we're using a linklocal address so that this
|
||||
// test can pass even machines that failed to reach a DHCP server.
|
||||
QTest::newRow("linklocal-ipv4") << QHostAddress("169.254.0.1");
|
||||
QSet<QHostAddress> added;
|
||||
const QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
|
||||
for (const QNetworkInterface &iface : ifaces) {
|
||||
if ((iface.flags() & QNetworkInterface::IsUp) == 0)
|
||||
continue;
|
||||
const QList<QNetworkAddressEntry> addrs = iface.addressEntries();
|
||||
for (const QNetworkAddressEntry &entry : addrs) {
|
||||
QHostAddress addr = entry.ip();
|
||||
if (addr.isLoopback())
|
||||
continue; // added above
|
||||
|
||||
if (isIPv6Working()) {
|
||||
// On the other hand, we can't list just any IPv6 here. It's very
|
||||
// likely that this machine has not received a route via ICMPv6-RA or
|
||||
// DHCPv6, so it won't have a global route. On some OSes, IPv6 may be
|
||||
// enabled per interface, so we need to know which ones work.
|
||||
const QList<QHostAddress> addrs = QNetworkInterface::allAddresses();
|
||||
for (const QHostAddress &addr : addrs) {
|
||||
QString scope = addr.scopeId();
|
||||
if (scope.isEmpty())
|
||||
if (addr.protocol() == QAbstractSocket::IPv4Protocol) {
|
||||
// add an IPv4 address with bits in the host portion of the address flipped
|
||||
quint32 ip4 = entry.ip().toIPv4Address();
|
||||
addr.setAddress(ip4 ^ ~entry.netmask().toIPv4Address());
|
||||
} else if (!ipv6 || entry.prefixLength() != 64) {
|
||||
continue;
|
||||
QTest::addRow("linklocal-ipv6-%s", qPrintable(scope))
|
||||
<< QHostAddress("fe80::1234%" + scope);
|
||||
} else {
|
||||
// add a random node in this IPv6 network
|
||||
quint64 randomid = qFromBigEndian(Q_UINT64_C(0x8f41f072e5733caa));
|
||||
QIPv6Address ip6 = addr.toIPv6Address();
|
||||
memcpy(&ip6[8], &randomid, sizeof(randomid));
|
||||
addr.setAddress(ip6);
|
||||
}
|
||||
|
||||
if (added.contains(addr))
|
||||
continue;
|
||||
added.insert(addr);
|
||||
|
||||
QTest::addRow("%s-%s", qPrintable(iface.name()), qPrintable(addr.toString())) << addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -965,9 +965,7 @@ void tst_QSqlQuery::blob()
|
||||
//don' make it too big otherwise sybase and mysql will complain
|
||||
QByteArray ba( BLOBSIZE, 0 );
|
||||
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < ( int )ba.size(); ++i )
|
||||
for (int i = 0; i < ba.size(); ++i)
|
||||
ba[i] = i % 256;
|
||||
|
||||
QSqlQuery q( db );
|
||||
@ -980,7 +978,7 @@ void tst_QSqlQuery::blob()
|
||||
|
||||
QVERIFY_SQL(q, prepare("insert into " + qTableName("qtest_blob", __FILE__, db) + " (id, t_blob) values (?, ?)"));
|
||||
|
||||
for ( i = 0; i < BLOBCOUNT; ++i ) {
|
||||
for (int i = 0; i < BLOBCOUNT; ++i) {
|
||||
q.addBindValue( i );
|
||||
q.addBindValue( ba );
|
||||
QVERIFY_SQL( q, exec() );
|
||||
@ -988,13 +986,13 @@ void tst_QSqlQuery::blob()
|
||||
|
||||
QVERIFY_SQL(q, exec("select * from " + qTableName("qtest_blob", __FILE__, db)));
|
||||
|
||||
for ( i = 0; i < BLOBCOUNT; ++i ) {
|
||||
for (int i = 0; i < BLOBCOUNT; ++i) {
|
||||
QVERIFY( q.next() );
|
||||
QByteArray res = q.value( 1 ).toByteArray();
|
||||
QVERIFY2( res.size() >= ba.size(),
|
||||
QString( "array sizes differ, expected %1, got %2" ).arg( ba.size() ).arg( res.size() ).toLatin1() );
|
||||
|
||||
for ( int i2 = 0; i2 < ( int )ba.size(); ++i2 ) {
|
||||
for (int i2 = 0; i2 < ba.size(); ++i2) {
|
||||
if ( res[i2] != ba[i2] )
|
||||
QFAIL( QString( "ByteArrays differ at position %1, expected %2, got %3" ).arg(
|
||||
i2 ).arg(( int )( unsigned char )ba[i2] ).arg(( int )( unsigned char )res[i2] ).toLatin1() );
|
||||
@ -1834,7 +1832,7 @@ void tst_QSqlQuery::oci_rawField()
|
||||
}
|
||||
|
||||
// test whether we can fetch values with more than DOUBLE precision
|
||||
// note that MySQL's 3.x highest precision is that of a double, although
|
||||
// note that SQLite highest precision is that of a double, although
|
||||
// you can define field with higher precision
|
||||
void tst_QSqlQuery::precision()
|
||||
{
|
||||
@ -1845,46 +1843,41 @@ void tst_QSqlQuery::precision()
|
||||
if (dbType == QSqlDriver::Interbase)
|
||||
QSKIP("DB unable to store high precision");
|
||||
|
||||
const auto oldPrecision = db.driver()->numericalPrecisionPolicy();
|
||||
db.driver()->setNumericalPrecisionPolicy(QSql::HighPrecision);
|
||||
const QString qtest_precision(qTableName("qtest_precision", __FILE__, db));
|
||||
static const char precStr[] = "1.2345678901234567891";
|
||||
const int precStrLen = sizeof(precStr);
|
||||
static const QLatin1String precStr("1.2345678901234567891");
|
||||
|
||||
{
|
||||
// need a new scope for SQLITE
|
||||
QSqlQuery q( db );
|
||||
|
||||
q.exec("drop table " + qtest_precision);
|
||||
if ( tst_Databases::isMSAccess( db ) )
|
||||
QVERIFY_SQL( q, exec( "create table " + qtest_precision + " (col1 number)" ) );
|
||||
if (tst_Databases::isMSAccess(db))
|
||||
QVERIFY_SQL(q, exec("CREATE TABLE " + qtest_precision + " (col1 number)"));
|
||||
else
|
||||
QVERIFY_SQL( q, exec( "create table " + qtest_precision + " (col1 numeric(21, 20))" ) );
|
||||
QVERIFY_SQL(q, exec("CREATE TABLE " + qtest_precision + " (col1 numeric(21, 20))"));
|
||||
|
||||
QVERIFY_SQL( q, exec( "insert into " + qtest_precision + " (col1) values (1.2345678901234567891)" ) );
|
||||
|
||||
QVERIFY_SQL( q, exec( "select * from " + qtest_precision ) );
|
||||
QVERIFY( q.next() );
|
||||
|
||||
QString val = q.value( 0 ).toString();
|
||||
|
||||
if ( !val.startsWith( "1.2345678901234567891" ) ) {
|
||||
QVERIFY_SQL(q, exec("INSERT INTO " + qtest_precision + " (col1) VALUES (" + precStr + ")"));
|
||||
QVERIFY_SQL(q, exec("SELECT * FROM " + qtest_precision));
|
||||
QVERIFY(q.next());
|
||||
const QString val = q.value(0).toString();
|
||||
if (!val.startsWith(precStr)) {
|
||||
int i = 0;
|
||||
|
||||
while ( i < precStrLen && i < val.size() && precStr[i] != 0 && *( precStr + i ) == val[i].toLatin1() )
|
||||
while (i < val.size() && precStr[i] != 0 && precStr[i] == val[i].toLatin1())
|
||||
i++;
|
||||
|
||||
// MySQL and TDS have crappy precisions by default
|
||||
if (dbType == QSqlDriver::MySqlServer) {
|
||||
if ( i < 17 )
|
||||
QWARN( "MySQL didn't return the right precision" );
|
||||
} else if (dbType == QSqlDriver::Sybase) {
|
||||
if ( i < 18 )
|
||||
QWARN( "TDS didn't return the right precision" );
|
||||
// TDS has crappy precisions by default
|
||||
if (dbType == QSqlDriver::Sybase) {
|
||||
if (i < 18)
|
||||
QWARN("TDS didn't return the right precision");
|
||||
} else {
|
||||
QWARN( QString( tst_Databases::dbToString( db ) + " didn't return the right precision (" +
|
||||
QString::number( i ) + " out of 21), " + val ).toLatin1() );
|
||||
QWARN(QString(tst_Databases::dbToString(db) + " didn't return the right precision (" +
|
||||
QString::number(i) + " out of 21), " + val).toUtf8());
|
||||
}
|
||||
}
|
||||
} // SQLITE scope
|
||||
db.driver()->setNumericalPrecisionPolicy(oldPrecision);
|
||||
}
|
||||
|
||||
void tst_QSqlQuery::nullResult()
|
||||
@ -2840,10 +2833,11 @@ void tst_QSqlQuery::psql_bindWithDoubleColonCastOperator()
|
||||
QVERIFY_SQL( q, exec() );
|
||||
QVERIFY_SQL( q, next() );
|
||||
|
||||
if ( db.driver()->hasFeature( QSqlDriver::PreparedQueries ) )
|
||||
QCOMPARE( q.executedQuery(), QString( "select sum((fld1 - fld2)::int) from " + tablename + " where id1 = ? and id2 =? and id3=?" ) );
|
||||
// the positional placeholders are converted to named placeholders in executedQuery()
|
||||
if (db.driver()->hasFeature(QSqlDriver::PreparedQueries))
|
||||
QCOMPARE(q.executedQuery(), QString("select sum((fld1 - fld2)::int) from " + tablename + " where id1 = :myid1 and id2 =:myid2 and id3=:myid3"));
|
||||
else
|
||||
QCOMPARE( q.executedQuery(), QString( "select sum((fld1 - fld2)::int) from " + tablename + " where id1 = 1 and id2 =2 and id3=3" ) );
|
||||
QCOMPARE(q.executedQuery(), QString("select sum((fld1 - fld2)::int) from " + tablename + " where id1 = 1 and id2 =2 and id3=3"));
|
||||
}
|
||||
|
||||
void tst_QSqlQuery::psql_specialFloatValues()
|
||||
@ -4003,8 +3997,8 @@ void tst_QSqlQuery::QTBUG_2192()
|
||||
|
||||
// Check if retrieved value preserves reported precision
|
||||
int precision = qMax(0, q.record().field("dt").precision());
|
||||
int diff = qAbs(q.value(0).toDateTime().msecsTo(dt));
|
||||
int keep = qMin(1000, (int)qPow(10.0, precision));
|
||||
qint64 diff = qAbs(q.value(0).toDateTime().msecsTo(dt));
|
||||
qint64 keep = qMin(1000LL, qRound64(qPow(10.0, precision)));
|
||||
QVERIFY(diff <= 1000 - keep);
|
||||
}
|
||||
}
|
||||
@ -4021,8 +4015,10 @@ void tst_QSqlQuery::QTBUG_36211()
|
||||
QSqlQuery q(db);
|
||||
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (dtwtz timestamptz, dtwotz timestamp)").arg(tableName)));
|
||||
|
||||
QTimeZone l_tzBrazil("BRT");
|
||||
QTimeZone l_tzChina("CST");
|
||||
QTimeZone l_tzBrazil("America/Sao_Paulo");
|
||||
QTimeZone l_tzChina("Asia/Shanghai");
|
||||
QVERIFY(l_tzBrazil.isValid());
|
||||
QVERIFY(l_tzChina.isValid());
|
||||
QDateTime dt = QDateTime(QDate(2014, 10, 30), QTime(14, 12, 02, 357));
|
||||
QVERIFY_SQL(q, prepare("INSERT INTO " + tableName + " (dtwtz, dtwotz) VALUES (:dt, :dt)"));
|
||||
q.bindValue(":dt", dt);
|
||||
@ -4040,8 +4036,8 @@ void tst_QSqlQuery::QTBUG_36211()
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
// Check if retrieved value preserves reported precision
|
||||
int precision = qMax(0, q.record().field(j).precision());
|
||||
int diff = qAbs(q.value(j).toDateTime().msecsTo(dt));
|
||||
int keep = qMin(1000, (int)qPow(10.0, precision));
|
||||
qint64 diff = qAbs(q.value(j).toDateTime().msecsTo(dt));
|
||||
qint64 keep = qMin(1000LL, qRound64(qPow(10.0, precision)));
|
||||
QVERIFY(diff <= 1000 - keep);
|
||||
}
|
||||
}
|
||||
|
@ -1380,6 +1380,7 @@ void tst_QFiledialog::clearLineEdit()
|
||||
fd.setFileMode(QFileDialog::AnyFile);
|
||||
fd.show();
|
||||
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&fd));
|
||||
QLineEdit *lineEdit = fd.findChild<QLineEdit*>("fileNameEdit");
|
||||
QVERIFY(lineEdit);
|
||||
QCOMPARE(lineEdit->text(), QLatin1String("foo"));
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include <QtGui/qpaintengine.h>
|
||||
#include <QtGui/qbackingstore.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtGui/qpa/qplatformwindow.h>
|
||||
#include <QtGui/qscreen.h>
|
||||
#include <qmenubar.h>
|
||||
#include <qcompleter.h>
|
||||
@ -227,6 +228,7 @@ private slots:
|
||||
void setFixedSize();
|
||||
|
||||
void ensureCreated();
|
||||
void createAndDestroy();
|
||||
void winIdChangeEvent();
|
||||
void persistentWinId();
|
||||
void showNativeChild();
|
||||
@ -4250,6 +4252,58 @@ public:
|
||||
int winIdChangeEventCount() const { return m_winIdList.count(); }
|
||||
};
|
||||
|
||||
class CreateDestroyWidget : public WinIdChangeWidget
|
||||
{
|
||||
public:
|
||||
void create() { QWidget::create(); }
|
||||
void destroy() { QWidget::destroy(); }
|
||||
};
|
||||
|
||||
void tst_QWidget::createAndDestroy()
|
||||
{
|
||||
CreateDestroyWidget widget;
|
||||
|
||||
// Create and destroy via QWidget
|
||||
widget.create();
|
||||
QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 1);
|
||||
QVERIFY(widget.internalWinId());
|
||||
|
||||
widget.destroy();
|
||||
QVERIFY(!widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 2);
|
||||
QVERIFY(!widget.internalWinId());
|
||||
|
||||
// Create via QWidget, destroy via QWindow
|
||||
widget.create();
|
||||
QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 3);
|
||||
QVERIFY(widget.internalWinId());
|
||||
|
||||
widget.windowHandle()->destroy();
|
||||
QVERIFY(!widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 4);
|
||||
QVERIFY(!widget.internalWinId());
|
||||
|
||||
// Create via QWidget again
|
||||
widget.create();
|
||||
QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 5);
|
||||
QVERIFY(widget.internalWinId());
|
||||
|
||||
// Destroy via QWindow, create via QWindow
|
||||
widget.windowHandle()->destroy();
|
||||
QVERIFY(widget.windowHandle());
|
||||
QVERIFY(!widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 6);
|
||||
QVERIFY(!widget.internalWinId());
|
||||
|
||||
widget.windowHandle()->create();
|
||||
QVERIFY(widget.testAttribute(Qt::WA_WState_Created));
|
||||
QCOMPARE(widget.winIdChangeEventCount(), 7);
|
||||
QVERIFY(widget.internalWinId());
|
||||
}
|
||||
|
||||
void tst_QWidget::winIdChangeEvent()
|
||||
{
|
||||
{
|
||||
|
@ -885,9 +885,6 @@ void tst_QLineEdit::hasAcceptableInputMask()
|
||||
qApp->sendEvent(testWidget, &lostFocus);
|
||||
QVERIFY(validInput);
|
||||
|
||||
// at the moment we don't strip the blank character if it is valid input, this makes the test between x vs X useless
|
||||
QEXPECT_FAIL( "Any optional and required", "To eat blanks or not? Known issue. Task 43172", Abort);
|
||||
|
||||
// test requiredMask
|
||||
testWidget->setInputMask(requiredMask);
|
||||
validInput = true;
|
||||
|
@ -155,6 +155,7 @@ private slots:
|
||||
#if QT_CONFIG(scrollbar)
|
||||
void updateAfterChangeCenterOnScroll();
|
||||
#endif
|
||||
void updateCursorPositionAfterEdit();
|
||||
|
||||
private:
|
||||
void createSelection();
|
||||
@ -1802,5 +1803,50 @@ void tst_QPlainTextEdit::updateAfterChangeCenterOnScroll()
|
||||
|
||||
#endif
|
||||
|
||||
void tst_QPlainTextEdit::updateCursorPositionAfterEdit()
|
||||
{
|
||||
QPlainTextEdit plaintextEdit;
|
||||
plaintextEdit.setPlainText("some text some text\nsome text some text");
|
||||
|
||||
const auto initialPosition = 1;
|
||||
|
||||
// select some text
|
||||
auto cursor = plaintextEdit.textCursor();
|
||||
cursor.setPosition(initialPosition, QTextCursor::MoveAnchor);
|
||||
cursor.setPosition(initialPosition + 3, QTextCursor::KeepAnchor);
|
||||
plaintextEdit.setTextCursor(cursor);
|
||||
QVERIFY(plaintextEdit.textCursor().hasSelection());
|
||||
|
||||
QTest::keyClick(&plaintextEdit, Qt::Key_Delete);
|
||||
QTest::keyClick(&plaintextEdit, Qt::Key_Down);
|
||||
QTest::keyClick(&plaintextEdit, Qt::Key_Up);
|
||||
|
||||
// Moving the cursor down and up should bring it to the initial position
|
||||
QCOMPARE(plaintextEdit.textCursor().position(), initialPosition);
|
||||
|
||||
// Test the same with backspace
|
||||
cursor = plaintextEdit.textCursor();
|
||||
cursor.setPosition(initialPosition + 3, QTextCursor::KeepAnchor);
|
||||
plaintextEdit.setTextCursor(cursor);
|
||||
QVERIFY(plaintextEdit.textCursor().hasSelection());
|
||||
|
||||
QTest::keyClick(&plaintextEdit, Qt::Key_Backspace);
|
||||
QTest::keyClick(&plaintextEdit, Qt::Key_Down);
|
||||
QTest::keyClick(&plaintextEdit, Qt::Key_Up);
|
||||
|
||||
// Moving the cursor down and up should bring it to the initial position
|
||||
QCOMPARE(plaintextEdit.textCursor().position(), initialPosition);
|
||||
|
||||
// Test insertion
|
||||
const QString txt("txt");
|
||||
QApplication::clipboard()->setText(txt);
|
||||
plaintextEdit.paste();
|
||||
QTest::keyClick(&plaintextEdit, Qt::Key_Down);
|
||||
QTest::keyClick(&plaintextEdit, Qt::Key_Up);
|
||||
|
||||
// The curser should move back to the end of the copied text
|
||||
QCOMPARE(plaintextEdit.textCursor().position(), initialPosition + txt.length());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QPlainTextEdit)
|
||||
#include "tst_qplaintextedit.moc"
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtCore/private/qmemory_p.h>
|
||||
#include <mutex>
|
||||
#if QT_HAS_INCLUDE(<shared_mutex>)
|
||||
#if __has_include(<shared_mutex>)
|
||||
#if __cplusplus > 201103L
|
||||
#include <shared_mutex>
|
||||
#endif
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <QButtonGroup>
|
||||
#include <QLineEdit>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QTabWidget>
|
||||
#include <QScrollBar>
|
||||
#include <QSlider>
|
||||
#include <QSpinBox>
|
||||
@ -51,12 +52,14 @@
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsTextItem>
|
||||
#include <QFile>
|
||||
#include <QFontMetrics>
|
||||
#include <QMouseEvent>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTimer>
|
||||
#include <QCommandLineParser>
|
||||
#include <QCommandLineOption>
|
||||
#include <QDebug>
|
||||
#include <QElapsedTimer>
|
||||
#include <private/qhighdpiscaling_p.h>
|
||||
#include <qpa/qplatformscreen.h>
|
||||
|
||||
@ -64,6 +67,12 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
static QTextStream &operator<<(QTextStream &str, const QSizeF &s)
|
||||
{
|
||||
str << s.width() << 'x' << s.height();
|
||||
return str;
|
||||
}
|
||||
|
||||
static QTextStream &operator<<(QTextStream &str, const QRect &r)
|
||||
{
|
||||
str << r.width() << 'x' << r.height() << Qt::forcesign << r.x() << r.y() << Qt::noforcesign;
|
||||
@ -1241,7 +1250,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class MetricsTest : public QWidget
|
||||
class MetricsTest : public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -1258,14 +1267,25 @@ QT_SCREEN_SCALE_FACTORS=N;N;N or QT_SCREEN_SCALE_FACTORS=name:N
|
||||
QT_SCALE_FACTOR_ROUNDING_POLICY=Round|Ceil|Floor|RoundPreferFloor|PassThrough
|
||||
QT_DPI_ADJUSTMENT_POLICY=AdjustDpi|DontAdjustDpi|AdjustUpOnly)";
|
||||
|
||||
resize(480, 360);
|
||||
m_textEdit = addTextPage("Parameters");
|
||||
m_logEdit = addTextPage("Screen Change Log");
|
||||
|
||||
auto layout = new QVBoxLayout(this);
|
||||
const auto screens = QGuiApplication::screens();
|
||||
for (auto screen : screens)
|
||||
connectScreenChangeSignals(screen);
|
||||
connect(qApp, &QGuiApplication::screenAdded, this, &MetricsTest::slotScreenAdded);
|
||||
connect(qApp, &QGuiApplication::primaryScreenChanged, this, &MetricsTest::slotPrimaryScreenChanged);
|
||||
connect(qApp, &QGuiApplication::screenRemoved, this, &MetricsTest::slotScreenRemoved);
|
||||
|
||||
m_textEdit = new QPlainTextEdit;
|
||||
m_textEdit->setReadOnly(true);
|
||||
layout->addWidget(m_textEdit);
|
||||
setWindowTitle(formatWindowTitle("Screens"));
|
||||
m_logTimer.start();
|
||||
logMessage(briefFormatScreens());
|
||||
|
||||
// Resize to roughly match the metrics text.
|
||||
const auto metrics = QFontMetrics(m_textEdit->font(), m_textEdit);
|
||||
const int width = 10 + metrics.horizontalAdvance(QStringLiteral("X")) * 50;
|
||||
const int height = 40 + metrics.height() * (10 + 8 * screens.size());
|
||||
resize(width, height);
|
||||
}
|
||||
|
||||
void setVisible(bool visible) override
|
||||
@ -1323,15 +1343,118 @@ QT_DPI_ADJUSTMENT_POLICY=AdjustDpi|DontAdjustDpi|AdjustUpOnly)";
|
||||
private slots:
|
||||
void screenChanged()
|
||||
{
|
||||
qDebug().noquote() << __FUNCTION__ << windowHandle()->screen()->name();
|
||||
const QString message = QLatin1String("screenChanged ") + windowHandle()->screen()->name();
|
||||
qInfo("%s", qPrintable(message));
|
||||
logMessage(message);
|
||||
updateMetrics();
|
||||
}
|
||||
|
||||
void slotScreenAdded(QScreen *);
|
||||
void slotScreenRemoved(QScreen *);
|
||||
void slotPrimaryScreenChanged(QScreen *);
|
||||
void slotScreenGeometryChanged(const QRect &geometry)
|
||||
{ logScreenChangeSignal(sender(), "geometry", geometry); }
|
||||
void slotScreenAvailableGeometryChanged(const QRect &geometry)
|
||||
{ logScreenChangeSignal(sender(), "availableGeometry", geometry); }
|
||||
void slotScreenPhysicalSizeChanged(const QSizeF &size)
|
||||
{ logScreenChangeSignal(sender(), "physicalSize", size); }
|
||||
void slotScreenPhysicalDotsPerInchChanged(qreal dpi)
|
||||
{ logScreenChangeSignal(sender(), "physicalDotsPerInch", dpi); }
|
||||
void slotScreenLogicalDotsPerInchChanged(qreal dpi)
|
||||
{ logScreenChangeSignal(sender(), "logicalDotsPerInch", dpi); }
|
||||
void slotScreenVirtualGeometryChanged(const QRect &rect)
|
||||
{ logScreenChangeSignal(sender(), "virtualGeometry", rect); }
|
||||
void slotScreenPrimaryOrientationChanged(Qt::ScreenOrientation orientation)
|
||||
{ logScreenChangeSignal(sender(), "primaryOrientation", orientation); }
|
||||
void slotScreenOrientationChanged(Qt::ScreenOrientation orientation)
|
||||
{ logScreenChangeSignal(sender(), "orientation", orientation); }
|
||||
void slotScreenRefreshRateChanged(qreal refreshRate)
|
||||
{ logScreenChangeSignal(sender(), "refreshRate", refreshRate); }
|
||||
|
||||
private:
|
||||
QPlainTextEdit *addTextPage(const QString &title);
|
||||
void logMessage(const QString &);
|
||||
void connectScreenChangeSignals(QScreen *s);
|
||||
static QString briefFormatScreens();
|
||||
template <class T>
|
||||
void logScreenChangeSignal(const QObject *o, const char *name, const T &value);
|
||||
|
||||
QPlainTextEdit *m_textEdit;
|
||||
QPlainTextEdit *m_logEdit;
|
||||
QElapsedTimer m_logTimer;
|
||||
bool m_screenChangedConnected = false;
|
||||
};
|
||||
|
||||
void MetricsTest::slotScreenAdded(QScreen *screen)
|
||||
{
|
||||
logMessage(QLatin1String("Added ") + screen->name() + QLatin1Char(' ')
|
||||
+ briefFormatScreens());
|
||||
connectScreenChangeSignals(screen);
|
||||
}
|
||||
|
||||
void MetricsTest::slotScreenRemoved(QScreen *screen)
|
||||
{
|
||||
logMessage(QLatin1String("Removed ") + screen->name() + QLatin1Char(' ')
|
||||
+ briefFormatScreens());
|
||||
}
|
||||
|
||||
void MetricsTest::slotPrimaryScreenChanged(QScreen *screen)
|
||||
{
|
||||
logMessage(QLatin1String("PrimaryScreenChanged ") + screen->name() + QLatin1Char(' ')
|
||||
+ briefFormatScreens());
|
||||
}
|
||||
|
||||
QPlainTextEdit *MetricsTest::addTextPage(const QString &title)
|
||||
{
|
||||
auto result = new QPlainTextEdit(this);
|
||||
result->setReadOnly(true);
|
||||
result->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||
addTab(result, title);
|
||||
return result;
|
||||
}
|
||||
|
||||
void MetricsTest::logMessage(const QString &m)
|
||||
{
|
||||
const QString timeStamp =
|
||||
QStringLiteral("%1ms: %2").arg(m_logTimer.elapsed(), 6, 10, QLatin1Char('0')).arg(m);
|
||||
m_logEdit->appendPlainText(timeStamp);
|
||||
}
|
||||
|
||||
void MetricsTest::connectScreenChangeSignals(QScreen *s)
|
||||
{
|
||||
connect(s, &QScreen::geometryChanged, this, &MetricsTest::slotScreenGeometryChanged);
|
||||
connect(s, &QScreen::availableGeometryChanged, this, &MetricsTest::slotScreenAvailableGeometryChanged);
|
||||
connect(s, &QScreen::physicalSizeChanged, this, &MetricsTest::slotScreenPhysicalSizeChanged);
|
||||
connect(s, &QScreen::physicalDotsPerInchChanged, this, &MetricsTest::slotScreenPhysicalDotsPerInchChanged);
|
||||
connect(s, &QScreen::logicalDotsPerInchChanged, this, &MetricsTest::slotScreenLogicalDotsPerInchChanged);
|
||||
connect(s, &QScreen::virtualGeometryChanged, this, &MetricsTest::slotScreenVirtualGeometryChanged);
|
||||
connect(s, &QScreen::primaryOrientationChanged, this, &MetricsTest::slotScreenPrimaryOrientationChanged);
|
||||
connect(s, &QScreen::orientationChanged, this, &MetricsTest::slotScreenOrientationChanged);
|
||||
connect(s, &QScreen::refreshRateChanged, this, &MetricsTest::slotScreenRefreshRateChanged);
|
||||
}
|
||||
|
||||
QString MetricsTest::briefFormatScreens()
|
||||
{
|
||||
QString message;
|
||||
QTextStream str(&message);
|
||||
const auto screens = QGuiApplication::screens();
|
||||
for (int i = 0, size = screens.size(); i < size; ++i) {
|
||||
str << (i ? ", " : "(");
|
||||
str << screens.at(i)->name() << " " << screens.at(i)->geometry();
|
||||
}
|
||||
str << ')';
|
||||
return message;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void MetricsTest::logScreenChangeSignal(const QObject *o, const char *name, const T &value)
|
||||
{
|
||||
auto screen = qobject_cast<const QScreen *>(o);
|
||||
QString message;
|
||||
QTextStream(&message) << (screen ? screen->name() : QString()) << ' ' << name << " changed: " << value;
|
||||
logMessage(message);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#define NOSCALINGOPTION "noscaling"
|
||||
|
@ -1,11 +1,20 @@
|
||||
version: '2.1'
|
||||
|
||||
# The tag of images is used by docker compose file to launch the corresponding
|
||||
# docker containers. The value of tag comes from the provisioning script
|
||||
# (coin/provisioning/.../testserver/docker_testserver.sh). The script gets SHA-1
|
||||
# of each server context as the tag of docker images. If one of the server
|
||||
# contexts gets changes, please make sure to update this compose file as well.
|
||||
# You can run command 'docker images' to list all the tags of test server images.
|
||||
# The tag of images is used by docker compose file to launch the correct
|
||||
# docker containers. By default we always launch the "latest" tag.
|
||||
#
|
||||
# But in the "docker build" phase, we also tag the images with a unique tag,
|
||||
# the SHA1 hash of all files used for "docker build" - see sha1tree() in
|
||||
# provisioning.
|
||||
#
|
||||
# So if you want to update the docker image at a specific time, make sure that
|
||||
# 1. you modify this file to run the specific image's SHA1 tag, instead of
|
||||
# "latest"
|
||||
# 2. you build two docker images in provisioning, the currently used one,
|
||||
# plus the new one that you tag as "latest"
|
||||
# 3. you switch this file to the "latest" tag when ready
|
||||
|
||||
# You can run `docker images` to list all the tags of available images:
|
||||
# For example:
|
||||
# REPOSITORY TAG
|
||||
# qt-test-server-apache2 537fe302f61851d1663f41495230d8e3554a4a13
|
||||
@ -20,7 +29,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
provisioningImage: qt-test-server-apache2:537fe302f61851d1663f41495230d8e3554a4a13
|
||||
provisioningImage: qt-test-server-apache2:latest
|
||||
shareDir: ./common
|
||||
serviceDir: ./apache2
|
||||
entrypoint: service/startup.sh
|
||||
@ -43,7 +52,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
provisioningImage: qt-test-server-squid:9c32f41b19aca3d778733c4d8fb0ecc5955e893c
|
||||
provisioningImage: qt-test-server-squid:latest
|
||||
shareDir: ./common
|
||||
serviceDir: ./squid
|
||||
entrypoint: service/startup.sh
|
||||
@ -58,7 +67,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
provisioningImage: qt-test-server-vsftpd:f3a9c8d793a77cc007c0e4e481bec01f9e3eeb7e
|
||||
provisioningImage: qt-test-server-vsftpd:latest
|
||||
shareDir: ./common
|
||||
serviceDir: ./vsftpd
|
||||
entrypoint: service/startup.sh
|
||||
@ -77,7 +86,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
provisioningImage: qt-test-server-ftp-proxy:d7de8b28392d173db512a558ccc84ead8bece2ae
|
||||
provisioningImage: qt-test-server-ftp-proxy:latest
|
||||
shareDir: ./common
|
||||
serviceDir: ./ftp-proxy
|
||||
entrypoint: service/startup.sh
|
||||
@ -102,7 +111,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
provisioningImage: qt-test-server-danted:35607f9b790524cf9690c7d12a9a401696b7b6b5
|
||||
provisioningImage: qt-test-server-danted:latest
|
||||
shareDir: ./common
|
||||
serviceDir: ./danted
|
||||
entrypoint: service/startup.sh
|
||||
@ -117,7 +126,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
provisioningImage: qt-test-server-cyrus:c8d72754abc0e501afd624ce838e4df35505abc9
|
||||
provisioningImage: qt-test-server-cyrus:latest
|
||||
shareDir: ./common
|
||||
serviceDir: ./cyrus
|
||||
entrypoint: service/startup.sh
|
||||
@ -132,7 +141,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
provisioningImage: qt-test-server-iptables:cb7a8bd6d28602085a88c8ced7d67e28e75781e2
|
||||
provisioningImage: qt-test-server-iptables:latest
|
||||
shareDir: ./common
|
||||
serviceDir: ./iptables
|
||||
entrypoint: service/startup.sh
|
||||
@ -150,7 +159,7 @@ services:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
provisioningImage: qt-test-server-echo:b29ad409e746a834c1055fd0f7a55fd5056da6ea
|
||||
provisioningImage: qt-test-server-echo:latest
|
||||
shareDir: ./common
|
||||
serviceDir: ./echo
|
||||
entrypoint: service/startup.sh
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user