summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qcompilerdetection.h77
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h4
-rw-r--r--src/corelib/global/qendian.h4
-rw-r--r--src/corelib/global/qglobal.cpp4
-rw-r--r--src/corelib/global/qglobal.h2
-rw-r--r--src/corelib/global/qglobal_p.h4
-rw-r--r--src/corelib/global/qlogging.cpp8
-rw-r--r--src/corelib/global/qnumeric_p.h2
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp2
-rw-r--r--src/corelib/io/qprocess.cpp2
-rw-r--r--src/corelib/io/qstandardpaths.cpp2
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp2
-rw-r--r--src/corelib/kernel/qdeadlinetimer.h4
-rw-r--r--src/corelib/kernel/qobject.h4
-rw-r--r--src/corelib/kernel/qtimer.h6
-rw-r--r--src/corelib/kernel/qvariant.h6
-rw-r--r--src/corelib/serialization/qcborarray.h2
-rw-r--r--src/corelib/serialization/qcbormap.h2
-rw-r--r--src/corelib/serialization/qcborvalue.h6
-rw-r--r--src/corelib/serialization/qcborvalue_p.h3
-rw-r--r--src/corelib/text/qbytearray.cpp2
-rw-r--r--src/corelib/text/qbytearray.h2
-rw-r--r--src/corelib/text/qstring.cpp7
-rw-r--r--src/corelib/text/qstring.h2
-rw-r--r--src/corelib/thread/qfutex_p.h4
-rw-r--r--src/corelib/thread/qmutex.h10
-rw-r--r--src/corelib/time/qdatetime.cpp100
-rw-r--r--src/corelib/time/qdatetimeparser.cpp2
-rw-r--r--src/corelib/time/qtimezoneprivate.cpp13
-rw-r--r--src/corelib/tools/qalgorithms.h4
-rw-r--r--src/corelib/tools/qscopeguard.h4
-rw-r--r--src/gui/kernel/qplatformcursor.cpp8
-rw-r--r--src/gui/kernel/qplatformcursor.h1
-rw-r--r--src/gui/painting/qcolorspace.cpp10
-rw-r--r--src/gui/rhi/qrhigles2.cpp77
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h9
-rw-r--r--src/gui/rhi/qrhimetal.mm5
-rw-r--r--src/gui/text/qtextcursor.cpp1
-rw-r--r--src/gui/text/qtextdocument.cpp14
-rw-r--r--src/plugins/platforms/cocoa/qcocoaclipboard.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm25
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm22
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm20
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm5
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.mm8
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.cpp24
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.h2
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp25
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h2
-rw-r--r--src/plugins/platforms/windows/qwindowssystemtrayicon.cpp10
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp11
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp1
-rw-r--r--src/testlib/doc/snippets/code/doc_src_cmakelists.txt14
-rw-r--r--src/testlib/doc/src/qttestlib-manual.qdoc43
-rw-r--r--src/widgets/accessible/qaccessiblemenu.cpp2
-rw-r--r--src/widgets/dialogs/qprogressdialog.cpp17
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp11
-rw-r--r--src/widgets/itemviews/qlistview.cpp4
-rw-r--r--src/widgets/kernel/qtooltip.cpp43
-rw-r--r--src/widgets/kernel/qwidget.cpp17
-rw-r--r--src/widgets/styles/qcommonstyle.cpp22
-rw-r--r--src/widgets/styles/qfusionstyle.cpp57
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp10
-rw-r--r--src/widgets/widgets/qdatetimeedit.cpp200
-rw-r--r--src/widgets/widgets/qlineedit.cpp4
-rw-r--r--src/widgets/widgets/qmenu.cpp2
-rw-r--r--src/widgets/widgets/qmenubar.cpp3
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp1
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp2
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp6
75 files changed, 693 insertions, 356 deletions
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 7cfbe1273f..fedf08301f 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -493,6 +493,39 @@
#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
*
* Paper Macro SD-6 macro
@@ -1019,37 +1052,6 @@
#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
*/
#ifdef Q_COMPILER_NULLPTR
@@ -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
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index c58dc56c42..2e6c3fbb20 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -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
diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h
index 5cd9d3160b..257efbbdbe 100644
--- a/src/corelib/global/qendian.h
+++ b/src/corelib/global/qendian.h
@@ -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
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 554c24356b..c2c91df756 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -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);
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 4dc63cae5e..80433ebeff 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -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
diff --git a/src/corelib/global/qglobal_p.h b/src/corelib/global/qglobal_p.h
index 58bc8b7bf3..5ab84fa8be 100644
--- a/src/corelib/global/qglobal_p.h
+++ b/src/corelib/global/qglobal_p.h
@@ -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
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index e011645605..ca4d8dbd11 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -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")))
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index c006296b3d..376da66e31 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -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
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 2e81f93bcf..3bbebc7fe9 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -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>
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index ad2e7fb6b8..816026a36c 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -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
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index b62dc24b47..a5128a868b 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -48,7 +48,7 @@
#include <qcoreapplication.h>
#endif
-#if QT_HAS_INCLUDE(<paths.h>)
+#if __has_include(<paths.h>)
#include <paths.h>
#endif
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 1e72241e68..37b8a60c37 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -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
diff --git a/src/corelib/kernel/qdeadlinetimer.h b/src/corelib/kernel/qdeadlinetimer.h
index 9dd92481d2..99e09eb31f 100644
--- a/src/corelib/kernel/qdeadlinetimer.h
+++ b/src/corelib/kernel/qdeadlinetimer.h
@@ -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)
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index ca5275a3ac..8d9cc3ab83 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -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)
{
diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h
index eb7185c12d..6bbfd741d9 100644
--- a/src/corelib/kernel/qtimer.h
+++ b/src/corelib/kernel/qtimer.h
@@ -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())); }
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 0457b6fbad..24c7bd44dd 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -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 &)
{
diff --git a/src/corelib/serialization/qcborarray.h b/src/corelib/serialization/qcborarray.h
index e06544f245..fe06b8630f 100644
--- a/src/corelib/serialization/qcborarray.h
+++ b/src/corelib/serialization/qcborarray.h
@@ -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);
diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h
index 4aea901eef..6636ce776a 100644
--- a/src/corelib/serialization/qcbormap.h
+++ b/src/corelib/serialization/qcbormap.h
@@ -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);
diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h
index 9c613dfcfb..071213e83a 100644
--- a/src/corelib/serialization/qcborvalue.h
+++ b/src/corelib/serialization/qcborvalue.h
@@ -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);
diff --git a/src/corelib/serialization/qcborvalue_p.h b/src/corelib/serialization/qcborvalue_p.h
index b5d3de74fe..53ba81fa18 100644
--- a/src/corelib/serialization/qcborvalue_p.h
+++ b/src/corelib/serialization/qcborvalue_p.h
@@ -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;
}
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp
index 83182dbd93..23296896b2 100644
--- a/src/corelib/text/qbytearray.cpp
+++ b/src/corelib/text/qbytearray.cpp
@@ -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 {
diff --git a/src/corelib/text/qbytearray.h b/src/corelib/text/qbytearray.h
index fa87ebf058..863898f7e2 100644
--- a/src/corelib/text/qbytearray.h
+++ b/src/corelib/text/qbytearray.h
@@ -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
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index 0f313e21ed..e8ce637453 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -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
diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h
index 27dc99b2e5..391e4788f2 100644
--- a/src/corelib/text/qstring.h
+++ b/src/corelib/text/qstring.h
@@ -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
diff --git a/src/corelib/thread/qfutex_p.h b/src/corelib/thread/qfutex_p.h
index 7bec4554b7..f287b752d7 100644
--- a/src/corelib/thread/qfutex_p.h
+++ b/src/corelib/thread/qfutex_p.h
@@ -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 {
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index c693ff65d8..93c4bf23e8 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -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
{
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index 979b8c9aeb..d2d09ceee6 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -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);
diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp
index a487534528..fa0884c827 100644
--- a/src/corelib/time/qdatetimeparser.cpp
+++ b/src/corelib/time/qdatetimeparser.cpp
@@ -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
diff --git a/src/corelib/time/qtimezoneprivate.cpp b/src/corelib/time/qtimezoneprivate.cpp
index 7d6ef0a404..facdf6661d 100644
--- a/src/corelib/time/qtimezoneprivate.cpp
+++ b/src/corelib/time/qtimezoneprivate.cpp
@@ -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;
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index b01ce0db58..aa79e0d4a9 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -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;
diff --git a/src/corelib/tools/qscopeguard.h b/src/corelib/tools/qscopeguard.h
index 45c3f93da4..40d2747b1d 100644
--- a/src/corelib/tools/qscopeguard.h
+++ b/src/corelib/tools/qscopeguard.h
@@ -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)
diff --git a/src/gui/kernel/qplatformcursor.cpp b/src/gui/kernel/qplatformcursor.cpp
index 12065078c1..5a438a54a2 100644
--- a/src/gui/kernel/qplatformcursor.cpp
+++ b/src/gui/kernel/qplatformcursor.cpp
@@ -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
diff --git a/src/gui/kernel/qplatformcursor.h b/src/gui/kernel/qplatformcursor.h
index f36a73c861..f3871d8780 100644
--- a/src/gui/kernel/qplatformcursor.h
+++ b/src/gui/kernel/qplatformcursor.h
@@ -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; }
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp
index 937bb505c9..9631fdb416 100644
--- a/src/gui/painting/qcolorspace.cpp
+++ b/src/gui/painting/qcolorspace.cpp
@@ -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;
}
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 563d59b318..3fb2ec38a7 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -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);
}
}
}
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index 0283fadb4e..4a98011d3d 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -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);
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 555ed5e79f..3aa68db585 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -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;
diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp
index b69b94d4e7..fa323ef4bd 100644
--- a/src/gui/text/qtextcursor.cpp
+++ b/src/gui/text/qtextcursor.cpp
@@ -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());
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 3382ec0b69..1d27cc30eb 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -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;
diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.mm b/src/plugins/platforms/cocoa/qcocoaclipboard.mm
index a35c153084..141940cc50 100644
--- a/src/plugins/platforms/cocoa/qcocoaclipboard.mm
+++ b/src/plugins/platforms/cocoa/qcocoaclipboard.mm
@@ -67,7 +67,7 @@ void QCocoaClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
}
pasteBoard->sync();
- pasteBoard->setMimeData(data);
+ pasteBoard->setMimeData(data, QMacPasteboard::LazyRequest);
emitChanged(mode);
}
}
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.h b/src/plugins/platforms/cocoa/qcocoacursor.h
index 58b9ef2151..5b008eff35 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.h
+++ b/src/plugins/platforms/cocoa/qcocoacursor.h
@@ -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);
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index 87a57c78c8..e0d623fc4c 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -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)
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index 69587a24be..b8d2532b8e 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -186,6 +186,7 @@ public:
QAtomicInt serialNumber;
int lastSerial;
bool interrupt;
+ bool propagateInterrupt = false;
static void postedEventsSourceCallback(void *info);
static void waitingObserverCallback(CFRunLoopObserverRef observer,
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 110c82bf1f..94b9e62eab 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -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;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h
index 4210a4ed3f..238067568b 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.h
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h
@@ -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
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index b312e033cd..6db4bdb9fd 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -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
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 643eac1e92..ad232d6d80 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -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 {
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm
index 358a6b49fd..654647b35a 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.mm
+++ b/src/plugins/platforms/cocoa/qmacclipboard.mm
@@ -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);
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
index 1b5f3b4954..491c314488 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
@@ -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);
}
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.h b/src/plugins/platforms/qnx/qqnxscreeneventthread.h
index 3c8d197545..e5b762369c 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.h
@@ -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;
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index 37f1ea832a..b6c9b9e377 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.cpp
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -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()
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 17e8cffb76..59457f1720 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -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) {
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index b896f4c7a9..cf3635bd6b 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -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);
diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
index f2dba4d06b..ab830e1461 100644
--- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
+++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp
@@ -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;
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index e5a9f275ae..cc293b777c 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -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;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 8bcaa78122..cc84e836b4 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -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) {
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index 68313b7ff0..3d8ed29b54 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -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);
diff --git a/src/testlib/doc/snippets/code/doc_src_cmakelists.txt b/src/testlib/doc/snippets/code/doc_src_cmakelists.txt
new file mode 100644
index 0000000000..96dbe1acee
--- /dev/null
+++ b/src/testlib/doc/snippets/code/doc_src_cmakelists.txt
@@ -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)
diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc
index 19d871d404..688cc2f2f6 100644
--- a/src/testlib/doc/src/qttestlib-manual.qdoc
+++ b/src/testlib/doc/src/qttestlib-manual.qdoc
@@ -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
diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp
index 51ba0adaa6..99a9444ff1 100644
--- a/src/widgets/accessible/qaccessiblemenu.cpp
+++ b/src/widgets/accessible/qaccessiblemenu.cpp
@@ -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;
}
diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp
index 42a24239a3..aaa4430c39 100644
--- a/src/widgets/dialogs/qprogressdialog.cpp
+++ b/src/widgets/dialogs/qprogressdialog.cpp
@@ -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
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 67c01adea7..0e54cf235f 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -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;
}
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index de32082b5a..ec01922746 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -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;
}
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index b290713440..33dd3e59b6 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -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);
-
- if (p.x() + this->width() > screen.x() + screen.width())
+ 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);
+
+ 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);
}
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index f507745e1e..ecea94c66a 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -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;
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 6b3e3679ae..03081658bb 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -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),
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index a732d59e48..0c668913e9 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -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:
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index c40bbbc96c..7e8c9a6050 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -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);
diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp
index b0689d0b9e..3d6716666d 100644
--- a/src/widgets/widgets/qdatetimeedit.cpp
+++ b/src/widgets/widgets/qdatetimeedit.cpp
@@ -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.
+
+ 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
+ \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.
-
- The default minimumDateTime can be restored with
- clearMinimumDateTime()
+ 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.
- By default, this property contains a date that refers to September 14,
- 1752 and a time of 00:00:00 and 0 milliseconds.
+ 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().
- \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.
-
- By default, this property contains a date that refers to December 31, 9999.
+ 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.
+
+ 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.
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 0d2568b85d..bd5e0b047e 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -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.
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index ddcd022fb6..fc7e2dbbcb 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -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;
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index a50068b5a0..59c8af30b4 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -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.
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 1856f0296b..0bfaa767c6 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -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());
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index a242947c11..9dd61c2c6a 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -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':
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index ce807c9f75..49a1a02867 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -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);