From a4fb128b733667dcc8269efbb1b0227f09e3a64c Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Thu, 2 Jan 2020 13:27:10 +0100 Subject: QSequentialIterableImpl: support append Task-number: QTBUG-80916 Change-Id: I87e74da0ce454e56b5fe94d9db3693a587d35edf Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Shawn Rutledge Reviewed-by: Ulf Hermann --- src/corelib/kernel/qmetatype.h | 88 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 8 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index d41f7ee80e..d13fdeb642 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -977,6 +977,30 @@ enum IteratorCapability RandomAccessCapability = 4 }; +enum ContainerCapability +{ + ContainerIsAppendable = 1 +}; + +template +struct ContainerCapabilitiesImpl +{ + enum {ContainerCapabilities = 0}; + using appendFunction = void(*)(const void *container, const void *newElement); + static constexpr const appendFunction appendImpl = nullptr; +}; + +template +struct ContainerCapabilitiesImpl().push_back(std::declval()))> +{ + 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(const_cast(container))->push_back(*static_cast(value)); } +}; + template::iterator_category> struct CapabilitiesImpl; @@ -1012,6 +1036,12 @@ template struct ContainerAPI > : CapabilitiesImpl > { static int size(const std::list *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: @@ -1020,19 +1050,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(_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; @@ -1059,6 +1107,15 @@ public: static void moveToEndImpl(const void *container, void **iterator) { IteratorOwner::assign(iterator, static_cast(container)->end()); } + template + static void moveToImpl(const void *container, void **iterator, Position position) + { + if (position == ToBegin) + moveToBeginImpl(container, iterator); + else + moveToEndImpl(container, iterator); + } + template static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags) { return VariantData(metaTypeId, IteratorOwner::getData(iterator), flags); } @@ -1069,11 +1126,11 @@ public: , _iterator(nullptr) , _metaType_id(qMetaTypeId()) , _metaType_flags(QTypeInfo::isPointer) - , _iteratorCapabilities(ContainerAPI::IteratorCapabilities) + , _iteratorCapabilities(ContainerAPI::IteratorCapabilities | (1 << 4) | (ContainerCapabilitiesImpl::ContainerCapabilities << (4+3))) , _size(sizeImpl) , _at(atImpl) - , _moveToBegin(moveToBeginImpl) - , _moveToEnd(moveToEndImpl) + , _moveTo(moveToImpl) + , _append(ContainerCapabilitiesImpl::appendImpl) , _advance(IteratorOwner::advance) , _get(getImpl) , _destroyIter(IteratorOwner::destroy) @@ -1087,7 +1144,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) @@ -1100,8 +1157,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); @@ -1109,6 +1176,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 -- cgit v1.2.3 From e6f1fde24f77f63fb16b2df239f82a89d2bf05dd Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 10 Jan 2020 09:26:27 -0800 Subject: QLibrary/Unix: do not attempt to load a library relative to $PWD I added the code in commit 5219c37f7c98f37f078fee00fe8ca35d83ff4f5d to find libraries in a haswell/ subdir of the main path, but we only need to do that transformation if the library is contains at least one directory seprator. That is, if the user asks to load "lib/foo", then we should try "lib/haswell/foo" (often, the path prefix will be absolute). When the library name the user requested has no directory separators, we let dlopen() do the transformation for us. Testing on Linux confirms glibc does so: $ LD_DEBUG=libs /lib64/ld-linux-x86-64.so.2 --inhibit-cache ./qml -help |& grep Xcursor 1972475: find library=libXcursor.so.1 [0]; searching 1972475: trying file=/usr/lib64/haswell/avx512_1/libXcursor.so.1 1972475: trying file=/usr/lib64/haswell/libXcursor.so.1 1972475: trying file=/usr/lib64/libXcursor.so.1 1972475: calling init: /usr/lib64/libXcursor.so.1 1972475: calling fini: /usr/lib64/libXcursor.so.1 [0] Fixes: QTBUG-81272 Change-Id: I596aec77785a4e4e84d5fffd15e89689bb91ffbb Reviewed-by: Thiago Macieira --- src/corelib/plugin/qlibrary_unix.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp index f0de1010d7..135b82cd37 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) { -- cgit v1.2.3 From bab1473b7e20c91287e5ce9685725be21abb7226 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Jan 2020 10:56:03 -0800 Subject: Doc: QPluginLoader: remove the claim we search the current dir Commit bf131e8d2181b3404f5293546ed390999f760404 removed it and it's a good thing. Change-Id: Idc3fae4d0f614c389d27fffd15ea245420035e66 Reviewed-by: Jani Heikkinen --- src/corelib/plugin/qpluginloader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index c2443dbdda..dac8502dae 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 -- cgit v1.2.3 From 601ce9e08aa92b273f1a6daf0bdbc67dbf9b4e5f Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 31 Oct 2019 17:20:13 +0100 Subject: Implement moving of a single file system entry to the trash This implements the operation for Windows, macOS, and Unix, for now only as a private API (since QFileSystemEngine is private). This adds the capability as a testable function; public API to be agreed on and added in a separate commit. The Unix implementation follows the freedesktop.org specification [1] version 1.0. [1] https://specifications.freedesktop.org/trash-spec/trashspec-1.0.html On macOS and Windows, native APIs are used, with each having some limitations: * on macOS, the file in the trash won't have a "put back" option, as we don't use Finder automation, for the reasons provided in the comments * on Windows, we might not be able to use the modern IFileOperation API, e.g. if Qt is built with mingw which doesn't seem to provide the interface definition; the fallback doesn't provide access to the file name in the trash The test case creates files and directories, and moves them to the trash. As part of the cleanup routine, it deletes all file system entries created. If run on Windows without IFileOperations support, this will add a file in the trash for each test run, filling up hard drive space. Task-number: QTBUG-47703 Change-Id: I5f5f4e578be2f45d7da84f70a03acbe1a12a1231 Reviewed-by: Vitaly Fanaskov --- src/corelib/io/io.pri | 4 +- src/corelib/io/qfilesystemengine_mac.mm | 79 ++++++++++++ src/corelib/io/qfilesystemengine_p.h | 3 +- src/corelib/io/qfilesystemengine_unix.cpp | 193 ++++++++++++++++++++++++++++++ src/corelib/io/qfilesystemengine_win.cpp | 192 +++++++++++++++++++++++++++++ 5 files changed, 469 insertions(+), 2 deletions(-) create mode 100644 src/corelib/io/qfilesystemengine_mac.mm (limited to 'src/corelib') 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/qfilesystemengine_mac.mm b/src/corelib/io/qfilesystemengine_mac.mm new file mode 100644 index 0000000000..4bbce9e5f6 --- /dev/null +++ b/src/corelib/io/qfilesystemengine_mac.mm @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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 +#include + +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) +{ + QFileInfo info(source.filePath()); + @autoreleasepool { + 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; +} + +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..16901be187 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 #include @@ -1197,6 +1199,197 @@ 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 +*/ +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; +} + +//static +bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, + QFileSystemEntry &newLocation, QSystemError &error) +{ + 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; + do { + while (QFile::exists(trashDir.filePath(filesDir) + uniqueTrashedName)) { + ++counter; + uniqueTrashedName = QString(QLatin1String("/%1-%2")) + .arg(trashedName) + .arg(counter, 4, 10, QLatin1Char('0')); + } + /* + "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); + } while (!infoFile.open(QIODevice::NewOnly | QIODevice::WriteOnly | QIODevice::Text)); + + const QString targetPath = trashDir.filePath(filesDir) + uniqueTrashedName; + const QFileSystemEntry target(targetPath); + + if (!renameFile(source, target, error)) { + infoFile.close(); + infoFile.remove(); + error = QSystemError(errno, QSystemError::StandardLibraryError); + 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 + //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..71a0e36693 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 @@ -59,6 +60,8 @@ #include #ifndef Q_OS_WINRT # include +# include +# include # include # include #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(this); + } else if (iid == __uuidof(IFileOperationProgressSink)) { + *ppvObject = static_cast(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,97 @@ 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()); + +# 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(sourcePath.utf16()), + nullptr, IID_PPV_ARGS(&deleteItem)); + if (!deleteItem) + return false; + sink = new FileOperationProgressSink; + hres = pfo->DeleteItem(deleteItem, static_cast(sink)); + if (!SUCCEEDED(hres)) + return false; + hres = pfo->PerformOperations(); + if (!SUCCEEDED(hres)) + return false; + newLocation = QFileSystemEntry(sink->targetPath); + +# else // no IFileOperation in SDK (mingw, likely) - fall back to SHFileOperation + + // double null termination needed, so can't use QString::utf16 + QVarLengthArray 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); +# endif // IFileOperation fallback + 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) -- cgit v1.2.3 From 4f077b7e5ff1081afc0e362bdab6522c2b7ee43b Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Mon, 11 Nov 2019 13:35:53 +0200 Subject: QScopeGuard: Make constructor public With Class Template Argument Deduction users might want to use the constructor itself instead of a separate helper function. In both cases it's possible to let the compiler deduce the template arguments. Try to make the usefulness of the helper function in the absence of CTAD still clear in the documentation. Change-Id: I9b07983c1fb276a6dd9e7ed4c3e606764e9b68ca Reviewed-by: Ville Voutilainen --- src/corelib/tools/qscopeguard.h | 37 +++++++++++++++++++++++----------- src/corelib/tools/qscopeguard.qdoc | 41 ++++++++++++++++++++++++++++---------- 2 files changed, 55 insertions(+), 23 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qscopeguard.h b/src/corelib/tools/qscopeguard.h index 40d2747b1d..4d2e715df1 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 +** 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. @@ -45,10 +46,6 @@ QT_BEGIN_NAMESPACE - -template class QScopeGuard; -template QScopeGuard qScopeGuard(F f); - template class #if __has_cpp_attribute(nodiscard) @@ -59,13 +56,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,28 +84,34 @@ 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); }; +#ifdef __cpp_deduction_guides +template QScopeGuard(F(&)()) -> QScopeGuard; +#endif template #if __has_cpp_attribute(nodiscard) Q_REQUIRED_RESULT #endif -QScopeGuard qScopeGuard(F f) +QScopeGuard qScopeGuard(F &&f) { return QScopeGuard(std::move(f)); } +template +#if __has_cpp_attribute(nodiscard) +Q_REQUIRED_RESULT +#endif +QScopeGuard qScopeGuard(const F &f) +{ + return QScopeGuard(f); +} + QT_END_NAMESPACE #endif // QSCOPEGUARD_H 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 +** 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 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 QScopeGuard::QScopeGuard(F &&f) + \fn template QScopeGuard::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 void QScopeGuard::dismiss() @@ -51,23 +76,17 @@ QT_BEGIN_NAMESPACE of the scope. \ingroup misc - QScopeGuard 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 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 -- cgit v1.2.3 From 22d0e91970b6ac53a51a715e47cae4e4209cd78b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 28 Jan 2020 12:55:15 +0100 Subject: QHash: Re-remove Java-style iterator When deprecating reverse iteratation for QHash the macro defining QHashIterator was expanded but QT_NO_JAVA_STYLE_ITERATORS was unfortunately forgotten. This patch brings it back. Amends dbb54805f63f9ed68d84fe090d608872f16170d2 Change-Id: I7b1912a13f6f8d2446c1f61a1c4a19afb2f28993 Reviewed-by: Lars Knoll --- src/corelib/tools/qhash.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 0b8a0b283d..921b781f4a 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -1264,6 +1264,7 @@ Q_OUTOFLINE_TEMPLATE int QMultiHash::count(const Key &akey) const return cnt; } +#if !defined(QT_NO_JAVA_STYLE_ITERATORS) template class QHashIterator { @@ -1438,6 +1439,7 @@ public: } #endif }; +#endif // !QT_NO_JAVA_STYLE_ITERATORS template uint qHash(const QHash &key, uint seed = 0) -- cgit v1.2.3 From f24b247961e8a3d22ae385c3e29b7df2fd50b032 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Tue, 21 Jan 2020 08:08:29 +0100 Subject: Doc: Add since version to enum value documentation Fixes: QTBUG-80980 Change-Id: I707c4f45d45cb088fb7419038a448d29a2e8dbf5 Reviewed-by: Leena Miettinen --- src/corelib/global/qnamespace.qdoc | 1 + src/corelib/text/qchar.cpp | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 16 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 1908fedead..31e1bcc0da 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1181,6 +1181,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. diff --git a/src/corelib/text/qchar.cpp b/src/corelib/text/qchar.cpp index 9b03a93278..1f9f51a53a 100644 --- a/src/corelib/text/qchar.cpp +++ b/src/corelib/text/qchar.cpp @@ -411,22 +411,22 @@ QT_BEGIN_NAMESPACE \value Script_Khudawadi \value Script_Tirhuta \value Script_WarangCiti - \value Script_Ahom - \value Script_AnatolianHieroglyphs - \value Script_Hatran - \value Script_Multani - \value Script_OldHungarian - \value Script_SignWriting - \value Script_Adlam - \value Script_Bhaiksuki - \value Script_Marchen - \value Script_Newa - \value Script_Osage - \value Script_Tangut - \value Script_MasaramGondi - \value Script_Nushu - \value Script_Soyombo - \value Script_ZanabazarSquare + \value Script_Ahom This value was introduced in Qt 5.6. + \value Script_AnatolianHieroglyphs This value was introduced in Qt 5.6. + \value Script_Hatran This value was introduced in Qt 5.6. + \value Script_Multani This value was introduced in Qt 5.6. + \value Script_OldHungarian This value was introduced in Qt 5.6. + \value Script_SignWriting This value was introduced in Qt 5.6. + \value Script_Adlam This value was introduced in Qt 5.11. + \value Script_Bhaiksuki This value was introduced in Qt 5.11. + \value Script_Marchen This value was introduced in Qt 5.11. + \value Script_Newa This value was introduced in Qt 5.11. + \value Script_Osage This value was introduced in Qt 5.11. + \value Script_Tangut This value was introduced in Qt 5.11. + \value Script_MasaramGondi This value was introduced in Qt 5.11. + \value Script_Nushu This value was introduced in Qt 5.11. + \value Script_Soyombo This value was introduced in Qt 5.11. + \value Script_ZanabazarSquare This value was introduced in Qt 5.11. \omitvalue ScriptCount -- cgit v1.2.3 From 5399f9443e30f7ca849b8096dbe9ee8c88a35c74 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 29 Jan 2020 11:06:35 +0100 Subject: Fix qt5_make_output_file macro for file base names with dots The qt5_make_output_file macro returns the wrong outfile for infiles containing multiple dots in the file name, e.g. 'foo.bar.h'. To fix this we need to use get_filename_component(... NAME_WLE) which is available since CMake 3.14. Re-implement the NAME_WLE functionality for older CMake versions by using multiple get_filename_component calls. Fixes: QTBUG-80295 Change-Id: Ib8e11a69a41ba7f6739eb3d5541ce8f6f59dc18c Reviewed-by: Alexandru Croitor --- src/corelib/Qt5CoreMacros.cmake | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index 84c75401b1..02f49a4b1e 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -59,7 +59,14 @@ macro(QT5_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() -- cgit v1.2.3 From 45967dfbd8192a14a324a75377d1860891845fbf Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 23 Jan 2020 18:03:59 +0100 Subject: Simplify textdate/datestring #if-ery Since datestring implies textdate, we don't need to check the latter inside the #if-ery of the former. Change-Id: I01e648245bc7707db024eac925092ed816173781 Reviewed-by: Thiago Macieira --- src/corelib/time/qdatetime.cpp | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index a8d643d483..cde8587094 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -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()) { @@ -1119,7 +1118,6 @@ static QString toStringTextDate(QDate date) { return toStringTextDate(date, QCalendar()); } -#endif // textdate static QString toStringIsoDate(const QDate &date) { @@ -1193,10 +1191,8 @@ QString QDate::toString(Qt::DateFormat format) const case Qt::RFC2822Date: return QLocale::c().toString(*this, u"dd MMM yyyy"); default: -#if QT_CONFIG(textdate) case Qt::TextDate: return toStringTextDate(*this); -#endif case Qt::ISODate: case Qt::ISODateWithMs: return toStringIsoDate(*this); @@ -1292,10 +1288,8 @@ QString QDate::toString(Qt::DateFormat format, QCalendar cal) const 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); @@ -1625,7 +1619,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; }; @@ -1680,7 +1674,6 @@ QDate QDate::fromString(const QString &string, Qt::DateFormat format) case Qt::RFC2822Date: return rfcDateImpl(string).date; default: -#if QT_CONFIG(textdate) case Qt::TextDate: { QVector parts = string.splitRef(QLatin1Char(' '), QString::SkipEmptyParts); @@ -1699,7 +1692,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 +2006,7 @@ int QTime::msec() const return ds() % 1000; } -#if QT_CONFIG(datestring) +#if QT_CONFIG(datestring) // depends on, so implies, textdate /*! \overload @@ -2347,7 +2339,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) { @@ -4292,7 +4284,7 @@ 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 @@ -4365,7 +4357,6 @@ QString QDateTime::toString(Qt::DateFormat format) const return buf; } default: -#if QT_CONFIG(textdate) case Qt::TextDate: { const QPair p = getDateTime(d); buf = p.first.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,7 +4379,6 @@ QString QDateTime::toString(Qt::DateFormat format) const } return buf; } -#endif case Qt::ISODate: case Qt::ISODateWithMs: { const QPair p = getDateTime(d); @@ -5202,7 +5192,7 @@ 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 @@ -5306,7 +5296,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 parts = string.splitRef(QLatin1Char(' '), QString::SkipEmptyParts); @@ -5412,7 +5401,6 @@ QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format) return QDateTime(date, time, Qt::UTC); } } -#endif // textdate } return QDateTime(); -- cgit v1.2.3 From 2130d282b1a2671049c90dd4e99e512b8009de9a Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 23 Jan 2020 18:21:58 +0100 Subject: Change examples and snippets to pass QDate and QTime by value They're value types, so we should show them being used as such. Change-Id: If9f0c366fac66306b7861f04e2f047540d444acc Reviewed-by: Christian Ehrlicher --- src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp | 4 ++-- src/corelib/doc/snippets/code/src_corelib_tools_qmap.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/corelib') 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 9813cc98d5..e070ada069 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. @@ -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/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: -- cgit v1.2.3 From 3041393d2e6dc094652334fcb4bc35597632d228 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 24 Jan 2020 15:48:41 +0100 Subject: Fix flawed logic in QSystemLocalePrivate::getLocaleInfo() If the first call to GetLocaleInfo() returned non-zero, then GetLastError()'s return has nothing to do with GetLocaleInfo(), since it didn't fail. The check for ERROR_INSUFFICIENT_BUFFER as last error needs to happen in the branch where GetLocaleInfo() failed, returning zero. Change-Id: Idb6eaad1515a003133c787998aff0c265ef98251 Reviewed-by: Friedemann Kleint --- src/corelib/text/qlocale_win.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp index 4b4152c519..d7319c1532 100644 --- a/src/corelib/text/qlocale_win.cpp +++ b/src/corelib/text/qlocale_win.cpp @@ -214,9 +214,9 @@ inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int siz QString QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) { QVarLengthArray 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())) { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return QString(); int cnt = getLocaleInfo(type, 0, 0); if (cnt == 0) return QString(); -- cgit v1.2.3 From 037369cc4d85c49e351c3df6544a398b61195656 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 11 Apr 2019 12:02:17 +0200 Subject: Deprecate QDateTime(const QDate &) in favor of QDate::startOfDay() It needed re-implemented in terms of the new API (in case QTime(0, 0) was skipped, on the date in question, by a spring-forwrd), which makes it redundant (and supports choice of spec and zone or offset, which it did not). Change-Id: I1e3c3e794632c234f254be754ed6e4ebdaaaa6bc Reviewed-by: Volker Hilsheimer Reviewed-by: Qt CI Bot --- src/corelib/kernel/qvariant.cpp | 6 +++--- src/corelib/time/qdatetime.cpp | 11 +++++++---- src/corelib/time/qdatetime.h | 6 ++++-- 3 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index b417683d2a..3be9a02248 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2018 Intel Corporation. ** Copyright (C) 2015 Olivier Goffart ** Contact: https://www.qt.io/licensing/ @@ -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(d)); + *dt = v_cast(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(result) = *v_cast(d); break; case QMetaType::QDate: - *static_cast(result) = QCborValue(QDateTime(*v_cast(d))); + *static_cast(result) = QCborValue(v_cast(d)->startOfDay()); break; case QMetaType::QDateTime: *static_cast(result) = QCborValue(*v_cast(d)); diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 80751e60a0..7cc8568bd5 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -3631,15 +3631,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 diff --git a/src/corelib/time/qdatetime.h b/src/corelib/time/qdatetime.h index 3eae8ebf64..2c2b52b1c2 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/ ** @@ -287,7 +287,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); -- cgit v1.2.3 From 9ede07613dc5b7759f398d5a8839b2ffdb4675a2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Jan 2020 16:59:59 -0800 Subject: QLockFile: Disable flock() on QNX It appears it's not implemented. [ChangeLog][QtCore][QLockFile] Suppressed the warning on QNX that said 'setNativeLocks failed: "Function not implemented"'. There is no difference in behavior: Qt will continue not to be able to apply an OS- level file lock, which means the lock could be accidentally stolen by buggy software. Correct software using QLockFile should not be affected. Fixes: QTBUG-81701 Change-Id: If79a52e476594446baccfffd15ee35bbac6c6e47 Reviewed-by: David Faure --- src/corelib/io/qlockfile_unix.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/corelib') 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 // 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 -- cgit v1.2.3 From b4b3b5c69469f67103309cb2f401c243d840cf4e Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 30 Jan 2020 17:24:01 +0100 Subject: Clarify handling of unspecified year in two QCalendar methods [ChangeLog][QtCore] QCalendar::monthsInYear(QCalendar::Unspecified) now returns maximumMonthsInYear(). QCalendar::daysInYear() now makes clear that its handling of unspecified year is undefined. Change-Id: Ifef8723193868c666f6afeb7f190af4929d30dea Reviewed-by: Paul Wicking Reviewed-by: Thiago Macieira --- src/corelib/time/qcalendar.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/corelib') 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; } /*! -- cgit v1.2.3 From 2b1068af97f1483b7bdb3d7a9257ab59fc4b2b59 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 23 Jan 2020 18:28:07 +0100 Subject: Pass QDate and QTime by value in various static and local functions They're value types, so pass them as such. Change-Id: I0dc46c63a3a0e6d859b821362f71390f0148b64c Reviewed-by: Thiago Macieira --- src/corelib/text/qlocale_mac.mm | 4 ++-- src/corelib/time/qdatetime.cpp | 10 +++++----- src/corelib/time/qdatetimeparser.cpp | 2 +- src/corelib/time/qtimezoneprivate_win.cpp | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/text/qlocale_mac.mm b/src/corelib/text/qlocale_mac.mm index 31ede1352b..7bdae662c7 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 myDate = QDateTime(date, QTime()).toCFDate(); QCFType 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 myDate = QDateTime(QDate::currentDate(), time).toCFDate(); QCFType mylocale = CFLocaleCopyCurrent(); diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index cde8587094..a5761055ed 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -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; @@ -1119,7 +1119,7 @@ static QString toStringTextDate(QDate date) return toStringTextDate(date, QCalendar()); } -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) @@ -2869,7 +2869,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(); @@ -3214,7 +3214,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; diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp index 2636928e69..2f7cbb4017 100644 --- a/src/corelib/time/qdatetimeparser.cpp +++ b/src/corelib/time/qdatetimeparser.cpp @@ -903,7 +903,7 @@ QDateTimeParser::parseSection(const QDateTime ¤tValue, 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(); -- cgit v1.2.3 From 05ce1821cd18e745f7d126ed93ab0c68125993b6 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 24 Jan 2020 18:26:14 +0100 Subject: Add missing calendar methods to QDateTime and docs We missed a few, so complete the general scheme of accepting an optional calendar, where it would be relevant. [ChangeLog][QtCore][QDateTime] Added some missing QCalendar variants of QDateTime::toString(). Included docs for QCalendar variants in both QDate and QDateTime. Change-Id: Ief7b4dada73d7a4055b75d8b47ff4d2e310ce738 Reviewed-by: Paul Wicking Reviewed-by: Volker Hilsheimer --- src/corelib/time/qdatetime.cpp | 54 ++++++++++++++++++++++++++++++++---------- src/corelib/time/qdatetime.h | 10 +++++--- 2 files changed, 48 insertions(+), 16 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 7cc8568bd5..94306345da 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -1131,11 +1131,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 @@ -1205,10 +1207,13 @@ QString QDate::toString(Qt::DateFormat format) const /*! \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: @@ -4298,10 +4303,13 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC) #if QT_CONFIG(datestring) /*! \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 @@ -4346,6 +4354,11 @@ 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()) @@ -4354,16 +4367,16 @@ QString QDateTime::toString(Qt::DateFormat format) const switch (format) { 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); 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; } @@ -4371,7 +4384,7 @@ QString QDateTime::toString(Qt::DateFormat format) const #if QT_CONFIG(textdate) case Qt::TextDate: { const QPair p = getDateTime(d); - buf = p.first.toString(Qt::TextDate); + buf = p.first.toString(Qt::TextDate, cal); // Insert time between date's day and year: buf.insert(buf.lastIndexOf(QLatin1Char(' ')), QLatin1Char(' ') + p.second.toString(Qt::TextDate)); @@ -4394,6 +4407,7 @@ QString QDateTime::toString(Qt::DateFormat format) const #endif case Qt::ISODate: case Qt::ISODateWithMs: { + // No calendar dependence const QPair p = getDateTime(d); const QDate &dt = p.first; const QTime &tm = p.second; @@ -4422,11 +4436,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 @@ -4460,11 +4478,21 @@ QString QDateTime::toString(QStringView format) const return QLocale::system().toString(*this, format); // QLocale::c() ### Qt6 } +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)); } + +QString QDateTime::toString(const QString &format, QCalendar cal) const +{ + return toString(qToStringViewIgnoringNull(format), cal); +} #endif #endif // datestring diff --git a/src/corelib/time/qdatetime.h b/src/corelib/time/qdatetime.h index 2c2b52b1c2..c1653b5585 100644 --- a/src/corelib/time/qdatetime.h +++ b/src/corelib/time/qdatetime.h @@ -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) @@ -332,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; -- cgit v1.2.3 From d6d98f782aeb798649c2bf5f7744065b7e86c035 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 22 Jan 2020 16:12:24 +0100 Subject: Deprecate locale-related DateFormat enum members Qt 6 shall remove all locale-dependence from Q(Date|Time)+. Task-number: QTBUG-80441 Change-Id: Iebaaa2bd776bccfe0d73c15f36cbdd456b71ca59 Reviewed-by: Fabian Kosmale --- src/corelib/global/qnamespace.h | 20 ++++--- src/corelib/global/qnamespace.qdoc | 54 +++++++++++------- src/corelib/text/qlocale.cpp | 6 ++ src/corelib/time/qdatetime.cpp | 113 ++++++++++++++++++++++--------------- 4 files changed, 117 insertions(+), 76 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 8f40393a7e..ea2c635303 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. @@ -1267,14 +1267,16 @@ public: 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 }; diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 9acb978efc..8debee7bb5 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 SystemLocaleLongDate The \l{QLocale::LongFormat}{long format} used - by the \l{QLocale::system()}{operating system}. - - \value DefaultLocaleShortDate The \l{QLocale::ShortFormat}{short format} specified - by the \l{QLocale::setDefault()}{application's locale}. - - \value DefaultLocaleLongDate The \l{QLocale::LongFormat}{long format} used - by the \l{QLocale::setDefault()}{application's locale}. - - \value SystemLocaleDate \e{This enum value is deprecated.} Use Qt::SystemLocaleShortDate - instead (or Qt::SystemLocaleLongDate if you want long dates). - - \value LocaleDate \e{This enum value is deprecated.} Use Qt::DefaultLocaleShortDate - instead (or Qt::DefaultLocaleLongDate if you want long dates). - - \value LocalDate \e{This enum value is deprecated.} Use Qt::SystemLocaleShortDate - instead (or Qt::SystemLocaleLongDate if you want long dates). + \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 \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 \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 \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 and shall + be removed in Qt 6.} It is equivalent to SystemLocaleShortDate. + + \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 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]} diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 6dbec8ba33..022c770ac3 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -2025,6 +2025,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 @@ -2179,6 +2182,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 diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 94306345da..a1cc719995 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/ ** @@ -1150,18 +1150,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 @@ -1171,8 +1169,7 @@ 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() */ @@ -1182,6 +1179,7 @@ QString QDate::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); @@ -1192,6 +1190,7 @@ QString QDate::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::RFC2822Date: return QLocale::c().toString(*this, u"dd MMM yyyy"); default: @@ -1284,6 +1283,7 @@ QString QDate::toString(Qt::DateFormat format, QCalendar cal) const return QString(); switch (format) { +#if QT_DEPRECATED_SINCE(5, 15) case Qt::SystemLocaleDate: case Qt::SystemLocaleShortDate: return QLocale::system().toString(*this, QLocale::ShortFormat, cal); @@ -1294,6 +1294,7 @@ QString QDate::toString(Qt::DateFormat format, QCalendar cal) const return QLocale().toString(*this, QLocale::ShortFormat, cal); case Qt::DefaultLocaleLongDate: return QLocale().toString(*this, QLocale::LongFormat, cal); +#endif // 5.15 case Qt::RFC2822Date: return QLocale::c().toString(*this, QStringView(u"dd MMM yyyy"), cal); default: @@ -1659,9 +1660,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() */ @@ -1672,6 +1678,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); @@ -1682,6 +1689,7 @@ 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: @@ -2035,18 +2043,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)}. @@ -2065,6 +2070,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); @@ -2075,6 +2081,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: @@ -2450,6 +2457,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) @@ -2458,6 +2471,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); @@ -2468,6 +2482,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: @@ -4326,19 +4341,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}. @@ -4346,8 +4359,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() @@ -4365,6 +4377,7 @@ QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const return buf; switch (format) { +#if QT_DEPRECATED_SINCE(5, 15) case Qt::SystemLocaleDate: case Qt::SystemLocaleShortDate: return QLocale::system().toString(*this, QLocale::ShortFormat, cal); @@ -4375,6 +4388,7 @@ QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const return QLocale().toString(*this, QLocale::ShortFormat, cal); case Qt::DefaultLocaleLongDate: 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 ", cal); buf += toOffsetString(Qt::TextDate, offsetFromUtc()); @@ -5239,9 +5253,14 @@ int QDateTime::utcOffset() const 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() */ @@ -5251,6 +5270,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); @@ -5261,6 +5281,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); -- cgit v1.2.3 From d6ba2ae441b56d13edf9acf1220b50eda5e093cd Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 28 Jan 2020 18:38:26 +0100 Subject: Consolidate some Q(Date|Time)+ methods to call calendared versions The string-returning methods were in any case delegating to either a local static or QLocale methods that delegate to their calendar variants, so do the default-calendar step early and reduce the number of distinct code-paths, along with the gross number of lines of code. In the process, short-cut past QDate::toString() when we can save its switch and go direct to the toString{Text|Iso}Date() it's calling. Tidy up somewhat in the process. Change-Id: I8ba70b29ef9e8b6553c41310ebb2b63ec5570bb9 Reviewed-by: Lars Knoll --- src/corelib/time/qdatetime.cpp | 83 ++++++++++++------------------------------ 1 file changed, 24 insertions(+), 59 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index a1cc719995..055287207c 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -1114,11 +1114,6 @@ 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) @@ -1174,6 +1169,11 @@ static QString toStringIsoDate(const QDate &date) \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(); @@ -1182,24 +1182,25 @@ QString QDate::toString(Qt::DateFormat format) const #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) +#ifndef QT_NO_TEXTDATE case Qt::TextDate: - return toStringTextDate(*this); + return toStringTextDate(*this, cal); #endif case Qt::ISODate: case Qt::ISODateWithMs: + // No calendar dependence return toStringIsoDate(*this); } } @@ -1267,45 +1268,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) { -#if QT_DEPRECATED_SINCE(5, 15) - 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); -#endif // 5.15 - 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 @@ -1314,6 +1277,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); @@ -4398,7 +4366,7 @@ QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const #if QT_CONFIG(textdate) case Qt::TextDate: { const QPair p = getDateTime(d); - buf = p.first.toString(Qt::TextDate, cal); + buf = toStringTextDate(p.first, cal); // Insert time between date's day and year: buf.insert(buf.lastIndexOf(QLatin1Char(' ')), QLatin1Char(' ') + p.second.toString(Qt::TextDate)); @@ -4423,13 +4391,10 @@ QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) const case Qt::ISODateWithMs: { // No calendar dependence const QPair 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'); @@ -4489,7 +4454,7 @@ QString QDateTime::toString(Qt::DateFormat format, QCalendar cal) 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 @@ -4500,7 +4465,7 @@ QString QDateTime::toString(QStringView format, QCalendar cal) const #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 -- cgit v1.2.3 From 6c4e0f2d2de5f877f698a0faa7bd0d027b7320c9 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 28 Jan 2020 19:45:35 +0100 Subject: Deprecate QLocale::toTime() variants taking a calendar The calendar is ignored, so adding these methods was a mistake. [ChangeLog][QtCore][QLocale] Deprecated toTime() variants taking a calendar. The calendar is ignored in time parsing. Change-Id: I79fa994ce88f13fdb931163b447eb1a9ad655c09 Reviewed-by: Volker Hilsheimer --- src/corelib/text/qlocale.cpp | 20 +++++++++++++++++++- src/corelib/text/qlocale.h | 8 ++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 022c770ac3..5fc9d9922c 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -2353,14 +2353,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 @@ -2425,12 +2430,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 { @@ -2447,6 +2464,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 513e0f097b..0dc9e1bd00 100644 --- a/src/corelib/text/qlocale.h +++ b/src/corelib/text/qlocale.h @@ -1037,11 +1037,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 -- cgit v1.2.3 From c76dd72dc6b78c34edb4dfc5196bb93a51cc488f Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 21 Nov 2019 15:51:34 +0100 Subject: Add a constructor for QRunnable from anonymous functions This makes it easier to create one without having to create a derivative class. The patch also adds a path to avoid using QRunnable directly in QThreadPool. Change-Id: I9caa7dabb6f641b547d4771c863aa6ab7f01b704 Reviewed-by: Thiago Macieira Reviewed-by: Sona Kurazyan --- src/corelib/thread/qrunnable.cpp | 27 +++++++++++++++++++++++++++ src/corelib/thread/qrunnable.h | 2 ++ src/corelib/thread/qthreadpool.cpp | 32 ++++++++++++++++++++++++++++++++ src/corelib/thread/qthreadpool.h | 5 +++++ 4 files changed, 66 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/thread/qrunnable.cpp b/src/corelib/thread/qrunnable.cpp index bd0a32b53d..58a764d407 100644 --- a/src/corelib/thread/qrunnable.cpp +++ b/src/corelib/thread/qrunnable.cpp @@ -114,4 +114,31 @@ QRunnable::~QRunnable() \sa autoDelete(), QThreadPool */ +class FunctionRunnable : public QRunnable +{ + std::function m_functor; +public: + FunctionRunnable(std::function 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 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 +#include QT_BEGIN_NAMESPACE @@ -59,6 +60,7 @@ public: QRunnable() : ref(0) { } virtual ~QRunnable(); + static QRunnable *create(std::function 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 @@ -511,6 +511,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 fun, int priority) +{ + if (!fun) + return; + start(QRunnable::create(std::move(fun)), priority); +} + /*! Attempts to reserve a thread to run \a runnable. @@ -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 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 #include +#include + 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 fun, int priority = 0); + bool tryStart(std::function fun); + int expiryTimeout() const; void setExpiryTimeout(int expiryTimeout); -- cgit v1.2.3 From 5ac1516edd17eb4ddd94fe43a04fa4d736c50041 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 30 Jan 2020 15:16:18 +0100 Subject: Check for (__ARM_FP & 2) to verify 16-bit FP support It appears __ARM_FP16_FORMAT_IEEE is sometimes incorrectly set, and we need to double-check that 16-bit floating point is available in the __ARM_FP macro as well. Task-number: QTBUG-68314 Fixes: QTBUG-81461 Change-Id: I878d6b286aa31e21271163dc6c8f8038b9534c76 Reviewed-by: BogDan Vatra Reviewed-by: Thiago Macieira --- src/corelib/global/qfloat16.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp index c868e879b7..0c9bb80cb2 100644 --- a/src/corelib/global/qfloat16.cpp +++ b/src/corelib/global/qfloat16.cpp @@ -205,7 +205,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; -- cgit v1.2.3 From 89f443dfbc980313f19cc8c6a205491a41c9926a Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Thu, 30 Jan 2020 12:46:47 +0200 Subject: QScopeGuard: Fix build failures with qScopeGuard() Partially reverts 4f077b7e5ff1081afc0e362bdab6522c2b7ee43b. Can't overload with forwarding references and lvalue references. Use a single forwarding reference overload, but take care of not trying to create a QScopeGuard of reference type and forward instead of moving. Add tests to ensure calling with both lvalues and rvalues is possible. Change-Id: Ia034afe0a8feb08246c2c7c154a85cae37421c98 Reviewed-by: Ville Voutilainen Reviewed-by: Volker Hilsheimer Reviewed-by: Simon Hausmann --- src/corelib/tools/qscopeguard.h | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qscopeguard.h b/src/corelib/tools/qscopeguard.h index 4d2e715df1..6a5bc6cc61 100644 --- a/src/corelib/tools/qscopeguard.h +++ b/src/corelib/tools/qscopeguard.h @@ -43,6 +43,8 @@ #include +#include +#include QT_BEGIN_NAMESPACE @@ -98,18 +100,9 @@ template #if __has_cpp_attribute(nodiscard) Q_REQUIRED_RESULT #endif -QScopeGuard qScopeGuard(F &&f) +QScopeGuard::type> qScopeGuard(F &&f) { - return QScopeGuard(std::move(f)); -} - -template -#if __has_cpp_attribute(nodiscard) -Q_REQUIRED_RESULT -#endif -QScopeGuard qScopeGuard(const F &f) -{ - return QScopeGuard(f); + return QScopeGuard::type>(std::forward(f)); } QT_END_NAMESPACE -- cgit v1.2.3 From dd42e5d5e7228f8186506bb91fd9af691e9c584c Mon Sep 17 00:00:00 2001 From: Vitaly Fanaskov Date: Thu, 30 Jan 2020 14:35:45 +0100 Subject: QSignalMapper: deprecate overridden signals Task-number: QTBUG-80906 Change-Id: I9beab78d8fe8dfc712969f65792f50360a890287 Reviewed-by: Friedemann Kleint Reviewed-by: Christian Ehrlicher --- .../doc/snippets/qsignalmapper/buttonwidget.cpp | 5 +- src/corelib/kernel/qsignalmapper.cpp | 115 +++++++++++++++++---- src/corelib/kernel/qsignalmapper.h | 10 ++ 3 files changed, 105 insertions(+), 25 deletions(-) (limited to 'src/corelib') 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::of(&QSignalMapper::mapped), + connect(signalMapper, &QSignalMapper::mappedString, //! [1] //! [2] this, &ButtonWidget::clicked); 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 + 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 intHash; QHash stringHash; QHash widgetHash; QHash 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(); -- cgit v1.2.3 From aadf21b25cad7026f07a5fe7bf19fbedfb1866b7 Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Fri, 31 Jan 2020 16:47:46 +0100 Subject: Fix 'the the' typo in comments Change-Id: I00fcb1c2374e7ca168b6240f9d41c0323fb0867c Reviewed-by: Giuseppe D'Angelo --- src/corelib/io/qiodevice.cpp | 2 +- src/corelib/kernel/qcore_mac_objc.mm | 2 +- src/corelib/tools/qbitarray.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index e26508e631..076b2394ba 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/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/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index f0b81cce66..ab3054d5be 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() -- cgit v1.2.3 From a049325cc708b483ed1aadc6589419f4d74b19f3 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 20 Jan 2020 15:54:42 +0100 Subject: Win: work around (estimated) 32k char limit for OutputDebugString MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reaching a certain number of characters, OutputDebugString will just eat the string and not give any output. As there is no way of handling that error properly we divide the string into usable chunks. Fixes: QTBUG-80996 Change-Id: Ic7ef34c48c212cbaec3a03790d1020506b7b4319 Reviewed-by: Miguel Costa Reviewed-by: Friedemann Kleint Reviewed-by: Mårten Nordheim --- src/corelib/global/qlogging.cpp | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 5a7f8242de..c1dd04f03c 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(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(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(message.utf16())); + win_outputDebugString_helper(message); return; #elif defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) if (!shouldLogToStderr()) { - OutputDebugString(reinterpret_cast(message.utf16())); + win_outputDebugString_helper(message); return; } #endif -- cgit v1.2.3 From e0f9b57462226b4f5842d1e857612d6c8fbe38fd Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 24 Jan 2020 16:01:33 +0100 Subject: qlocale_win.cpp: distinguish empty QString from null QVariant An empty string, when packaged as a QVariant, is non-null (as a QVariant); and QSystemLocale::query()'s callers care about the difference. Some callers of the internal getLocaleInfo(LCTYPE type, int maxlen) need an actual QString return, while others are what query() returns, so need to return a QVariant; where the former want an empty string, the latter need a null QVariant. So make that getLocaleInfo() into a template, so callers can chose QString or QVariant as return type, only affecting the failure returns. Change-Id: I7b9a698badedc0e0d8aef8c6e85c22931c33297a Reviewed-by: Friedemann Kleint Reviewed-by: Volker Hilsheimer --- src/corelib/text/qlocale_win.cpp | 55 +++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 26 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp index d7319c1532..faaa15cf6b 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 + 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,18 +213,19 @@ inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int siz #endif } -QString QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) +template +T QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) { QVarLengthArray buf(maxlen ? maxlen : 64); if (!getLocaleInfo(type, buf.data(), buf.size())) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - return QString(); + 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 {}; } return QString::fromWCharArray(buf.data()); } @@ -298,7 +301,7 @@ QString &QSystemLocalePrivate::substituteDigits(QString &string) return string; } -QString QSystemLocalePrivate::zeroDigit() +QVariant QSystemLocalePrivate::zeroDigit() { if (zero.isEmpty()) { /* Ten digits plus a terminator. @@ -317,24 +320,24 @@ QString QSystemLocalePrivate::zeroDigit() return zero; } -QString QSystemLocalePrivate::decimalPoint() +QVariant QSystemLocalePrivate::decimalPoint() { - return getLocaleInfo(LOCALE_SDECIMAL); + return getLocaleInfo(LOCALE_SDECIMAL); } -QString QSystemLocalePrivate::groupSeparator() +QVariant QSystemLocalePrivate::groupSeparator() { - return getLocaleInfo(LOCALE_STHOUSAND); + return getLocaleInfo(LOCALE_STHOUSAND); } -QString QSystemLocalePrivate::negativeSign() +QVariant QSystemLocalePrivate::negativeSign() { - return getLocaleInfo(LOCALE_SNEGATIVESIGN); + return getLocaleInfo(LOCALE_SNEGATIVESIGN); } -QString QSystemLocalePrivate::positiveSign() +QVariant QSystemLocalePrivate::positiveSign() { - return getLocaleInfo(LOCALE_SPOSITIVESIGN); + return getLocaleInfo(LOCALE_SPOSITIVESIGN); } QVariant QSystemLocalePrivate::dateFormat(QLocale::FormatType type) @@ -392,10 +395,10 @@ QVariant QSystemLocalePrivate::dayName(int day, QLocale::FormatType type) day -= 1; if (type == QLocale::LongFormat) - return getLocaleInfo(long_day_map[day]); + return getLocaleInfo(long_day_map[day]); if (type == QLocale::NarrowFormat) - return getLocaleInfo(narrow_day_map[day]); - return getLocaleInfo(short_day_map[day]); + return getLocaleInfo(narrow_day_map[day]); + return getLocaleInfo(short_day_map[day]); } QVariant QSystemLocalePrivate::monthName(int month, QLocale::FormatType type) @@ -418,7 +421,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(lctype); } QVariant QSystemLocalePrivate::toString(QDate date, QLocale::FormatType type) @@ -485,7 +488,7 @@ QVariant QSystemLocalePrivate::measurementSystem() QVariant QSystemLocalePrivate::collation() { - return getLocaleInfo(LOCALE_SSORTLOCALE); + return getLocaleInfo(LOCALE_SSORTLOCALE); } QVariant QSystemLocalePrivate::amText() @@ -687,12 +690,12 @@ QVariant QSystemLocalePrivate::uiLanguages() QVariant QSystemLocalePrivate::nativeLanguageName() { - return getLocaleInfo(LOCALE_SNATIVELANGUAGENAME); + return getLocaleInfo(LOCALE_SNATIVELANGUAGENAME); } QVariant QSystemLocalePrivate::nativeCountryName() { - return getLocaleInfo(LOCALE_SNATIVECOUNTRYNAME); + return getLocaleInfo(LOCALE_SNATIVECOUNTRYNAME); } -- cgit v1.2.3 From 3730452bfe098f8cdc68ec2183dd283a17f7ad39 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 23 Jan 2020 10:53:01 +0100 Subject: Fall back to "+" if MS returns empty string for positive sign MS's documentation says empty means "+" here, so implement that fallback (which shall over-ride whatever the CLDR has given us for the fallbackUiLanguage's positive sign). Task-number: QTBUG-81530 Change-Id: Ic3f10dd061d0c46d1433f29b8065988da94c38e6 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/corelib/text/qlocale_win.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp index faaa15cf6b..4a38adf309 100644 --- a/src/corelib/text/qlocale_win.cpp +++ b/src/corelib/text/qlocale_win.cpp @@ -216,9 +216,17 @@ inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int siz template 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 buf(maxlen ? maxlen : 64); if (!getLocaleInfo(type, buf.data(), buf.size())) { - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + 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) @@ -227,6 +235,8 @@ T QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen) if (!getLocaleInfo(type, buf.data(), buf.size())) return {}; } + if (type == LOCALE_SPOSITIVESIGN && !buf[0]) + return plus; return QString::fromWCharArray(buf.data()); } -- cgit v1.2.3 From 71fa90a37c4f250aa4a6ae8e6bd957dd372566c8 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 6 Jan 2020 13:15:06 +0100 Subject: Enable system locale to skip digit-grouping if configured to do so On macOS it's possible to configure the system locale to not do digit grouping (separating "thousands", in most western locales); it then returns an empty string when asked for the grouping character, which QLocale's system-configuration then ignored, falling back on using the base UI locale's grouping separator. This could lead to the same separator being used for decimal and grouping, which should never happen, least of all when configured to not group at all. In order to notice when this happens, query() must take care to return an empty QString (as a QVariant, which is then non-null) when it *has* a value for the locale property, and that value is empty, as opposed to a null QVariant when it doesn't find a configured value. The caller can then distinguish the two cases. Furthermore, the group and decimal separators need to be distinct, so we need to take care to avoid cases where the system overrides one with what the CLDR has given for the other and doesn't over-ride that other. Only presently implemented for macOS and MS-Win, since the (other) Unix implementation of the system locale returns single QChar values for the numeric tokens - see QTBUG-69324, QTBUG-81053. Fixes: QTBUG-80459 Change-Id: Ic3fbb0fb86e974604a60781378b09abc13bab15d Reviewed-by: Ulf Hermann --- src/corelib/text/qlocale.cpp | 36 ++++++++++++++++++++++++++++++++---- src/corelib/text/qlocale_mac.mm | 16 +++++++--------- src/corelib/text/qlocale_p.h | 4 ++-- 3 files changed, 41 insertions(+), 15 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 26db674a99..11e788c200 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, 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 @@ -834,8 +864,6 @@ static const int locale_data_size = sizeof(locale_data)/sizeof(QLocaleData) - 1; Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer, defaultLocalePrivate, (QLocalePrivate::create(defaultData()))) -Q_GLOBAL_STATIC_WITH_ARGS(QExplicitlySharedDataPointer, systemLocalePrivate, - (QLocalePrivate::create(systemData()))) static QLocalePrivate *localePrivateByName(const QString &name) { diff --git a/src/corelib/text/qlocale_mac.mm b/src/corelib/text/qlocale_mac.mm index 7bdae662c7..5381f0f975 100644 --- a/src/corelib/text/qlocale_mac.mm +++ b/src/corelib/text/qlocale_mac.mm @@ -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 locale = CFLocaleCopyCurrent(); CFTypeRef value = CFLocaleGetValue(locale, key); + if (!value) + return QVariant(); return QString::fromCFString(CFStringRef(static_cast(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 bb24009523..7e26e86fdf 100644 --- a/src/corelib/text/qlocale_p.h +++ b/src/corelib/text/qlocale_p.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/ ** @@ -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 -- cgit v1.2.3 From 056230cc9c3309823a93df0e34c92affb29df9e4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Jan 2020 14:32:06 -0800 Subject: qfloat16: include the tables in AVX2 binaries regardless Having a QtCore build optimized for AVX2 does not imply all user binaries and libraries are optimized the same way. Most of them will actually have been built for the base platform, which means they require access to these tables to operate if they are using qfloat16. Introduced by 5e40d3d982d014cd01db4dbe6aecc6ea6baf840a. Change-Id: If79a52e476594446baccfffd15ee2da9e3693cce Reviewed-by: Allan Sandfeld Jensen --- src/corelib/global/qfloat16tables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') 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, -- cgit v1.2.3 From 336b3bb0dd494409b89e1de480eb7204ff7b554e Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 31 Jan 2020 12:54:17 +0100 Subject: Address failing test case for internal implementation of moveToTrash This ammends 601ce9e08aa92b273f1a6daf0bdbc67dbf9b4e5f, which added a new test case for the internal Qt APIs. The test was not getting executed by coin as it wasn't included in the io.pro file, and trying to fix that generates link errors on Windows, since these internal APIs depend on other internal APIs. Short of bootstrapping much of QtCore into this test case, the only sensible option is to remove this test case again, and cover the testing when the public API is added in a follow up commit. At the same time, address those failures that were discovered on platforms that could build the test, and fix compilation on iOS platforms in Coin. Change-Id: Id31b43c9df9f205476c48bccb6b87c7a53ed15c5 Reviewed-by: Vitaly Fanaskov --- src/corelib/io/qfilesystemengine_mac.mm | 26 +++++++++++++++----------- src/corelib/io/qfilesystemengine_unix.cpp | 22 +++++++++++++++------- 2 files changed, 30 insertions(+), 18 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qfilesystemengine_mac.mm b/src/corelib/io/qfilesystemengine_mac.mm index 4bbce9e5f6..258ae2e8e0 100644 --- a/src/corelib/io/qfilesystemengine_mac.mm +++ b/src/corelib/io/qfilesystemengine_mac.mm @@ -60,20 +60,24 @@ QT_BEGIN_NAMESPACE 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()); - @autoreleasepool { - 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()); + 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_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 16901be187..eed34086b4 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1341,13 +1341,15 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, QString infoFileName; int counter = 0; QFile infoFile; - do { - while (QFile::exists(trashDir.filePath(filesDir) + uniqueTrashedName)) { - ++counter; - uniqueTrashedName = QString(QLatin1String("/%1-%2")) + 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 @@ -1363,15 +1365,21 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, infoFileName = trashDir.filePath(infoDir) + uniqueTrashedName + QLatin1String(".trashinfo"); infoFile.setFileName(infoFileName); - } while (!infoFile.open(QIODevice::NewOnly | QIODevice::WriteOnly | QIODevice::Text)); + 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(); - error = QSystemError(errno, QSystemError::StandardLibraryError); return false; } -- cgit v1.2.3 From f8e39a66569b27bb45cc7a49508dba29038122a4 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 4 Feb 2020 14:47:28 +0100 Subject: Fix build of bootstrapped tools with clang 10 Building of qmake fails with clang 10 due to QStorageInfo symbols not being resolved. Since bootstrapped tools don't need this functionality, we can remove the respective code and make the function fail as "not implemented". Change-Id: I48bbbd822e4f70630d903e5caead1a08fe4f13a8 Reviewed-by: Robert Loehning --- src/corelib/io/qfilesystemengine_unix.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index eed34086b4..eaf4e2d9af 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1203,6 +1203,9 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy /* 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 { @@ -1298,11 +1301,18 @@ static QString freeDesktopTrashLocation(const QString &sourcePath) 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); @@ -1395,8 +1405,9 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, newLocation = QFileSystemEntry(targetPath); return true; +#endif // QT_BOOTSTRAPPED } -#endif +#endif // Q_OS_DARWIN //static bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error) -- cgit v1.2.3 From a20dbcf7c77c9bc92cce87eed7bada4ab202f2af Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Mon, 3 Feb 2020 11:50:57 +0100 Subject: Deprecate QLinkedList [ChangeLog][Deprecation Notice] QLinkedList is deprecated and will be moved to Qt5Compat in Qt 6. It is recommended to use std::list instead. Task-number: QTBUG-81630 Task-number: QTBUG-80312 Change-Id: I2c2b64e51d1cc2fd305aee6a11e9a89788f51eb4 Reviewed-by: Lars Knoll --- src/corelib/tools/qcontainerfwd.h | 2 +- src/corelib/tools/qiterator.qdoc | 2 ++ src/corelib/tools/qlinkedlist.cpp | 14 ++++++++++++++ src/corelib/tools/qlinkedlist.h | 24 ++++++++++++++++++++---- 4 files changed, 37 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qcontainerfwd.h b/src/corelib/tools/qcontainerfwd.h index 532b4c95ce..00a8c85b66 100644 --- a/src/corelib/tools/qcontainerfwd.h +++ b/src/corelib/tools/qcontainerfwd.h @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE template class QCache; template class QHash; -#ifndef QT_NO_LINKED_LIST +#if !defined(QT_NO_LINKED_LIST) && QT_DEPRECATED_SINCE(5, 15) template class QLinkedList; #endif template class QList; 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::shared_null), const_cast(&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\ 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 8970d39be0..64c6b4d326 100644 --- a/src/corelib/tools/qlinkedlist.h +++ b/src/corelib/tools/qlinkedlist.h @@ -55,10 +55,22 @@ #include #include -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 -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 QLinkedList +class QT_DEPRECATED_VERSION_X_5_15("Use std::list instead") QLinkedList { typedef QLinkedListNode Node; union { QLinkedListData *d; QLinkedListNode *e; }; @@ -594,6 +606,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 -- cgit v1.2.3 From c9b8ebc2234027a11eae0dfc45c13d276dfc92a1 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 4 Feb 2020 15:17:52 +0100 Subject: QUrl::topLevelDomain() - deprecate in 5.15 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And remove in Qt 6 (with private API remaining). [ChangeLog][Deprecation Notice] QUrl::topLevelDomain() was deprecated in 5.15 and will be removed in 6.0 Task-number: QTBUG-80308 Change-Id: Ie053c9c8813274c971e2d6fc442dd6ce716fadf1 Reviewed-by: Thiago Macieira Reviewed-by: Mårten Nordheim --- src/corelib/io/qurl.cpp | 7 +++++-- src/corelib/io/qurl.h | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 659552b72f..def4a1095f 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; -- cgit v1.2.3 From 41b2c477b771e7c214d09138af1a48701f573912 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 27 Jan 2020 13:12:45 +0100 Subject: Take care of NULL data from QStringView in QCollator Back-ends need to catch NULL data so as not to call system APIs with invalid pointers. [ChangeLog][QtCore][QCollator] Fixed a regression introduced in 5.14.0 that caused QCollator not to operate with default-constructed QStrings and print a warning on Windows. Fixes: QTBUG-81673 Change-Id: I2eafe1e188b436afcca3cf2ecdf98bba707c44c9 Reviewed-by: Thiago Macieira --- src/corelib/text/qcollator_icu.cpp | 7 ++++++- src/corelib/text/qcollator_macx.cpp | 7 ++++++- src/corelib/text/qcollator_posix.cpp | 7 ++++++- src/corelib/text/qcollator_win.cpp | 7 ++++++- 4 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src/corelib') 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 ** 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 +** Copyright (C) 2020 Aleix Pol Gonzalez ** 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 +** Copyright (C) 2020 Aleix Pol Gonzalez ** 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 &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 +** Copyright (C) 2020 Aleix Pol Gonzalez ** 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); -- cgit v1.2.3 From 2767367795dc92c14f828e093a1d97478214b2fb Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 3 Sep 2019 15:37:22 +0200 Subject: Coding style: put case bodies on separate lines from the case label While the single-line-case format is more readable when consistently applied through the whole switch, it works less well when several of the cases are too complex to fit on a single line. Change-Id: I6a84a3d3d1493dadddab103da0336a8ef860563c Reviewed-by: Volker Hilsheimer --- src/corelib/time/qdatetimeparser.cpp | 37 ++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp index 2f7cbb4017..24f3969851 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::max(); + return std::numeric_limits::max(); case CalendarPopupSection: case Internal: -- cgit v1.2.3 From 74a2467edd1bf0800cbaf1878984c6bccd42570d Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 21 Jan 2020 15:51:31 +0100 Subject: Add QFile::moveToTrash, which moves a file to the trash Due to the nature of QFile just operating on a file path, this also works for paths that are actually directories. The test covers files from different locations on which this operation should typically succeed, but tries to handle the case where trashing files will fail because of the file system structure. On Windows 7, running the test will open a confirmation dialog as the implementation of IFileOperation doesn't respect the various flags. This might depend on the specific Windows 7 patch level, and the option to always use SHFileOperation on that platform needs to be evaluated further. [ChangeLog][QtCore][QFile] Introduce QFile::moveToTrash to allow applications to move files to the trash. Change-Id: I45019040c25b30f7db293b6933c63aca2f319514 Fixes: QTBUG-47703 Reviewed-by: Vitaly Fanaskov --- src/corelib/io/qfile.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ src/corelib/io/qfile.h | 3 +++ 2 files changed, 60 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 5320ae2986..a516c6cd27 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -551,6 +551,63 @@ QFile::remove(const QString &fileName) return QFile(fileName).remove(); } +/*! + 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(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; +} + +/*! + \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); -- cgit v1.2.3 From c3050b6d96d636e53ead46c1009b83453565221c Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Sun, 26 Jan 2020 16:52:47 +0800 Subject: Rename Qt::ReturnByValue_t -> Qt::ReturnByValueConstant Copy the convention of QDeadlineTimer::ForeverConstant Task-number: QTBUG-48701 Change-Id: Ic7760b7ffec630f1cd47361f5adda3f17fffb9f6 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Lars Knoll --- src/corelib/global/qnamespace.h | 2 +- src/corelib/global/qnamespace.qdoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index ea2c635303..17ae73536d 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1770,7 +1770,7 @@ public: }; // 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 QT_Q_ENUM if a corresponding Q_Q_FLAG exists. diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 6a84662323..708ecb11ab 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -3334,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. -- cgit v1.2.3 From d75d22f785374b468cd56007b30864c52e896472 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 6 Feb 2020 10:48:40 +0100 Subject: Docs: tag newly added QFile and QFileInfo APIs as \since 5.15 Change-Id: I7d8605221a28cd05b4ebdbf20adf00ec3e121b58 Reviewed-by: Paul Wicking --- src/corelib/io/qfile.cpp | 3 +++ src/corelib/io/qfileinfo.cpp | 2 ++ 2 files changed, 5 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index a516c6cd27..0cdc5bd6d3 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -552,6 +552,8 @@ 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. @@ -586,6 +588,7 @@ QFile::moveToTrash() } /*! + \since 5.15 \overload Moves the file specified by fileName() to the trash. Returns \c true if successful, 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. -- cgit v1.2.3 From ef7773e5664dd8278831ed4d7d24dd4fc1aaefd3 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 30 Jan 2020 17:37:09 +0100 Subject: Doc: QPersistentModelIndex cannot be stored in a QStandardItem As discussed in the bug report, making sure that the reference counts are correct in such scenarios adds substantial complexity to the code, only to support a bad use-case for which QStandardItemModel was not designed. Change-Id: I663b490ed3471875386add17e7eadb7d8df50489 Fixes: QTBUG-78142 Reviewed-by: Paul Wicking --- src/corelib/itemmodels/qabstractitemmodel.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 6e97c2fd39..5caddf6aea 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -107,6 +107,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 */ -- cgit v1.2.3 From e79979ba40992d5ae8e12084f91c0d06f158a4df Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 6 Feb 2020 10:17:52 +0100 Subject: On Windows 7, fall back to SHFileOperation to avoid confirmation dialogs Moving a file to the trash should preferably done via IFileOperation. However, the implementation on Windows 7 ignores the operation flags that request the shell not to show any confirmation dialogs or other UI elements. SHFileOperation is an old API that doesn't show any UI, but has the limitation that it doesn't report the location of the file in the trash after the move. So an application cannot restore the file, but the user can do so via Explorer. Overall, the better compromise is to not have dialogs at the expense of not being able to report the new path. This allows us to run the unit test on Windows 7 as well. Change-Id: Ib8e651a69e2c6750f668b52d2a70925d156cc8ae Fixes: QTBUG-81927 Reviewed-by: Vitaly Fanaskov --- src/corelib/io/qfilesystemengine_win.cpp | 132 ++++++++++++++++--------------- 1 file changed, 69 insertions(+), 63 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 71a0e36693..36d43e9cb7 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1546,73 +1546,79 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, // 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(); + 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(sourcePath.utf16()), + nullptr, IID_PPV_ARGS(&deleteItem)); + if (!deleteItem) + return false; + sink = new FileOperationProgressSink; + hres = pfo->DeleteItem(deleteItem, static_cast(sink)); + if (!SUCCEEDED(hres)) + return false; + hres = pfo->PerformOperations(); if (!SUCCEEDED(hres)) - error = QSystemError(hres, QSystemError::NativeError); - }); + return false; + newLocation = QFileSystemEntry(sink->targetPath); - 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(sourcePath.utf16()), - nullptr, IID_PPV_ARGS(&deleteItem)); - if (!deleteItem) - return false; - sink = new FileOperationProgressSink; - hres = pfo->DeleteItem(deleteItem, static_cast(sink)); - if (!SUCCEEDED(hres)) - return false; - hres = pfo->PerformOperations(); - if (!SUCCEEDED(hres)) - return false; - newLocation = QFileSystemEntry(sink->targetPath); - -# else // no IFileOperation in SDK (mingw, likely) - fall back to SHFileOperation - - // double null termination needed, so can't use QString::utf16 - QVarLengthArray 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; +# endif // no IFileOperation in SDK (mingw, likely) - fall back to SHFileOperation + } else { + // double null termination needed, so can't use QString::utf16 + QVarLengthArray 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); } - /* - 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); -# endif // IFileOperation fallback return true; #else // Q_OS_WINRT -- cgit v1.2.3 From 2c189ac79b2000041bba85b21b667cedf7fffbd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 31 Jan 2020 12:50:19 +0100 Subject: QMultiMap: fix QDoc warning The iterator is a QMultiMap iterator, not QMap, so the QDoc would complain. Change-Id: I1e3d2b454e21049d676387945e1e860e50854de8 Reviewed-by: Lars Knoll --- src/corelib/tools/qmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') 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 typename QMap::iterator QMultiMap::insert(typename QMap::const_iterator pos, const Key &key, const T &value) +/*! \fn template typename QMultiMap::iterator QMultiMap::insert(typename QMultiMap::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 -- cgit v1.2.3 From 23d42a6a3088904f4d297a98e961fc520d156673 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 30 Jan 2020 12:53:39 -0800 Subject: QStorageInfo/Linux: resolve non-existent devices via /dev/block On systems with very simple boot sequences, the kernel will create a device called /dev/root and use that to mount the root filesystem. However, that doesn't actually exist in /dev and could cause confusion. So we try to resolve using /dev/block if the /dev entry does not exist but udev is in use (udevd has the string "/dev/%s/%u:%u"). [ChangeLog][QtCore][QStorageInfo] Improved discovery of device nodes on Linux if the /dev entry was renamed after the filesystem was mounted and udev is in use. Fixes: QTBUG-81464 Change-Id: If79a52e476594446baccfffd15eec573ae3deb0d Reviewed-by: Volker Hilsheimer Reviewed-by: Thiago Macieira --- src/corelib/io/qstorageinfo_unix.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src/corelib') 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 # include +# include #elif defined(Q_OS_SOLARIS) # include # include @@ -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(&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::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); } -- cgit v1.2.3 From 95577150167951c47f25071adade8562fbe91d25 Mon Sep 17 00:00:00 2001 From: Dmitriy Purgin Date: Tue, 7 Jan 2020 15:50:40 +0100 Subject: std::chrono overload added to QStateMachine::postDelayedEvent() Some Qt classes already accept std::chrono durations in their methods (see, for example, QTimer). The proposed change adds an overload with std::chrono::milliseconds to QStateMachine::postDelayedEvent(). Change-Id: I360fd2bb54fedc7415e9ec17e096095be3604d41 Reviewed-by: Erik Verbruggen --- src/corelib/statemachine/qstatemachine.cpp | 20 ++++++++++++++++++++ src/corelib/statemachine/qstatemachine.h | 11 +++++++++++ 2 files changed, 31 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 9d2505ba2e..a257cbc306 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -3273,6 +3273,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 #include +#if __has_include() +# include +#endif + QT_REQUIRE_CONFIG(statemachine); QT_BEGIN_NAMESPACE @@ -145,6 +149,13 @@ public: bool eventFilter(QObject *watched, QEvent *event) override; #endif +#if __has_include() || 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(); -- cgit v1.2.3 From b1089787d1dd9dd2b6b09a74923ea5f573d04bb2 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 26 Dec 2019 19:32:00 +0100 Subject: QMimeData: Extract Method QMimeDataPrivate::find() Centralize the search for the QMimeDataStruct with a given format in find() (overloaded on const and non-const, but implemented only once), and use it in the three other functions that performed lookup before. In setData(), optimize the case where data is overwritten. Use a std::vector to not have to think about hidden detaches when implementing the const find() in terms of the non-const one. Change-Id: I874e5c6ef9c97d98b42f29faccbc3043e8c6a855 Reviewed-by: David Faure --- src/corelib/kernel/qmimedata.cpp | 53 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 25 deletions(-) (limited to 'src/corelib') 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 dataList; + std::vector::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::const_iterator find(const QString &format) const noexcept { + return const_cast(this)->find(format); + } + + std::vector dataList; }; void QMimeDataPrivate::removeData(const QString &format) { - for (int i=0; idata = data; } QVariant QMimeDataPrivate::getData(const QString &format) const { - QVariant data; - for (int i=0; idata; } 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(d->dataList.size())); + for (auto &e : d->dataList) + list += e.format; return list; } -- cgit v1.2.3 From dce61f04503d6730b954b153395cc3f9ce5d7c24 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 23 Jan 2020 12:02:06 +0100 Subject: QTranslator: Expose origin file of the translation Task-number: QTBUG-36608 Change-Id: I8ef0968404370b8fc25dc8b4c1e2c9e4484ae55c Reviewed-by: Oswald Buddenhagen Reviewed-by: Simon Hausmann --- src/corelib/kernel/qtranslator.cpp | 23 ++++++++++++++++++++++- src/corelib/kernel/qtranslator.h | 2 ++ 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 93d75feafa..822f96c499 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -316,6 +316,8 @@ public: uint contextLength; uint numerusRulesLength; + 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 +599,10 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo } } - if (ok && d->do_load(reinterpret_cast(d->unmapPointer), d->unmapLength, directory)) + if (ok && d->do_load(reinterpret_cast(d->unmapPointer), d->unmapLength, directory)) { + d->filePath = realname; return true; + } #if defined(QT_USE_MMAP) if (used_mmap) { @@ -1091,6 +1095,8 @@ void QTranslatorPrivate::clear() qDeleteAll(subTranslators); subTranslators.clear(); + filePath.clear(); + if (QCoreApplicationPrivate::isTranslatorInstalled(q)) QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::LanguageChange)); @@ -1132,6 +1138,21 @@ bool QTranslator::isEmpty() const && d->subTranslators.isEmpty(); } +/*! + \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..0c6efbbc7f 100644 --- a/src/corelib/kernel/qtranslator.h +++ b/src/corelib/kernel/qtranslator.h @@ -63,6 +63,8 @@ public: virtual bool isEmpty() const; + QString filePath() const; + bool load(const QString & filename, const QString & directory = QString(), const QString & search_delimiters = QString(), -- cgit v1.2.3 From e541a3f099798e2258116d3c031b35274d789783 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 30 Jan 2020 11:08:50 +0100 Subject: QTranslator: Expose language of translation file This allows for instance to show the current UI language in the UI, or to load additional translations that match the .qm file by other means. This is especially useful in the case of QTranslator::load(QLocale(), ...), in which case different language and country combinations might be tried. Another option is to inspect the file name via QTranslator::filePath(); however, this is more error-prone, and might also miss information (if the .qm file name doesn't have a country suffix, or no suffix at all). Change-Id: I6f565d53d8f50e21241ccae6c4de264747ac8f81 Reviewed-by: Simon Hausmann --- src/corelib/kernel/qtranslator.cpp | 19 +++++++++++++++++-- src/corelib/kernel/qtranslator.h | 1 + 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 822f96c499..2205366696 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,7 @@ public: uint contextLength; uint numerusRulesLength; + QString language; QString filePath; bool do_load(const QString &filename, const QString &directory); @@ -833,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) { @@ -1095,6 +1098,7 @@ void QTranslatorPrivate::clear() qDeleteAll(subTranslators); subTranslators.clear(); + language.clear(); filePath.clear(); if (QCoreApplicationPrivate::isTranslatorInstalled(q)) @@ -1138,6 +1142,17 @@ 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 diff --git a/src/corelib/kernel/qtranslator.h b/src/corelib/kernel/qtranslator.h index 0c6efbbc7f..61a39c4089 100644 --- a/src/corelib/kernel/qtranslator.h +++ b/src/corelib/kernel/qtranslator.h @@ -63,6 +63,7 @@ public: virtual bool isEmpty() const; + QString language() const; QString filePath() const; bool load(const QString & filename, -- cgit v1.2.3