summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/.prev_CMakeLists.txt1
-rw-r--r--src/corelib/CMakeLists.txt1
-rw-r--r--src/corelib/Qt6CoreMacros.cmake9
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp4
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp2
-rw-r--r--src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp5
-rw-r--r--src/corelib/global/qfloat16.cpp2
-rw-r--r--src/corelib/global/qfloat16tables.cpp2
-rw-r--r--src/corelib/global/qlogging.cpp30
-rw-r--r--src/corelib/global/qnamespace.h22
-rw-r--r--src/corelib/global/qnamespace.qdoc45
-rw-r--r--src/corelib/io/io.pri4
-rw-r--r--src/corelib/io/qfile.cpp60
-rw-r--r--src/corelib/io/qfile.h3
-rw-r--r--src/corelib/io/qfileinfo.cpp2
-rw-r--r--src/corelib/io/qfilesystemengine_mac.mm83
-rw-r--r--src/corelib/io/qfilesystemengine_p.h3
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp212
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp198
-rw-r--r--src/corelib/io/qiodevice.cpp2
-rw-r--r--src/corelib/io/qlockfile_unix.cpp3
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp21
-rw-r--r--src/corelib/io/qurl.cpp7
-rw-r--r--src/corelib/io/qurl.h4
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp3
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm2
-rw-r--r--src/corelib/kernel/qmetatype.h88
-rw-r--r--src/corelib/kernel/qmimedata.cpp53
-rw-r--r--src/corelib/kernel/qsignalmapper.cpp115
-rw-r--r--src/corelib/kernel/qsignalmapper.h10
-rw-r--r--src/corelib/kernel/qtranslator.cpp42
-rw-r--r--src/corelib/kernel/qtranslator.h3
-rw-r--r--src/corelib/kernel/qvariant.cpp4
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp4
-rw-r--r--src/corelib/plugin/qpluginloader.cpp2
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp20
-rw-r--r--src/corelib/statemachine/qstatemachine.h11
-rw-r--r--src/corelib/text/qcollator_icu.cpp7
-rw-r--r--src/corelib/text/qcollator_macx.cpp7
-rw-r--r--src/corelib/text/qcollator_posix.cpp7
-rw-r--r--src/corelib/text/qcollator_win.cpp7
-rw-r--r--src/corelib/text/qlocale.cpp62
-rw-r--r--src/corelib/text/qlocale.h8
-rw-r--r--src/corelib/text/qlocale_mac.mm20
-rw-r--r--src/corelib/text/qlocale_p.h2
-rw-r--r--src/corelib/text/qlocale_win.cpp69
-rw-r--r--src/corelib/thread/qrunnable.cpp27
-rw-r--r--src/corelib/thread/qrunnable.h2
-rw-r--r--src/corelib/thread/qthreadpool.cpp32
-rw-r--r--src/corelib/thread/qthreadpool.h5
-rw-r--r--src/corelib/time/qcalendar.cpp11
-rw-r--r--src/corelib/time/qdatetime.cpp289
-rw-r--r--src/corelib/time/qdatetime.h16
-rw-r--r--src/corelib/time/qdatetimeparser.cpp39
-rw-r--r--src/corelib/time/qtimezoneprivate_win.cpp2
-rw-r--r--src/corelib/tools/qbitarray.cpp2
-rw-r--r--src/corelib/tools/qcontainerfwd.h2
-rw-r--r--src/corelib/tools/qhash.h2
-rw-r--r--src/corelib/tools/qiterator.qdoc2
-rw-r--r--src/corelib/tools/qlinkedlist.cpp14
-rw-r--r--src/corelib/tools/qlinkedlist.h24
-rw-r--r--src/corelib/tools/qmap.cpp2
-rw-r--r--src/corelib/tools/qscopeguard.h32
-rw-r--r--src/corelib/tools/qscopeguard.qdoc41
64 files changed, 1458 insertions, 357 deletions
diff --git a/src/corelib/.prev_CMakeLists.txt b/src/corelib/.prev_CMakeLists.txt
index a6e862e1de..78b9c17b3f 100644
--- a/src/corelib/.prev_CMakeLists.txt
+++ b/src/corelib/.prev_CMakeLists.txt
@@ -385,6 +385,7 @@ qt_extend_target(Core CONDITION WIN32 AND NOT WINRT
qt_extend_target(Core CONDITION APPLE
SOURCES
global/qoperatingsystemversion_darwin.mm
+ io/qfilesystemengine_mac.mm
io/qstandardpaths_mac.mm
io/qstorageinfo_mac.cpp
kernel/qcfsocketnotifier.cpp kernel/qcfsocketnotifier_p.h
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index 64c993fe9f..45b0033abe 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -492,6 +492,7 @@ qt_extend_target(Core CONDITION WIN32 AND NOT WINRT
qt_extend_target(Core CONDITION APPLE
SOURCES
global/qoperatingsystemversion_darwin.mm
+ io/qfilesystemengine_mac.mm
io/qstandardpaths_mac.mm
io/qstorageinfo_mac.cpp
kernel/qcfsocketnotifier.cpp kernel/qcfsocketnotifier_p.h
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index 2bc97c6d12..94d270b739 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -59,7 +59,14 @@ macro(qt6_make_output_file infile prefix ext outfile )
set(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${rel}")
string(REPLACE ".." "__" _outfile ${_outfile})
get_filename_component(outpath ${_outfile} PATH)
- get_filename_component(_outfile ${_outfile} NAME_WE)
+ if(CMAKE_VERSION VERSION_LESS "3.14")
+ get_filename_component(_outfile_ext ${_outfile} EXT)
+ get_filename_component(_outfile_ext ${_outfile_ext} NAME_WE)
+ get_filename_component(_outfile ${_outfile} NAME_WE)
+ string(APPEND _outfile ${_outfile_ext})
+ else()
+ get_filename_component(_outfile ${_outfile} NAME_WLE)
+ endif()
file(MAKE_DIRECTORY ${outpath})
set(${outfile} ${outpath}/${prefix}${_outfile}.${ext})
endmacro()
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp
index a140175956..d30ad50ffc 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -135,7 +135,7 @@ class Employee
{
public:
Employee() {}
- Employee(const QString &name, const QDate &dateOfBirth);
+ Employee(const QString &name, QDate dateOfBirth);
...
private:
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp
index 506022f082..145cd10d84 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp
@@ -151,7 +151,7 @@ class Employee
{
public:
Employee() {}
- Employee(const QString &name, const QDate &dateOfBirth);
+ Employee(const QString &name, QDate dateOfBirth);
...
private:
diff --git a/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp b/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp
index 84a156bb6d..879cdbe329 100644
--- a/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp
+++ b/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp
@@ -61,14 +61,13 @@ ButtonWidget::ButtonWidget(const QStringList &texts, QWidget *parent)
QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i) {
QPushButton *button = new QPushButton(texts[i]);
- connect(button, &QPushButton::clicked,
- signalMapper, &QSignalMapper::map);
+ connect(button, &QPushButton::clicked, signalMapper, &QSignalMapper::map);
//! [0] //! [1]
signalMapper->setMapping(button, texts[i]);
gridLayout->addWidget(button, i / 3, i % 3);
}
- connect(signalMapper, QOverload<const QString &>::of(&QSignalMapper::mapped),
+ connect(signalMapper, &QSignalMapper::mappedString,
//! [1] //! [2]
this, &ButtonWidget::clicked);
diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp
index 51766c9760..80a851e4e4 100644
--- a/src/corelib/global/qfloat16.cpp
+++ b/src/corelib/global/qfloat16.cpp
@@ -213,7 +213,7 @@ f16cextern void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype
#undef f16cextern
}
-#elif defined(__ARM_FP16_FORMAT_IEEE) && defined(__ARM_NEON__)
+#elif defined(__ARM_FP16_FORMAT_IEEE) && defined(__ARM_NEON__) && (__ARM_FP & 2)
static inline bool hasFastF16()
{
return true;
diff --git a/src/corelib/global/qfloat16tables.cpp b/src/corelib/global/qfloat16tables.cpp
index 3d764937d7..b87986d6b8 100644
--- a/src/corelib/global/qfloat16tables.cpp
+++ b/src/corelib/global/qfloat16tables.cpp
@@ -44,7 +44,7 @@
QT_BEGIN_NAMESPACE
-#if !defined(__F16C__) && !defined(__ARM_FP16_FORMAT_IEEE)
+#if !defined(__ARM_FP16_FORMAT_IEEE)
const quint32 qfloat16::mantissatable[2048] = {
0,
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index ca4d8dbd11..123cc88ad6 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1669,14 +1669,34 @@ static bool android_default_message_handler(QtMsgType type,
#endif //Q_OS_ANDROID
#ifdef Q_OS_WIN
+static void win_outputDebugString_helper(QStringView message)
+{
+ const int maxOutputStringLength = 32766;
+ static QBasicMutex m;
+ auto locker = qt_unique_lock(m);
+ // fast path: Avoid string copies if one output is enough
+ if (message.length() <= maxOutputStringLength) {
+ OutputDebugString(reinterpret_cast<const wchar_t *>(message.utf16()));
+ } else {
+ wchar_t *messagePart = new wchar_t[maxOutputStringLength + 1];
+ for (int i = 0; i < message.length(); i += maxOutputStringLength ) {
+ const int length = std::min(message.length() - i, maxOutputStringLength );
+ const int len = message.mid(i, length).toWCharArray(messagePart);
+ Q_ASSERT(len == length);
+ messagePart[len] = 0;
+ OutputDebugString(messagePart);
+ }
+ delete[] messagePart;
+ }
+}
+
static bool win_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &message)
{
if (shouldLogToStderr())
return false; // Leave logging up to stderr handler
- QString formattedMessage = qFormatLogMessage(type, context, message);
- formattedMessage.append(QLatin1Char('\n'));
- OutputDebugString(reinterpret_cast<const wchar_t *>(formattedMessage.utf16()));
+ const QString formattedMessage = qFormatLogMessage(type, context, message).append('\n');
+ win_outputDebugString_helper(formattedMessage);
return true; // Prevent further output to stderr
}
@@ -1832,11 +1852,11 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
static void qt_message_print(const QString &message)
{
#if defined(Q_OS_WINRT)
- OutputDebugString(reinterpret_cast<const wchar_t*>(message.utf16()));
+ win_outputDebugString_helper(message);
return;
#elif defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED)
if (!shouldLogToStderr()) {
- OutputDebugString(reinterpret_cast<const wchar_t*>(message.utf16()));
+ win_outputDebugString_helper(message);
return;
}
#endif
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index f278850ccf..57ccd308d7 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -1249,14 +1249,16 @@ namespace Qt {
enum DateFormat {
TextDate, // default Qt
ISODate, // ISO 8601
- SystemLocaleDate, // deprecated
- LocalDate = SystemLocaleDate, // deprecated
- LocaleDate, // deprecated
- SystemLocaleShortDate,
- SystemLocaleLongDate,
- DefaultLocaleShortDate,
- DefaultLocaleLongDate,
- RFC2822Date, // RFC 2822 (+ 850 and 1036 during parsing)
+#if QT_DEPRECATED_SINCE(5, 15)
+ SystemLocaleDate Q_DECL_ENUMERATOR_DEPRECATED_X("Use QLocale"),
+ LocalDate Q_DECL_ENUMERATOR_DEPRECATED_X("Use QLocale") = 2, // i.e. SystemLocaleDate
+ LocaleDate Q_DECL_ENUMERATOR_DEPRECATED_X("Use QLocale"),
+ SystemLocaleShortDate Q_DECL_ENUMERATOR_DEPRECATED_X("Use QLocale"),
+ SystemLocaleLongDate Q_DECL_ENUMERATOR_DEPRECATED_X("Use QLocale"),
+ DefaultLocaleShortDate Q_DECL_ENUMERATOR_DEPRECATED_X("Use QLocale"),
+ DefaultLocaleLongDate Q_DECL_ENUMERATOR_DEPRECATED_X("Use QLocale"),
+#endif
+ RFC2822Date = 8, // RFC 2822 (+ 850 and 1036 during parsing)
ISODateWithMs
};
@@ -1750,7 +1752,7 @@ namespace Qt {
};
// QTBUG-48701
- enum ReturnByValue_t { ReturnByValue }; // ### Qt 7: Remove me
+ enum ReturnByValueConstant { ReturnByValue }; // ### Qt 7: Remove me
#ifndef Q_QDOC
// NOTE: Generally, do not add Q_ENUM_NS if a corresponding Q_FLAG_NS exists.
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 9acb978efc..708ecb11ab 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -709,26 +709,38 @@
\value ISODateWithMs \l{ISO 8601} extended format, including milliseconds if applicable.
- \value SystemLocaleShortDate The \l{QLocale::ShortFormat}{short format} used
- by the \l{QLocale::system()}{operating system}.
+ \value SystemLocaleShortDate \e{This enum value is deprecated and
+ shall be removed in Qt 6.} Use QLocale's methods for converting
+ dates and times to and from strings, with the
+ \l{QLocale::ShortFormat}{short format} of
+ \l{QLocale::system()}{the locale used by the operating system}.
- \value SystemLocaleLongDate The \l{QLocale::LongFormat}{long format} used
- by the \l{QLocale::system()}{operating system}.
+ \value SystemLocaleLongDate \e{This enum value is deprecated and
+ shall be removed in Qt 6.} Use QLocale's methods for converting
+ dates and times to and from strings, with the
+ \l{QLocale::LongFormat}{long format} of \l{QLocale::system()}{the
+ locale used by the operating system}.
- \value DefaultLocaleShortDate The \l{QLocale::ShortFormat}{short format} specified
- by the \l{QLocale::setDefault()}{application's locale}.
+ \value DefaultLocaleShortDate \e{This enum value is deprecated and
+ shall be removed in Qt 6.} Use QLocale's methods for converting
+ dates and times to and from strings, with the
+ \l{QLocale::ShortFormat}{short format} of
+ \l{QLocale::setDefault()}{the application's locale}.
- \value DefaultLocaleLongDate The \l{QLocale::LongFormat}{long format} used
- by the \l{QLocale::setDefault()}{application's locale}.
+ \value DefaultLocaleLongDate \e{This enum value is deprecated and
+ shall be removed in Qt 6.} Use QLocale's methods for converting
+ dates and times to and from strings, with the
+ \l{QLocale::LongFormat}{long format} \l{QLocale::setDefault()}{the
+ application's locale}.
- \value SystemLocaleDate \e{This enum value is deprecated.} Use Qt::SystemLocaleShortDate
- instead (or Qt::SystemLocaleLongDate if you want long dates).
+ \value SystemLocaleDate \e{This enum value is deprecated and shall
+ be removed in Qt 6.} It is equivalent to SystemLocaleShortDate.
- \value LocaleDate \e{This enum value is deprecated.} Use Qt::DefaultLocaleShortDate
- instead (or Qt::DefaultLocaleLongDate if you want long dates).
+ \value LocaleDate \e{This enum value is deprecated and shall be
+ removed in Qt 6.} It is equivalent to DefaultLocaleShortDate.
- \value LocalDate \e{This enum value is deprecated.} Use Qt::SystemLocaleShortDate
- instead (or Qt::SystemLocaleLongDate if you want long dates).
+ \value LocalDate \e{This enum value is deprecated and shall be
+ removed in Qt 6.} It is equivalent to SystemLocaleShortDate.
\value RFC2822Date \l{RFC 2822}, \l{RFC 850} and \l{RFC 1036} format:
either \c{[ddd,] dd MMM yyyy [hh:mm[:ss]][ ±tzoff]}
@@ -1187,6 +1199,7 @@
\value WA_StyleSheetTarget Indicates that the widget appearance was modified
by a \l{Qt Style Sheets}{style sheet}. WA_StyleSheet will also be set.
+ This value was introduced in Qt 5.12.
\value WA_TabletTracking Indicates that the widget has tablet
tracking enabled. See QWidget::tabletTracking.
@@ -3321,7 +3334,7 @@
*/
/*!
- \enum Qt::ReturnByValue_t
+ \enum Qt::ReturnByValueConstant
\since 5.15
This is a dummy type, designed to help users transition from certain deprecated APIs to their replacement APIs.
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index c4c6f41387..a33ffe75f2 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -183,7 +183,9 @@ win32 {
SOURCES += io/qstorageinfo_mac.cpp
qtConfig(processenvironment): \
OBJECTIVE_SOURCES += io/qprocess_darwin.mm
- OBJECTIVE_SOURCES += io/qstandardpaths_mac.mm
+ OBJECTIVE_SOURCES += \
+ io/qstandardpaths_mac.mm \
+ io/qfilesystemengine_mac.mm
osx {
LIBS += -framework DiskArbitration -framework IOKit
} else {
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 5320ae2986..0cdc5bd6d3 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -552,6 +552,66 @@ QFile::remove(const QString &fileName)
}
/*!
+ \since 5.15
+
+ Moves the file specified by fileName() to the trash. Returns \c true if successful,
+ and sets the fileName() to the path at which the file can be found within the trash;
+ otherwise returns \c false.
+
+ \note On systems where the system API doesn't report the location of the file in the
+ trash, fileName() will be set to the null string once the file has been moved. On
+ systems that don't have a trash can, this function always returns false.
+*/
+bool
+QFile::moveToTrash()
+{
+ Q_D(QFile);
+ if (d->fileName.isEmpty() &&
+ !static_cast<QFSFileEngine *>(d->engine())->isUnnamedFile()) {
+ qWarning("QFile::remove: Empty or null file name");
+ return false;
+ }
+ unsetError();
+ close();
+ if (error() == QFile::NoError) {
+ QFileSystemEntry fileEntry(d->fileName);
+ QFileSystemEntry trashEntry;
+ QSystemError error;
+ if (QFileSystemEngine::moveFileToTrash(fileEntry, trashEntry, error)) {
+ setFileName(trashEntry.filePath());
+ unsetError();
+ return true;
+ }
+ d->setError(QFile::RenameError, error.toString());
+ }
+ return false;
+}
+
+/*!
+ \since 5.15
+ \overload
+
+ Moves the file specified by fileName() to the trash. Returns \c true if successful,
+ and sets \a pathInTrash (if provided) to the path at which the file can be found within
+ the trash; otherwise returns \c false.
+
+ \note On systems where the system API doesn't report the path of the file in the
+ trash, \a pathInTrash will be set to the null string once the file has been moved.
+ On systems that don't have a trash can, this function always returns false.
+*/
+bool
+QFile::moveToTrash(const QString &fileName, QString *pathInTrash)
+{
+ QFile file(fileName);
+ if (file.moveToTrash()) {
+ if (pathInTrash)
+ *pathInTrash = file.fileName();
+ return true;
+ }
+ return false;
+}
+
+/*!
Renames the file currently specified by fileName() to \a newName.
Returns \c true if successful; otherwise returns \c false.
diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h
index 2099b2852f..917fec4e1a 100644
--- a/src/corelib/io/qfile.h
+++ b/src/corelib/io/qfile.h
@@ -125,6 +125,9 @@ public:
bool remove();
static bool remove(const QString &fileName);
+ bool moveToTrash();
+ static bool moveToTrash(const QString &fileName, QString *pathInTrash = nullptr);
+
bool rename(const QString &newName);
static bool rename(const QString &oldName, const QString &newName);
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 3fe1aec41f..64b1557231 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -1147,6 +1147,8 @@ bool QFileInfo::isShortcut() const
/*!
+ \since 5.15
+
Returns \c true if the object points to a junction;
otherwise returns \c false.
diff --git a/src/corelib/io/qfilesystemengine_mac.mm b/src/corelib/io/qfilesystemengine_mac.mm
new file mode 100644
index 0000000000..258ae2e8e0
--- /dev/null
+++ b/src/corelib/io/qfilesystemengine_mac.mm
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+#include "qfilesystemengine_p.h"
+#include "qfile.h"
+#include "qurl.h"
+
+#include <QtCore/private/qcore_mac_p.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ This implementation does not enable the "put back" option in Finder
+ for the trashed object. The only way to get this is to use Finder automation,
+ which would query the user for permission to access Finder using a modal,
+ blocking dialog - which we definitely can't have in a console application.
+
+ Using Finder would also play the trash sound, which we don't want either in
+ such a core API; applications that want that can play the sound themselves.
+*/
+//static
+bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source,
+ QFileSystemEntry &newLocation, QSystemError &error)
+{
+#ifdef Q_OS_MACOS // desktop macOS has a trash can
+ QMacAutoReleasePool pool;
+
+ QFileInfo info(source.filePath());
+ NSString *filepath = info.filePath().toNSString();
+ NSURL *fileurl = [NSURL fileURLWithPath:filepath isDirectory:info.isDir()];
+ NSURL *resultingUrl = nil;
+ NSError *nserror = nil;
+ NSFileManager *fm = [NSFileManager defaultManager];
+ if ([fm trashItemAtURL:fileurl resultingItemURL:&resultingUrl error:&nserror] != YES) {
+ error = QSystemError(nserror.code, QSystemError::NativeError);
+ return false;
+ }
+ newLocation = QFileSystemEntry(QUrl::fromNSURL(resultingUrl).path());
+ return true;
+#else // watch, tv, iOS don't have a trash can
+ return false;
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/io/qfilesystemengine_p.h b/src/corelib/io/qfilesystemengine_p.h
index ecfdc03743..555483a972 100644
--- a/src/corelib/io/qfilesystemengine_p.h
+++ b/src/corelib/io/qfilesystemengine_p.h
@@ -88,7 +88,7 @@ inline bool qIsFilenameBroken(const QFileSystemEntry &entry)
Q_RETURN_ON_INVALID_FILENAME("Broken filename passed to function", (result)); \
} while (false)
-class QFileSystemEngine
+class Q_AUTOTEST_EXPORT QFileSystemEngine
{
public:
static bool isCaseSensitive()
@@ -155,6 +155,7 @@ public:
static bool createLink(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error);
static bool copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error);
+ static bool moveFileToTrash(const QFileSystemEntry &source, QFileSystemEntry &newLocation, QSystemError &error);
static bool renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error);
static bool renameOverwriteFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error);
static bool removeFile(const QFileSystemEntry &entry, QSystemError &error);
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 3bbebc7fe9..eaf4e2d9af 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -42,6 +42,8 @@
#include "qplatformdefs.h"
#include "qfilesystemengine_p.h"
#include "qfile.h"
+#include "qstorageinfo.h"
+#include "qtextstream.h"
#include <QtCore/qoperatingsystemversion.h>
#include <QtCore/private/qcore_unix_p.h>
@@ -1197,6 +1199,216 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy
return false;
}
+#ifndef Q_OS_DARWIN
+/*
+ Implementing as per https://specifications.freedesktop.org/trash-spec/trashspec-1.0.html
+*/
+
+// bootstrapped tools don't need this, and we don't want QStorageInfo
+#ifndef QT_BOOTSTRAPPED
+static QString freeDesktopTrashLocation(const QString &sourcePath)
+{
+ auto makeTrashDir = [](const QDir &topDir, const QString &trashDir) -> QString {
+ auto ownerPerms = QFileDevice::ReadOwner
+ | QFileDevice::WriteOwner
+ | QFileDevice::ExeOwner;
+ QString targetDir = topDir.filePath(trashDir);
+ if (topDir.mkdir(trashDir))
+ QFile::setPermissions(targetDir, ownerPerms);
+ if (QFileInfo(targetDir).isDir())
+ return targetDir;
+ return QString();
+ };
+ auto isSticky = [](const QFileInfo &fileInfo) -> bool {
+ struct stat st;
+ if (stat(QFile::encodeName(fileInfo.absoluteFilePath()).constData(), &st) == 0)
+ return st.st_mode & S_ISVTX;
+
+ return false;
+ };
+
+ QString trash;
+ const QLatin1String dotTrash(".Trash");
+ const QStorageInfo sourceStorage(sourcePath);
+ const QStorageInfo homeStorage(QDir::home());
+ // We support trashing of files outside the users home partition
+ if (sourceStorage != homeStorage) {
+ QDir topDir(sourceStorage.rootPath());
+ /*
+ Method 1:
+ "An administrator can create an $topdir/.Trash directory. The permissions on this
+ directories should permit all users who can trash files at all to write in it;
+ and the “sticky bit” in the permissions must be set, if the file system supports
+ it.
+ When trashing a file from a non-home partition/device, an implementation
+ (if it supports trashing in top directories) MUST check for the presence
+ of $topdir/.Trash."
+ */
+ const QString userID = QString::number(::getuid());
+ if (topDir.cd(dotTrash)) {
+ const QFileInfo trashInfo(topDir.path());
+
+ // we MUST check that the sticky bit is set, and that it is not a symlink
+ if (trashInfo.isSymLink()) {
+ // we SHOULD report the failed check to the administrator
+ qCritical("Warning: '%s' is a symlink to '%s'",
+ trashInfo.absoluteFilePath().toLocal8Bit().constData(),
+ trashInfo.symLinkTarget().toLatin1().constData());
+ } else if (!isSticky(trashInfo)) {
+ // we SHOULD report the failed check to the administrator
+ qCritical("Warning: '%s' doesn't have sticky bit set!",
+ trashInfo.absoluteFilePath().toLocal8Bit().constData());
+ } else if (trashInfo.isDir()) {
+ /*
+ "If the directory exists and passes the checks, a subdirectory of the
+ $topdir/.Trash directory is to be used as the user's trash directory
+ for this partition/device. The name of this subdirectory is the numeric
+ identifier of the current user ($topdir/.Trash/$uid).
+ When trashing a file, if this directory does not exist for the current user,
+ the implementation MUST immediately create it, without any warnings or
+ delays for the user."
+ */
+ trash = makeTrashDir(topDir, userID);
+ }
+ }
+ /*
+ Method 2:
+ "If an $topdir/.Trash directory is absent, an $topdir/.Trash-$uid directory is to be
+ used as the user's trash directory for this device/partition. [...] When trashing a
+ file, if an $topdir/.Trash-$uid directory does not exist, the implementation MUST
+ immediately create it, without any warnings or delays for the user."
+ */
+ if (trash.isEmpty()) {
+ topDir = QDir(sourceStorage.rootPath());
+ const QString userTrashDir = dotTrash + QLatin1Char('-') + userID;
+ trash = makeTrashDir(topDir, userTrashDir);
+ }
+ }
+ /*
+ "If both (1) and (2) fail [...], the implementation MUST either trash the
+ file into the user's “home trash” or refuse to trash it."
+
+ We trash the file into the user's home trash.
+ */
+ if (trash.isEmpty()) {
+ QDir topDir = QDir::home();
+ trash = makeTrashDir(topDir, dotTrash);
+ if (!QFileInfo(trash).isDir()) {
+ qWarning("Unable to establish trash directory %s in %s",
+ dotTrash.latin1(), topDir.path().toLocal8Bit().constData());
+ }
+ }
+
+ return trash;
+}
+#endif // QT_BOOTSTRAPPED
+
+//static
+bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source,
+ QFileSystemEntry &newLocation, QSystemError &error)
+{
+#ifdef QT_BOOTSTRAPPED
+ Q_UNUSED(source);
+ Q_UNUSED(newLocation);
+ error = QSystemError(ENOSYS, QSystemError::StandardLibraryError);
+ return false;
+#else
+ const QFileInfo sourceInfo(source.filePath());
+ if (!sourceInfo.exists()) {
+ error = QSystemError(ENOENT, QSystemError::StandardLibraryError);
+ return false;
+ }
+ const QString sourcePath = sourceInfo.absoluteFilePath();
+
+ QDir trashDir(freeDesktopTrashLocation(sourcePath));
+ if (!trashDir.exists())
+ return false;
+ /*
+ "A trash directory contains two subdirectories, named info and files."
+ */
+ const QLatin1String filesDir("files");
+ const QLatin1String infoDir("info");
+ trashDir.mkdir(filesDir);
+ int savedErrno = errno;
+ trashDir.mkdir(infoDir);
+ if (!savedErrno)
+ savedErrno = errno;
+ if (!trashDir.exists(filesDir) || !trashDir.exists(infoDir)) {
+ error = QSystemError(savedErrno, QSystemError::StandardLibraryError);
+ return false;
+ }
+ /*
+ "The $trash/files directory contains the files and directories that were trashed.
+ The names of files in this directory are to be determined by the implementation;
+ the only limitation is that they must be unique within the directory. Even if a
+ file with the same name and location gets trashed many times, each subsequent
+ trashing must not overwrite a previous copy."
+ */
+ const QString trashedName = sourceInfo.isDir()
+ ? QDir(sourcePath).dirName()
+ : sourceInfo.fileName();
+ QString uniqueTrashedName = QLatin1Char('/') + trashedName;
+ QString infoFileName;
+ int counter = 0;
+ QFile infoFile;
+ auto makeUniqueTrashedName = [trashedName, &counter]() -> QString {
+ ++counter;
+ return QString(QLatin1String("/%1-%2"))
+ .arg(trashedName)
+ .arg(counter, 4, 10, QLatin1Char('0'));
+ };
+ do {
+ while (QFile::exists(trashDir.filePath(filesDir) + uniqueTrashedName))
+ uniqueTrashedName = makeUniqueTrashedName();
+ /*
+ "The $trash/info directory contains an "information file" for every file and directory
+ in $trash/files. This file MUST have exactly the same name as the file or directory in
+ $trash/files, plus the extension ".trashinfo"
+ [...]
+ When trashing a file or directory, the implementation MUST create the corresponding
+ file in $trash/info first. Moreover, it MUST try to do this in an atomic fashion,
+ so that if two processes try to trash files with the same filename this will result
+ in two different trash files. On Unix-like systems this is done by generating a
+ filename, and then opening with O_EXCL. If that succeeds the creation was atomic
+ (at least on the same machine), if it fails you need to pick another filename."
+ */
+ infoFileName = trashDir.filePath(infoDir)
+ + uniqueTrashedName + QLatin1String(".trashinfo");
+ infoFile.setFileName(infoFileName);
+ if (!infoFile.open(QIODevice::NewOnly | QIODevice::WriteOnly | QIODevice::Text))
+ uniqueTrashedName = makeUniqueTrashedName();
+ } while (!infoFile.isOpen());
+
+ const QString targetPath = trashDir.filePath(filesDir) + uniqueTrashedName;
+ const QFileSystemEntry target(targetPath);
+
+ /*
+ We might fail to rename if source and target are on different file systems.
+ In that case, we don't try further, i.e. copying and removing the original
+ is usually not what the user would expect to happen.
+ */
+ if (!renameFile(source, target, error)) {
+ infoFile.close();
+ infoFile.remove();
+ return false;
+ }
+
+ QTextStream out(&infoFile);
+#if QT_CONFIG(textcodec)
+ out.setCodec("UTF-8");
+#endif
+ out << "[Trash Info]" << Qt::endl;
+ out << "Path=" << sourcePath << Qt::endl;
+ out << "DeletionDate="
+ << QDateTime::currentDateTime().toString(QLatin1String("yyyy-MM-ddThh:mm:ss")) << Qt::endl;
+ infoFile.close();
+
+ newLocation = QFileSystemEntry(targetPath);
+ return true;
+#endif // QT_BOOTSTRAPPED
+}
+#endif // Q_OS_DARWIN
+
//static
bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 0579872f8d..36d43e9cb7 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -41,6 +41,7 @@
#include "qoperatingsystemversion.h"
#include "qplatformdefs.h"
#include "qsysinfo.h"
+#include "qscopeguard.h"
#include "private/qabstractfileengine_p.h"
#include "private/qfsfileengine_p.h"
#include <private/qsystemlibrary_p.h>
@@ -59,6 +60,8 @@
#include <objbase.h>
#ifndef Q_OS_WINRT
# include <shlobj.h>
+# include <shobjidl.h>
+# include <shellapi.h>
# include <lm.h>
# include <accctrl.h>
#endif
@@ -422,6 +425,104 @@ static inline bool getFindData(QString path, WIN32_FIND_DATA &findData)
return false;
}
+#if defined(__IFileOperation_INTERFACE_DEFINED__)
+class FileOperationProgressSink : public IFileOperationProgressSink
+{
+public:
+ FileOperationProgressSink()
+ : ref(1)
+ {}
+ virtual ~FileOperationProgressSink() {}
+
+ ULONG STDMETHODCALLTYPE AddRef()
+ {
+ return ++ref;
+ }
+ ULONG STDMETHODCALLTYPE Release()
+ {
+ if (--ref == 0) {
+ delete this;
+ return 0;
+ }
+ return ref;
+ }
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject)
+ {
+ if (!ppvObject)
+ return E_POINTER;
+
+ *ppvObject = nullptr;
+
+ if (iid == __uuidof(IUnknown)) {
+ *ppvObject = static_cast<IUnknown*>(this);
+ } else if (iid == __uuidof(IFileOperationProgressSink)) {
+ *ppvObject = static_cast<IFileOperationProgressSink*>(this);
+ }
+
+ if (*ppvObject) {
+ AddRef();
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+ }
+
+ HRESULT STDMETHODCALLTYPE StartOperations()
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE FinishOperations(HRESULT)
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE PreRenameItem(DWORD, IShellItem *, LPCWSTR)
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE PostRenameItem(DWORD, IShellItem *, LPCWSTR, HRESULT, IShellItem *)
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE PreMoveItem(DWORD, IShellItem *, IShellItem *, LPCWSTR)
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE PostMoveItem(DWORD, IShellItem *, IShellItem *, LPCWSTR, HRESULT,
+ IShellItem *)
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE PreCopyItem(DWORD, IShellItem *, IShellItem *, LPCWSTR )
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE PostCopyItem(DWORD, IShellItem *, IShellItem *, LPCWSTR, HRESULT,
+ IShellItem *)
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE PreDeleteItem(DWORD dwFlags, IShellItem *)
+ {
+ // stop the operation if the file will be deleted rather than trashed
+ return (dwFlags & TSF_DELETE_RECYCLE_IF_POSSIBLE) ? S_OK : E_FAIL;
+ }
+ HRESULT STDMETHODCALLTYPE PostDeleteItem(DWORD /* dwFlags */, IShellItem * /* psiItem */,
+ HRESULT /* hrDelete */, IShellItem *psiNewlyCreated)
+ {
+ if (psiNewlyCreated) {
+ wchar_t *pszName = nullptr;
+ psiNewlyCreated->GetDisplayName(SIGDN_FILESYSPATH, &pszName);
+ if (pszName) {
+ targetPath = QString::fromWCharArray(pszName);
+ CoTaskMemFree(pszName);
+ }
+ }
+ return S_OK;
+ }
+ HRESULT STDMETHODCALLTYPE PreNewItem(DWORD, IShellItem *, LPCWSTR)
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE PostNewItem(DWORD, IShellItem *, LPCWSTR, LPCWSTR, DWORD, HRESULT,
+ IShellItem *)
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE UpdateProgress(UINT,UINT)
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE ResetTimer()
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE PauseTimer()
+ { return S_OK; }
+ HRESULT STDMETHODCALLTYPE ResumeTimer()
+ { return S_OK; }
+
+ QString targetPath;
+private:
+ ULONG ref;
+};
+#endif
+
bool QFileSystemEngine::uncListSharesOnServer(const QString &server, QStringList *list)
{
DWORD res = ERROR_NOT_SUPPORTED;
@@ -1431,6 +1532,103 @@ bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QSystemError &
return ret;
}
+/*
+ If possible, we use the IFileOperation implementation, which allows us to determine
+ the location of the object in the trash.
+ If not (likely on mingw), we fall back to the old API, which won't allow us to know
+ that.
+*/
+//static
+bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source,
+ QFileSystemEntry &newLocation, QSystemError &error)
+{
+#ifndef Q_OS_WINRT
+ // we need the "display name" of the file, so can't use nativeFilePath
+ const QString sourcePath = QDir::toNativeSeparators(source.filePath());
+
+ /*
+ Windows 7 insists on showing confirmation dialogs and ignores the respective
+ flags set on IFileOperation. Fall back to SHFileOperation, even if it doesn't
+ give us the new location of the file.
+ */
+ if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) {
+# if defined(__IFileOperation_INTERFACE_DEFINED__)
+ CoInitialize(NULL);
+ IFileOperation *pfo = nullptr;
+ IShellItem *deleteItem = nullptr;
+ FileOperationProgressSink *sink = nullptr;
+ HRESULT hres = E_FAIL;
+
+ auto coUninitialize = qScopeGuard([&](){
+ if (sink)
+ sink->Release();
+ if (deleteItem)
+ deleteItem->Release();
+ if (pfo)
+ pfo->Release();
+ CoUninitialize();
+ if (!SUCCEEDED(hres))
+ error = QSystemError(hres, QSystemError::NativeError);
+ });
+
+ hres = CoCreateInstance(CLSID_FileOperation, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pfo));
+ if (!pfo)
+ return false;
+ pfo->SetOperationFlags(FOF_ALLOWUNDO | FOFX_RECYCLEONDELETE | FOF_NOCONFIRMATION
+ | FOF_SILENT | FOF_NOERRORUI);
+ hres = SHCreateItemFromParsingName(reinterpret_cast<const wchar_t*>(sourcePath.utf16()),
+ nullptr, IID_PPV_ARGS(&deleteItem));
+ if (!deleteItem)
+ return false;
+ sink = new FileOperationProgressSink;
+ hres = pfo->DeleteItem(deleteItem, static_cast<IFileOperationProgressSink*>(sink));
+ if (!SUCCEEDED(hres))
+ return false;
+ hres = pfo->PerformOperations();
+ if (!SUCCEEDED(hres))
+ return false;
+ newLocation = QFileSystemEntry(sink->targetPath);
+
+# endif // no IFileOperation in SDK (mingw, likely) - fall back to SHFileOperation
+ } else {
+ // double null termination needed, so can't use QString::utf16
+ QVarLengthArray<wchar_t, MAX_PATH + 1> winFile(sourcePath.length() + 2);
+ sourcePath.toWCharArray(winFile.data());
+ winFile[sourcePath.length()] = wchar_t{};
+ winFile[sourcePath.length() + 1] = wchar_t{};
+
+ SHFILEOPSTRUCTW operation;
+ operation.hwnd = nullptr;
+ operation.wFunc = FO_DELETE;
+ operation.pFrom = winFile.constData();
+ operation.pTo = nullptr;
+ operation.fFlags = FOF_ALLOWUNDO | FOF_NO_UI;
+ operation.fAnyOperationsAborted = FALSE;
+ operation.hNameMappings = nullptr;
+ operation.lpszProgressTitle = nullptr;
+
+ int result = SHFileOperation(&operation);
+ if (result != 0) {
+ error = QSystemError(result, QSystemError::NativeError);
+ return false;
+ }
+ /*
+ This implementation doesn't let us know where the file ended up, even if
+ we would specify FOF_WANTMAPPINGHANDLE | FOF_RENAMEONCOLLISION, as
+ FOF_RENAMEONCOLLISION has no effect unless files are moved, copied, or renamed.
+ */
+ Q_UNUSED(newLocation);
+ }
+ return true;
+
+#else // Q_OS_WINRT
+ Q_UNUSED(source);
+ Q_UNUSED(newLocation);
+ Q_UNUSED(error);
+ return false;
+#endif
+}
+
//static
bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Permissions permissions, QSystemError &error,
QFileSystemMetaData *data)
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index f7a86c25cd..cc1d110252 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -714,7 +714,7 @@ void QIODevicePrivate::setReadChannelCount(int count)
/*!
\since 5.7
- Returns the the index of the current write channel.
+ Returns the index of the current write channel.
\sa setCurrentWriteChannel(), writeChannelCount()
*/
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index b2bf77c0da..ce2b7e8faa 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -58,7 +58,8 @@
#include <sys/file.h> // flock
#endif
-#if defined(Q_OS_RTEMS)
+#if defined(Q_OS_RTEMS) || defined(Q_OS_QNX)
+// flock() does not work in these OSes and produce warnings when we try to use
# undef LOCK_EX
# undef LOCK_NB
#endif
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 37b8a60c37..698c4ddf41 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -60,6 +60,7 @@
#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
# include <mntent.h>
# include <sys/statvfs.h>
+# include <sys/sysmacros.h>
#elif defined(Q_OS_SOLARIS)
# include <sys/mnttab.h>
# include <sys/statvfs.h>
@@ -152,7 +153,7 @@ private:
//(2) parent ID: the ID of the parent mount (or of self for the top of the mount tree).
// int parent_id;
//(3) major:minor: the value of st_dev for files on this filesystem (see stat(2)).
-// dev_t rdev;
+ dev_t rdev;
//(4) root: the pathname of the directory in the filesystem which forms the root of this mount.
char *subvolume;
//(5) mount point: the pathname of the mount point relative to the process's root directory.
@@ -503,8 +504,7 @@ inline bool QStorageIterator::next()
int rdevminor = qstrtoll(ptr + 1, const_cast<const char **>(&ptr), 10, &ok);
if (!ptr || !ok)
return false;
- Q_UNUSED(rdevmajor);
- Q_UNUSED(rdevminor);
+ mnt.rdev = makedev(rdevmajor, rdevminor);
if (*ptr != ' ')
return false;
@@ -566,6 +566,21 @@ inline QByteArray QStorageIterator::fileSystemType() const
inline QByteArray QStorageIterator::device() const
{
+ // check that the device exists
+ if (mnt.mnt_fsname[0] == '/' && access(mnt.mnt_fsname, F_OK) != 0) {
+ // It doesn't, so let's try to resolve the dev_t from /dev/block.
+ // Note how strlen("4294967295") == digits10 + 1, so we need to add 1
+ // for each number, plus the ':'.
+ char buf[sizeof("/dev/block/") + 2 * std::numeric_limits<unsigned>::digits10 + 3];
+ QByteArray dev(PATH_MAX, Qt::Uninitialized);
+ char *devdata = dev.data();
+
+ snprintf(buf, sizeof(buf), "/dev/block/%u:%u", major(mnt.rdev), minor(mnt.rdev));
+ if (realpath(buf, devdata)) {
+ dev.truncate(strlen(devdata));
+ return dev;
+ }
+ }
return QByteArray(mnt.mnt_fsname);
}
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 0a5f9256eb..1beeb7b2a2 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -415,7 +415,7 @@
#include "qhash.h"
#include "qdir.h" // for QDir::fromNativeSeparators
#include "qdatastream.h"
-#if QT_CONFIG(topleveldomain)
+#if QT_CONFIG(topleveldomain) // ### Qt6: Remove section
#include "qtldurl_p.h"
#endif
#include "private/qipaddress_p.h"
@@ -3149,10 +3149,13 @@ bool QUrl::hasFragment() const
return d->hasFragment();
}
+#if QT_DEPRECATED_SINCE(5, 15)
#if QT_CONFIG(topleveldomain)
/*!
\since 4.8
+ \deprecated
+
Returns the TLD (Top-Level Domain) of the URL, (e.g. .co.uk, .net).
Note that the return value is prefixed with a '.' unless the
URL does not contain a valid TLD, in which case the function returns
@@ -3185,7 +3188,7 @@ QString QUrl::topLevelDomain(ComponentFormattingOptions options) const
return tld;
}
#endif
-
+#endif // QT_DEPRECATED_SINCE(5, 15)
/*!
Returns the result of the merge of this URL with \a relative. This
URL is used as a base to convert \a relative to an absolute URL.
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index 94269e4369..eb7fb8087c 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -233,9 +233,11 @@ public:
void setHost(const QString &host, ParsingMode mode = DecodedMode);
QString host(ComponentFormattingOptions = FullyDecoded) const;
+#if QT_DEPRECATED_SINCE(5, 15)
#if QT_CONFIG(topleveldomain)
- QString topLevelDomain(ComponentFormattingOptions options = FullyDecoded) const;
+ QT_DEPRECATED QString topLevelDomain(ComponentFormattingOptions options = FullyDecoded) const;
#endif
+#endif // QT_DEPRECATED_SINCE(5, 15)
void setPort(int port);
int port(int defaultPort = -1) const;
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index f132cba473..a5df17e386 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -108,6 +108,9 @@ void QPersistentModelIndexData::destroy(QPersistentModelIndexData *data)
It is good practice to check that persistent model indexes are valid
before using them.
+ \note You cannot store a QStandardItemModel's QPersistentModelIndex
+ in one of the model's items.
+
\sa {Model/View Programming}, QModelIndex, QAbstractItemModel
*/
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index b1f3b74cd4..a042361686 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -247,7 +247,7 @@ AppleApplication *qt_apple_sharedApplication()
qWarning() << "accessing the shared" << [AppleApplication class]
<< "is not allowed in application extensions";
- // In practice the application is actually available, but the the App
+ // In practice the application is actually available, but the App
// review process will likely catch uses of it, so we return nil just
// in case, unless we don't care about being App Store compliant.
#if QT_CONFIG(appstore_compliant)
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 927bfb7667..b5a62d1aa0 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -988,6 +988,30 @@ enum IteratorCapability
RandomAccessCapability = 4
};
+enum ContainerCapability
+{
+ ContainerIsAppendable = 1
+};
+
+template<typename Container, typename T = void>
+struct ContainerCapabilitiesImpl
+{
+ enum {ContainerCapabilities = 0};
+ using appendFunction = void(*)(const void *container, const void *newElement);
+ static constexpr const appendFunction appendImpl = nullptr;
+};
+
+template<typename Container>
+struct ContainerCapabilitiesImpl<Container, decltype(std::declval<Container>().push_back(std::declval<typename Container::value_type>()))>
+{
+ enum {ContainerCapabilities = ContainerIsAppendable};
+
+ // The code below invokes undefined behavior if and only if the pointer passed into QSequentialIterableImpl
+ // pointed to a const object to begin with
+ static void appendImpl(const void *container, const void *value)
+ { static_cast<Container *>(const_cast<void *>(container))->push_back(*static_cast<const typename Container::value_type *>(value)); }
+};
+
template<typename T, typename Category = typename std::iterator_traits<typename T::const_iterator>::iterator_category>
struct CapabilitiesImpl;
@@ -1019,6 +1043,12 @@ template<typename T>
struct ContainerAPI<std::list<T> > : CapabilitiesImpl<std::list<T> >
{ static int size(const std::list<T> *t) { return int(t->size()); } };
+/*
+ revision 0: _iteratorCapabilities is simply a uint, where the bits at _revision were never set
+ revision 1: _iteratorCapabilties is treated as a bitfield, the remaining bits are used to introduce
+ _revision, _containerCapabilities and _unused. The latter contains 21 bits that are
+ not used yet
+*/
class QSequentialIterableImpl
{
public:
@@ -1027,19 +1057,37 @@ public:
int _metaType_id;
uint _metaType_flags;
uint _iteratorCapabilities;
+ // Iterator capabilities looks actually like
+ // uint _iteratorCapabilities:4;
+ // uint _revision:3;
+ // uint _containerCapabilities:4;
+ // uint _unused:21;*/
typedef int(*sizeFunc)(const void *p);
typedef const void * (*atFunc)(const void *p, int);
typedef void (*moveIteratorFunc)(const void *p, void **);
+ enum Position { ToBegin, ToEnd };
+ typedef void (*moveIteratorFunc2)(const void *p, void **, Position position);
typedef void (*advanceFunc)(void **p, int);
typedef VariantData (*getFunc)( void * const *p, int metaTypeId, uint flags);
typedef void (*destroyIterFunc)(void **p);
typedef bool (*equalIterFunc)(void * const *p, void * const *other);
typedef void (*copyIterFunc)(void **, void * const *);
+ typedef void(*appendFunction)(const void *container, const void *newElement);
+
+ IteratorCapability iteratorCapabilities() {return static_cast<IteratorCapability>(_iteratorCapabilities & 0xF);}
+ uint revision() {return _iteratorCapabilities >> 4 & 0x7;}
+ uint containerCapabilities() {return _iteratorCapabilities >> 7 & 0xF;}
sizeFunc _size;
atFunc _at;
- moveIteratorFunc _moveToBegin;
- moveIteratorFunc _moveToEnd;
+ union {
+ moveIteratorFunc _moveToBegin;
+ moveIteratorFunc2 _moveTo;
+ };
+ union {
+ moveIteratorFunc _moveToEnd;
+ appendFunction _append;
+ };
advanceFunc _advance;
getFunc _get;
destroyIterFunc _destroyIter;
@@ -1066,6 +1114,15 @@ public:
static void moveToEndImpl(const void *container, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
+ template<class Container>
+ static void moveToImpl(const void *container, void **iterator, Position position)
+ {
+ if (position == ToBegin)
+ moveToBeginImpl<Container>(container, iterator);
+ else
+ moveToEndImpl<Container>(container, iterator);
+ }
+
template<class T>
static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); }
@@ -1076,11 +1133,11 @@ public:
, _iterator(nullptr)
, _metaType_id(qMetaTypeId<typename T::value_type>())
, _metaType_flags(QTypeInfo<typename T::value_type>::isPointer)
- , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities)
+ , _iteratorCapabilities(ContainerAPI<T>::IteratorCapabilities | (1 << 4) | (ContainerCapabilitiesImpl<T>::ContainerCapabilities << (4+3)))
, _size(sizeImpl<T>)
, _at(atImpl<T>)
- , _moveToBegin(moveToBeginImpl<T>)
- , _moveToEnd(moveToEndImpl<T>)
+ , _moveTo(moveToImpl<T>)
+ , _append(ContainerCapabilitiesImpl<T>::appendImpl)
, _advance(IteratorOwner<typename T::const_iterator>::advance)
, _get(getImpl<T>)
, _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
@@ -1094,7 +1151,7 @@ public:
, _iterator(nullptr)
, _metaType_id(QMetaType::UnknownType)
, _metaType_flags(0)
- , _iteratorCapabilities(0)
+ , _iteratorCapabilities(0 | (1 << 4) ) // no iterator capabilities, revision 1
, _size(nullptr)
, _at(nullptr)
, _moveToBegin(nullptr)
@@ -1107,8 +1164,18 @@ public:
{
}
- inline void moveToBegin() { _moveToBegin(_iterable, &_iterator); }
- inline void moveToEnd() { _moveToEnd(_iterable, &_iterator); }
+ inline void moveToBegin() {
+ if (revision() == 0)
+ _moveToBegin(_iterable, &_iterator);
+ else
+ _moveTo(_iterable, &_iterator, ToBegin);
+ }
+ inline void moveToEnd() {
+ if (revision() == 0)
+ _moveToEnd(_iterable, &_iterator);
+ else
+ _moveTo(_iterable, &_iterator, ToEnd);
+ }
inline bool equal(const QSequentialIterableImpl&other) const { return _equalIter(&_iterator, &other._iterator); }
inline QSequentialIterableImpl &advance(int i) {
Q_ASSERT(i > 0 || _iteratorCapabilities & BiDirectionalCapability);
@@ -1116,6 +1183,11 @@ public:
return *this;
}
+ inline void append(const void *newElement) {
+ if (containerCapabilities() & ContainerIsAppendable)
+ _append(_iterable, newElement);
+ }
+
inline VariantData getCurrent() const { return _get(&_iterator, _metaType_id, _metaType_flags); }
VariantData at(int idx) const
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index fca258c9e3..c38dab3e3f 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -72,40 +72,44 @@ public:
QVariant retrieveTypedData(const QString &format, QMetaType::Type type) const;
- QVector<QMimeDataStruct> dataList;
+ std::vector<QMimeDataStruct>::iterator find(const QString &format) noexcept {
+ const auto formatEquals = [](const QString &format) {
+ return [&format](const QMimeDataStruct &s) { return s.format == format; };
+ };
+ return std::find_if(dataList.begin(), dataList.end(), formatEquals(format));
+ }
+
+ std::vector<QMimeDataStruct>::const_iterator find(const QString &format) const noexcept {
+ return const_cast<QMimeDataPrivate*>(this)->find(format);
+ }
+
+ std::vector<QMimeDataStruct> dataList;
};
void QMimeDataPrivate::removeData(const QString &format)
{
- for (int i=0; i<dataList.size(); i++) {
- if (dataList.at(i).format == format) {
- dataList.removeAt(i);
- return;
- }
- }
+ const auto it = find(format);
+ if (it != dataList.end())
+ dataList.erase(it);
}
void QMimeDataPrivate::setData(const QString &format, const QVariant &data)
{
- // remove it first if the format is already here.
- removeData(format);
- QMimeDataStruct mimeData;
- mimeData.format = format;
- mimeData.data = data;
- dataList += mimeData;
+ const auto it = find(format);
+ if (it == dataList.end())
+ dataList.push_back({format, data});
+ else
+ it->data = data;
}
QVariant QMimeDataPrivate::getData(const QString &format) const
{
- QVariant data;
- for (int i=0; i<dataList.size(); i++) {
- if (dataList.at(i).format == format) {
- data = dataList.at(i).data;
- break;
- }
- }
- return data;
+ const auto it = find(format);
+ if (it == dataList.cend())
+ return {};
+ else
+ return it->data;
}
QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QMetaType::Type type) const
@@ -635,10 +639,9 @@ QStringList QMimeData::formats() const
{
Q_D(const QMimeData);
QStringList list;
- const int size = d->dataList.size();
- list.reserve(size);
- for (int i = 0; i < size; ++i)
- list += d->dataList.at(i).format;
+ list.reserve(static_cast<int>(d->dataList.size()));
+ for (auto &e : d->dataList)
+ list += e.format;
return list;
}
diff --git a/src/corelib/kernel/qsignalmapper.cpp b/src/corelib/kernel/qsignalmapper.cpp
index 24b174972f..dc0dfe8f40 100644
--- a/src/corelib/kernel/qsignalmapper.cpp
+++ b/src/corelib/kernel/qsignalmapper.cpp
@@ -53,11 +53,36 @@ public:
Q_Q(QSignalMapper);
q->removeMappings(q->sender());
}
+
+ template <class Signal, class Container>
+ void emitMappedValue(QObject *sender, Signal signal, const Container &mappedValues)
+ {
+ Q_Q(QSignalMapper);
+
+ auto it = mappedValues.find(sender);
+ if (it != mappedValues.end()) {
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+ Q_EMIT q->mapped(*it);
+QT_WARNING_POP
+#endif
+ Q_EMIT (q->*signal)(*it);
+ }
+ }
+
+ void emitMappedValues(QObject *sender)
+ {
+ emitMappedValue(sender, &QSignalMapper::mappedInt, intHash);
+ emitMappedValue(sender, &QSignalMapper::mappedString, stringHash);
+ emitMappedValue(sender, &QSignalMapper::mappedWidget, widgetHash);
+ emitMappedValue(sender, &QSignalMapper::mappedObject, objectHash);
+ }
+
QHash<QObject *, int> intHash;
QHash<QObject *, QString> stringHash;
QHash<QObject *, QWidget*> widgetHash;
QHash<QObject *, QObject*> objectHash;
-
};
/*!
@@ -74,11 +99,12 @@ public:
use lambdas for passing custom parameters to slots. This is less
costly and will simplify the code.
- The class supports the mapping of particular strings or integers
- with particular objects using setMapping(). The objects' signals
- can then be connected to the map() slot which will emit the
- mapped() signal with the string or integer associated with the
- original signalling object. Mappings can be removed later using
+ The class supports the mapping of particular strings, integers,
+ objects and widgets with particular objects using setMapping().
+ The objects' signals can then be connected to the map() slot which
+ will emit a signal (it could be mappedInt(), mappedString(),
+ mappedWidget() and mappedObject()) with a value associated with
+ the original signalling object. Mappings can be removed later using
removeMappings().
Example: Suppose we want to create a custom widget that contains
@@ -106,8 +132,8 @@ public:
created. We connect each button's \c clicked() signal to the
signal mapper's map() slot, and create a mapping in the signal
mapper from each button to the button's text. Finally we connect
- the signal mapper's mapped() signal to the custom widget's \c
- clicked() signal. When the user clicks a button, the custom
+ the signal mapper's mappedString() signal to the custom widget's
+ \c clicked() signal. When the user clicks a button, the custom
widget will emit a single \c clicked() signal whose argument is
the text of the button the user clicked.
@@ -137,7 +163,7 @@ QSignalMapper::~QSignalMapper()
/*!
Adds a mapping so that when map() is signalled from the given \a
- sender, the signal mapped(\a id) is emitted.
+ sender, the signal mappedInt(\a id) is emitted.
There may be at most one integer ID for each sender.
@@ -152,7 +178,7 @@ void QSignalMapper::setMapping(QObject *sender, int id)
/*!
Adds a mapping so that when map() is signalled from the \a sender,
- the signal mapped(\a text ) is emitted.
+ the signal mappedString(\a text ) is emitted.
There may be at most one text for each sender.
*/
@@ -165,7 +191,7 @@ void QSignalMapper::setMapping(QObject *sender, const QString &text)
/*!
Adds a mapping so that when map() is signalled from the \a sender,
- the signal mapped(\a widget ) is emitted.
+ the signal mappedWidget(\a widget ) is emitted.
There may be at most one widget for each sender.
*/
@@ -178,7 +204,7 @@ void QSignalMapper::setMapping(QObject *sender, QWidget *widget)
/*!
Adds a mapping so that when map() is signalled from the \a sender,
- the signal mapped(\a object ) is emitted.
+ the signal mappedObject(\a object ) is emitted.
There may be at most one object for each sender.
*/
@@ -259,20 +285,14 @@ void QSignalMapper::map() { map(sender()); }
*/
void QSignalMapper::map(QObject *sender)
{
- Q_D(QSignalMapper);
- if (d->intHash.contains(sender))
- emit mapped(d->intHash.value(sender));
- if (d->stringHash.contains(sender))
- emit mapped(d->stringHash.value(sender));
- if (d->widgetHash.contains(sender))
- emit mapped(d->widgetHash.value(sender));
- if (d->objectHash.contains(sender))
- emit mapped(d->objectHash.value(sender));
+ d_func()->emitMappedValues(sender);
}
-
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\fn void QSignalMapper::mapped(int i)
+ \obsolete
+ \overload
This signal is emitted when map() is signalled from an object that
has an integer mapping set. The object's mapped integer is passed
@@ -283,6 +303,8 @@ void QSignalMapper::map(QObject *sender)
/*!
\fn void QSignalMapper::mapped(const QString &text)
+ \obsolete
+ \overload
This signal is emitted when map() is signalled from an object that
has a string mapping set. The object's mapped string is passed in
@@ -293,6 +315,8 @@ void QSignalMapper::map(QObject *sender)
/*!
\fn void QSignalMapper::mapped(QWidget *widget)
+ \obsolete
+ \overload
This signal is emitted when map() is signalled from an object that
has a widget mapping set. The object's mapped widget is passed in
@@ -303,6 +327,53 @@ void QSignalMapper::map(QObject *sender)
/*!
\fn void QSignalMapper::mapped(QObject *object)
+ \obsolete
+ \overload
+
+ This signal is emitted when map() is signalled from an object that
+ has an object mapping set. The object provided by the map is passed in
+ \a object.
+
+ \sa setMapping()
+*/
+#endif
+
+/*!
+ \fn void QSignalMapper::mappedInt(int i)
+ \since 5.15
+
+ This signal is emitted when map() is signalled from an object that
+ has an integer mapping set. The object's mapped integer is passed
+ in \a i.
+
+ \sa setMapping()
+*/
+
+/*!
+ \fn void QSignalMapper::mappedString(const QString &text)
+ \since 5.15
+
+ This signal is emitted when map() is signalled from an object that
+ has a string mapping set. The object's mapped string is passed in
+ \a text.
+
+ \sa setMapping()
+*/
+
+/*!
+ \fn void QSignalMapper::mappedWidget(QWidget *widget)
+ \since 5.15
+
+ This signal is emitted when map() is signalled from an object that
+ has a widget mapping set. The object's mapped widget is passed in
+ \a widget.
+
+ \sa setMapping()
+*/
+
+/*!
+ \fn void QSignalMapper::mappedObject(QObject *object)
+ \since 5.15
This signal is emitted when map() is signalled from an object that
has an object mapping set. The object provided by the map is passed in
diff --git a/src/corelib/kernel/qsignalmapper.h b/src/corelib/kernel/qsignalmapper.h
index 0da1e8f87d..592986e6a5 100644
--- a/src/corelib/kernel/qsignalmapper.h
+++ b/src/corelib/kernel/qsignalmapper.h
@@ -66,10 +66,20 @@ public:
QObject *mapping(QObject *object) const;
Q_SIGNALS:
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_VERSION_X_5_15("Use QSignalMapper::mappedInt(int) instead")
void mapped(int);
+ QT_DEPRECATED_VERSION_X_5_15("Use QSignalMapper::mappedString(const QString&) instead")
void mapped(const QString &);
+ QT_DEPRECATED_VERSION_X_5_15("Use QSignalMapper::mappedWidget(QWidget *) instead")
void mapped(QWidget *);
+ QT_DEPRECATED_VERSION_X_5_15("Use QSignalMapper::mappedObject(QObject *) instead")
void mapped(QObject *);
+#endif
+ void mappedInt(int);
+ void mappedString(const QString &);
+ void mappedWidget(QWidget *);
+ void mappedObject(QObject *);
public Q_SLOTS:
void map();
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index 4bd8874630..5767d52f6a 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -283,7 +283,7 @@ class QTranslatorPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QTranslator)
public:
- enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88, Dependencies = 0x96 };
+ enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88, Dependencies = 0x96, Language = 0xa7 };
QTranslatorPrivate() :
#if defined(QT_USE_MMAP)
@@ -316,6 +316,9 @@ public:
uint contextLength;
uint numerusRulesLength;
+ QString language;
+ QString filePath;
+
bool do_load(const QString &filename, const QString &directory);
bool do_load(const uchar *data, qsizetype len, const QString &directory);
QString do_translate(const char *context, const char *sourceText, const char *comment,
@@ -597,8 +600,10 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
}
}
- if (ok && d->do_load(reinterpret_cast<const uchar *>(d->unmapPointer), d->unmapLength, directory))
+ if (ok && d->do_load(reinterpret_cast<const uchar *>(d->unmapPointer), d->unmapLength, directory)) {
+ d->filePath = realname;
return true;
+ }
#if defined(QT_USE_MMAP)
if (used_mmap) {
@@ -829,7 +834,9 @@ bool QTranslatorPrivate::do_load(const uchar *data, qsizetype len, const QString
break;
}
- if (tag == QTranslatorPrivate::Contexts) {
+ if (tag == QTranslatorPrivate::Language) {
+ language = QString::fromUtf8((const char*)data, blockLen);
+ } else if (tag == QTranslatorPrivate::Contexts) {
contextArray = data;
contextLength = blockLen;
} else if (tag == QTranslatorPrivate::Hashes) {
@@ -1091,6 +1098,9 @@ void QTranslatorPrivate::clear()
qDeleteAll(subTranslators);
subTranslators.clear();
+ language.clear();
+ filePath.clear();
+
if (QCoreApplicationPrivate::isTranslatorInstalled(q))
QCoreApplication::postEvent(QCoreApplication::instance(),
new QEvent(QEvent::LanguageChange));
@@ -1132,6 +1142,32 @@ bool QTranslator::isEmpty() const
&& d->subTranslators.isEmpty();
}
+/*!
+ \since 5.15
+
+ Returns the target language as stored in the translation file.
+ */
+QString QTranslator::language() const
+{
+ Q_D(const QTranslator);
+ return d->language;
+}
+
+/*!
+ \since 5.15
+
+ Returns the path of the loaded translation file.
+
+ The file path is empty if no translation was loaded yet,
+ the loading failed, or if the translation was not loaded
+ from a file.
+ */
+QString QTranslator::filePath() const
+{
+ Q_D(const QTranslator);
+ return d->filePath;
+}
+
QT_END_NAMESPACE
#include "moc_qtranslator.cpp"
diff --git a/src/corelib/kernel/qtranslator.h b/src/corelib/kernel/qtranslator.h
index e7c39191e7..61a39c4089 100644
--- a/src/corelib/kernel/qtranslator.h
+++ b/src/corelib/kernel/qtranslator.h
@@ -63,6 +63,9 @@ public:
virtual bool isEmpty() const;
+ QString language() const;
+ QString filePath() const;
+
bool load(const QString & filename,
const QString & directory = QString(),
const QString & search_delimiters = QString(),
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 4ac26e3048..e3d565f185 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -662,7 +662,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
# endif
#endif
case QMetaType::QDate:
- *dt = QDateTime(*v_cast<QDate>(d));
+ *dt = v_cast<QDate>(d)->startOfDay();
break;
default:
return false;
@@ -1229,7 +1229,7 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*static_cast<QCborValue *>(result) = *v_cast<QByteArray>(d);
break;
case QMetaType::QDate:
- *static_cast<QCborValue *>(result) = QCborValue(QDateTime(*v_cast<QDate>(d)));
+ *static_cast<QCborValue *>(result) = QCborValue(v_cast<QDate>(d)->startOfDay());
break;
case QMetaType::QDateTime:
*static_cast<QCborValue *>(result) = QCborValue(*v_cast<QDateTime>(d));
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 6eb84b327b..4a092abb3e 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2018 Intel Corporation
+** Copyright (C) 2020 Intel Corporation
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -218,6 +218,8 @@ bool QLibraryPrivate::load_sys()
for(int suffix = 0; retry && !pHnd && suffix < suffixes.size(); suffix++) {
if (!prefixes.at(prefix).isEmpty() && name.startsWith(prefixes.at(prefix)))
continue;
+ if (path.isEmpty() && prefixes.at(prefix).contains(QLatin1Char('/')))
+ continue;
if (!suffixes.at(suffix).isEmpty() && name.endsWith(suffixes.at(suffix)))
continue;
if (loadHints & QLibrary::LoadArchiveMemberHint) {
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index aed1704d5f..f34578ea81 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -342,7 +342,7 @@ static QString locatePlugin(const QString& fileName)
QPluginLoader will automatically look for the file with the appropriate
suffix (see QLibrary::isLibrary()).
- When loading the plugin, QPluginLoader searches in the current directory and
+ When loading the plugin, QPluginLoader searches
in all plugin locations specified by QCoreApplication::libraryPaths(),
unless the file name has an absolute path. After loading the plugin
successfully, fileName() returns the fully-qualified file name of
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index fb551d5197..c1fa700959 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -3185,6 +3185,26 @@ QStateMachine::WrappedEvent::~WrappedEvent()
\sa QStateMachine::running
*/
+/*!
+ \fn QStateMachine::postDelayedEvent(QEvent *event, std::chrono::milliseconds delay)
+ \since 5.15
+ \overload
+ \threadsafe
+
+ Posts the given \a event for processing by this state machine, with the
+ given \a delay in milliseconds. Returns an identifier associated with the
+ delayed event, or -1 if the event could not be posted.
+
+ This function returns immediately. When the delay has expired, the event
+ will be added to the state machine's event queue for processing. The state
+ machine takes ownership of the event and deletes it once it has been
+ processed.
+
+ You can only post events when the state machine is running.
+
+ \sa cancelDelayedEvent(), postEvent()
+*/
+
QT_END_NAMESPACE
#include "qstatemachine.moc"
diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h
index 07781d09a4..b3c87a959b 100644
--- a/src/corelib/statemachine/qstatemachine.h
+++ b/src/corelib/statemachine/qstatemachine.h
@@ -48,6 +48,10 @@
#include <QtCore/qset.h>
#include <QtCore/qvariant.h>
+#if __has_include(<chrono>)
+# include <chrono>
+#endif
+
QT_REQUIRE_CONFIG(statemachine);
QT_BEGIN_NAMESPACE
@@ -145,6 +149,13 @@ public:
bool eventFilter(QObject *watched, QEvent *event) override;
#endif
+#if __has_include(<chrono>) || defined(Q_QDOC)
+ int postDelayedEvent(QEvent *event, std::chrono::milliseconds delay)
+ {
+ return postDelayedEvent(event, int(delay.count()));
+ }
+#endif
+
public Q_SLOTS:
void start();
void stop();
diff --git a/src/corelib/text/qcollator_icu.cpp b/src/corelib/text/qcollator_icu.cpp
index 8acda45070..0dca1ee9c9 100644
--- a/src/corelib/text/qcollator_icu.cpp
+++ b/src/corelib/text/qcollator_icu.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
** Contact: https://www.qt.io/licensing/
**
@@ -109,6 +109,11 @@ void QCollatorPrivate::cleanup()
int QCollator::compare(QStringView s1, QStringView s2) const
{
+ if (!s1.size())
+ return s2.size() ? -1 : 0;
+ if (!s2.size())
+ return +1;
+
if (d->dirty)
d->init();
diff --git a/src/corelib/text/qcollator_macx.cpp b/src/corelib/text/qcollator_macx.cpp
index 071d7c048f..cb8e073d4a 100644
--- a/src/corelib/text/qcollator_macx.cpp
+++ b/src/corelib/text/qcollator_macx.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
+** Copyright (C) 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -94,6 +94,11 @@ void QCollatorPrivate::cleanup()
int QCollator::compare(QStringView s1, QStringView s2) const
{
+ if (!s1.size())
+ return s2.size() ? -1 : 0;
+ if (!s2.size())
+ return +1;
+
if (d->dirty)
d->init();
if (!d->collator)
diff --git a/src/corelib/text/qcollator_posix.cpp b/src/corelib/text/qcollator_posix.cpp
index 9cbc539ebe..ffcd214cfb 100644
--- a/src/corelib/text/qcollator_posix.cpp
+++ b/src/corelib/text/qcollator_posix.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
+** Copyright (C) 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -75,6 +75,11 @@ static void stringToWCharArray(QVarLengthArray<wchar_t> &ret, QStringView string
int QCollator::compare(QStringView s1, QStringView s2) const
{
+ if (!s1.size())
+ return s2.size() ? -1 : 0;
+ if (!s2.size())
+ return +1;
+
if (d->isC())
return s1.compare(s2, caseSensitivity());
if (d->dirty)
diff --git a/src/corelib/text/qcollator_win.cpp b/src/corelib/text/qcollator_win.cpp
index 9d81de882f..54f57f1d24 100644
--- a/src/corelib/text/qcollator_win.cpp
+++ b/src/corelib/text/qcollator_win.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
+** Copyright (C) 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -89,6 +89,11 @@ void QCollatorPrivate::cleanup()
int QCollator::compare(QStringView s1, QStringView s2) const
{
+ if (!s1.size())
+ return s2.size() ? -1 : 0;
+ if (!s2.size())
+ return +1;
+
if (d->isC())
return s1.compare(s2, d->caseSensitivity);
diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp
index 05fe638f46..268e96bfd2 100644
--- a/src/corelib/text/qlocale.cpp
+++ b/src/corelib/text/qlocale.cpp
@@ -660,6 +660,11 @@ static QLocalePrivate *c_private()
return &c_locale;
}
+static const QLocaleData *systemData();
+static QLocale::NumberOptions system_number_options = QLocale::DefaultNumberOptions;
+Q_GLOBAL_STATIC_WITH_ARGS(QExplicitlySharedDataPointer<QLocalePrivate>, systemLocalePrivate,
+ (QLocalePrivate::create(systemData(), system_number_options)))
+
#ifndef QT_NO_SYSTEMLOCALE
/******************************************************************************
** Default system locale behavior
@@ -711,6 +716,7 @@ static void updateSystemPrivate()
{
// This function is NOT thread-safe!
// It *should not* be called by anything but systemData()
+ // It *is* called before {system,default}LocalePrivate exist.
const QSystemLocale *sys_locale = systemLocale();
// tell the object that the system locale has changed.
@@ -718,11 +724,14 @@ static void updateSystemPrivate()
// Populate global with fallback as basis:
globalLocaleData = *sys_locale->fallbackUiLocaleData();
+ system_number_options = QLocale::DefaultNumberOptions;
QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
if (!res.isNull()) {
globalLocaleData.m_language_id = res.toInt();
globalLocaleData.m_script_id = QLocale::AnyScript; // default for compatibility
+ if (globalLocaleData.m_language_id == QLocale::C)
+ system_number_options = QLocale::OmitGroupSeparator;
}
res = sys_locale->query(QSystemLocale::CountryId, QVariant());
if (!res.isNull()) {
@@ -737,9 +746,26 @@ static void updateSystemPrivate()
if (!res.isNull() && !res.toString().isEmpty())
globalLocaleData.m_decimal = res.toString().at(0).unicode();
+ // System may supply empty group separator to say we should omit grouping;
+ // and it makes no sense to use the same separator for decimal and grouping
+ // (which might happen by system supplying, as decimal, what CLDR has given
+ // us for grouping; or the other way round). Assume, at least, that each of
+ // system and CLDR has decimal != group, all the same.
res = sys_locale->query(QSystemLocale::GroupSeparator, QVariant());
- if (!res.isNull() && !res.toString().isEmpty())
- globalLocaleData.m_group = res.toString().at(0).unicode();
+ if (res.isNull()) {
+ // The case where system over-rides decimal but not group, and its
+ // decimal clashes with CLDR's group.
+ if (globalLocaleData.m_group == globalLocaleData.m_decimal)
+ system_number_options |= QLocale::OmitGroupSeparator;
+ } else if (res.toString().isEmpty()) {
+ system_number_options |= QLocale::OmitGroupSeparator;
+ } else {
+ const ushort group = res.toString().at(0).unicode();
+ if (group != globalLocaleData.m_decimal)
+ globalLocaleData.m_group = group;
+ else if (group == globalLocaleData.m_group)
+ qWarning("System-supplied decimal and grouping character are both 0x%hx", group);
+ }
res = sys_locale->query(QSystemLocale::ZeroDigit, QVariant());
if (!res.isNull() && !res.toString().isEmpty())
@@ -752,6 +778,10 @@ static void updateSystemPrivate()
res = sys_locale->query(QSystemLocale::PositiveSign, QVariant());
if (!res.isNull() && !res.toString().isEmpty())
globalLocaleData.m_plus = res.toString().at(0).unicode();
+
+ if (systemLocalePrivate.exists())
+ systemLocalePrivate->data()->m_numberOptions = system_number_options;
+ // else: system_number_options will be passed to create() when constructing.
}
#endif // !QT_NO_SYSTEMLOCALE
@@ -812,8 +842,6 @@ static const int locale_data_size = sizeof(locale_data)/sizeof(QLocaleData) - 1;
Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, defaultLocalePrivate,
(QLocalePrivate::create(defaultData())))
-Q_GLOBAL_STATIC_WITH_ARGS(QExplicitlySharedDataPointer<QLocalePrivate>, systemLocalePrivate,
- (QLocalePrivate::create(systemData())))
static QLocalePrivate *localePrivateByName(const QString &name)
{
@@ -1996,6 +2024,9 @@ QString QLocale::toString(const QDate &date, QStringView format) const
/*!
Returns a localized string representation of the given \a date according
to the specified \a format.
+
+ \note Some locales may use formats that limit the range of years they can
+ represent.
*/
QString QLocale::toString(const QDate &date, FormatType format) const
@@ -2150,6 +2181,9 @@ QString QLocale::toString(const QDateTime &dateTime, QStringView format, QCalend
Returns a localized string representation of the given \a dateTime according
to the specified \a format.
+
+ \note Some locales may use formats that limit the range of years they can
+ represent.
*/
QString QLocale::toString(const QDateTime &dateTime, FormatType format) const
@@ -2302,14 +2336,19 @@ QTime QLocale::toTime(const QString &string, FormatType format) const
return toTime(string, timeFormat(format));
}
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\since 5.14
\overload
+ \deprecated
*/
QTime QLocale::toTime(const QString &string, FormatType format, QCalendar cal) const
{
+QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
return toTime(string, timeFormat(format), cal);
+QT_WARNING_POP
}
+#endif
/*!
\since 4.4
@@ -2374,12 +2413,24 @@ QDateTime QLocale::toDateTime(const QString &string, FormatType format, QCalenda
*/
QTime QLocale::toTime(const QString &string, const QString &format) const
{
- return toTime(string, format, QCalendar());
+ QTime time;
+#if QT_CONFIG(datetimeparser)
+ QDateTimeParser dt(QMetaType::QTime, QDateTimeParser::FromString, QCalendar());
+ dt.setDefaultLocale(*this);
+ if (dt.parseFormat(format))
+ dt.fromString(string, nullptr, &time);
+#else
+ Q_UNUSED(string);
+ Q_UNUSED(format);
+#endif
+ return time;
}
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\since 5.14
\overload
+ \deprecated
*/
QTime QLocale::toTime(const QString &string, const QString &format, QCalendar cal) const
{
@@ -2396,6 +2447,7 @@ QTime QLocale::toTime(const QString &string, const QString &format, QCalendar ca
#endif
return time;
}
+#endif
/*!
\since 4.4
diff --git a/src/corelib/text/qlocale.h b/src/corelib/text/qlocale.h
index cbdcebc57d..a9933bbb2e 100644
--- a/src/corelib/text/qlocale.h
+++ b/src/corelib/text/qlocale.h
@@ -1038,11 +1038,15 @@ public:
QDateTime toDateTime(const QString &string, const QString &format) const;
// Calendar-aware API
QDate toDate(const QString &string, FormatType format, QCalendar cal) const;
- QTime toTime(const QString &string, FormatType format, QCalendar cal) const;
QDateTime toDateTime(const QString &string, FormatType format, QCalendar cal) const;
QDate toDate(const QString &string, const QString &format, QCalendar cal) const;
- QTime toTime(const QString &string, const QString &format, QCalendar cal) const;
QDateTime toDateTime(const QString &string, const QString &format, QCalendar cal) const;
+# if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Calendar is ignored when parsing times")
+ QTime toTime(const QString &string, FormatType format, QCalendar cal) const;
+ QT_DEPRECATED_X("Calendar is ignored when parsing times")
+ QTime toTime(const QString &string, const QString &format, QCalendar cal) const;
+# endif // 5.15
#endif
// ### Qt 6: We need to return QString from these function since
diff --git a/src/corelib/text/qlocale_mac.mm b/src/corelib/text/qlocale_mac.mm
index 31ede1352b..5381f0f975 100644
--- a/src/corelib/text/qlocale_mac.mm
+++ b/src/corelib/text/qlocale_mac.mm
@@ -119,7 +119,7 @@ static QString macDayName(int day, bool short_format)
return QString();
}
-static QString macDateToString(const QDate &date, bool short_format)
+static QString macDateToString(QDate date, bool short_format)
{
QCFType<CFDateRef> myDate = QDateTime(date, QTime()).toCFDate();
QCFType<CFLocaleRef> mylocale = CFLocaleCopyCurrent();
@@ -131,7 +131,7 @@ static QString macDateToString(const QDate &date, bool short_format)
return QCFString(CFDateFormatterCreateStringWithDate(0, myFormatter, myDate));
}
-static QString macTimeToString(const QTime &time, bool short_format)
+static QString macTimeToString(QTime time, bool short_format)
{
QCFType<CFDateRef> myDate = QDateTime(QDate::currentDate(), time).toCFDate();
QCFType<CFLocaleRef> mylocale = CFLocaleCopyCurrent();
@@ -283,10 +283,12 @@ static QString getMacTimeFormat(CFDateFormatterStyle style)
return macToQtFormat(QString::fromCFString(CFDateFormatterGetFormat(formatter)));
}
-static QString getCFLocaleValue(CFStringRef key)
+static QVariant getCFLocaleValue(CFStringRef key)
{
QCFType<CFLocaleRef> locale = CFLocaleCopyCurrent();
CFTypeRef value = CFLocaleGetValue(locale, key);
+ if (!value)
+ return QVariant();
return QString::fromCFString(CFStringRef(static_cast<CFTypeRef>(value)));
}
@@ -411,14 +413,10 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const
switch(type) {
// case Name:
// return getMacLocaleName();
- case DecimalPoint: {
- QString value = getCFLocaleValue(kCFLocaleDecimalSeparator);
- return value.isEmpty() ? QVariant() : value;
- }
- case GroupSeparator: {
- QString value = getCFLocaleValue(kCFLocaleGroupingSeparator);
- return value.isEmpty() ? QVariant() : value;
- }
+ case DecimalPoint:
+ return getCFLocaleValue(kCFLocaleDecimalSeparator);
+ case GroupSeparator:
+ return getCFLocaleValue(kCFLocaleGroupingSeparator);
case DateFormatLong:
case DateFormatShort:
return getMacDateFormat(type == DateFormatShort
diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h
index a7c15d08fb..11a42b7fee 100644
--- a/src/corelib/text/qlocale_p.h
+++ b/src/corelib/text/qlocale_p.h
@@ -87,7 +87,7 @@ public:
LanguageId, // uint
CountryId, // uint
DecimalPoint, // QString
- GroupSeparator, // QString
+ GroupSeparator, // QString (empty QString means: don't group digits)
ZeroDigit, // QString
NegativeSign, // QString
DateFormatLong, // QString
diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp
index 4b4152c519..4a38adf309 100644
--- a/src/corelib/text/qlocale_win.cpp
+++ b/src/corelib/text/qlocale_win.cpp
@@ -106,11 +106,11 @@ struct QSystemLocalePrivate
{
QSystemLocalePrivate();
- QString zeroDigit();
- QString decimalPoint();
- QString groupSeparator();
- QString negativeSign();
- QString positiveSign();
+ QVariant zeroDigit();
+ QVariant decimalPoint();
+ QVariant groupSeparator();
+ QVariant negativeSign();
+ QVariant positiveSign();
QVariant dateFormat(QLocale::FormatType);
QVariant timeFormat(QLocale::FormatType);
QVariant dateTimeFormat(QLocale::FormatType);
@@ -150,7 +150,9 @@ private:
QString zero; // cached value for zeroDigit()
int getLocaleInfo(LCTYPE type, LPWSTR data, int size);
- QString getLocaleInfo(LCTYPE type, int maxlen = 0);
+ // Need to distinguish empty QString packaged as (non-null) QVariant from null QVariant:
+ template <typename T = QString>
+ T getLocaleInfo(LCTYPE type, int maxlen = 0);
int getLocaleInfo_int(LCTYPE type, int maxlen = 0);
int getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size);
@@ -211,19 +213,30 @@ inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int siz
#endif
}
-QString QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen)
+template<typename T>
+T QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen)
{
+ // https://docs.microsoft.com/en-us/windows/win32/intl/locale-spositivesign
+ // says empty for LOCALE_SPOSITIVESIGN means "+", although GetLocaleInfo()
+ // is documented to return 0 only on failure, so it's not clear how it
+ // returns empty to mean this; hence the two checks for it below.
+ const QString plus = QStringLiteral("+");
QVarLengthArray<wchar_t, 64> buf(maxlen ? maxlen : 64);
- if (!getLocaleInfo(type, buf.data(), buf.size()))
- return QString();
- if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ if (!getLocaleInfo(type, buf.data(), buf.size())) {
+ const auto lastError = GetLastError();
+ if (type == LOCALE_SPOSITIVESIGN && lastError == ERROR_SUCCESS)
+ return plus;
+ if (lastError != ERROR_INSUFFICIENT_BUFFER)
+ return {};
int cnt = getLocaleInfo(type, 0, 0);
if (cnt == 0)
- return QString();
+ return {};
buf.resize(cnt);
if (!getLocaleInfo(type, buf.data(), buf.size()))
- return QString();
+ return {};
}
+ if (type == LOCALE_SPOSITIVESIGN && !buf[0])
+ return plus;
return QString::fromWCharArray(buf.data());
}
@@ -298,7 +311,7 @@ QString &QSystemLocalePrivate::substituteDigits(QString &string)
return string;
}
-QString QSystemLocalePrivate::zeroDigit()
+QVariant QSystemLocalePrivate::zeroDigit()
{
if (zero.isEmpty()) {
/* Ten digits plus a terminator.
@@ -317,24 +330,24 @@ QString QSystemLocalePrivate::zeroDigit()
return zero;
}
-QString QSystemLocalePrivate::decimalPoint()
+QVariant QSystemLocalePrivate::decimalPoint()
{
- return getLocaleInfo(LOCALE_SDECIMAL);
+ return getLocaleInfo<QVariant>(LOCALE_SDECIMAL);
}
-QString QSystemLocalePrivate::groupSeparator()
+QVariant QSystemLocalePrivate::groupSeparator()
{
- return getLocaleInfo(LOCALE_STHOUSAND);
+ return getLocaleInfo<QVariant>(LOCALE_STHOUSAND);
}
-QString QSystemLocalePrivate::negativeSign()
+QVariant QSystemLocalePrivate::negativeSign()
{
- return getLocaleInfo(LOCALE_SNEGATIVESIGN);
+ return getLocaleInfo<QVariant>(LOCALE_SNEGATIVESIGN);
}
-QString QSystemLocalePrivate::positiveSign()
+QVariant QSystemLocalePrivate::positiveSign()
{
- return getLocaleInfo(LOCALE_SPOSITIVESIGN);
+ return getLocaleInfo<QVariant>(LOCALE_SPOSITIVESIGN);
}
QVariant QSystemLocalePrivate::dateFormat(QLocale::FormatType type)
@@ -392,10 +405,10 @@ QVariant QSystemLocalePrivate::dayName(int day, QLocale::FormatType type)
day -= 1;
if (type == QLocale::LongFormat)
- return getLocaleInfo(long_day_map[day]);
+ return getLocaleInfo<QVariant>(long_day_map[day]);
if (type == QLocale::NarrowFormat)
- return getLocaleInfo(narrow_day_map[day]);
- return getLocaleInfo(short_day_map[day]);
+ return getLocaleInfo<QVariant>(narrow_day_map[day]);
+ return getLocaleInfo<QVariant>(short_day_map[day]);
}
QVariant QSystemLocalePrivate::monthName(int month, QLocale::FormatType type)
@@ -418,7 +431,7 @@ QVariant QSystemLocalePrivate::monthName(int month, QLocale::FormatType type)
LCTYPE lctype = (type == QLocale::ShortFormat || type == QLocale::NarrowFormat)
? short_month_map[month] : long_month_map[month];
- return getLocaleInfo(lctype);
+ return getLocaleInfo<QVariant>(lctype);
}
QVariant QSystemLocalePrivate::toString(QDate date, QLocale::FormatType type)
@@ -485,7 +498,7 @@ QVariant QSystemLocalePrivate::measurementSystem()
QVariant QSystemLocalePrivate::collation()
{
- return getLocaleInfo(LOCALE_SSORTLOCALE);
+ return getLocaleInfo<QVariant>(LOCALE_SSORTLOCALE);
}
QVariant QSystemLocalePrivate::amText()
@@ -687,12 +700,12 @@ QVariant QSystemLocalePrivate::uiLanguages()
QVariant QSystemLocalePrivate::nativeLanguageName()
{
- return getLocaleInfo(LOCALE_SNATIVELANGUAGENAME);
+ return getLocaleInfo<QVariant>(LOCALE_SNATIVELANGUAGENAME);
}
QVariant QSystemLocalePrivate::nativeCountryName()
{
- return getLocaleInfo(LOCALE_SNATIVECOUNTRYNAME);
+ return getLocaleInfo<QVariant>(LOCALE_SNATIVECOUNTRYNAME);
}
diff --git a/src/corelib/thread/qrunnable.cpp b/src/corelib/thread/qrunnable.cpp
index b355ca605f..5b883a05da 100644
--- a/src/corelib/thread/qrunnable.cpp
+++ b/src/corelib/thread/qrunnable.cpp
@@ -113,4 +113,31 @@ QRunnable::~QRunnable()
\sa autoDelete(), QThreadPool
*/
+class FunctionRunnable : public QRunnable
+{
+ std::function<void()> m_functor;
+public:
+ FunctionRunnable(std::function<void()> functor) : m_functor(std::move(functor))
+ {
+ }
+ void run() override
+ {
+ m_functor();
+ }
+};
+
+/*!
+ \since 5.15
+
+ Creates a QRunnable that calls \a fun in run().
+
+ Auto-deletion is enabled by default.
+
+ \sa run(), autoDelete()
+*/
+QRunnable *QRunnable::create(std::function<void()> fun)
+{
+ return new FunctionRunnable(std::move(fun));
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qrunnable.h b/src/corelib/thread/qrunnable.h
index b8e842118c..c13aa3fa8c 100644
--- a/src/corelib/thread/qrunnable.h
+++ b/src/corelib/thread/qrunnable.h
@@ -41,6 +41,7 @@
#define QRUNNABLE_H
#include <QtCore/qglobal.h>
+#include <functional>
QT_BEGIN_NAMESPACE
@@ -59,6 +60,7 @@ public:
QRunnable() : ref(0) { }
virtual ~QRunnable();
+ static QRunnable *create(std::function<void()> fun);
bool autoDelete() const { return ref != -1; }
void setAutoDelete(bool _autoDelete) { ref = _autoDelete ? 0 : -1; }
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index 5f23a78c8a..d1875a69a9 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -512,6 +512,22 @@ void QThreadPool::start(QRunnable *runnable, int priority)
}
/*!
+ \overload
+ \since 5.15
+
+ Reserves a thread and uses it to run \a fun, unless this thread will
+ make the current thread count exceed maxThreadCount(). In that case,
+ \a fun is added to a run queue instead. The \a priority argument can
+ be used to control the run queue's order of execution.
+*/
+void QThreadPool::start(std::function<void()> fun, int priority)
+{
+ if (!fun)
+ return;
+ start(QRunnable::create(std::move(fun)), priority);
+}
+
+/*!
Attempts to reserve a thread to run \a runnable.
If no threads are available at the time of calling, then this function
@@ -542,6 +558,22 @@ bool QThreadPool::tryStart(QRunnable *runnable)
return d->tryStart(runnable);
}
+/*!
+ \overload
+ \since 5.15
+ Attempts to reserve a thread to run \a fun.
+
+ If no threads are available at the time of calling, then this function
+ does nothing and returns \c false. Otherwise, \a fun is run immediately
+ using one available thread and this function returns \c true.
+*/
+bool QThreadPool::tryStart(std::function<void()> fun)
+{
+ if (!fun)
+ return false;
+ return tryStart(QRunnable::create(std::move(fun)));
+}
+
/*! \property QThreadPool::expiryTimeout
Threads that are unused for \a expiryTimeout milliseconds are considered
diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h
index cd27b7c08a..2eede44eca 100644
--- a/src/corelib/thread/qthreadpool.h
+++ b/src/corelib/thread/qthreadpool.h
@@ -45,6 +45,8 @@
#include <QtCore/qthread.h>
#include <QtCore/qrunnable.h>
+#include <functional>
+
QT_REQUIRE_CONFIG(thread);
QT_BEGIN_NAMESPACE
@@ -70,6 +72,9 @@ public:
void start(QRunnable *runnable, int priority = 0);
bool tryStart(QRunnable *runnable);
+ void start(std::function<void()> fun, int priority = 0);
+ bool tryStart(std::function<void()> fun);
+
int expiryTimeout() const;
void setExpiryTimeout(int expiryTimeout);
diff --git a/src/corelib/time/qcalendar.cpp b/src/corelib/time/qcalendar.cpp
index 9d485f181e..32f0a511a3 100644
--- a/src/corelib/time/qcalendar.cpp
+++ b/src/corelib/time/qcalendar.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -750,6 +750,8 @@ int QCalendar::daysInMonth(int month, int year) const
/*!
Returns the number of days in the given \a year.
+
+ Handling of \c Unspecified as \a year is undefined.
*/
int QCalendar::daysInYear(int year) const
{
@@ -758,10 +760,15 @@ int QCalendar::daysInYear(int year) const
/*!
Returns the number of months in the given \a year.
+
+ If \a year is \c Unspecified, returns the maximum number of months in a
+ year.
+
+ \sa maximumMonthsInYear()
*/
int QCalendar::monthsInYear(int year) const
{
- return d ? d->monthsInYear(year) : 0;
+ return d ? year == Unspecified ? d->maximumMonthsInYear() : d->monthsInYear(year) : 0;
}
/*!
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index 80751e60a0..773280ad68 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -682,7 +682,7 @@ static bool inDateTimeRange(qint64 jd, bool start)
return jd >= minDay && jd < maxDay;
}
-static QDateTime toEarliest(const QDate &day, const QDateTime &form)
+static QDateTime toEarliest(QDate day, const QDateTime &form)
{
const Qt::TimeSpec spec = form.timeSpec();
const int offset = (spec == Qt::OffsetFromUTC) ? form.offsetFromUtc() : 0;
@@ -806,7 +806,7 @@ QDateTime QDate::startOfDay(const QTimeZone &zone) const
}
#endif // timezone
-static QDateTime toLatest(const QDate &day, const QDateTime &form)
+static QDateTime toLatest(QDate day, const QDateTime &form)
{
const Qt::TimeSpec spec = form.timeSpec();
const int offset = (spec == Qt::OffsetFromUTC) ? form.offsetFromUtc() : 0;
@@ -1098,9 +1098,8 @@ QString QDate::longDayName(int weekday, MonthNameType type)
}
#endif // textdate && deprecated
-#if QT_CONFIG(datestring)
+#if QT_CONFIG(datestring) // depends on, so implies, textdate
-#if QT_CONFIG(textdate)
static QString toStringTextDate(QDate date, QCalendar cal)
{
if (date.isValid()) {
@@ -1115,13 +1114,7 @@ static QString toStringTextDate(QDate date, QCalendar cal)
return QString();
}
-static QString toStringTextDate(QDate date)
-{
- return toStringTextDate(date, QCalendar());
-}
-#endif // textdate
-
-static QString toStringIsoDate(const QDate &date)
+static QString toStringIsoDate(QDate date)
{
const auto parts = QCalendar().partsFromDate(date);
if (parts.isValid() && parts.year >= 0 && parts.year <= 9999)
@@ -1131,11 +1124,13 @@ static QString toStringIsoDate(const QDate &date)
/*!
\fn QString QDate::toString(Qt::DateFormat format) const
+ \fn QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
\overload
- Returns the date as a string. The \a format parameter determines
- the format of the string.
+ Returns the date as a string. The \a format parameter determines the format
+ of the string. If \a cal is supplied, it determines the calendar used to
+ represent the date; it defaults to Gregorian.
If the \a format is Qt::TextDate, the string is formatted in the default
way. The day and month names will be localized names using the system
@@ -1148,18 +1143,16 @@ static QString toStringIsoDate(const QDate &date)
year, MM is the month of the year (between 01 and 12), and dd is
the day of the month between 01 and 31.
- If the \a format is Qt::SystemLocaleShortDate or
- Qt::SystemLocaleLongDate, the string format depends on the locale
- settings of the system. Identical to calling
- QLocale::system().toString(date, QLocale::ShortFormat) or
- QLocale::system().toString(date, QLocale::LongFormat).
-
- If the \a format is Qt::DefaultLocaleShortDate or
- Qt::DefaultLocaleLongDate, the string format depends on the
- default application locale. This is the locale set with
- QLocale::setDefault(), or the system locale if no default locale
- has been set. Identical to calling
- \l {QLocale::toString()}{QLocale().toString(date, QLocale::ShortFormat) } or
+ The \a format options Qt::SystemLocaleDate, Qt::SystemLocaleShortDate and
+ Qt::SystemLocaleLongDate shall be removed in Qt 6. Their use should be
+ replaced with
+ \l {QLocale::toString()}{QLocale::system().toString(date, QLocale::ShortFormat)} or
+ \l {QLocale::toString()}{QLocale::system().toString(date, QLocale::LongFormat)}.
+
+ The \a format options Qt::LocaleDate, Qt::DefaultLocaleShortDate and
+ Qt::DefaultLocaleLongDate shall be removed in Qt 6. Their use should be
+ replaced with
+ \l {QLocale::toString()}{QLocale().toString(date, QLocale::ShortFormat)} or
\l {QLocale::toString()}{QLocale().toString(date, QLocale::LongFormat)}.
If the \a format is Qt::RFC2822Date, the string is formatted in
@@ -1169,46 +1162,54 @@ static QString toStringIsoDate(const QDate &date)
If the date is invalid, an empty string will be returned.
\warning The Qt::ISODate format is only valid for years in the
- range 0 to 9999. This restriction may apply to locale-aware
- formats as well, depending on the locale settings.
+ range 0 to 9999.
\sa fromString(), QLocale::toString()
*/
QString QDate::toString(Qt::DateFormat format) const
{
+ return toString(format, QCalendar());
+}
+
+QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
+{
if (!isValid())
return QString();
switch (format) {
+#if QT_DEPRECATED_SINCE(5, 15)
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
- return QLocale::system().toString(*this, QLocale::ShortFormat);
+ return QLocale::system().toString(*this, QLocale::ShortFormat, cal);
case Qt::SystemLocaleLongDate:
- return QLocale::system().toString(*this, QLocale::LongFormat);
+ return QLocale::system().toString(*this, QLocale::LongFormat, cal);
case Qt::LocaleDate:
case Qt::DefaultLocaleShortDate:
- return QLocale().toString(*this, QLocale::ShortFormat);
+ return QLocale().toString(*this, QLocale::ShortFormat, cal);
case Qt::DefaultLocaleLongDate:
- return QLocale().toString(*this, QLocale::LongFormat);
+ return QLocale().toString(*this, QLocale::LongFormat, cal);
+#endif // 5.15
case Qt::RFC2822Date:
- return QLocale::c().toString(*this, u"dd MMM yyyy");
+ return QLocale::c().toString(*this, QStringView(u"dd MMM yyyy"), cal);
default:
-#if QT_CONFIG(textdate)
case Qt::TextDate:
- return toStringTextDate(*this);
-#endif
+ return toStringTextDate(*this, cal);
case Qt::ISODate:
case Qt::ISODateWithMs:
+ // No calendar dependence
return toStringIsoDate(*this);
}
}
/*!
\fn QString QDate::toString(const QString &format) const
+ \fn QString QDate::toString(const QString &format, QCalendar cal) const
\fn QString QDate::toString(QStringView format) const
+ \fn QString QDate::toString(QStringView format, QCalendar cal) const
- Returns the date as a string. The \a format parameter determines
- the format of the result string.
+ Returns the date as a string. The \a format parameter determines the format
+ of the result string. If \cal is supplied, it determines the calendar used
+ to represent the date; it defaults to Gregorian.
These expressions may be used:
@@ -1263,43 +1264,7 @@ QString QDate::toString(Qt::DateFormat format) const
*/
QString QDate::toString(QStringView format) const
{
- return QLocale::system().toString(*this, format); // QLocale::c() ### Qt6
-}
-
-#if QT_STRINGVIEW_LEVEL < 2
-QString QDate::toString(const QString &format) const
-{
- return toString(qToStringViewIgnoringNull(format));
-}
-#endif
-
-QString QDate::toString(Qt::DateFormat format, QCalendar cal) const
-{
- if (!isValid())
- return QString();
-
- switch (format) {
- case Qt::SystemLocaleDate:
- case Qt::SystemLocaleShortDate:
- return QLocale::system().toString(*this, QLocale::ShortFormat, cal);
- case Qt::SystemLocaleLongDate:
- return QLocale::system().toString(*this, QLocale::LongFormat, cal);
- case Qt::LocaleDate:
- case Qt::DefaultLocaleShortDate:
- return QLocale().toString(*this, QLocale::ShortFormat, cal);
- case Qt::DefaultLocaleLongDate:
- return QLocale().toString(*this, QLocale::LongFormat, cal);
- case Qt::RFC2822Date:
- return QLocale::c().toString(*this, QStringView(u"dd MMM yyyy"), cal);
- default:
-#ifndef QT_NO_TEXTDATE
- case Qt::TextDate:
- return toStringTextDate(*this, cal);
-#endif
- case Qt::ISODate:
- case Qt::ISODateWithMs:
- return toStringIsoDate(*this);
- }
+ return toString(format, QCalendar());
}
QString QDate::toString(QStringView format, QCalendar cal) const
@@ -1308,6 +1273,11 @@ QString QDate::toString(QStringView format, QCalendar cal) const
}
#if QT_STRINGVIEW_LEVEL < 2
+QString QDate::toString(const QString &format) const
+{
+ return toString(qToStringViewIgnoringNull(format), QCalendar());
+}
+
QString QDate::toString(const QString &format, QCalendar cal) const
{
return toString(qToStringViewIgnoringNull(format), cal);
@@ -1625,7 +1595,7 @@ qint64 QDate::daysTo(const QDate &d) const
\sa QTime::currentTime(), QDateTime::currentDateTime()
*/
-#if QT_CONFIG(datestring)
+#if QT_CONFIG(datestring) // depends on, so implies, textdate
namespace {
struct ParsedInt { int value = 0; bool ok = false; };
@@ -1654,9 +1624,14 @@ ParsedInt readInt(QStringView text)
\a format given, or an invalid date if the string cannot be
parsed.
- Note for Qt::TextDate: It is recommended that you use the
- English short month names (e.g. "Jan"). Although localized month
- names can also be used, they depend on the user's locale settings.
+ Note for Qt::TextDate: It is recommended that you use the English short
+ month names (e.g. "Jan"). Although localized month names can also be used in
+ Qt 5, they depend on the user's locale settings.
+
+ \note Support for localized dates, including the format options
+ Qt::SystemLocaleDate, Qt::SystemLocaleShortDate, Qt::SystemLocaleLongDate,
+ Qt::LocaleDate, Qt::DefaultLocaleShortDate, and Qt::DefaultLocaleLongDate,
+ shall be removed in Qt 6. Use QLocale::toDate() instead.
\sa toString(), QLocale::toDate()
*/
@@ -1667,6 +1642,7 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
return QDate();
switch (format) {
+#if QT_DEPRECATED_SINCE(5, 15)
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
return QLocale::system().toDate(string, QLocale::ShortFormat);
@@ -1677,10 +1653,10 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
return QLocale().toDate(string, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
return QLocale().toDate(string, QLocale::LongFormat);
+#endif // 5.15
case Qt::RFC2822Date:
return rfcDateImpl(string).date;
default:
-#if QT_CONFIG(textdate)
case Qt::TextDate: {
QVector<QStringRef> parts = string.splitRef(QLatin1Char(' '), QString::SkipEmptyParts);
@@ -1699,7 +1675,6 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format)
return QDate(year, month, day);
}
-#endif // textdate
case Qt::ISODate:
// Semi-strict parsing, must be long enough and have punctuators as separators
if (string.size() >= 10 && string.at(4).isPunct() && string.at(7).isPunct()
@@ -2014,7 +1989,7 @@ int QTime::msec() const
return ds() % 1000;
}
-#if QT_CONFIG(datestring)
+#if QT_CONFIG(datestring) // depends on, so implies, textdate
/*!
\overload
@@ -2030,18 +2005,15 @@ int QTime::msec() const
date, use the \a format Qt::ISODateWithMs, which corresponds to
HH:mm:ss.zzz.
- If the \a format is Qt::SystemLocaleShortDate or
- Qt::SystemLocaleLongDate, the string format depends on the locale
- settings of the system. Identical to calling
- QLocale::system().toString(time, QLocale::ShortFormat) or
- QLocale::system().toString(time, QLocale::LongFormat).
-
- If the \a format is Qt::DefaultLocaleShortDate or
- Qt::DefaultLocaleLongDate, the string format depends on the
- default application locale. This is the locale set with
- QLocale::setDefault(), or the system locale if no default locale
- has been set. Identical to calling
+ The \a format options Qt::SystemLocaleDate:, Qt::SystemLocaleShortDate and
+ Qt::SystemLocaleLongDate shall be removed in Qt 6. Their use should be
+ replaced with:
+ \l {QLocale::toString()}{QLocale::system().toString(time, QLocale::ShortFormat)} or
+ \l {QLocale::toString()}{QLocale::system().toString(time, QLocale::LongFormat)}.
+ The \a format options Qt::LocaleDate, Qt::DefaultLocaleShortDate and
+ Qt::DefaultLocaleLongDate shall be removed in Qt 6. Their use should be
+ replaced with:
\l {QLocale::toString()}{QLocale().toString(time, QLocale::ShortFormat)} or
\l {QLocale::toString()}{QLocale().toString(time, QLocale::LongFormat)}.
@@ -2060,6 +2032,7 @@ QString QTime::toString(Qt::DateFormat format) const
return QString();
switch (format) {
+#if QT_DEPRECATED_SINCE(5, 15)
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
return QLocale::system().toString(*this, QLocale::ShortFormat);
@@ -2070,6 +2043,7 @@ QString QTime::toString(Qt::DateFormat format) const
return QLocale().toString(*this, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
return QLocale().toString(*this, QLocale::LongFormat);
+#endif // 5.15
case Qt::ISODateWithMs:
return QString::asprintf("%02d:%02d:%02d.%03d", hour(), minute(), second(), msec());
case Qt::RFC2822Date:
@@ -2347,7 +2321,7 @@ int QTime::msecsTo(const QTime &t) const
\sa QDateTime::currentDateTime(), QDateTime::currentDateTimeUtc()
*/
-#if QT_CONFIG(datestring)
+#if QT_CONFIG(datestring) // depends on, so implies, textdate
static QTime fromIsoTimeString(QStringView string, Qt::DateFormat format, bool *isMidnight24)
{
@@ -2445,6 +2419,12 @@ static QTime fromIsoTimeString(QStringView string, Qt::DateFormat format, bool *
fails for the default locale). This should be considered an
implementation detail.
+
+ \note Support for localized dates, including the format options
+ Qt::SystemLocaleDate, Qt::SystemLocaleShortDate, Qt::SystemLocaleLongDate,
+ Qt::LocaleDate, Qt::DefaultLocaleShortDate, and Qt::DefaultLocaleLongDate,
+ shall be removed in Qt 6. Use QLocale::toTime() instead.
+
\sa toString(), QLocale::toTime()
*/
QTime QTime::fromString(const QString &string, Qt::DateFormat format)
@@ -2453,6 +2433,7 @@ QTime QTime::fromString(const QString &string, Qt::DateFormat format)
return QTime();
switch (format) {
+#if QT_DEPRECATED_SINCE(5, 15)
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
return QLocale::system().toTime(string, QLocale::ShortFormat);
@@ -2463,6 +2444,7 @@ QTime QTime::fromString(const QString &string, Qt::DateFormat format)
return QLocale().toTime(string, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
return QLocale().toTime(string, QLocale::LongFormat);
+#endif // 5.15
case Qt::RFC2822Date:
return rfcDateImpl(string).time;
case Qt::ISODate:
@@ -2877,7 +2859,7 @@ static void msecsToTime(qint64 msecs, QDate *date, QTime *time)
}
// Converts a date/time value into msecs
-static qint64 timeToMSecs(const QDate &date, const QTime &time)
+static qint64 timeToMSecs(QDate date, QTime time)
{
return ((date.toJulianDay() - JULIAN_DAY_FOR_EPOCH) * MSECS_PER_DAY)
+ time.msecsSinceStartOfDay();
@@ -3222,7 +3204,7 @@ static void setTimeSpec(QDateTimeData &d, Qt::TimeSpec spec, int offsetSeconds)
}
}
-static void setDateTime(QDateTimeData &d, const QDate &date, const QTime &time)
+static void setDateTime(QDateTimeData &d, QDate date, QTime time)
{
// If the date is valid and the time is not we set time to 00:00:00
QTime useTime = time;
@@ -3631,15 +3613,18 @@ QDateTime::QDateTime() noexcept(Data::CanBeSmall)
}
+#if QT_DEPRECATED_SINCE(5, 17) // ### Qt 6: remove
/*!
- Constructs a datetime with the given \a date, a valid
- time(00:00:00.000), and sets the timeSpec() to Qt::LocalTime.
-*/
+ Constructs a datetime with the given \a date, using Qt::LocalTime as the
+ timeSpec() and the time at the start of that date.
+ \sa QDate::startOfDay()
+*/
QDateTime::QDateTime(const QDate &date)
- : d(QDateTimePrivate::create(date, QTime(0, 0), Qt::LocalTime, 0))
+ : QDateTime(date.startOfDay(Qt::LocalTime, 0))
{
}
+#endif
/*!
Constructs a datetime with the given \a date and \a time, using
@@ -4292,13 +4277,16 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
}
#endif
-#if QT_CONFIG(datestring)
+#if QT_CONFIG(datestring) // depends on, so implies, textdate
/*!
\fn QString QDateTime::toString(Qt::DateFormat format) const
+ \fn QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
\overload
- Returns the datetime as a string in the \a format given.
+ Returns the datetime as a string in the \a format given. If \cal is
+ supplied, it determines the calendar used to represent the date; it defaults
+ to Gregorian.
If the \a format is Qt::TextDate, the string is formatted in the default
way. The day and month names will be localized names using the system
@@ -4315,19 +4303,17 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
date, use the \a format Qt::ISODateWithMs, which corresponds to
yyyy-MM-ddTHH:mm:ss.zzz[Z|[+|-]HH:mm].
- If the \a format is Qt::SystemLocaleShortDate or
- Qt::SystemLocaleLongDate, the string format depends on the locale
- settings of the system. Identical to calling
- QLocale::system().toString(datetime, QLocale::ShortFormat) or
- QLocale::system().toString(datetime, QLocale::LongFormat).
+ The \a format options Qt::SystemLocaleDate, Qt::SystemLocaleShortDate and
+ Qt::SystemLocaleLongDate shall be removed in Qt 6. Their use should be
+ replaced with
+ \l {QLocale::toString()}{QLocale::system().toString(datetime, QLocale::ShortFormat)} or
+ \l {QLocale::toString()}{QLocale::system().toString(datetime, QLocale::LongFormat)}.
- If the \a format is Qt::DefaultLocaleShortDate or
- Qt::DefaultLocaleLongDate, the string format depends on the
- default application locale. This is the locale set with
- QLocale::setDefault(), or the system locale if no default locale
- has been set. Identical to calling QLocale().toString(datetime,
- QLocale::ShortFormat) or QLocale().toString(datetime,
- QLocale::LongFormat).
+ The \a format options Qt::LocaleDate, Qt::DefaultLocaleShortDate and
+ Qt::DefaultLocaleLongDate shall be removed in Qt 6. Their use should be
+ replaced with
+ \l {QLocale::toString()}{QLocale().toString(datetime, QLocale::ShortFormat)} or
+ \l {QLocale::toString()}{QLocale().toString(datetime, QLocale::LongFormat)}.
If the \a format is Qt::RFC2822Date, the string is formatted
following \l{RFC 2822}.
@@ -4335,8 +4321,7 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
If the datetime is invalid, an empty string will be returned.
\warning The Qt::ISODate format is only valid for years in the
- range 0 to 9999. This restriction may apply to locale-aware
- formats as well, depending on the locale settings.
+ range 0 to 9999.
\sa fromString(), QDate::toString(), QTime::toString(),
QLocale::toString()
@@ -4344,31 +4329,37 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC)
QString QDateTime::toString(Qt::DateFormat format) const
{
+ return toString(format, QCalendar());
+}
+
+QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const
+{
QString buf;
if (!isValid())
return buf;
switch (format) {
+#if QT_DEPRECATED_SINCE(5, 15)
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
- return QLocale::system().toString(*this, QLocale::ShortFormat);
+ return QLocale::system().toString(*this, QLocale::ShortFormat, cal);
case Qt::SystemLocaleLongDate:
- return QLocale::system().toString(*this, QLocale::LongFormat);
+ return QLocale::system().toString(*this, QLocale::LongFormat, cal);
case Qt::LocaleDate:
case Qt::DefaultLocaleShortDate:
- return QLocale().toString(*this, QLocale::ShortFormat);
+ return QLocale().toString(*this, QLocale::ShortFormat, cal);
case Qt::DefaultLocaleLongDate:
- return QLocale().toString(*this, QLocale::LongFormat);
+ return QLocale().toString(*this, QLocale::LongFormat, cal);
+#endif // 5.15
case Qt::RFC2822Date: {
- buf = QLocale::c().toString(*this, u"dd MMM yyyy hh:mm:ss ");
+ buf = QLocale::c().toString(*this, u"dd MMM yyyy hh:mm:ss ", cal);
buf += toOffsetString(Qt::TextDate, offsetFromUtc());
return buf;
}
default:
-#if QT_CONFIG(textdate)
case Qt::TextDate: {
const QPair<QDate, QTime> p = getDateTime(d);
- buf = p.first.toString(Qt::TextDate);
+ buf = toStringTextDate(p.first, cal);
// Insert time between date's day and year:
buf.insert(buf.lastIndexOf(QLatin1Char(' ')),
QLatin1Char(' ') + p.second.toString(Qt::TextDate));
@@ -4376,11 +4367,11 @@ QString QDateTime::toString(Qt::DateFormat format) const
switch (timeSpec()) {
case Qt::LocalTime:
break;
-# if QT_CONFIG(timezone)
+#if QT_CONFIG(timezone)
case Qt::TimeZone:
buf += QLatin1Char(' ') + d->m_timeZone.abbreviation(*this);
break;
-# endif
+#endif
default:
buf += QLatin1String(" GMT");
if (getSpec(d) == Qt::OffsetFromUTC)
@@ -4388,17 +4379,14 @@ QString QDateTime::toString(Qt::DateFormat format) const
}
return buf;
}
-#endif
case Qt::ISODate:
case Qt::ISODateWithMs: {
+ // No calendar dependence
const QPair<QDate, QTime> p = getDateTime(d);
- const QDate &dt = p.first;
- const QTime &tm = p.second;
- buf = dt.toString(Qt::ISODate);
+ buf = toStringIsoDate(p.first);
if (buf.isEmpty())
return QString(); // failed to convert
- buf += QLatin1Char('T');
- buf += tm.toString(format);
+ buf += QLatin1Char('T') + p.second.toString(format);
switch (getSpec(d)) {
case Qt::UTC:
buf += QLatin1Char('Z');
@@ -4419,11 +4407,15 @@ QString QDateTime::toString(Qt::DateFormat format) const
/*!
\fn QString QDateTime::toString(const QString &format) const
+ \fn QString QDateTime::toString(const QString &format, QCalendar cal) const
\fn QString QDateTime::toString(QStringView format) const
+ \fn QString QDateTime::toString(QStringView format, QCalendar cal) const
Returns the datetime as a string. The \a format parameter determines the
- format of the result string. See QTime::toString() and QDate::toString() for
- the supported specifiers for time and date, respectively.
+ format of the result string. If \cal is supplied, it determines the calendar
+ used to represent the date; it defaults to Gregorian. See QTime::toString()
+ and QDate::toString() for the supported specifiers for time and date,
+ respectively.
Any sequence of characters enclosed in single quotes will be included
verbatim in the output string (stripped of the quotes), even if it contains
@@ -4454,13 +4446,23 @@ QString QDateTime::toString(Qt::DateFormat format) const
*/
QString QDateTime::toString(QStringView format) const
{
- return QLocale::system().toString(*this, format); // QLocale::c() ### Qt6
+ return toString(format, QCalendar());
+}
+
+QString QDateTime::toString(QStringView format, QCalendar cal) const
+{
+ return QLocale::system().toString(*this, format, cal); // QLocale::c() ### Qt6
}
#if QT_STRINGVIEW_LEVEL < 2
QString QDateTime::toString(const QString &format) const
{
- return toString(qToStringViewIgnoringNull(format));
+ return toString(qToStringViewIgnoringNull(format), QCalendar());
+}
+
+QString QDateTime::toString(const QString &format, QCalendar cal) const
+{
+ return toString(qToStringViewIgnoringNull(format), cal);
}
#endif
@@ -5202,15 +5204,20 @@ int QDateTime::utcOffset() const
}
#endif // QT_DEPRECATED_SINCE
-#if QT_CONFIG(datestring)
+#if QT_CONFIG(datestring) // depends on, so implies, textdate
/*!
Returns the QDateTime represented by the \a string, using the
\a format given, or an invalid datetime if this is not possible.
- Note for Qt::TextDate: It is recommended that you use the
- English short month names (e.g. "Jan"). Although localized month
- names can also be used, they depend on the user's locale settings.
+ Note for Qt::TextDate: It is recommended that you use the English short
+ month names (e.g. "Jan"). Although localized month names can also be used in
+ Qt 5, they depend on the user's locale settings.
+
+ \note Support for localized dates, including the format options
+ Qt::SystemLocaleDate, Qt::SystemLocaleShortDate, Qt::SystemLocaleLongDate,
+ Qt::LocaleDate, Qt::DefaultLocaleShortDate, and Qt::DefaultLocaleLongDate,
+ shall be removed in Qt 6. Use QLocale::toDateTime() instead.
\sa toString(), QLocale::toDateTime()
*/
@@ -5220,6 +5227,7 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
return QDateTime();
switch (format) {
+#if QT_DEPRECATED_SINCE(5, 15)
case Qt::SystemLocaleDate:
case Qt::SystemLocaleShortDate:
return QLocale::system().toDateTime(string, QLocale::ShortFormat);
@@ -5230,6 +5238,7 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
return QLocale().toDateTime(string, QLocale::ShortFormat);
case Qt::DefaultLocaleLongDate:
return QLocale().toDateTime(string, QLocale::LongFormat);
+#endif // 5.15
case Qt::RFC2822Date: {
const ParsedRfcDateTime rfc = rfcDateImpl(string);
@@ -5306,7 +5315,6 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
date = date.addDays(1);
return QDateTime(date, time, spec, offset);
}
-#if QT_CONFIG(textdate)
case Qt::TextDate: {
QVector<QStringRef> parts = string.splitRef(QLatin1Char(' '), QString::SkipEmptyParts);
@@ -5412,7 +5420,6 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
return QDateTime(date, time, Qt::UTC);
}
}
-#endif // textdate
}
return QDateTime();
diff --git a/src/corelib/time/qdatetime.h b/src/corelib/time/qdatetime.h
index 3eae8ebf64..c1653b5585 100644
--- a/src/corelib/time/qdatetime.h
+++ b/src/corelib/time/qdatetime.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@@ -110,14 +110,15 @@ public:
static QString longDayName(int weekday, MonthNameType type = DateFormat);
#endif // textdate && deprecated
#if QT_CONFIG(datestring)
- QString toString(Qt::DateFormat f = Qt::TextDate) const;
+ QString toString(Qt::DateFormat format = Qt::TextDate) const;
+ QString toString(Qt::DateFormat format, QCalendar cal) const;
+
#if QT_STRINGVIEW_LEVEL < 2
QString toString(const QString &format) const;
QString toString(const QString &format, QCalendar cal) const;
#endif
QString toString(QStringView format) const;
- QString toString(Qt::DateFormat f, QCalendar cal) const;
QString toString(QStringView format, QCalendar cal) const;
#endif
#if QT_DEPRECATED_SINCE(5,0)
@@ -287,7 +288,9 @@ class Q_CORE_EXPORT QDateTime
public:
QDateTime() noexcept(Data::CanBeSmall);
- explicit QDateTime(const QDate &); // ### Qt 6: plain QDate, QTime
+#if QT_DEPRECATED_SINCE(5, 15) // ### Qt 6: remove
+ QT_DEPRECATED_X("Use QDate::startOfDay()") explicit QDateTime(const QDate &);
+#endif
QDateTime(const QDate &, const QTime &, Qt::TimeSpec spec = Qt::LocalTime);
// ### Qt 6: Merge with above with default offsetSeconds = 0
QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec, int offsetSeconds);
@@ -330,11 +333,14 @@ public:
void setSecsSinceEpoch(qint64 secs);
#if QT_CONFIG(datestring)
- QString toString(Qt::DateFormat f = Qt::TextDate) const;
+ QString toString(Qt::DateFormat format = Qt::TextDate) const;
+ QString toString(Qt::DateFormat format, QCalendar cal) const;
#if QT_STRINGVIEW_LEVEL < 2
QString toString(const QString &format) const;
+ QString toString(const QString &format, QCalendar cal) const;
#endif
QString toString(QStringView format) const;
+ QString toString(QStringView format, QCalendar cal) const;
#endif
Q_REQUIRED_RESULT QDateTime addDays(qint64 days) const;
Q_REQUIRED_RESULT QDateTime addMonths(int months) const;
diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp
index 70460ae632..790c20004a 100644
--- a/src/corelib/time/qdatetimeparser.cpp
+++ b/src/corelib/time/qdatetimeparser.cpp
@@ -219,7 +219,8 @@ int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
const SectionNode &sn = sectionNode(s);
switch (sn.type) {
#if QT_CONFIG(timezone)
- case TimeZoneSection: return QTimeZone::MaxUtcOffsetSecs;
+ case TimeZoneSection:
+ return QTimeZone::MaxUtcOffsetSecs;
#endif
case Hour24Section:
case Hour12Section:
@@ -227,20 +228,25 @@ int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
// We want it to be 23 for the stepBy case.
return 23;
case MinuteSection:
- case SecondSection: return 59;
- case MSecSection: return 999;
+ case SecondSection:
+ return 59;
+ case MSecSection:
+ return 999;
case YearSection2Digits:
case YearSection:
// sectionMaxSize will prevent people from typing in a larger number in
// count == 2 sections; stepBy() will work on real years anyway.
return 9999;
- case MonthSection: return calendar.maximumMonthsInYear();
+ case MonthSection:
+ return calendar.maximumMonthsInYear();
case DaySection:
case DayOfWeekSectionShort:
case DayOfWeekSectionLong:
return cur.isValid() ? cur.date().daysInMonth(calendar) : calendar.maximumDaysInMonth();
- case AmPmSection: return 1;
- default: break;
+ case AmPmSection:
+ return 1;
+ default:
+ break;
}
qWarning("QDateTimeParser::absoluteMax() Internal error (%ls)",
qUtf16Printable(sn.name()));
@@ -620,7 +626,8 @@ int QDateTimeParser::sectionMaxSize(Section s, int count) const
switch (s) {
case FirstSection:
case NoSection:
- case LastSection: return 0;
+ case LastSection:
+ return 0;
case AmPmSection: {
const int lowerMax = qMax(getAmPmText(AmText, LowerCase).size(),
@@ -634,7 +641,9 @@ int QDateTimeParser::sectionMaxSize(Section s, int count) const
case Hour12Section:
case MinuteSection:
case SecondSection:
- case DaySection: return 2;
+ case DaySection:
+ return 2;
+
case DayOfWeekSectionShort:
case DayOfWeekSectionLong:
#if !QT_CONFIG(textdate)
@@ -663,11 +672,15 @@ int QDateTimeParser::sectionMaxSize(Section s, int count) const
return ret;
}
#endif
- case MSecSection: return 3;
- case YearSection: return 4;
- case YearSection2Digits: return 2;
+ case MSecSection:
+ return 3;
+ case YearSection:
+ return 4;
+ case YearSection2Digits:
+ return 2;
+ case TimeZoneSection:
// Arbitrarily many tokens (each up to 14 bytes) joined with / separators:
- case TimeZoneSection: return std::numeric_limits<int>::max();
+ return std::numeric_limits<int>::max();
case CalendarPopupSection:
case Internal:
@@ -903,7 +916,7 @@ QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionIndex,
by \a weekDay.
*/
-static int weekDayWithinMonth(const QCalendar &calendar, const QDate &rough, int weekDay)
+static int weekDayWithinMonth(QCalendar calendar, QDate rough, int weekDay)
{
// TODO: can we adapt this to cope gracefully with intercallary days (day of
// week > 7) without making it slower for more widely-used calendars ?
diff --git a/src/corelib/time/qtimezoneprivate_win.cpp b/src/corelib/time/qtimezoneprivate_win.cpp
index 0fec5355b2..0aaf469ed9 100644
--- a/src/corelib/time/qtimezoneprivate_win.cpp
+++ b/src/corelib/time/qtimezoneprivate_win.cpp
@@ -363,7 +363,7 @@ QDate calculateTransitionLocalDate(const SYSTEMTIME &rule, int year)
}
// Converts a date/time value into msecs
-inline qint64 timeToMSecs(const QDate &date, const QTime &time)
+inline qint64 timeToMSecs(QDate date, QTime time)
{
return ((date.toJulianDay() - JULIAN_DAY_FOR_EPOCH) * MSECS_PER_DAY)
+ time.msecsSinceStartOfDay();
diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp
index a1dd537d4d..12ad6f4573 100644
--- a/src/corelib/tools/qbitarray.cpp
+++ b/src/corelib/tools/qbitarray.cpp
@@ -305,7 +305,7 @@ void QBitArray::fill(bool value, int begin, int end)
\since 5.11
Returns a pointer to a dense bit array for this QBitArray. Bits are counted
- upwards from the least significant bit in each byte. The the number of bits
+ upwards from the least significant bit in each byte. The number of bits
relevant in the last byte is given by \c{size() % 8}.
\sa fromBits(), size()
diff --git a/src/corelib/tools/qcontainerfwd.h b/src/corelib/tools/qcontainerfwd.h
index f6efa99b6a..d6e30d77e3 100644
--- a/src/corelib/tools/qcontainerfwd.h
+++ b/src/corelib/tools/qcontainerfwd.h
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
template <class Key, class T> class QCache;
template <class Key, class T> class QHash;
-#ifndef QT_NO_LINKED_LIST
+#if !defined(QT_NO_LINKED_LIST) && QT_DEPRECATED_SINCE(5, 15)
template <class T> class QLinkedList;
#endif
template <class Key, class T> class QMap;
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index c56324eef7..47fa0520d9 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -1245,6 +1245,7 @@ Q_OUTOFLINE_TEMPLATE int QMultiHash<Key, T>::count(const Key &akey) const
return cnt;
}
+#if !defined(QT_NO_JAVA_STYLE_ITERATORS)
template <class Key, class T>
class QHashIterator
{
@@ -1419,6 +1420,7 @@ public:
}
#endif
};
+#endif // !QT_NO_JAVA_STYLE_ITERATORS
template <class Key, class T>
uint qHash(const QHash<Key, T> &key, uint seed = 0)
diff --git a/src/corelib/tools/qiterator.qdoc b/src/corelib/tools/qiterator.qdoc
index b4d332b7b1..3531fb202c 100644
--- a/src/corelib/tools/qiterator.qdoc
+++ b/src/corelib/tools/qiterator.qdoc
@@ -203,6 +203,7 @@
/*!
\class QLinkedListIterator
\inmodule QtCore
+ \obsolete
\brief The QLinkedListIterator class provides a Java-style const iterator for QLinkedList.
@@ -416,6 +417,7 @@
/*!
\class QMutableLinkedListIterator
\inmodule QtCore
+ \obsolete
\brief The QMutableLinkedListIterator class provides a Java-style non-const iterator for QLinkedList.
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
index 3b1bc8aab1..6a423545da 100644
--- a/src/corelib/tools/qlinkedlist.cpp
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -45,6 +45,11 @@
QT_BEGIN_NAMESPACE
+#if QT_DEPRECATED_SINCE(5, 15)
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
const QLinkedListData QLinkedListData::shared_null = {
const_cast<QLinkedListData *>(&QLinkedListData::shared_null),
const_cast<QLinkedListData *>(&QLinkedListData::shared_null),
@@ -53,6 +58,7 @@ const QLinkedListData QLinkedListData::shared_null = {
/*! \class QLinkedList
\inmodule QtCore
+ \obsolete
\brief The QLinkedList class is a template class that provides linked lists.
\ingroup tools
@@ -60,6 +66,8 @@ const QLinkedListData QLinkedListData::shared_null = {
\reentrant
+ \note This class is obsolete, please use std::list instead.
+
QLinkedList\<T\> is one of Qt's generic \l{container classes}. It
stores a list of values and provides iterator-based access as
well as \l{constant time} insertions and removals.
@@ -720,6 +728,7 @@ const QLinkedListData QLinkedListData::shared_null = {
/*! \class QLinkedList::iterator
\inmodule QtCore
+ \obsolete
\brief The QLinkedList::iterator class provides an STL-style non-const iterator for QLinkedList.
QLinkedList features both \l{STL-style iterators} and
@@ -965,6 +974,7 @@ const QLinkedListData QLinkedListData::shared_null = {
/*! \class QLinkedList::const_iterator
\inmodule QtCore
+ \obsolete
\brief The QLinkedList::const_iterator class provides an STL-style const iterator for QLinkedList.
QLinkedList features both \l{STL-style iterators} and
@@ -1221,4 +1231,8 @@ const QLinkedListData QLinkedListData::shared_null = {
\sa fromStdList()
*/
+QT_WARNING_POP
+
+#endif // QT_DEPRECATED_SINCE(5, 15)
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index e3713d2c1c..fd3df74059 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -55,10 +55,22 @@
#include <iterator>
#include <list>
-QT_BEGIN_NAMESPACE
+#if 0
+// This is needed because of QTBUG-80347
+#pragma qt_class(QLinkedList)
+#pragma qt_class(QLinkedListData)
+#pragma qt_class(QLinkedListNode)
+#endif
+
+#if QT_DEPRECATED_SINCE(5, 15)
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
-struct Q_CORE_EXPORT QLinkedListData
+QT_BEGIN_NAMESPACE
+
+struct QT_DEPRECATED_VERSION_5_15 Q_CORE_EXPORT QLinkedListData
{
QLinkedListData *n, *p;
QtPrivate::RefCount ref;
@@ -69,7 +81,7 @@ struct Q_CORE_EXPORT QLinkedListData
};
template <typename T>
-struct QLinkedListNode
+struct QT_DEPRECATED_VERSION_5_15 QLinkedListNode
{
inline QLinkedListNode(const T &arg): t(arg) { }
QLinkedListNode *n, *p;
@@ -77,7 +89,7 @@ struct QLinkedListNode
};
template <class T>
-class QLinkedList
+class QT_DEPRECATED_VERSION_X_5_15("Use std::list instead") QLinkedList
{
typedef QLinkedListNode<T> Node;
union { QLinkedListData *d; QLinkedListNode<T> *e; };
@@ -591,6 +603,10 @@ QT_END_NAMESPACE
Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(QLinkedList)
+QT_WARNING_POP
+
+#endif // QT_DEPRECATED_SINCE(5, 15)
+
#endif // QT_NO_LINKED_LIST
#endif // QLINKEDLIST_H
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index e2b7705b55..9b9c67e42b 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -1999,7 +1999,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
\sa replace()
*/
-/*! \fn template <class Key, class T> typename QMap<Key, T>::iterator QMultiMap<Key, T>::insert(typename QMap<Key, T>::const_iterator pos, const Key &key, const T &value)
+/*! \fn template <class Key, class T> typename QMultiMap<Key, T>::iterator QMultiMap<Key, T>::insert(typename QMultiMap<Key, T>::const_iterator pos, const Key &key, const T &value)
\since 5.1
Inserts a new item with the key \a key and value \a value and with hint \a pos
diff --git a/src/corelib/tools/qscopeguard.h b/src/corelib/tools/qscopeguard.h
index 40d2747b1d..6a5bc6cc61 100644
--- a/src/corelib/tools/qscopeguard.h
+++ b/src/corelib/tools/qscopeguard.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com>
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -42,13 +43,11 @@
#include <QtCore/qglobal.h>
+#include <type_traits>
+#include <utility>
QT_BEGIN_NAMESPACE
-
-template <typename F> class QScopeGuard;
-template <typename F> QScopeGuard<F> qScopeGuard(F f);
-
template <typename F>
class
#if __has_cpp_attribute(nodiscard)
@@ -59,13 +58,23 @@ Q_REQUIRED_RESULT
QScopeGuard
{
public:
+ explicit QScopeGuard(F &&f) noexcept
+ : m_func(std::move(f))
+ {
+ }
+
+ explicit QScopeGuard(const F &f) noexcept
+ : m_func(f)
+ {
+ }
+
QScopeGuard(QScopeGuard &&other) noexcept
: m_func(std::move(other.m_func))
, m_invoke(qExchange(other.m_invoke, false))
{
}
- ~QScopeGuard()
+ ~QScopeGuard() noexcept
{
if (m_invoke)
m_func();
@@ -77,26 +86,23 @@ public:
}
private:
- explicit QScopeGuard(F &&f) noexcept
- : m_func(std::move(f))
- {
- }
-
Q_DISABLE_COPY(QScopeGuard)
F m_func;
bool m_invoke = true;
- friend QScopeGuard qScopeGuard<F>(F);
};
+#ifdef __cpp_deduction_guides
+template <typename F> QScopeGuard(F(&)()) -> QScopeGuard<F(*)()>;
+#endif
template <typename F>
#if __has_cpp_attribute(nodiscard)
Q_REQUIRED_RESULT
#endif
-QScopeGuard<F> qScopeGuard(F f)
+QScopeGuard<typename std::decay<F>::type> qScopeGuard(F &&f)
{
- return QScopeGuard<F>(std::move(f));
+ return QScopeGuard<typename std::decay<F>::type>(std::forward<F>(f));
}
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qscopeguard.qdoc b/src/corelib/tools/qscopeguard.qdoc
index 6b3c942e84..572934d890 100644
--- a/src/corelib/tools/qscopeguard.qdoc
+++ b/src/corelib/tools/qscopeguard.qdoc
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sérgio Martins <sergio.martins@kdab.com>
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -35,6 +36,30 @@ QT_BEGIN_NAMESPACE
\inmodule QtCore
\brief Provides a scope guard for calling a function at the end of
a scope.
+
+ QScopeGuard<F> is a class of which the sole purpose is to run the function
+ \a f in its destructor. This is useful for guaranteeing
+ your cleanup code is executed, whether the function is exited normally,
+ exited early by a return statement, or exited by an exception.
+
+ \note Exceptions are not supported. The callable shouldn't throw when
+ executed, copied or moved.
+
+ \sa QScopedValueRollback
+*/
+
+/*!
+ \fn template <typename F> QScopeGuard<F>::QScopeGuard(F &&f)
+ \fn template <typename F> QScopeGuard<F>::QScopeGuard(const F &f)
+
+ Create a scope guard that will execute \a f at the end of the scope.
+
+ If \e F is a lambda, its type cannot be written. In that case you need to
+ either rely on class template argument deduction (C++17 feature) and leave
+ the template parameter out completely or use the helper function
+ qScopeGuard() instead of this constructor.
+
+ \since 5.15
*/
/*! \fn template <typename F> void QScopeGuard<F>::dismiss()
@@ -51,23 +76,17 @@ QT_BEGIN_NAMESPACE
of the scope.
\ingroup misc
- QScopeGuard<F> is a class of which the sole purpose is to run the function
- \a f in its destructor. This is useful for guaranteeing
- your cleanup code is executed, whether the function is exited normally,
- exited early by a return statement, or exited by an exception.
+ Create a scope guard that will execute \a f at the end of the scope.
- If \e F is a lambda then you cannot instantiate the template directly,
- therefore the qScopeGuard() helper is provided and QScopeGuard<F> is made a
- private implementation detail.
+ This helper function is provided so that you can easily construct a
+ QScopeGuard without having to name the template parameter for the type of
+ the callable. If \e F is a lambda then you cannot write its type and relying
+ on this helper or class template argument deduction is necessary.
Example usage is as follows:
\snippet code/src_corelib_tools_qscopeguard.cpp 0
- \note Exceptions are not supported. The callable shouldn't throw when
- executed, copied or moved.
-
- \sa QScopedValueRollback
*/
QT_END_NAMESPACE