summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/animation/qabstractanimation.cpp2
-rw-r--r--src/corelib/animation/qpropertyanimation.cpp2
-rw-r--r--src/corelib/configure.json1
-rw-r--r--src/corelib/doc/src/filestorage.qdoc2
-rw-r--r--src/corelib/global/qcompilerdetection.h17
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h9
-rw-r--r--src/corelib/global/qglobal.cpp7
-rw-r--r--src/corelib/global/qglobal.h2
-rw-r--r--src/corelib/global/qlibraryinfo.cpp130
-rw-r--r--src/corelib/global/qlibraryinfo.h2
-rw-r--r--src/corelib/global/qnamespace.qdoc7
-rw-r--r--src/corelib/io/qlockfile.cpp3
-rw-r--r--src/corelib/io/qlockfile_unix.cpp13
-rw-r--r--src/corelib/io/qprocess.cpp3
-rw-r--r--src/corelib/io/qurl.cpp2
-rw-r--r--src/corelib/itemmodels/qidentityproxymodel.cpp18
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.h18
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp98
-rw-r--r--src/corelib/kernel/qcore_unix_p.h4
-rw-r--r--src/corelib/kernel/qmetatype.cpp2
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h55
-rw-r--r--src/corelib/kernel/qsharedmemory_p.h2
-rw-r--r--src/corelib/kernel/qvariant.cpp2
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp27
-rw-r--r--src/corelib/mimetypes/qmimedatabase_p.h2
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern.cpp50
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern_p.h5
-rw-r--r--src/corelib/mimetypes/qmimemagicrule.cpp16
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp15
-rw-r--r--src/corelib/mimetypes/qmimeprovider_p.h7
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp2
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp4
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h10
-rw-r--r--src/corelib/thread/qthread.h4
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp21
-rw-r--r--src/corelib/tools/qlocale.cpp87
-rw-r--r--src/corelib/tools/qvector.h2
37 files changed, 344 insertions, 309 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 662774b484..8c189e9288 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -242,6 +242,7 @@ QUnifiedTimer *QUnifiedTimer::instance(bool create)
inst = unifiedTimer() ? unifiedTimer()->localData() : 0;
}
#else
+ Q_UNUSED(create);
static QUnifiedTimer unifiedTimer;
inst = &unifiedTimer;
#endif
@@ -576,6 +577,7 @@ QAnimationTimer *QAnimationTimer::instance(bool create)
inst = animationTimer() ? animationTimer()->localData() : 0;
}
#else
+ Q_UNUSED(create);
static QAnimationTimer animationTimer;
inst = &animationTimer;
#endif
diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp
index 6e5b08c295..9fd845bb93 100644
--- a/src/corelib/animation/qpropertyanimation.cpp
+++ b/src/corelib/animation/qpropertyanimation.cpp
@@ -269,10 +269,8 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State newState,
QPropertyAnimation *animToStop = 0;
{
-#ifndef QT_NO_THREAD
static QBasicMutex mutex;
QMutexLocker locker(&mutex);
-#endif
typedef QPair<QObject *, QByteArray> QPropertyAnimationPair;
typedef QHash<QPropertyAnimationPair, QPropertyAnimation*> QPropertyAnimationHash;
static QPropertyAnimationHash hash;
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index f84a13fa50..60248e9cd2 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -305,6 +305,7 @@
"label": "Mimetype handling",
"purpose": "Provides MIME type handling.",
"section": "Utilities",
+ "condition": "features.textcodec",
"output": [ "publicFeature", "feature" ]
},
"system-pcre2": {
diff --git a/src/corelib/doc/src/filestorage.qdoc b/src/corelib/doc/src/filestorage.qdoc
index c6a4a85646..e291ba1375 100644
--- a/src/corelib/doc/src/filestorage.qdoc
+++ b/src/corelib/doc/src/filestorage.qdoc
@@ -75,7 +75,7 @@ by a Sun SPARC running Solaris. You can also use a data stream to read/write
raw unencoded binary data.
For more details on the datatypes that QDataStream can serialize, see
-{Serializing Qt Data Types}.
+\l{Serializing Qt Data Types}.
The QTextStream class provides a convenient interface for reading and
writing text. QTextStream can operate on a QIODevice, a QByteArray or
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index 723611e1d8..a9922bb31d 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -996,11 +996,20 @@
#ifdef __cplusplus
# include <utility>
# if defined(Q_OS_QNX)
-// QNX: test if we are using libcpp (Dinkumware-based).
-// Older versions (QNX 650) do not support C++11 features
+// By default, QNX 7.0 uses libc++ (from LLVM) and
+// QNX 6.X uses Dinkumware's libcpp. In all versions,
+// it is also possible to use GNU libstdc++.
+
+// For Dinkumware, some features must be disabled
+// (mostly because of library problems).
+// Dinkumware is assumed when __GLIBCXX__ (GNU libstdc++)
+// and _LIBCPP_VERSION (LLVM libc++) are both absent.
+# if !defined(__GLIBCXX__) && !defined(_LIBCPP_VERSION)
+
+// Older versions of libcpp (QNX 650) do not support C++11 features
// _HAS_* macros are set to 1 by toolchains that actually include
// Dinkum C++11 libcpp.
-# if !defined(__GLIBCXX__)
+
# if !defined(_HAS_CPP0X) || !_HAS_CPP0X
// Disable C++11 features that depend on library support
# undef Q_COMPILER_INITIALIZER_LISTS
@@ -1017,7 +1026,7 @@
// Disable constexpr support on QNX even if the compiler supports it
# undef Q_COMPILER_CONSTEXPR
# endif // !_HAS_CONSTEXPR
-# endif // !__GLIBCXX__
+# endif // !__GLIBCXX__ && !_LIBCPP_VERSION
# endif // Q_OS_QNX
# if (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) && defined(Q_OS_MAC) && defined(__GNUC_LIBSTD__) \
&& ((__GNUC_LIBSTD__-0) * 100 + __GNUC_LIBSTD_MINOR__-0 <= 402)
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index d0e45478cc..d7849d4699 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -83,11 +83,14 @@
#define QT_NO_TRANSLATION
#define QT_FEATURE_translation -1
#define QT_NO_GEOM_VARIANT
+#define QT_FEATURE_sharedmemory -1
+#define QT_FEATURE_systemsemaphore -1
-#if defined(QT_BUILD_QMAKE) || defined(QT_BUILD_CONFIGURE)
+#ifdef QT_BUILD_QMAKE
#define QT_FEATURE_commandlineparser -1
#define QT_NO_COMPRESS
#define QT_JSON_READONLY
+#define QT_NO_STANDARDPATHS
#define QT_NO_TEXTCODEC
#define QT_FEATURE_textcodec -1
#else
@@ -97,8 +100,4 @@
#define QT_FEATURE_textcodec 1
#endif
-#if defined(QT_BUILD_QMAKE)
-#define QT_NO_STANDARDPATHS
-#endif
-
#endif // QT_BOOTSTRAPPED
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index b34e8ec659..010f2c18c4 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1516,6 +1516,13 @@ bool qSharedBuild() Q_DECL_NOTHROW
*/
/*!
+ \macro Q_CC_CLANG
+ \relates <QtGlobal>
+
+ Defined if the application is compiled using Clang.
+*/
+
+/*!
\macro Q_CC_BOR
\relates <QtGlobal>
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index a020be7fb2..e6d4848491 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -83,7 +83,7 @@
1: The feature is available
*/
#define QT_CONFIG(feature) (1/QT_FEATURE_##feature == 1)
-#define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(QT_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " not vailable.")
+#define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(QT_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " not available.")
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
# define QT_NO_UNSHARABLE_CONTAINERS
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 87ee75fa45..0de8b50900 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -41,18 +41,15 @@
#include "qdir.h"
#include "qstringlist.h"
#include "qfile.h"
-#include "qtemporaryfile.h"
#include "qsettings.h"
#include "qlibraryinfo.h"
#include "qscopedpointer.h"
#ifdef QT_BUILD_QMAKE
QT_BEGIN_NAMESPACE
-extern QString qmake_absoluteLocation();
extern QString qmake_libraryInfoFile();
QT_END_NAMESPACE
#else
-# include "qconfig.cpp"
# include "qcoreapplication.h"
#endif
@@ -60,6 +57,10 @@ QT_END_NAMESPACE
# include "private/qcore_mac_p.h"
#endif
+#ifndef QT_BUILD_QMAKE_BOOTSTRAP
+# include "qconfig.cpp"
+#endif
+
#include "archdetect.cpp"
QT_BEGIN_NAMESPACE
@@ -72,16 +73,9 @@ struct QLibrarySettings
{
QLibrarySettings();
void load();
-#ifdef QT_BUILD_QMAKE
- void loadBuiltinValues(QSettings *config);
-#endif
QScopedPointer<QSettings> settings;
#ifdef QT_BUILD_QMAKE
- QString builtinValues[QLibraryInfo::LastHostPath + 1];
-# ifndef Q_OS_WIN
- QString builtinSettingsPath;
-# endif
bool haveDevicePaths;
bool haveEffectiveSourcePaths;
bool haveEffectivePaths;
@@ -113,25 +107,6 @@ public:
? ls->haveDevicePaths
: ls->havePaths) : false;
}
- static bool sysrootify()
- {
- // This is actually bogus, as it does not consider post-configure settings.
- QLibrarySettings *ls = qt_library_settings();
- return ls ? (!ls->builtinValues[QLibraryInfo::SysrootPath].isEmpty()
- && ls->builtinValues[QLibraryInfo::ExtPrefixPath].isEmpty()) : false;
- }
- static QString builtinValue(int loc)
- {
- QLibrarySettings *ls = qt_library_settings();
- return ls ? ls->builtinValues[loc] : QString();
- }
-# ifndef Q_OS_WIN
- static QString builtinSettingsPath()
- {
- QLibrarySettings *ls = qt_library_settings();
- return ls ? ls->builtinSettingsPath : QString();
- }
-# endif
#endif
static QSettings *configuration()
{
@@ -155,20 +130,6 @@ QLibrarySettings::QLibrarySettings()
load();
}
-#ifdef QT_BUILD_QMAKE
-static QByteArray qtconfSeparator()
-{
-# ifdef Q_OS_WIN
- QByteArray header = QByteArrayLiteral("\r\n===========================================================\r\n");
-# else
- QByteArray header = QByteArrayLiteral("\n===========================================================\n");
-# endif
- QByteArray content = QByteArrayLiteral("==================== qt.conf beginning ====================");
- // Assemble from pieces to avoid that the string appears in a raw executable
- return header + content + header;
-}
-#endif
-
void QLibrarySettings::load()
{
// If we get any settings here, those won't change when the application shows up.
@@ -206,27 +167,6 @@ void QLibrarySettings::load()
havePaths = false;
#endif
}
-
-#ifdef QT_BUILD_QMAKE
- // Try to use an embedded qt.conf appended to the QMake executable.
- QFile qmakeFile(qmake_absoluteLocation());
- if (!qmakeFile.open(QIODevice::ReadOnly))
- return;
- qmakeFile.seek(qmakeFile.size() - 10000);
- QByteArray tail = qmakeFile.read(10000);
- QByteArray separator = qtconfSeparator();
- int qtconfOffset = tail.lastIndexOf(separator);
- if (qtconfOffset < 0)
- return;
- tail.remove(0, qtconfOffset + separator.size());
- // If QSettings had a c'tor taking a QIODevice, we'd pass a QBuffer ...
- QTemporaryFile tmpFile;
- tmpFile.open();
- tmpFile.write(tail);
- tmpFile.close();
- QSettings builtinSettings(tmpFile.fileName(), QSettings::IniFormat);
- loadBuiltinValues(&builtinSettings);
-#endif
}
QSettings *QLibraryInfoPrivate::findConfiguration()
@@ -483,29 +423,17 @@ static const struct {
{ "Tests", "tests" },
#ifdef QT_BUILD_QMAKE
{ "Sysroot", "" },
+ { "SysrootifyPrefix", "" },
{ "HostBinaries", "bin" },
{ "HostLibraries", "lib" },
{ "HostData", "." },
{ "TargetSpec", "" },
{ "HostSpec", "" },
- { "ExtPrefix", "" },
{ "HostPrefix", "" },
#endif
};
#ifdef QT_BUILD_QMAKE
-void QLibrarySettings::loadBuiltinValues(QSettings *config)
-{
- config->beginGroup(QLatin1String("Paths"));
- for (int i = 0; i <= QLibraryInfo::LastHostPath; i++)
- builtinValues[i] = config->value(QLatin1String(qtConfEntries[i].key),
- QLatin1String(qtConfEntries[i].value)).toString();
-# ifndef Q_OS_WIN
- builtinSettingsPath = config->value(QLatin1String("Settings")).toString();
-# endif
- config->endGroup();
-}
-
void QLibraryInfo::reload()
{
QLibraryInfoPrivate::reload();
@@ -522,13 +450,17 @@ QLibraryInfo::location(LibraryLocation loc)
QString ret = rawLocation(loc, FinalPaths);
// Automatically prepend the sysroot to target paths
- if ((loc < SysrootPath || loc > LastHostPath) && QLibraryInfoPrivate::sysrootify()) {
+ if (loc < SysrootPath || loc > LastHostPath) {
QString sysroot = rawLocation(SysrootPath, FinalPaths);
- if (!sysroot.isEmpty() && ret.length() > 2 && ret.at(1) == QLatin1Char(':')
- && (ret.at(2) == QLatin1Char('/') || ret.at(2) == QLatin1Char('\\')))
- ret.replace(0, 2, sysroot); // Strip out the drive on Windows targets
- else
- ret.prepend(sysroot);
+ if (!sysroot.isEmpty()
+ && QVariant::fromValue(rawLocation(SysrootifyPrefixPath, FinalPaths)).toBool()) {
+ if (ret.length() > 2 && ret.at(1) == QLatin1Char(':')
+ && (ret.at(2) == QLatin1Char('/') || ret.at(2) == QLatin1Char('\\'))) {
+ ret.replace(0, 2, sysroot); // Strip out the drive on Windows targets
+ } else {
+ ret.prepend(sysroot);
+ }
+ }
}
return ret;
@@ -591,7 +523,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
if (loc == HostPrefixPath)
ret = config->value(QLatin1String(qtConfEntries[PrefixPath].key),
QLatin1String(qtConfEntries[PrefixPath].value)).toString();
- else if (loc == TargetSpecPath || loc == HostSpecPath)
+ else if (loc == TargetSpecPath || loc == HostSpecPath || loc == SysrootifyPrefixPath)
fromConf = false;
// The last case here is SysrootPath, which can be legitimately empty.
// All other keys have non-empty fallbacks to start with.
@@ -615,38 +547,36 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
}
#endif // QT_NO_SETTINGS
+#ifndef QT_BUILD_QMAKE_BOOTSTRAP
if (!fromConf) {
-#ifdef QT_BUILD_QMAKE
- if ((unsigned)loc <= (unsigned)LastHostPath) {
- if (loc == PrefixPath && group != DevicePaths)
- ret = QLibraryInfoPrivate::builtinValue(ExtPrefixPath);
- else
- ret = QLibraryInfoPrivate::builtinValue(loc);
-# ifndef Q_OS_WIN // On Windows we use the registry
- } else if (loc == SettingsPath) {
- ret = QLibraryInfoPrivate::builtinSettingsPath();
-# endif
- }
-#else // QT_BUILD_QMAKE
const char * volatile path = 0;
if (loc == PrefixPath) {
- path = QT_CONFIGURE_PREFIX_PATH;
+ path =
+# ifdef QT_BUILD_QMAKE
+ (group != DevicePaths) ?
+ QT_CONFIGURE_EXT_PREFIX_PATH :
+# endif
+ QT_CONFIGURE_PREFIX_PATH;
} else if (unsigned(loc) <= sizeof(qt_configure_str_offsets)/sizeof(qt_configure_str_offsets[0])) {
path = qt_configure_strs + qt_configure_str_offsets[loc - 1];
#ifndef Q_OS_WIN // On Windows we use the registry
} else if (loc == SettingsPath) {
path = QT_CONFIGURE_SETTINGS_PATH;
#endif
+# ifdef QT_BUILD_QMAKE
+ } else if (loc == HostPrefixPath) {
+ path = QT_CONFIGURE_HOST_PREFIX_PATH;
+# endif
}
if (path)
ret = QString::fromLocal8Bit(path);
-#endif
}
+#endif
#ifdef QT_BUILD_QMAKE
- // The specs need to be returned verbatim.
- if (loc == TargetSpecPath || loc == HostSpecPath)
+ // These values aren't actually paths and thus need to be returned verbatim.
+ if (loc == TargetSpecPath || loc == HostSpecPath || loc == SysrootifyPrefixPath)
return ret;
#endif
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index 9d794ce1da..809813d99d 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -91,12 +91,12 @@ public:
#ifdef QT_BUILD_QMAKE
// These are not subject to binary compatibility constraints
SysrootPath,
+ SysrootifyPrefixPath,
HostBinariesPath,
HostLibrariesPath,
HostDataPath,
TargetSpecPath,
HostSpecPath,
- ExtPrefixPath,
HostPrefixPath,
LastHostPath = HostPrefixPath,
#endif
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index dfecc3e2d3..af485a1832 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -123,16 +123,14 @@
\value AA_PluginApplication Indicates that Qt is used to author a plugin. Depending
on the operating system, it suppresses specific initializations that do not
necessarily make sense in the plugin case.
-
For example on OS X, this includes avoiding loading our nib for the main
menu and not taking possession of the native menu bar. Setting this
attribute to true will also set the AA_DontUseNativeMenuBar attribute
to true. It also disables native event filters.
-
This attribute has been added in Qt 5.7. It must be set before
\l {QGuiApplication}{Q(Gui)Application} is constructed.
- \value AA_MacPluginApplication This attribute has been deprecated.
+ \value AA_MacPluginApplication This attribute has been deprecated.
Use AA_PluginApplication instead.
\value AA_DontUseNativeMenuBar All menubars created while this attribute is
@@ -166,7 +164,6 @@
\value AA_UseHighDpiPixmaps Make QIcon::pixmap() generate high-dpi pixmaps
that can be larger than the requested size. Such pixmaps will have
\l {QPixmap::devicePixelRatio}{devicePixelRatio()} set to a value higher than 1.
-
After setting this attribute, application code that uses pixmap
sizes in layout geometry calculations should typically divide by
\l {QPixmap::devicePixelRatio}{devicePixelRatio()} to get device-independent layout geometry.
@@ -2660,7 +2657,7 @@
\value FontRole The font used for items rendered with the default
delegate. (QFont)
\value TextAlignmentRole The alignment of the text for items rendered with the
- default delegate. (Qt::AlignmentFlag)
+ default delegate. (Qt::Alignment)
\value BackgroundRole The background brush used for items rendered with
the default delegate. (QBrush)
\value BackgroundColorRole This role is obsolete. Use BackgroundRole instead.
diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp
index ae3a7c6abc..cb1ff93ad3 100644
--- a/src/corelib/io/qlockfile.cpp
+++ b/src/corelib/io/qlockfile.cpp
@@ -84,6 +84,9 @@ QT_BEGIN_NAMESPACE
For the use case of protecting a resource over a long time, you should therefore call
setStaleLockTime(0), and when tryLock() returns LockFailedError, inform the user
that the document is locked, possibly using getLockInfo() for more details.
+
+ \note On Windows, this class has problems detecting a stale lock if the
+ machine's hostname contains characters outside the US-ASCII character set.
*/
/*!
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index 82beb15912..3a80014c00 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -81,15 +81,6 @@
QT_BEGIN_NAMESPACE
-static QByteArray localHostName() // from QHostInfo::localHostName(), modified to return a QByteArray
-{
- QByteArray hostName(512, Qt::Uninitialized);
- if (gethostname(hostName.data(), hostName.size()) == -1)
- return QByteArray();
- hostName.truncate(strlen(hostName.data()));
- return hostName;
-}
-
// ### merge into qt_safe_write?
static qint64 qt_write_loop(int fd, const char *data, qint64 len)
{
@@ -185,7 +176,7 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
// Use operator% from the fast builder to avoid multiple memory allocations.
QByteArray fileData = QByteArray::number(QCoreApplication::applicationPid()) % '\n'
% QCoreApplication::applicationName().toUtf8() % '\n'
- % localHostName() % '\n';
+ % QSysInfo::machineHostName().toUtf8() % '\n';
const QByteArray lockFileName = QFile::encodeName(fileName);
const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0666);
@@ -242,7 +233,7 @@ bool QLockFilePrivate::isApparentlyStale() const
qint64 pid;
QString hostname, appname;
if (getLockInfo(&pid, &hostname, &appname)) {
- if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) {
+ if (hostname.isEmpty() || hostname == QSysInfo::machineHostName()) {
if (::kill(pid, 0) == -1 && errno == ESRCH)
return true; // PID doesn't exist anymore
const QString processName = processNameByPid(pid);
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index f2c2ba4476..c27484acbe 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -513,6 +513,9 @@ void QProcessPrivate::Channel::clear()
You can also call error() to find the type of error that occurred
last, and state() to find the current process state.
+ \note QProcess is not supported on VxWorks, iOS, tvOS, watchOS,
+ or the Universal Windows Platform.
+
\section1 Communicating via Channels
Processes have two predefined output channels: The standard
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index c224b032aa..a6372b75f6 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -240,7 +240,7 @@
Only valid if RemovePath is not set.
\value PreferLocalFile If the URL is a local file according to isLocalFile()
and contains no query or fragment, a local file path is returned.
- \value StripTrailingSlash The trailing slash is removed if one is present.
+ \value StripTrailingSlash The trailing slash is removed from the path, if one is present.
\value NormalizePathSegments Modifies the path to remove redundant directory separators,
and to resolve "."s and ".."s (as far as possible).
diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp
index e537793146..7c306799d0 100644
--- a/src/corelib/itemmodels/qidentityproxymodel.cpp
+++ b/src/corelib/itemmodels/qidentityproxymodel.cpp
@@ -496,15 +496,6 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPe
{
Q_Q(QIdentityProxyModel);
- const auto proxyPersistentIndexes = q->persistentIndexList();
- for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) {
- proxyIndexes << proxyPersistentIndex;
- Q_ASSERT(proxyPersistentIndex.isValid());
- const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
- Q_ASSERT(srcPersistentIndex.isValid());
- layoutChangePersistentIndexes << srcPersistentIndex;
- }
-
QList<QPersistentModelIndex> parents;
parents.reserve(sourceParents.size());
for (const QPersistentModelIndex &parent : sourceParents) {
@@ -518,6 +509,15 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPe
}
q->layoutAboutToBeChanged(parents, hint);
+
+ const auto proxyPersistentIndexes = q->persistentIndexList();
+ for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) {
+ proxyIndexes << proxyPersistentIndex;
+ Q_ASSERT(proxyPersistentIndex.isValid());
+ const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
+ Q_ASSERT(srcPersistentIndex.isValid());
+ layoutChangePersistentIndexes << srcPersistentIndex;
+ }
}
void QIdentityProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint)
diff --git a/src/corelib/itemmodels/qitemselectionmodel.h b/src/corelib/itemmodels/qitemselectionmodel.h
index 92c459a243..2421610bce 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.h
+++ b/src/corelib/itemmodels/qitemselectionmodel.h
@@ -228,6 +228,24 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QItemSelectionModel::SelectionFlags)
// dummy implentation of qHash() necessary for instantiating QList<QItemSelectionRange>::toSet() with MSVC
inline uint qHash(const QItemSelectionRange &) { return 0; }
+#ifdef Q_CC_MSVC
+
+/*
+ ### Qt 6:
+ ### This needs to be removed for next releases of Qt. It is a workaround for vc++ because
+ ### Qt exports QItemSelection that inherits QList<QItemSelectionRange>.
+*/
+
+# ifndef Q_TEMPLATE_EXTERN
+# if defined(QT_BUILD_CORE_LIB)
+# define Q_TEMPLATE_EXTERN
+# else
+# define Q_TEMPLATE_EXTERN extern
+# endif
+# endif
+Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QList<QItemSelectionRange>;
+#endif // Q_CC_MSVC
+
class Q_CORE_EXPORT QItemSelection : public QList<QItemSelectionRange>
{
public:
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index b0ddfa879d..226a2401e1 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -171,6 +171,7 @@ public:
QRowsRemoval itemsBeingRemoved;
QModelIndexPairList saved_persistent_indexes;
+ QList<QPersistentModelIndex> saved_layoutChange_parents;
QHash<QModelIndex, Mapping *>::const_iterator create_mapping(
const QModelIndex &source_parent) const;
@@ -1331,23 +1332,23 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<Q
Q_UNUSED(hint); // We can't forward Hint because we might filter additional rows or columns
saved_persistent_indexes.clear();
- QList<QPersistentModelIndex> parents;
+ saved_layoutChange_parents.clear();
for (const QPersistentModelIndex &parent : sourceParents) {
if (!parent.isValid()) {
- parents << QPersistentModelIndex();
+ saved_layoutChange_parents << QPersistentModelIndex();
continue;
}
const QModelIndex mappedParent = q->mapFromSource(parent);
// Might be filtered out.
if (mappedParent.isValid())
- parents << mappedParent;
+ saved_layoutChange_parents << mappedParent;
}
// All parents filtered out.
- if (!sourceParents.isEmpty() && parents.isEmpty())
+ if (!sourceParents.isEmpty() && saved_layoutChange_parents.isEmpty())
return;
- emit q->layoutAboutToBeChanged(parents);
+ emit q->layoutAboutToBeChanged(saved_layoutChange_parents);
if (persistent.indexes.isEmpty())
return;
@@ -1359,6 +1360,9 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersisten
Q_Q(QSortFilterProxyModel);
Q_UNUSED(hint); // We can't forward Hint because we might filter additional rows or columns
+ if (!sourceParents.isEmpty() && saved_layoutChange_parents.isEmpty())
+ return;
+
// Optimize: We only actually have to clear the mapping related to the contents of
// sourceParents, not everything.
qDeleteAll(source_index_mapping);
@@ -1373,21 +1377,8 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersisten
source_index_mapping.clear();
}
- QList<QPersistentModelIndex> parents;
- for (const QPersistentModelIndex &parent : sourceParents) {
- if (!parent.isValid()) {
- parents << QPersistentModelIndex();
- continue;
- }
- const QModelIndex mappedParent = q->mapFromSource(parent);
- if (mappedParent.isValid())
- parents << mappedParent;
- }
-
- if (!sourceParents.isEmpty() && parents.isEmpty())
- return;
-
- emit q->layoutChanged(parents);
+ emit q->layoutChanged(saved_layoutChange_parents);
+ saved_layoutChange_parents.clear();
}
void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted(
@@ -1427,49 +1418,27 @@ void QSortFilterProxyModelPrivate::_q_sourceRowsRemoved(
void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeMoved(
const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */)
{
- Q_Q(QSortFilterProxyModel);
// Because rows which are contiguous in the source model might not be contiguous
// in the proxy due to sorting, the best thing we can do here is be specific about what
// parents are having their children changed.
// Optimize: Emit move signals if the proxy is not sorted. Will need to account for rows
// being filtered out though.
- saved_persistent_indexes.clear();
-
QList<QPersistentModelIndex> parents;
- parents << q->mapFromSource(sourceParent);
+ parents << sourceParent;
if (sourceParent != destParent)
- parents << q->mapFromSource(destParent);
- emit q->layoutAboutToBeChanged(parents);
- if (persistent.indexes.isEmpty())
- return;
- saved_persistent_indexes = store_persistent_indexes();
+ parents << destParent;
+ _q_sourceLayoutAboutToBeChanged(parents, QAbstractItemModel::NoLayoutChangeHint);
}
void QSortFilterProxyModelPrivate::_q_sourceRowsMoved(
const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */)
{
- Q_Q(QSortFilterProxyModel);
-
- // Optimize: We only need to clear and update the persistent indexes which are children of
- // sourceParent or destParent
- qDeleteAll(source_index_mapping);
- source_index_mapping.clear();
-
- update_persistent_indexes(saved_persistent_indexes);
- saved_persistent_indexes.clear();
-
- if (dynamic_sortfilter && update_source_sort_column()) {
- //update_source_sort_column might have created wrong mapping so we have to clear it again
- qDeleteAll(source_index_mapping);
- source_index_mapping.clear();
- }
-
QList<QPersistentModelIndex> parents;
- parents << q->mapFromSource(sourceParent);
+ parents << sourceParent;
if (sourceParent != destParent)
- parents << q->mapFromSource(destParent);
- emit q->layoutChanged(parents);
+ parents << destParent;
+ _q_sourceLayoutChanged(parents, QAbstractItemModel::NoLayoutChangeHint);
}
void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeInserted(
@@ -1531,42 +1500,21 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved(
void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeMoved(
const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */)
{
- Q_Q(QSortFilterProxyModel);
-
- saved_persistent_indexes.clear();
-
QList<QPersistentModelIndex> parents;
- parents << q->mapFromSource(sourceParent);
+ parents << sourceParent;
if (sourceParent != destParent)
- parents << q->mapFromSource(destParent);
- emit q->layoutAboutToBeChanged(parents);
-
- if (persistent.indexes.isEmpty())
- return;
- saved_persistent_indexes = store_persistent_indexes();
+ parents << destParent;
+ _q_sourceLayoutAboutToBeChanged(parents, QAbstractItemModel::NoLayoutChangeHint);
}
void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved(
const QModelIndex &sourceParent, int /* sourceStart */, int /* sourceEnd */, const QModelIndex &destParent, int /* dest */)
{
- Q_Q(QSortFilterProxyModel);
-
- qDeleteAll(source_index_mapping);
- source_index_mapping.clear();
-
- update_persistent_indexes(saved_persistent_indexes);
- saved_persistent_indexes.clear();
-
- if (dynamic_sortfilter && update_source_sort_column()) {
- qDeleteAll(source_index_mapping);
- source_index_mapping.clear();
- }
-
QList<QPersistentModelIndex> parents;
- parents << q->mapFromSource(sourceParent);
+ parents << sourceParent;
if (sourceParent != destParent)
- parents << q->mapFromSource(destParent);
- emit q->layoutChanged(parents);
+ parents << destParent;
+ _q_sourceLayoutChanged(parents, QAbstractItemModel::NoLayoutChangeHint);
}
/*!
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index b5756af994..80058d9115 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -370,7 +370,7 @@ union qt_semun {
};
#ifndef QT_POSIX_IPC
-#ifndef QT_NO_SHAREDMEMORY
+#if QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore)
#ifndef Q_OS_ANDROID
static inline key_t qt_safe_ftok(const QByteArray &filename, int proj_id)
{
@@ -379,7 +379,7 @@ static inline key_t qt_safe_ftok(const QByteArray &filename, int proj_id)
return ::ftok(filename.constData(), qHash(filename, proj_id));
}
#endif // !Q_OS_ANDROID
-#endif // !QT_NO_SHAREDMEMORY
+#endif // QT_CONFIG(sharedmemory) || QT_CONFIG(systemsemaphore)
#endif // !QT_POSIX_IPC
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index fb86d0222e..5623b085b8 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -207,8 +207,6 @@ struct DefinedTypesFilter {
\enum QMetaType::Type
These are the built-in types supported by QMetaType:
- Read doc on QChar
- Read doc on \l QChar
\value Void \c void
\value Bool \c bool
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index 79c9c8303e..1768e8ccc6 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -149,6 +149,20 @@ namespace QtPrivate {
(o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
}
};
+#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
+ template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
+ struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) noexcept> {
+ static void call(SlotRet (Obj::*f)(SlotArgs...) noexcept, Obj *o, void **arg) {
+ (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+ template <int... II, typename... SignalArgs, typename R, typename... SlotArgs, typename SlotRet, class Obj>
+ struct FunctorCall<IndexesList<II...>, List<SignalArgs...>, R, SlotRet (Obj::*)(SlotArgs...) const noexcept> {
+ static void call(SlotRet (Obj::*f)(SlotArgs...) const noexcept, Obj *o, void **arg) {
+ (o->*f)((*reinterpret_cast<typename RemoveRef<SignalArgs>::Type *>(arg[II+1]))...), ApplyReturnValue<R>(arg[0]);
+ }
+ };
+#endif
template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...)>
{
@@ -187,6 +201,47 @@ namespace QtPrivate {
}
};
+#if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
+ template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...) noexcept>
+ {
+ typedef Obj Object;
+ typedef List<Args...> Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (Obj::*Function) (Args...) noexcept;
+ template <class Base> struct ChangeClass { typedef Ret (Base:: *Type)(Args...) noexcept; };
+ enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
+ template <typename SignalArgs, typename R>
+ static void call(Function f, Obj *o, void **arg) {
+ FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, o, arg);
+ }
+ };
+ template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...) const noexcept>
+ {
+ typedef Obj Object;
+ typedef List<Args...> Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (Obj::*Function) (Args...) const noexcept;
+ template <class Base> struct ChangeClass { typedef Ret (Base:: *Type)(Args...) const noexcept; };
+ enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = true};
+ template <typename SignalArgs, typename R>
+ static void call(Function f, Obj *o, void **arg) {
+ FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, o, arg);
+ }
+ };
+
+ template<typename Ret, typename... Args> struct FunctionPointer<Ret (*) (Args...) noexcept>
+ {
+ typedef List<Args...> Arguments;
+ typedef Ret ReturnType;
+ typedef Ret (*Function) (Args...) noexcept;
+ enum {ArgumentCount = sizeof...(Args), IsPointerToMemberFunction = false};
+ template <typename SignalArgs, typename R>
+ static void call(Function f, void *, void **arg) {
+ FunctorCall<typename Indexes<ArgumentCount>::Value, SignalArgs, R, Function>::call(f, arg);
+ }
+ };
+#endif
+
template<typename Function, int N> struct Functor
{
template <typename SignalArgs, typename R>
diff --git a/src/corelib/kernel/qsharedmemory_p.h b/src/corelib/kernel/qsharedmemory_p.h
index 51f729cf23..95fe0d1083 100644
--- a/src/corelib/kernel/qsharedmemory_p.h
+++ b/src/corelib/kernel/qsharedmemory_p.h
@@ -53,6 +53,8 @@
#include "qsharedmemory.h"
+#include <QtCore/qstring.h>
+
#ifdef QT_NO_SHAREDMEMORY
# ifndef QT_NO_SYSTEMSEMAPHORE
namespace QSharedMemoryPrivate
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 4a4d5b9294..8a4ad8bbf3 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1186,7 +1186,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names
\snippet code/src_corelib_kernel_qvariant.cpp 1
QVariant can be extended to support other types than those
- mentioned in the \l Type enum. See the \l QMetaType documentation
+ mentioned in the \l Type enum. See \l{Creating Custom Qt Types}{Creating Custom Qt Types}
for details.
\section1 A Note on GUI Types
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index 448e6117b1..fda9f01643 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -108,12 +108,12 @@ QMimeType QMimeDatabasePrivate::mimeTypeForName(const QString &nameOrAlias)
return provider()->mimeTypeForName(provider()->resolveAlias(nameOrAlias));
}
-QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName, QString *foundSuffix)
+QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName)
{
if (fileName.endsWith(QLatin1Char('/')))
return QStringList() << QLatin1String("inode/directory");
- QStringList matchingMimeTypes = provider()->findByFileName(QFileInfo(fileName).fileName(), foundSuffix);
+ QStringList matchingMimeTypes = provider()->findByFileName(QFileInfo(fileName).fileName()).m_matchingMimeTypes;
matchingMimeTypes.sort(); // make it deterministic
return matchingMimeTypes;
}
@@ -168,13 +168,17 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
*accuracyPtr = 0;
// Pass 1) Try to match on the file name
- QStringList candidatesByName = mimeTypeForFileName(fileName);
- if (candidatesByName.count() == 1) {
+ QMimeGlobMatchResult candidatesByName;
+ if (fileName.endsWith(QLatin1Char('/')))
+ candidatesByName.addMatch(QLatin1String("inode/directory"), 100, QString());
+ else
+ candidatesByName = provider()->findByFileName(QFileInfo(fileName).fileName());
+ if (candidatesByName.m_allMatchingMimeTypes.count() == 1) {
*accuracyPtr = 100;
- const QMimeType mime = mimeTypeForName(candidatesByName.at(0));
+ const QMimeType mime = mimeTypeForName(candidatesByName.m_matchingMimeTypes.at(0));
if (mime.isValid())
return mime;
- candidatesByName.clear();
+ candidatesByName = {};
}
// Extension is unknown, or matches multiple mimetypes.
@@ -193,7 +197,7 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
// "for glob_match in glob_matches:"
// "if glob_match is subclass or equal to sniffed_type, use glob_match"
const QString sniffedMime = candidateByData.name();
- for (const QString &m : qAsConst(candidatesByName)) {
+ for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) {
if (inherits(m, sniffedMime)) {
// We have magic + pattern pointing to this, so it's a pretty good match
*accuracyPtr = 100;
@@ -205,9 +209,10 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
}
}
- if (candidatesByName.count() > 1) {
+ if (candidatesByName.m_allMatchingMimeTypes.count() > 1) {
+ candidatesByName.m_matchingMimeTypes.sort(); // make it deterministic
*accuracyPtr = 20;
- const QMimeType mime = mimeTypeForName(candidatesByName.at(0));
+ const QMimeType mime = mimeTypeForName(candidatesByName.m_matchingMimeTypes.at(0));
if (mime.isValid())
return mime;
}
@@ -455,9 +460,7 @@ QList<QMimeType> QMimeDatabase::mimeTypesForFileName(const QString &fileName) co
QString QMimeDatabase::suffixForFileName(const QString &fileName) const
{
QMutexLocker locker(&d->mutex);
- QString foundSuffix;
- d->mimeTypeForFileName(fileName, &foundSuffix);
- return foundSuffix;
+ return d->provider()->findByFileName(QFileInfo(fileName).fileName()).m_foundSuffix;
}
/*!
diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h
index 4ff5110a5b..3f63f5f103 100644
--- a/src/corelib/mimetypes/qmimedatabase_p.h
+++ b/src/corelib/mimetypes/qmimedatabase_p.h
@@ -90,7 +90,7 @@ public:
QMimeType mimeTypeForName(const QString &nameOrAlias);
QMimeType mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device, int *priorityPtr);
QMimeType findByData(const QByteArray &data, int *priorityPtr);
- QStringList mimeTypeForFileName(const QString &fileName, QString *foundSuffix = 0);
+ QStringList mimeTypeForFileName(const QString &fileName);
mutable QMimeProviderBase *m_provider;
const QString m_defaultMimeType;
diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp
index 568f9bf4de..a4d2b046fa 100644
--- a/src/corelib/mimetypes/qmimeglobpattern.cpp
+++ b/src/corelib/mimetypes/qmimeglobpattern.cpp
@@ -58,9 +58,13 @@ QT_BEGIN_NAMESPACE
void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const QString &pattern)
{
+ if (m_allMatchingMimeTypes.contains(mimeType))
+ return;
// Is this a lower-weight pattern than the last match? Skip this match then.
- if (weight < m_weight)
+ if (weight < m_weight) {
+ m_allMatchingMimeTypes.append(mimeType);
return;
+ }
bool replace = weight > m_weight;
if (!replace) {
// Compare the length of the match
@@ -79,6 +83,7 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
}
if (!m_matchingMimeTypes.contains(mimeType)) {
m_matchingMimeTypes.append(mimeType);
+ m_allMatchingMimeTypes.append(mimeType);
if (pattern.startsWith(QLatin1String("*.")))
m_foundSuffix = pattern.mid(2);
}
@@ -201,35 +206,32 @@ void QMimeGlobPatternList::match(QMimeGlobMatchResult &result,
}
}
-QStringList QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QString *foundSuffix) const
+QMimeGlobMatchResult QMimeAllGlobPatterns::matchingGlobs(const QString &fileName) const
{
// First try the high weight matches (>50), if any.
QMimeGlobMatchResult result;
m_highWeightGlobs.match(result, fileName);
- if (result.m_matchingMimeTypes.isEmpty()) {
-
- // Now use the "fast patterns" dict, for simple *.foo patterns with weight 50
- // (which is most of them, so this optimization is definitely worth it)
- const int lastDot = fileName.lastIndexOf(QLatin1Char('.'));
- if (lastDot != -1) { // if no '.', skip the extension lookup
- const int ext_len = fileName.length() - lastDot - 1;
- const QString simpleExtension = fileName.right(ext_len).toLower();
- // (toLower because fast patterns are always case-insensitive and saved as lowercase)
-
- const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension);
- const QString simplePattern = QLatin1String("*.") + simpleExtension;
- for (const QString &mime : matchingMimeTypes)
- result.addMatch(mime, 50, simplePattern);
- // Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway,
- // at least those with weight 50.
- }
- // Finally, try the low weight matches (<=50)
- m_lowWeightGlobs.match(result, fileName);
+ // Now use the "fast patterns" dict, for simple *.foo patterns with weight 50
+ // (which is most of them, so this optimization is definitely worth it)
+ const int lastDot = fileName.lastIndexOf(QLatin1Char('.'));
+ if (lastDot != -1) { // if no '.', skip the extension lookup
+ const int ext_len = fileName.length() - lastDot - 1;
+ const QString simpleExtension = fileName.right(ext_len).toLower();
+ // (toLower because fast patterns are always case-insensitive and saved as lowercase)
+
+ const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension);
+ const QString simplePattern = QLatin1String("*.") + simpleExtension;
+ for (const QString &mime : matchingMimeTypes)
+ result.addMatch(mime, 50, simplePattern);
+ // Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway,
+ // at least those with weight 50.
}
- if (foundSuffix)
- *foundSuffix = result.m_foundSuffix;
- return result.m_matchingMimeTypes;
+
+ // Finally, try the low weight matches (<=50)
+ m_lowWeightGlobs.match(result, fileName);
+
+ return result;
}
void QMimeAllGlobPatterns::clear()
diff --git a/src/corelib/mimetypes/qmimeglobpattern_p.h b/src/corelib/mimetypes/qmimeglobpattern_p.h
index 3e4fdb50f6..c8b70464fd 100644
--- a/src/corelib/mimetypes/qmimeglobpattern_p.h
+++ b/src/corelib/mimetypes/qmimeglobpattern_p.h
@@ -68,7 +68,8 @@ struct QMimeGlobMatchResult
void addMatch(const QString &mimeType, int weight, const QString &pattern);
- QStringList m_matchingMimeTypes;
+ QStringList m_matchingMimeTypes; // only those with highest weight
+ QStringList m_allMatchingMimeTypes;
int m_weight;
int m_matchingPatternLength;
QString m_foundSuffix;
@@ -153,7 +154,7 @@ public:
void addGlob(const QMimeGlobPattern &glob);
void removeMimeType(const QString &mimeType);
- QStringList matchingGlobs(const QString &fileName, QString *foundSuffix) const;
+ QMimeGlobMatchResult matchingGlobs(const QString &fileName) const;
void clear();
PatternsMap m_fastPatterns; // example: "doc" -> "application/msword", "text/plain"
diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp
index 7e07f8acb9..5bbf1bba9d 100644
--- a/src/corelib/mimetypes/qmimemagicrule.cpp
+++ b/src/corelib/mimetypes/qmimemagicrule.cpp
@@ -161,7 +161,7 @@ bool QMimeMagicRule::matchNumber(const QByteArray &data) const
//qDebug() << "mask" << QString::number(m_numberMask, 16);
const char *p = data.constData() + m_startPos;
- const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), m_endPos + 1);
+ const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), m_endPos);
for ( ; p <= e; ++p) {
if ((qFromUnaligned<T>(p) & mask) == (value & mask))
return true;
@@ -299,20 +299,30 @@ QMimeMagicRule::QMimeMagicRule(const QString &type,
}
break;
case Big16:
- case Host16:
case Little16:
if (m_number <= quint16(-1)) {
m_number = m_type == Little16 ? qFromLittleEndian<quint16>(m_number) : qFromBigEndian<quint16>(m_number);
+ if (m_numberMask != 0)
+ m_numberMask = m_type == Little16 ? qFromLittleEndian<quint16>(m_numberMask) : qFromBigEndian<quint16>(m_numberMask);
+ }
+ Q_FALLTHROUGH();
+ case Host16:
+ if (m_number <= quint16(-1)) {
if (m_numberMask == 0)
m_numberMask = quint16(-1);
m_matchFunction = &QMimeMagicRule::matchNumber<quint16>;
}
break;
case Big32:
- case Host32:
case Little32:
if (m_number <= quint32(-1)) {
m_number = m_type == Little32 ? qFromLittleEndian<quint32>(m_number) : qFromBigEndian<quint32>(m_number);
+ if (m_numberMask != 0)
+ m_numberMask = m_type == Little32 ? qFromLittleEndian<quint32>(m_numberMask) : qFromBigEndian<quint32>(m_numberMask);
+ }
+ Q_FALLTHROUGH();
+ case Host32:
+ if (m_number <= quint32(-1)) {
if (m_numberMask == 0)
m_numberMask = quint32(-1);
m_matchFunction = &QMimeMagicRule::matchNumber<quint32>;
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 65b011b439..959421bf52 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -287,13 +287,13 @@ QMimeType QMimeBinaryProvider::mimeTypeForName(const QString &name)
return mimeTypeForNameUnchecked(name);
}
-QStringList QMimeBinaryProvider::findByFileName(const QString &fileName, QString *foundSuffix)
+QMimeGlobMatchResult QMimeBinaryProvider::findByFileName(const QString &fileName)
{
checkCache();
+ QMimeGlobMatchResult result;
if (fileName.isEmpty())
- return QStringList();
+ return result;
const QString lowerFileName = fileName.toLower();
- QMimeGlobMatchResult result;
// TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly.
for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
matchGlobList(result, cacheFile, cacheFile->getUint32(PosLiteralListOffset), fileName);
@@ -305,9 +305,7 @@ QStringList QMimeBinaryProvider::findByFileName(const QString &fileName, QString
if (result.m_matchingMimeTypes.isEmpty())
matchSuffixTree(result, cacheFile, numRoots, firstRootOffset, fileName, fileName.length() - 1, true);
}
- if (foundSuffix)
- *foundSuffix = result.m_foundSuffix;
- return result.m_matchingMimeTypes;
+ return result;
}
void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName)
@@ -728,12 +726,11 @@ QMimeType QMimeXMLProvider::mimeTypeForName(const QString &name)
return m_nameMimeTypeMap.value(name);
}
-QStringList QMimeXMLProvider::findByFileName(const QString &fileName, QString *foundSuffix)
+QMimeGlobMatchResult QMimeXMLProvider::findByFileName(const QString &fileName)
{
ensureLoaded();
- const QStringList matchingMimeTypes = m_mimeTypeGlobs.matchingGlobs(fileName, foundSuffix);
- return matchingMimeTypes;
+ return m_mimeTypeGlobs.matchingGlobs(fileName);
}
QMimeType QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr)
diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h
index e6fc47bf80..f410e62267 100644
--- a/src/corelib/mimetypes/qmimeprovider_p.h
+++ b/src/corelib/mimetypes/qmimeprovider_p.h
@@ -56,6 +56,7 @@
#ifndef QT_NO_MIMETYPE
+#include "qmimeglobpattern_p.h"
#include <QtCore/qdatetime.h>
#include <QtCore/qset.h>
#include <QtCore/qelapsedtimer.h>
@@ -72,7 +73,7 @@ public:
virtual bool isValid() = 0;
virtual QMimeType mimeTypeForName(const QString &name) = 0;
- virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix) = 0;
+ virtual QMimeGlobMatchResult findByFileName(const QString &fileName) = 0;
virtual QStringList parents(const QString &mime) = 0;
virtual QString resolveAlias(const QString &name) = 0;
virtual QStringList listAliases(const QString &name) = 0;
@@ -99,7 +100,7 @@ public:
virtual bool isValid() Q_DECL_OVERRIDE;
virtual QMimeType mimeTypeForName(const QString &name) Q_DECL_OVERRIDE;
- virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix) Q_DECL_OVERRIDE;
+ virtual QMimeGlobMatchResult findByFileName(const QString &fileName) Q_DECL_OVERRIDE;
virtual QStringList parents(const QString &mime) Q_DECL_OVERRIDE;
virtual QString resolveAlias(const QString &name) Q_DECL_OVERRIDE;
virtual QStringList listAliases(const QString &name) Q_DECL_OVERRIDE;
@@ -142,7 +143,7 @@ public:
virtual bool isValid() Q_DECL_OVERRIDE;
virtual QMimeType mimeTypeForName(const QString &name) Q_DECL_OVERRIDE;
- virtual QStringList findByFileName(const QString &fileName, QString *foundSuffix) Q_DECL_OVERRIDE;
+ virtual QMimeGlobMatchResult findByFileName(const QString &fileName) Q_DECL_OVERRIDE;
virtual QStringList parents(const QString &mime) Q_DECL_OVERRIDE;
virtual QString resolveAlias(const QString &name) Q_DECL_OVERRIDE;
virtual QStringList listAliases(const QString &name) Q_DECL_OVERRIDE;
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index c09dc6c22b..b8e18cc9a8 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -282,6 +282,7 @@ QObject *QFactoryLoader::instance(int index) const
return 0;
#ifndef QT_NO_LIBRARY
+ QMutexLocker lock(&d->mutex);
if (index < d->libraryList.size()) {
QLibraryPrivate *library = d->libraryList.at(index);
if (library->instance || library->loadPlugin()) {
@@ -297,6 +298,7 @@ QObject *QFactoryLoader::instance(int index) const
return 0;
}
index -= d->libraryList.size();
+ lock.unlock();
#endif
QVector<QStaticPlugin> staticPlugins = QPluginLoader::staticPlugins();
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 433f595611..d7cdec9aac 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -2024,7 +2024,9 @@ void QStateMachinePrivate::processEvents(EventProcessingMode processingMode)
if (QThread::currentThread() == q->thread()) {
_q_process();
break;
- } // fallthrough -- processing must be done in the machine thread
+ }
+ // processing must be done in the machine thread, so:
+ Q_FALLTHROUGH();
case QueuedProcessing:
processingScheduled = true;
QMetaObject::invokeMethod(q, "_q_process", Qt::QueuedConnection);
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index 9418813afd..c28b162305 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -79,7 +79,7 @@ class QFinalState;
class QHistoryState;
class QState;
-#ifndef QT_NO_ANIMATION
+#if QT_CONFIG(animation)
class QAbstractAnimation;
#endif
@@ -123,7 +123,7 @@ public:
// private slots
void _q_start();
void _q_process();
-#ifndef QT_NO_ANIMATION
+#if QT_CONFIG(animation)
void _q_animationFinished();
#endif
void _q_startDelayedEventTimer(int id, int delay);
@@ -152,7 +152,7 @@ public:
const QList<QAbstractState*> &statesToEnter_sorted,
const QSet<QAbstractState*> &statesForDefaultEntry,
QHash<QAbstractState *, QVector<QPropertyAssignment> > &propertyAssignmentsForState
-#ifndef QT_NO_ANIMATION
+#if QT_CONFIG(animation)
, const QList<QAbstractAnimation*> &selectedAnimations
#endif
);
@@ -264,7 +264,7 @@ public:
QSet<QAbstractState *> pendingErrorStates;
QSet<QAbstractState *> pendingErrorStatesForDefaultEntry;
-#ifndef QT_NO_ANIMATION
+#if QT_CONFIG(animation)
bool animated;
struct InitializeAnimationResult {
@@ -326,7 +326,9 @@ public:
static const Handler *handler;
};
+#if QT_CONFIG(animation)
Q_DECLARE_SHARED(QStateMachinePrivate::InitializeAnimationResult)
+#endif
Q_CORE_EXPORT const QStateMachinePrivate::Handler *qcoreStateMachineHandler();
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index 410f642ca7..45786537e2 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -140,10 +140,10 @@ public:
static QThread* currentThread();
protected:
- QThread(QThreadPrivate &dd, QObject *parent = 0);
+ QThread(QThreadPrivate &dd, QObject *parent = nullptr);
private:
- explicit QThread(QObject *parent = 0);
+ explicit QThread(QObject *parent = nullptr);
static QThread *instance;
friend class QCoreApplication;
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index 621c877174..65016933a0 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -1139,6 +1139,7 @@ end:
}
break; }
}
+ Q_FALLTHROUGH();
case MonthSection:
if (sn.count >= 3) {
const int currentMonth = newCurrentValue.date().month();
@@ -1216,15 +1217,15 @@ end:
} else {
if (context == FromString) {
// optimization
- Q_ASSERT(getMaximum().date().toJulianDay() == 4642999);
+ Q_ASSERT(maximum.date().toJulianDay() == 4642999);
if (newCurrentValue.date().toJulianDay() > 4642999)
state = Invalid;
} else {
- if (newCurrentValue > getMaximum())
+ if (newCurrentValue > maximum)
state = Invalid;
}
- QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << getMinimum() << getMaximum();
+ QDTPDEBUG << "not checking intermediate because newCurrentValue is" << newCurrentValue << minimum << maximum;
}
}
StateNode node;
@@ -1607,13 +1608,13 @@ bool QDateTimeParser::potentialValue(const QStringRef &str, int min, int max, in
bool QDateTimeParser::skipToNextSection(int index, const QDateTime &current, const QStringRef &text) const
{
- Q_ASSERT(current >= getMinimum() && current <= getMaximum());
-
const SectionNode &node = sectionNode(index);
Q_ASSERT(text.size() < sectionMaxSize(index));
const QDateTime maximum = getMaximum();
const QDateTime minimum = getMinimum();
+ Q_ASSERT(current >= minimum && current <= maximum);
+
QDateTime tmp = current;
int min = absoluteMin(index);
setDigit(tmp, index, min);
@@ -1713,11 +1714,21 @@ bool QDateTimeParser::fromString(const QString &t, QDate *date, QTime *time) con
QDateTime QDateTimeParser::getMinimum() const
{
+ // Cache the most common case
+ if (spec == Qt::LocalTime) {
+ static const QDateTime localTimeMin(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, Qt::LocalTime);
+ return localTimeMin;
+ }
return QDateTime(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN, spec);
}
QDateTime QDateTimeParser::getMaximum() const
{
+ // Cache the most common case
+ if (spec == Qt::LocalTime) {
+ static const QDateTime localTimeMax(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, Qt::LocalTime);
+ return localTimeMax;
+ }
return QDateTime(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX, spec);
}
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 77f7ba963b..cdda5292e7 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -334,33 +334,17 @@ QByteArray QLocalePrivate::bcp47Name(char separator) const
return localeId.withLikelySubtagsRemoved().name(separator);
}
-const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country)
+static const QLocaleData *findLocaleDataById(const QLocaleId &localeId)
{
- QLocaleId localeId = QLocaleId::fromIds(language, script, country);
- localeId = localeId.withLikelySubtagsAdded();
-
- uint idx = locale_index[localeId.language_id];
+ const uint idx = locale_index[localeId.language_id];
const QLocaleData *data = locale_data + idx;
- if (idx == 0) // default language has no associated country
+ if (idx == 0) // default language has no associated script or country
return data;
Q_ASSERT(data->m_language_id == localeId.language_id);
- if (localeId.script_id != QLocale::AnyScript && localeId.country_id != QLocale::AnyCountry) {
- // both script and country are explicitly specified
- do {
- if (data->m_script_id == localeId.script_id && data->m_country_id == localeId.country_id)
- return data;
- ++data;
- } while (data->m_language_id == localeId.language_id);
-
- // no match; try again with default script
- localeId.script_id = QLocale::AnyScript;
- data = locale_data + idx;
- }
-
if (localeId.script_id == QLocale::AnyScript && localeId.country_id == QLocale::AnyCountry)
return data;
@@ -369,15 +353,72 @@ const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLoca
if (data->m_country_id == localeId.country_id)
return data;
++data;
- } while (data->m_language_id == localeId.language_id);
+ } while (data->m_language_id && data->m_language_id == localeId.language_id);
} else if (localeId.country_id == QLocale::AnyCountry) {
do {
if (data->m_script_id == localeId.script_id)
return data;
++data;
- } while (data->m_language_id == localeId.language_id);
+ } while (data->m_language_id && data->m_language_id == localeId.language_id);
+ } else {
+ do {
+ if (data->m_script_id == localeId.script_id && data->m_country_id == localeId.country_id)
+ return data;
+ ++data;
+ } while (data->m_language_id && data->m_language_id == localeId.language_id);
+ }
+
+ return 0;
+}
+
+const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country)
+{
+ QLocaleId localeId = QLocaleId::fromIds(language, script, country);
+ localeId = localeId.withLikelySubtagsAdded();
+
+ const uint idx = locale_index[localeId.language_id];
+
+ // Try a straight match
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ QList<QLocaleId> tried;
+ tried.push_back(localeId);
+
+ // No match; try again with likely country
+ localeId = QLocaleId::fromIds(language, script, QLocale::AnyCountry);
+ localeId = localeId.withLikelySubtagsAdded();
+ if (!tried.contains(localeId)) {
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ tried.push_back(localeId);
}
+ // No match; try again with any country
+ localeId = QLocaleId::fromIds(language, script, QLocale::AnyCountry);
+ if (!tried.contains(localeId)) {
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ tried.push_back(localeId);
+ }
+
+ // No match; try again with likely script
+ localeId = QLocaleId::fromIds(language, QLocale::AnyScript, country);
+ localeId = localeId.withLikelySubtagsAdded();
+ if (!tried.contains(localeId)) {
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ tried.push_back(localeId);
+ }
+
+ // No match; try again with any script
+ localeId = QLocaleId::fromIds(language, QLocale::AnyScript, country);
+ if (!tried.contains(localeId)) {
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ tried.push_back(localeId);
+ }
+
+ // No match; return data at original index
return locale_data + idx;
}
@@ -1305,8 +1346,8 @@ float QLocale::toFloat(const QString &s, bool *ok) const
If \a ok is not 0, reports failure by setting
*ok to false and success by setting *ok to true.
- Unlike QString::toDouble(), this function does not fall back to
- the "C" locale if the string cannot be interpreted in this
+ Unlike QString::toDouble(), this function does not use
+ the 'C' locale if the string cannot be interpreted in this
locale.
\snippet code/src_corelib_tools_qlocale.cpp 3
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 4dbf95c315..5225b68d40 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -982,11 +982,13 @@ QT_BEGIN_INCLUDE_NAMESPACE
#include <QtCore/qpoint.h>
QT_END_INCLUDE_NAMESPACE
+#ifndef Q_TEMPLATE_EXTERN
#if defined(QT_BUILD_CORE_LIB)
#define Q_TEMPLATE_EXTERN
#else
#define Q_TEMPLATE_EXTERN extern
#endif
+#endif
Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPointF>;
Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector<QPoint>;
#endif