From c20920fbe150275e12e864db79dd9665b322b0f7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 18 Jan 2016 13:22:35 +0100 Subject: QFutureInterface: add missing mutex lock to progress getters These variables are accessed from both the executing thread as well as the thread waiting for results. Note for some variables which threads access them. Change-Id: I1c84ddff92585abb32341c42072106066e485f7e Reviewed-by: Thiago Macieira --- src/corelib/thread/qfutureinterface.cpp | 3 +++ src/corelib/thread/qfutureinterface_p.h | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index 05c4371a58..60155c96fd 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -193,16 +193,19 @@ void QFutureInterfaceBase::waitForResume() int QFutureInterfaceBase::progressValue() const { + const QMutexLocker lock(&d->m_mutex); return d->m_progressValue; } int QFutureInterfaceBase::progressMinimum() const { + const QMutexLocker lock(&d->m_mutex); return d->m_progressMinimum; } int QFutureInterfaceBase::progressMaximum() const { + const QMutexLocker lock(&d->m_mutex); return d->m_progressMaximum; } diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h index 2321ce8d72..e2d588cd07 100644 --- a/src/corelib/thread/qfutureinterface_p.h +++ b/src/corelib/thread/qfutureinterface_p.h @@ -146,18 +146,20 @@ public: QAtomicInt m_refCountT; }; + // T: accessed from executing thread + // Q: accessed from the waiting/querying thread RefCount refCount; mutable QMutex m_mutex; QWaitCondition waitCondition; QList outputConnections; - int m_progressValue; - int m_progressMinimum; - int m_progressMaximum; + int m_progressValue; // TQ + int m_progressMinimum; // TQ + int m_progressMaximum; // TQ QFutureInterfaceBase::State state; QElapsedTimer progressTime; QWaitCondition pausedWaitCondition; QtPrivate::ResultStoreBase m_results; - bool manualProgress; + bool manualProgress; // only accessed from executing thread int m_expectedResultCount; QtPrivate::ExceptionStore m_exceptionStore; QString m_progressText; -- cgit v1.2.3 From 088eef57566cb59b9c3b10e218a80b0516cb7e8a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 25 Jan 2016 19:59:51 +0100 Subject: QStringBuilder: fix appending QLatin1String to QByteArray The old code did the equivalent of strcpy(), thus stopping at the first NUL byte, ignoring the QLatin1String's size(). That is not acceptable, for two reasons: 1. Appending QLatin1String to a QString uses the size(), too. 2. The QConcatenable claims an ExactSize = true, so it cannot go and write less data than it's own size() said it would. Even worse, it will happily write _more_ data, too, if the QLatin1String is not properly zero-terminated. This change has low risk, because the equivalent change to the QString branch has been applied between 5.2 and 5.3 (in fd0f1bc3), with no complaints from the user base. It is also in a branch that is very unlikely to be taken: Since QConcatenable is setting ConvertTo to QString, any QStringBuilder expression containing it will only implicitly convert to QString, not QByteArray. In fact, I don't even know how to make it invoke the changed code in normal operation... Change-Id: I486a76352af7f318ba05da845d3afee7d826c92a Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Lars Knoll --- src/corelib/tools/qstringbuilder.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 3d41aeee18..69bd344f47 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -236,9 +236,9 @@ template <> struct QConcatenable : private QAbstractConcatenable } static inline void appendTo(const QLatin1String a, char *&out) { - if (a.data()) { - for (const char *s = a.data(); *s; ) - *out++ = *s++; + if (const char *data = a.data()) { + memcpy(out, data, a.size()); + out += a.size(); } } }; -- cgit v1.2.3 From 97b448b152f0148adb2426c2a4e1f83dd150db3c Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 26 Jan 2016 12:06:40 +0300 Subject: Use QFile::exists(f) instead of QFile(f).exists(). It's faster. Change-Id: Ie57619b4e0c53975aa955c83c833c34e1446e4c8 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index ce1684a943..4474fd3f52 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -747,7 +747,7 @@ QFile::copy(const QString &newName) qWarning("QFile::copy: Empty or null file name"); return false; } - if (QFile(newName).exists()) { + if (QFile::exists(newName)) { // ### Race condition. If a file is moved in after this, it /will/ be // overwritten. On Unix, the proper solution is to use hardlinks: // return ::link(old, new) && ::remove(old); See also rename(). -- cgit v1.2.3 From 3a30a2fcb3f026ffba4d9484ad92479419d79547 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 19 Jan 2016 13:29:15 +0100 Subject: Allow QFinalStatePrivate to be subclassed. - put it in a separate private header - add a protected QFinalState constructor that takes a QFinalStatePrivate - when passing through, also export QStatePrivate, so the linker can find the symbol Change-Id: I8563da16739731d9d6142be438a8769fc29de148 Reviewed-by: Marc Mutz --- src/corelib/statemachine/qfinalstate.cpp | 26 +++++++----- src/corelib/statemachine/qfinalstate.h | 4 +- src/corelib/statemachine/qfinalstate_p.h | 68 +++++++++++++++++++++++++++++++ src/corelib/statemachine/qstate.cpp | 3 +- src/corelib/statemachine/qstate_p.h | 7 +++- src/corelib/statemachine/statemachine.pri | 1 + 6 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 src/corelib/statemachine/qfinalstate_p.h (limited to 'src/corelib') diff --git a/src/corelib/statemachine/qfinalstate.cpp b/src/corelib/statemachine/qfinalstate.cpp index ea96cc64c4..7e159ec1d1 100644 --- a/src/corelib/statemachine/qfinalstate.cpp +++ b/src/corelib/statemachine/qfinalstate.cpp @@ -31,12 +31,10 @@ ** ****************************************************************************/ -#include "qfinalstate.h" +#include "qfinalstate_p.h" #ifndef QT_NO_STATEMACHINE -#include "qabstractstate_p.h" - QT_BEGIN_NAMESPACE /*! @@ -76,19 +74,16 @@ QT_BEGIN_NAMESPACE \sa QState::finished() */ -class QFinalStatePrivate : public QAbstractStatePrivate -{ - Q_DECLARE_PUBLIC(QFinalState) - -public: - QFinalStatePrivate(); -}; - QFinalStatePrivate::QFinalStatePrivate() : QAbstractStatePrivate(FinalState) { } +QFinalStatePrivate::~QFinalStatePrivate() +{ + // to prevent vtables being generated in every file that includes the private header +} + /*! Constructs a new QFinalState object with the given \a parent state. */ @@ -97,6 +92,15 @@ QFinalState::QFinalState(QState *parent) { } +/*! + \internal + */ +QFinalState::QFinalState(QFinalStatePrivate &dd, QState *parent) + : QAbstractState(dd, parent) +{ +} + + /*! Destroys this final state. */ diff --git a/src/corelib/statemachine/qfinalstate.h b/src/corelib/statemachine/qfinalstate.h index 2c76e7b6e6..74f73d559c 100644 --- a/src/corelib/statemachine/qfinalstate.h +++ b/src/corelib/statemachine/qfinalstate.h @@ -38,7 +38,6 @@ QT_BEGIN_NAMESPACE - #ifndef QT_NO_STATEMACHINE class QFinalStatePrivate; @@ -55,6 +54,9 @@ protected: bool event(QEvent *e) Q_DECL_OVERRIDE; +protected: + explicit QFinalState(QFinalStatePrivate &dd, QState *parent); + private: Q_DISABLE_COPY(QFinalState) Q_DECLARE_PRIVATE(QFinalState) diff --git a/src/corelib/statemachine/qfinalstate_p.h b/src/corelib/statemachine/qfinalstate_p.h new file mode 100644 index 0000000000..74640289f1 --- /dev/null +++ b/src/corelib/statemachine/qfinalstate_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFINALSTATE_P_H +#define QFINALSTATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qfinalstate.h" +#include "private/qabstractstate_p.h" + +#ifndef QT_NO_STATEMACHINE + +QT_BEGIN_NAMESPACE + +class Q_CORE_EXPORT QFinalStatePrivate : public QAbstractStatePrivate +{ + Q_DECLARE_PUBLIC(QFinalState) + +public: + QFinalStatePrivate(); + ~QFinalStatePrivate(); +}; + +QT_END_NAMESPACE + +#endif // QT_NO_STATEMACHINE + +#endif // QFINALSTATE_P_H diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index 3b84230cb2..cad524c720 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -31,11 +31,10 @@ ** ****************************************************************************/ -#include "qstate.h" +#include "qstate_p.h" #ifndef QT_NO_STATEMACHINE -#include "qstate_p.h" #include "qhistorystate.h" #include "qhistorystate_p.h" #include "qabstracttransition.h" diff --git a/src/corelib/statemachine/qstate_p.h b/src/corelib/statemachine/qstate_p.h index 3b8dae9499..938822bcda 100644 --- a/src/corelib/statemachine/qstate_p.h +++ b/src/corelib/statemachine/qstate_p.h @@ -45,6 +45,7 @@ // We mean it. // +#include "qstate.h" #include "private/qabstractstate_p.h" #include @@ -52,6 +53,8 @@ #include #include +#ifndef QT_NO_STATEMACHINE + QT_BEGIN_NAMESPACE #ifndef QT_NO_PROPERTIES @@ -83,7 +86,7 @@ class QAbstractTransition; class QHistoryState; class QState; -class Q_AUTOTEST_EXPORT QStatePrivate : public QAbstractStatePrivate +class Q_CORE_EXPORT QStatePrivate : public QAbstractStatePrivate { Q_DECLARE_PUBLIC(QState) public: @@ -115,4 +118,6 @@ public: QT_END_NAMESPACE +#endif // QT_NO_STATEMACHINE + #endif diff --git a/src/corelib/statemachine/statemachine.pri b/src/corelib/statemachine/statemachine.pri index 910cf5e9b3..c5396a2ef8 100644 --- a/src/corelib/statemachine/statemachine.pri +++ b/src/corelib/statemachine/statemachine.pri @@ -6,6 +6,7 @@ HEADERS += $$PWD/qstatemachine.h \ $$PWD/qstate.h \ $$PWD/qstate_p.h \ $$PWD/qfinalstate.h \ + $$PWD/qfinalstate_p.h \ $$PWD/qhistorystate.h \ $$PWD/qhistorystate_p.h \ $$PWD/qabstracttransition.h \ -- cgit v1.2.3 From 7236721bf8bacc0978fc872d7e4805c7be7824f0 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 26 Jan 2016 23:11:20 +0100 Subject: QJsonObject has random-access iterators ... but they were only marked as bidirectional. Fixed. This change is slightly BiC, because if some class used tag dispatching on this iterator type, a recompile might now pick a different overload, and the old one may not be available to a user anymore (no longer instantiated). I do not think Qt uses that technique, yet, though. Not on iterator categories, at least. Change-Id: I75fb334af7e191f882d11575dec83c879a6b50ee Reviewed-by: Thiago Macieira --- src/corelib/json/qjsonobject.cpp | 14 ++++++++++---- src/corelib/json/qjsonobject.h | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index c225606717..27f937e750 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -679,8 +679,11 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const /*! \typedef QJsonObject::iterator::iterator_category - A synonym for \e {std::bidirectional_iterator_tag} indicating - this iterator is a bidirectional iterator. + A synonym for \e {std::random_access_iterator_tag} indicating + this iterator is a random-access iterator. + + \note In Qt versions before 5.6, this was set by mistake to + \e {std::bidirectional_iterator_tag}. */ /*! \typedef QJsonObject::iterator::reference @@ -886,8 +889,11 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const /*! \typedef QJsonObject::const_iterator::iterator_category - A synonym for \e {std::bidirectional_iterator_tag} indicating - this iterator is a bidirectional iterator. + A synonym for \e {std::random_access_iterator_tag} indicating + this iterator is a random-access iterator. + + \note In Qt versions before 5.6, this was set by mistake to + \e {std::bidirectional_iterator_tag}. */ /*! \typedef QJsonObject::const_iterator::reference diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h index 5b475f52ae..8535da4a6c 100644 --- a/src/corelib/json/qjsonobject.h +++ b/src/corelib/json/qjsonobject.h @@ -100,7 +100,7 @@ public: int i; public: - typedef std::bidirectional_iterator_tag iterator_category; + typedef std::random_access_iterator_tag iterator_category; typedef int difference_type; typedef QJsonValue value_type; typedef QJsonValueRef reference; @@ -143,7 +143,7 @@ public: int i; public: - typedef std::bidirectional_iterator_tag iterator_category; + typedef std::random_access_iterator_tag iterator_category; typedef int difference_type; typedef QJsonValue value_type; typedef QJsonValue reference; -- cgit v1.2.3 From 910f719bd111813f37278b67d07f9d12cb03a4ff Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 26 Jan 2016 10:44:28 +0100 Subject: Refactor QStandardPaths for Desktop Windows. Replace the large switch in QStandardPaths::writableLocation() by a function mapping QStandardPaths::StandardLocation to the int clsid required by SHGetSpecialFolderPath(). Warn if SHGetSpecialFolderPath() fails for config location and append prefixes (cache/application name/organization) only on success. Change the logic in QStandardPaths::standardLocations() to append the writable location first, avoiding the prepend(). Task-number: QTBUG-50570 Change-Id: I9d80e83d1ca7af3ea8d3ac2c720ee981b1b2c32a Reviewed-by: Joerg Bornemann --- src/corelib/io/qstandardpaths_win.cpp | 258 +++++++++++++++++++--------------- 1 file changed, 143 insertions(+), 115 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index ed1c14ad8a..73d49cbc25 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -41,9 +41,7 @@ #include #endif -#if !defined(Q_OS_WINCE) const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } }; -#endif #include #include @@ -64,113 +62,152 @@ const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x6 QT_BEGIN_NAMESPACE -#if !defined(Q_OS_WINCE) -typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*); -#endif - static QString convertCharArray(const wchar_t *path) { return QDir::fromNativeSeparators(QString::fromWCharArray(path)); } -static inline int clsidForAppDataLocation(QStandardPaths::StandardLocation type) +static inline bool isGenericConfigLocation(QStandardPaths::StandardLocation type) { -#ifndef Q_OS_WINCE - return type == QStandardPaths::AppDataLocation ? - CSIDL_APPDATA : // "Roaming" path - CSIDL_LOCAL_APPDATA; // Local path -#else - Q_UNUSED(type) - return CSIDL_APPDATA; -#endif + return type == QStandardPaths::GenericConfigLocation || type == QStandardPaths::GenericDataLocation; } -QString QStandardPaths::writableLocation(StandardLocation type) +static inline bool isConfigLocation(QStandardPaths::StandardLocation type) { - QString result; + return type == QStandardPaths::ConfigLocation || type == QStandardPaths::AppConfigLocation + || type == QStandardPaths::AppDataLocation || type == QStandardPaths::AppLocalDataLocation + || isGenericConfigLocation(type); +} -#if !defined(Q_OS_WINCE) - static GetKnownFolderPath SHGetKnownFolderPath = (GetKnownFolderPath)QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath"); +static void appendOrganizationAndApp(QString &path) // Courtesy qstandardpaths_unix.cpp +{ +#ifndef QT_BOOTSTRAPPED + const QString &org = QCoreApplication::organizationName(); + if (!org.isEmpty()) + path += QLatin1Char('/') + org; + const QString &appName = QCoreApplication::applicationName(); + if (!appName.isEmpty()) + path += QLatin1Char('/') + appName; +#else // !QT_BOOTSTRAPPED + Q_UNUSED(path) #endif +} - wchar_t path[MAX_PATH]; - - switch (type) { - case ConfigLocation: // same as AppLocalDataLocation, on Windows - case GenericConfigLocation: // same as GenericDataLocation on Windows - case AppConfigLocation: - case AppDataLocation: - case AppLocalDataLocation: - case GenericDataLocation: - if (SHGetSpecialFolderPath(0, path, clsidForAppDataLocation(type), FALSE)) - result = convertCharArray(path); - if (isTestModeEnabled()) - result += QLatin1String("/qttest"); +static inline QString displayName(QStandardPaths::StandardLocation type) +{ #ifndef QT_BOOTSTRAPPED - if (type != GenericDataLocation && type != GenericConfigLocation) { - if (!QCoreApplication::organizationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::organizationName(); - if (!QCoreApplication::applicationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::applicationName(); - } + return QStandardPaths::displayName(type); +#else + return QString::number(type); #endif - break; +} - case DesktopLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, FALSE)) - result = convertCharArray(path); - break; +static inline void appendTestMode(QString &path) +{ + if (QStandardPaths::isTestModeEnabled()) + path += QLatin1String("/qttest"); +} - case DownloadLocation: -#if !defined(Q_OS_WINCE) - if (SHGetKnownFolderPath) { - LPWSTR path; - if (SHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, 0, 0, &path) == S_OK) { - result = convertCharArray(path); - CoTaskMemFree(path); - } - break; +// Map QStandardPaths::StandardLocation to CLSID of SHGetSpecialFolderPath() +static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type) +{ + static const int clsids[] = { + CSIDL_DESKTOPDIRECTORY, // DesktopLocation + CSIDL_PERSONAL, // DocumentsLocation + CSIDL_FONTS, // FontsLocation + CSIDL_PROGRAMS, // ApplicationsLocation + CSIDL_MYMUSIC, // MusicLocation + CSIDL_MYVIDEO, // MoviesLocation + CSIDL_MYPICTURES, // PicturesLocation + -1, -1, // TempLocation/HomeLocation + CSIDL_LOCAL_APPDATA, // AppLocalDataLocation ("Local" path), AppLocalDataLocation = DataLocation + -1, // CacheLocation + CSIDL_LOCAL_APPDATA, // GenericDataLocation ("Local" path) + -1, // RuntimeLocation + CSIDL_LOCAL_APPDATA, // ConfigLocation ("Local" path) + -1, -1, // DownloadLocation/GenericCacheLocation + CSIDL_LOCAL_APPDATA, // GenericConfigLocation ("Local" path) + CSIDL_APPDATA, // AppDataLocation ("Roaming" path) + CSIDL_LOCAL_APPDATA, // AppConfigLocation ("Local" path) + }; + + Q_STATIC_ASSERT(sizeof(clsids) / sizeof(clsids[0]) == size_t(QStandardPaths::AppConfigLocation + 1)); + return size_t(type) < sizeof(clsids) / sizeof(clsids[0]) ? clsids[type] : -1; +}; + +// Convenience for SHGetSpecialFolderPath(). +static QString sHGetSpecialFolderPath(int clsid, QStandardPaths::StandardLocation type, bool warn = false) +{ + QString result; + wchar_t path[MAX_PATH]; + if (Q_LIKELY(clsid >= 0 && SHGetSpecialFolderPath(0, path, clsid, FALSE))) { + result = convertCharArray(path); + } else { + if (warn) { + qErrnoWarning("SHGetSpecialFolderPath() failed for standard location \"%s\", clsid=0x%x.", + qPrintable(displayName(type)), clsid); } -#endif - // fall through - case DocumentsLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE)) - result = convertCharArray(path); - break; - - case FontsLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_FONTS, FALSE)) - result = convertCharArray(path); - break; - - case ApplicationsLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_PROGRAMS, FALSE)) - result = convertCharArray(path); - break; - - case MusicLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYMUSIC, FALSE)) - result = convertCharArray(path); - break; + } + return result; +} - case MoviesLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYVIDEO, FALSE)) - result = convertCharArray(path); - break; +// Convenience for SHGetKnownFolderPath(). +static QString sHGetKnownFolderPath(const GUID &clsid, QStandardPaths::StandardLocation type, bool warn = false) +{ + QString result; +#ifndef Q_OS_WINCE + typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*); + + static const GetKnownFolderPath sHGetKnownFolderPath = // Vista onwards. + reinterpret_cast(QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath")); + + LPWSTR path; + if (Q_LIKELY(sHGetKnownFolderPath && SUCCEEDED(sHGetKnownFolderPath(clsid, 0, 0, &path)))) { + result = convertCharArray(path); + CoTaskMemFree(path); + } else { + if (warn) { + qErrnoWarning("SHGetKnownFolderPath() failed for standard location \"%s\".", + qPrintable(displayName(type))); + } + } +#else // !Q_OS_WINCE + Q_UNUSED(clsid) + Q_UNUSED(type) + Q_UNUSED(warn) +#endif + return result; +} - case PicturesLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_MYPICTURES, FALSE)) - result = convertCharArray(path); +QString QStandardPaths::writableLocation(StandardLocation type) +{ + QString result; + switch (type) { + case DownloadLocation: + result = sHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, type); + if (result.isEmpty()) + result = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); break; case CacheLocation: // Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache // location for everyone. Most applications seem to be using a // cache directory located in their AppData directory - return writableLocation(AppLocalDataLocation) + QLatin1String("/cache"); + result = sHGetSpecialFolderPath(writableSpecialFolderClsid(AppLocalDataLocation), type, /* warn */ true); + if (!result.isEmpty()) { + appendTestMode(result); + appendOrganizationAndApp(result); + result += QLatin1String("/cache"); + } + break; case GenericCacheLocation: - return writableLocation(GenericDataLocation) + QLatin1String("/cache"); + result = sHGetSpecialFolderPath(writableSpecialFolderClsid(GenericDataLocation), type, /* warn */ true); + if (!result.isEmpty()) { + appendTestMode(result); + result += QLatin1String("/cache"); + } + break; case RuntimeLocation: case HomeLocation: @@ -180,6 +217,15 @@ QString QStandardPaths::writableLocation(StandardLocation type) case TempLocation: result = QDir::tempPath(); break; + + default: + result = sHGetSpecialFolderPath(writableSpecialFolderClsid(type), type, /* warn */ isConfigLocation(type)); + if (!result.isEmpty() && isConfigLocation(type)) { + appendTestMode(result); + if (!isGenericConfigLocation(type)) + appendOrganizationAndApp(result); + } + break; } return result; } @@ -187,44 +233,26 @@ QString QStandardPaths::writableLocation(StandardLocation type) QStringList QStandardPaths::standardLocations(StandardLocation type) { QStringList dirs; + const QString localDir = writableLocation(type); + if (!localDir.isEmpty()) + dirs.append(localDir); // type-specific handling goes here - #ifndef Q_OS_WINCE - { - wchar_t path[MAX_PATH]; - switch (type) { - case ConfigLocation: // same as AppLocalDataLocation, on Windows (oversight, but too late to fix it) - case GenericConfigLocation: // same as GenericDataLocation, on Windows - case AppConfigLocation: // same as AppLocalDataLocation, that one on purpose - case AppDataLocation: - case AppLocalDataLocation: - case GenericDataLocation: - if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) { - QString result = convertCharArray(path); - if (type != GenericDataLocation && type != GenericConfigLocation) { -#ifndef QT_BOOTSTRAPPED - if (!QCoreApplication::organizationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::organizationName(); - if (!QCoreApplication::applicationName().isEmpty()) - result += QLatin1Char('/') + QCoreApplication::applicationName(); -#endif - } - dirs.append(result); -#ifndef QT_BOOTSTRAPPED - dirs.append(QCoreApplication::applicationDirPath()); - dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data")); -#endif - } - break; - default: - break; + if (isConfigLocation(type)) { + QString programData = sHGetSpecialFolderPath(CSIDL_COMMON_APPDATA, type); + if (!programData.isEmpty()) { + if (!isGenericConfigLocation(type)) + appendOrganizationAndApp(programData); + dirs.append(programData); } - } -#endif +# ifndef QT_BOOTSTRAPPED + dirs.append(QCoreApplication::applicationDirPath()); + dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data")); +# endif // !QT_BOOTSTRAPPED + } // isConfigLocation() +#endif // !Q_OS_WINCE - const QString localDir = writableLocation(type); - dirs.prepend(localDir); return dirs; } -- cgit v1.2.3 From 54ece34283f0eea4181772d6ce5fcd16c96a8962 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 18 Jan 2016 13:33:22 +0100 Subject: Avoid shadowing in QDateTimeParser::findAmPm. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A parameter was called index; but an inner block re-used that name. Rename the parameter. Change-Id: I2fa18f32aa129c5b1d8de6c4b6571438eeefea14 Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qdatetimeparser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 9ca2e1ffc0..c604b977c7 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1371,9 +1371,9 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex */ -int QDateTimeParser::findAmPm(QString &str, int index, int *used) const +int QDateTimeParser::findAmPm(QString &str, int sectionIndex, int *used) const { - const SectionNode &s = sectionNode(index); + const SectionNode &s = sectionNode(sectionIndex); if (s.type != AmPmSection) { qWarning("QDateTimeParser::findAmPm Internal error"); return -1; @@ -1384,7 +1384,7 @@ int QDateTimeParser::findAmPm(QString &str, int index, int *used) const return PossibleBoth; } const QLatin1Char space(' '); - int size = sectionMaxSize(index); + int size = sectionMaxSize(sectionIndex); enum { amindex = 0, -- cgit v1.2.3 From fbe7000ba3fa1edbeeaacaa529c25510d69f3472 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 18 Jan 2016 14:19:54 +0100 Subject: Make initializers into declare-and-initialize. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminates separate declaration line, makes unambiguous that all are initialized. Change-Id: Ib419a385b38f98070c06428da246d4580b0a0dbc Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qdatetimeparser.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index c604b977c7..1ffdf8e9ab 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -125,14 +125,13 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const } const SectionNode &node = sectionNodes.at(index); - int year, month, day, hour, minute, second, msec; - year = v.date().year(); - month = v.date().month(); - day = v.date().day(); - hour = v.time().hour(); - minute = v.time().minute(); - second = v.time().second(); - msec = v.time().msec(); + int year = v.date().year(); + int month = v.date().month(); + int day = v.date().day(); + int hour = v.time().hour(); + int minute = v.time().minute(); + int second = v.time().second(); + int msec = v.time().msec(); switch (node.type) { case Hour24Section: case Hour12Section: hour = newVal; break; -- cgit v1.2.3 From ee6463ffd3d12f9d5b4c90d22ca9fcab30483ebc Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 18 Jan 2016 17:20:48 +0100 Subject: Refactor one QDateTimeParser::sectionText() via the other. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid duplicated code thereby. Change-Id: Icb4e95887e92e8fe8f172329cc383f9e868874a4 Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qdatetimeparser.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 1ffdf8e9ab..26c17b24ce 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -669,15 +669,7 @@ QString QDateTimeParser::sectionText(const QString &text, int sectionIndex, int QString QDateTimeParser::sectionText(int sectionIndex) const { const SectionNode &sn = sectionNode(sectionIndex); - switch (sn.type) { - case NoSectionIndex: - case FirstSectionIndex: - case LastSectionIndex: - return QString(); - default: break; - } - - return displayText().mid(sn.pos, sectionSize(sectionIndex)); + return sectionText(displayText(), sectionIndex, sn.pos); } -- cgit v1.2.3 From 2736d7921dfcedaa88382e8279dc23e9b1fd3214 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 19 Jan 2016 19:34:52 +0100 Subject: Don't let a good day cause date-time parser to forget a conflict. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting conflicts to isSet & DaySection cleared it if we hadn't seen the day stipulated, even if there had been a conflict (e.g. over year) before we hit the day-of-week that didn't match the (unset, so defaulting to) 1st of the month. Explicitly test for conflict and only set conflicts (to true) if there is a conflict. Added regression test. Change-Id: I7363eb66a8bb808d341738d14969039834f50db8 Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qdatetimeparser.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 26c17b24ce..cf4fcd4929 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -997,8 +997,10 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos const QDate date(year, month, day); const int diff = dayofweek - date.dayOfWeek(); - if (diff != 0 && state == Acceptable && isSet & (DayOfWeekSectionShort|DayOfWeekSectionLong)) { - conflicts = isSet & DaySection; + if (diff != 0 && state == Acceptable + && isSet & (DayOfWeekSectionShort | DayOfWeekSectionLong)) { + if (isSet & DaySection) + conflicts = true; const SectionNode &sn = sectionNode(currentSectionIndex); if (sn.type & (DayOfWeekSectionShort|DayOfWeekSectionLong) || currentSectionIndex == -1) { // dayofweek should be preferred -- cgit v1.2.3 From c459ea84c4abb1bc68bc76dbbd4889a0f5bf4125 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 20 Jan 2016 14:27:23 +0100 Subject: Set correct Section type for QDateTimeParser::last MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting it to FirstSection was obviously wrong and left LastSection nowhere set ... Change-Id: I26260182e9d986b41b5f3a5d6df94540a5fc116a Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qdatetimeparser_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h index a1cf8f283f..c96def6046 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -87,7 +87,7 @@ public: first.pos = -1; first.count = -1; first.zeroesAdded = 0; - last.type = FirstSection; + last.type = LastSection; last.pos = -1; last.count = -1; last.zeroesAdded = 0; -- cgit v1.2.3 From 0ec1e13234684feb632fc980ba2a90db9a2dd936 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 9 Apr 2015 16:17:37 +0200 Subject: Do not build QWindowsPipeWriter on Windows CE QWindowsPipeWriter is not used in the Windows CE port. Change-Id: I068dd2408bb21a7e2a86886e0692b1636016ff6a Reviewed-by: Andreas Holzammer --- src/corelib/io/io.pri | 6 +++--- src/corelib/io/qprocess_wince.cpp | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index b2bcbdf727..8d9908cd90 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -107,8 +107,6 @@ win32 { !winrt { SOURCES += io/qsettings_win.cpp - HEADERS += io/qwindowspipewriter_p.h - SOURCES += io/qwindowspipewriter.cpp SOURCES += io/qstandardpaths_win.cpp wince* { @@ -117,11 +115,13 @@ win32 { } else { HEADERS += \ io/qwinoverlappedionotifier_p.h \ - io/qwindowspipereader_p.h + io/qwindowspipereader_p.h \ + io/qwindowspipewriter_p.h SOURCES += \ io/qprocess_win.cpp \ io/qwinoverlappedionotifier.cpp \ io/qwindowspipereader.cpp \ + io/qwindowspipewriter.cpp \ io/qstorageinfo_win.cpp LIBS += -lmpr } diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index acacdb8540..050d6879db 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -33,7 +33,6 @@ #include "qprocess.h" #include "qprocess_p.h" -#include "qwindowspipewriter_p.h" #include #include @@ -156,7 +155,7 @@ void QProcessPrivate::startProcess() } // give the process a chance to start ... - Sleep(SLEEPMIN * 2); + Sleep(20); _q_startupNotification(); } -- cgit v1.2.3 From 7c797b4905cd80a863bbdf635d5e2306ac6b57ef Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 21 Jan 2016 16:35:22 +0100 Subject: Bump copyright year to 2016 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bump copyright year in tool output and user visible strings to 2016. Task-number: QTBUG-50578 Change-Id: I2f4aa9089c6672726f554cba7e6009b425d27683 Reviewed-by: Liang Qi Reviewed-by: Topi Reiniö Reviewed-by: Martin Smith --- src/corelib/global/qlibraryinfo.cpp | 2 +- src/corelib/kernel/qtcore_eval.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 0cfcc4e659..b0c7c65c1b 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -647,7 +647,7 @@ extern "C" void qt_core_boilerplate(); void qt_core_boilerplate() { printf("This is the QtCore library version " QT_BUILD_STR "\n" - "Copyright (C) 2015 The Qt Company Ltd.\n" + "Copyright (C) 2016 The Qt Company Ltd.\n" "Contact: http://www.qt.io/licensing/\n" "\n" "Installation prefix: %s\n" diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp index 0dd0e64977..60873b5616 100644 --- a/src/corelib/kernel/qtcore_eval.cpp +++ b/src/corelib/kernel/qtcore_eval.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE static const char boilerplate_supported_but_time_limited[] = "\nQt %1 Evaluation License\n" - "Copyright (C) 2015 The Qt Company Ltd.\n" + "Copyright (C) 2016 The Qt Company Ltd.\n" "This trial version may only be used for evaluation purposes\n" "and will shut down after 120 minutes.\n" "Registered to:\n" @@ -57,7 +57,7 @@ static const char boilerplate_supported_but_time_limited[] = static const char boilerplate_supported[] = "\nQt %1 Evaluation License\n" - "Copyright (C) 2015 The Qt Company Ltd.\n" + "Copyright (C) 2016 The Qt Company Ltd.\n" "This trial version may only be used for evaluation purposes\n" "Registered to:\n" " Licensee: %2\n\n" -- cgit v1.2.3 From 164c631d807d80a7dc2b19b8c55bc83734be9312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 26 Jan 2016 12:32:57 +0100 Subject: Move Cocoa key code helper functions to QtCore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Can be useful for e.g. testlib for handling native key events. Change-Id: I6560c6e28799e25eb3bdcaa0f2ca3c17644c62db Reviewed-by: Jake Petroules Reviewed-by: Tor Arne Vestbø --- src/corelib/kernel/qcore_mac_objc.mm | 148 +++++++++++++++++++++++++++++++++++ src/corelib/kernel/qcore_mac_p.h | 5 ++ 2 files changed, 153 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 14c0f803b9..798307f8ab 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -34,6 +34,11 @@ #include +#ifdef Q_OS_OSX +#include +#include +#endif + #include #ifdef Q_OS_IOS @@ -148,5 +153,148 @@ QMacAutoReleasePool::~QMacAutoReleasePool() // ------------------------------------------------------------------------- +#ifdef Q_OS_OSX + +// Use this method to keep all the information in the TextSegment. As long as it is ordered +// we are in OK shape, and we can influence that ourselves. +struct KeyPair +{ + QChar cocoaKey; + Qt::Key qtKey; +}; + +bool operator==(const KeyPair &entry, QChar qchar) +{ + return entry.cocoaKey == qchar; +} + +bool operator<(const KeyPair &entry, QChar qchar) +{ + return entry.cocoaKey < qchar; +} + +bool operator<(QChar qchar, const KeyPair &entry) +{ + return qchar < entry.cocoaKey; +} + +bool operator<(const Qt::Key &key, const KeyPair &entry) +{ + return key < entry.qtKey; +} + +bool operator<(const KeyPair &entry, const Qt::Key &key) +{ + return entry.qtKey < key; +} + +struct qtKey2CocoaKeySortLessThan +{ + typedef bool result_type; + Q_DECL_CONSTEXPR result_type operator()(const KeyPair &entry1, const KeyPair &entry2) const Q_DECL_NOTHROW + { + return entry1.qtKey < entry2.qtKey; + } +}; + +static const int NumEntries = 59; +static const KeyPair entries[NumEntries] = { + { NSEnterCharacter, Qt::Key_Enter }, + { NSBackspaceCharacter, Qt::Key_Backspace }, + { NSTabCharacter, Qt::Key_Tab }, + { NSNewlineCharacter, Qt::Key_Return }, + { NSCarriageReturnCharacter, Qt::Key_Return }, + { NSBackTabCharacter, Qt::Key_Backtab }, + { kEscapeCharCode, Qt::Key_Escape }, + // Cocoa sends us delete when pressing backspace! + // (NB when we reverse this list in qtKey2CocoaKey, there + // will be two indices of Qt::Key_Backspace. But is seems to work + // ok for menu shortcuts (which uses that function): + { NSDeleteCharacter, Qt::Key_Backspace }, + { NSUpArrowFunctionKey, Qt::Key_Up }, + { NSDownArrowFunctionKey, Qt::Key_Down }, + { NSLeftArrowFunctionKey, Qt::Key_Left }, + { NSRightArrowFunctionKey, Qt::Key_Right }, + { NSF1FunctionKey, Qt::Key_F1 }, + { NSF2FunctionKey, Qt::Key_F2 }, + { NSF3FunctionKey, Qt::Key_F3 }, + { NSF4FunctionKey, Qt::Key_F4 }, + { NSF5FunctionKey, Qt::Key_F5 }, + { NSF6FunctionKey, Qt::Key_F6 }, + { NSF7FunctionKey, Qt::Key_F7 }, + { NSF8FunctionKey, Qt::Key_F8 }, + { NSF9FunctionKey, Qt::Key_F9 }, + { NSF10FunctionKey, Qt::Key_F10 }, + { NSF11FunctionKey, Qt::Key_F11 }, + { NSF12FunctionKey, Qt::Key_F12 }, + { NSF13FunctionKey, Qt::Key_F13 }, + { NSF14FunctionKey, Qt::Key_F14 }, + { NSF15FunctionKey, Qt::Key_F15 }, + { NSF16FunctionKey, Qt::Key_F16 }, + { NSF17FunctionKey, Qt::Key_F17 }, + { NSF18FunctionKey, Qt::Key_F18 }, + { NSF19FunctionKey, Qt::Key_F19 }, + { NSF20FunctionKey, Qt::Key_F20 }, + { NSF21FunctionKey, Qt::Key_F21 }, + { NSF22FunctionKey, Qt::Key_F22 }, + { NSF23FunctionKey, Qt::Key_F23 }, + { NSF24FunctionKey, Qt::Key_F24 }, + { NSF25FunctionKey, Qt::Key_F25 }, + { NSF26FunctionKey, Qt::Key_F26 }, + { NSF27FunctionKey, Qt::Key_F27 }, + { NSF28FunctionKey, Qt::Key_F28 }, + { NSF29FunctionKey, Qt::Key_F29 }, + { NSF30FunctionKey, Qt::Key_F30 }, + { NSF31FunctionKey, Qt::Key_F31 }, + { NSF32FunctionKey, Qt::Key_F32 }, + { NSF33FunctionKey, Qt::Key_F33 }, + { NSF34FunctionKey, Qt::Key_F34 }, + { NSF35FunctionKey, Qt::Key_F35 }, + { NSInsertFunctionKey, Qt::Key_Insert }, + { NSDeleteFunctionKey, Qt::Key_Delete }, + { NSHomeFunctionKey, Qt::Key_Home }, + { NSEndFunctionKey, Qt::Key_End }, + { NSPageUpFunctionKey, Qt::Key_PageUp }, + { NSPageDownFunctionKey, Qt::Key_PageDown }, + { NSPrintScreenFunctionKey, Qt::Key_Print }, + { NSScrollLockFunctionKey, Qt::Key_ScrollLock }, + { NSPauseFunctionKey, Qt::Key_Pause }, + { NSSysReqFunctionKey, Qt::Key_SysReq }, + { NSMenuFunctionKey, Qt::Key_Menu }, + { NSHelpFunctionKey, Qt::Key_Help }, +}; +static const KeyPair * const end = entries + NumEntries; + +QChar qt_mac_qtKey2CocoaKey(Qt::Key key) +{ + // The first time this function is called, create a reverse + // lookup table sorted on Qt Key rather than Cocoa key: + static QVector rev_entries(NumEntries); + static bool mustInit = true; + if (mustInit){ + mustInit = false; + for (int i=0; i::iterator i + = std::lower_bound(rev_entries.begin(), rev_entries.end(), key); + if ((i == rev_entries.end()) || (key < *i)) + return QChar(); + return i->cocoaKey; +} + +Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode) +{ + const KeyPair *i = std::lower_bound(entries, end, keyCode); + if ((i == end) || (keyCode < *i)) + return Qt::Key(keyCode.toUpper().unicode()); + return i->qtKey; +} + +#endif // Q_OS_OSX + +// ------------------------------------------------------------------------- + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index 16156d0f2c..e79f310163 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -137,6 +137,11 @@ typedef struct { QAppleOperatingSystemVersion qt_apple_os_version(); +#ifdef Q_OS_OSX +Q_CORE_EXPORT QChar qt_mac_qtKey2CocoaKey(Qt::Key key); +Q_CORE_EXPORT Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode); +#endif + QT_END_NAMESPACE #endif // QCORE_MAC_P_H -- cgit v1.2.3 From ad77422e824df3556984b793d5b304a87d7c757b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Fri, 15 Jan 2016 16:07:04 +0100 Subject: Fix memory leak if QMetaType::create is called for an unknown type The memory should be allocated only if we operates on a valid type, It is a regression introduced by 3d575d4845926bd141ff0c14e57427bba79644d0 Change-Id: Ia31bccd5b41fe090c29df1aeaa69efb706cd25bb Reviewed-by: Thiago Macieira --- src/corelib/kernel/qmetatype.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index e6d745bb74..dc6e3737b6 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1698,8 +1698,9 @@ bool QMetaType::load(QDataStream &stream, int type, void *data) void *QMetaType::create(int type, const void *copy) { QMetaType info(type); - int size = info.sizeOf(); - return info.construct(operator new(size), copy); + if (int size = info.sizeOf()) + return info.construct(operator new(size), copy); + return 0; } /*! -- cgit v1.2.3