summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2018-06-01 14:15:15 +0200
committerMorten Johan Sørvig <morten.sorvig@qt.io>2018-06-01 14:15:15 +0200
commit02c8fa204f53af27907ef48bc74c500d7a05c3a0 (patch)
tree56519f143a72884a47c757d96c411e26c10c8a10 /src/corelib
parent36e8cf3cdb50c0447695f35c2e63eed139704c13 (diff)
parent0a63d5fed6e020e81d3c570d299d1292c33fa284 (diff)
Merge remote-tracking branch 'gerrit/5.11' into wip/webassembly
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/configure.json3
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp16
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp13
-rw-r--r--src/corelib/doc/snippets/qstringlist/main.cpp11
-rw-r--r--src/corelib/global/qglobal.cpp78
-rw-r--r--src/corelib/global/qglobal.h2
-rw-r--r--src/corelib/global/qlogging.cpp3
-rw-r--r--src/corelib/global/qnamespace.qdoc9
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm2
-rw-r--r--src/corelib/io/qloggingcategory.cpp27
-rw-r--r--src/corelib/io/qprocess_unix.cpp2
-rw-r--r--src/corelib/io/qprocess_win.cpp7
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.cpp69
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp5
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.h1
-rw-r--r--src/corelib/kernel/qcore_mac_objc.mm28
-rw-r--r--src/corelib/kernel/qcore_mac_p.h14
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf.mm17
-rw-r--r--src/corelib/kernel/qobject.cpp1
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp4
-rw-r--r--src/corelib/serialization/qjson.cpp45
-rw-r--r--src/corelib/serialization/qjson_p.h2
-rw-r--r--src/corelib/serialization/qjsondocument.cpp3
-rw-r--r--src/corelib/tools/qarraydataops.h10
-rw-r--r--src/corelib/tools/qbytearray.cpp67
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp2
-rw-r--r--src/corelib/tools/qlist.cpp13
-rw-r--r--src/corelib/tools/qlocale_unix.cpp52
-rw-r--r--src/corelib/tools/qpoint.h12
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h11
-rw-r--r--src/corelib/tools/qsimd_p.h5
-rw-r--r--src/corelib/tools/qstring.cpp97
-rw-r--r--src/corelib/tools/qstringlist.cpp15
34 files changed, 423 insertions, 225 deletions
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index 5019497dad..4c2506d8bc 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -569,7 +569,8 @@
},
"linkat": {
"label": "linkat()",
- "autoDetect": "config.linux",
+ "comment": "Currently only used by QTemporaryFile; linkat() exists on Android, but hardlink creation fails due to security rules",
+ "autoDetect": "config.linux && !config.android",
"condition": "tests.linkat",
"output": [ "privateFeature" ]
},
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
index ceb3f8adf3..2d7b9a9ac8 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
@@ -387,11 +387,11 @@ CONFIG += no_keywords
//! [34]
QString FriendlyConversation::greeting(int type)
{
-static const char *greeting_strings[] = {
- QT_TR_NOOP("Hello"),
- QT_TR_NOOP("Goodbye")
-};
-return tr(greeting_strings[type]);
+ static const char *greeting_strings[] = {
+ QT_TR_NOOP("Hello"),
+ QT_TR_NOOP("Goodbye")
+ };
+ return tr(greeting_strings[type]);
}
//! [34]
@@ -410,7 +410,7 @@ QString FriendlyConversation::greeting(int type)
QString global_greeting(int type)
{
return qApp->translate("FriendlyConversation",
- greeting_strings[type]);
+ greeting_strings[type]);
}
//! [35]
@@ -434,8 +434,8 @@ QString FriendlyConversation::greeting(int type)
QString global_greeting(int type)
{
return qApp->translate("FriendlyConversation",
- greeting_strings[type].source,
- greeting_strings[type].comment);
+ greeting_strings[type].source,
+ greeting_strings[type].comment);
}
//! [36]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
index ac17de1bee..27565a7878 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
@@ -54,11 +54,14 @@ QList<QDate> dateList;
//! [0]
-//! [1]
-QList<QString> list;
-list << "one" << "two" << "three";
-// list: ["one", "two", "three"]
-//! [1]
+//! [1a]
+QList<QString> list = { "one", "two", "three" };
+//! [1a]
+
+
+//! [1b]
+list << "four" << "five";
+//! [1b]
//! [2]
diff --git a/src/corelib/doc/snippets/qstringlist/main.cpp b/src/corelib/doc/snippets/qstringlist/main.cpp
index 4d9c015747..55c60650fe 100644
--- a/src/corelib/doc/snippets/qstringlist/main.cpp
+++ b/src/corelib/doc/snippets/qstringlist/main.cpp
@@ -61,10 +61,13 @@ public:
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
-//! [0]
- QStringList fonts;
- fonts << "Arial" << "Helvetica" << "Times" << "Courier";
-//! [0]
+//! [0a]
+ QStringList fonts = { "Arial", "Helvetica", "Times" };
+//! [0a]
+
+//! [0b]
+ fonts << "Courier" << "Verdana";
+//! [0b]
//! [1]
for (int i = 0; i < fonts.size(); ++i)
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index ad015ee048..2fbd31b3d7 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -648,10 +648,10 @@ Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value));
compiler or platform specific code to their application.
The remaining macros are convenience macros for larger operations:
- The QT_TRANSLATE_NOOP() and QT_TR_NOOP() macros provide the
- possibility of marking text for dynamic translation,
- i.e. translation without changing the stored source text. The
- Q_ASSERT() and Q_ASSERT_X() enables warning messages of various
+ The QT_TR_NOOP(), QT_TRANSLATE_NOOP(), and QT_TRANSLATE_NOOP3()
+ macros provide the possibility of marking strings for delayed
+ translation.
+ The Q_ASSERT() and Q_ASSERT_X() enables warning messages of various
level of refinement. The Q_FOREACH() and foreach() macros
implement Qt's foreach loop.
@@ -662,11 +662,11 @@ Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value));
memory, if the pointer is 0. The qPrintable() and qUtf8Printable()
macros represent an easy way of printing text.
- Finally, the QT_POINTER_SIZE macro expands to the size of a
- pointer in bytes, and the QT_VERSION and QT_VERSION_STR macros
- expand to a numeric value or a string, respectively, specifying
- Qt's version number, i.e the version the application is compiled
- against.
+ The QT_POINTER_SIZE macro expands to the size of a pointer in bytes.
+
+ The macros QT_VERSION and QT_VERSION_STR expand to a numeric value
+ or a string, respectively, that specifies the version of Qt that the
+ application is compiled against.
\sa <QtAlgorithms>, QSysInfo
*/
@@ -939,6 +939,8 @@ Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value));
Rounds \a d to the nearest integer.
+ Rounds half up (e.g. 0.5 -> 1, -0.5 -> 0).
+
Example:
\snippet code/src_corelib_global_qglobal.cpp 11A
@@ -949,6 +951,8 @@ Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value));
Rounds \a d to the nearest integer.
+ Rounds half up (e.g. 0.5f -> 1, -0.5f -> 0).
+
Example:
\snippet code/src_corelib_global_qglobal.cpp 11B
@@ -959,6 +963,8 @@ Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value));
Rounds \a d to the nearest 64-bit integer.
+ Rounds half up (e.g. 0.5 -> 1, -0.5 -> 0).
+
Example:
\snippet code/src_corelib_global_qglobal.cpp 12A
@@ -969,6 +975,8 @@ Q_STATIC_ASSERT((std::is_same<qsizetype, qptrdiff>::value));
Rounds \a d to the nearest 64-bit integer.
+ Rounds half up (e.g. 0.5f -> 1, -0.5f -> 0).
+
Example:
\snippet code/src_corelib_global_qglobal.cpp 12B
@@ -3268,14 +3276,15 @@ QByteArray qgetenv(const char *varName)
/*!
- QString qEnvironmentVariable(const char *varName, const QString &defaultValue);
+ \fn QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
+ \fn QString qEnvironmentVariable(const char *varName)
\relates <QtGlobal>
\since 5.10
- Returns the value of the environment variable with name \a varName as a
- QString. If no variable by that name is found in the environment, this
- function returns \a defaultValue.
+ These functions return the value of the environment variable, \a varName, as a
+ QString. If no variable \a varName is found in the environment and \a defaultValue
+ is provided, \a defaultValue is returned. Otherwise QString() is returned.
The Qt environment manipulation functions are thread-safe, but this
requires that the C library equivalent functions like getenv and putenv are
@@ -3344,9 +3353,6 @@ QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
#endif
}
-/*!
- \internal
-*/
QString qEnvironmentVariable(const char *varName)
{
return qEnvironmentVariable(varName, QString());
@@ -3678,19 +3684,18 @@ bool qunsetenv(const char *varName)
\macro QT_TR_NOOP(sourceText)
\relates <QtGlobal>
- Marks the string literal \a sourceText for dynamic translation in
- the current context (class), i.e the stored \a sourceText will not
- be altered.
+ Marks the UTF-8 encoded string literal \a sourceText for delayed
+ translation in the current context (class).
- The macro expands to \a sourceText.
+ The macro tells lupdate to collect the string, and expands to
+ \a sourceText itself.
Example:
\snippet code/src_corelib_global_qglobal.cpp 34
- The macro QT_TR_NOOP_UTF8() is identical except that it tells lupdate
- that the source string is encoded in UTF-8. Corresponding variants
- exist in the QT_TRANSLATE_NOOP() family of macros, too.
+ The macro QT_TR_NOOP_UTF8() is identical and obsolete; this applies
+ to all other _UTF8 macros as well.
\sa QT_TRANSLATE_NOOP(), {Internationalization with Qt}
*/
@@ -3699,12 +3704,12 @@ bool qunsetenv(const char *varName)
\macro QT_TRANSLATE_NOOP(context, sourceText)
\relates <QtGlobal>
- Marks the string literal \a sourceText for dynamic translation in
- the given \a context; i.e, the stored \a sourceText will not be
- altered. The \a context is typically a class and also needs to
- be specified as string literal.
+ Marks the UTF-8 encoded string literal \a sourceText for delayed
+ translation in the given \a context. The \a context is typically
+ a class name and also needs to be specified as a string literal.
- The macro expands to \a sourceText.
+ The macro tells lupdate to collect the string, and expands to
+ \a sourceText itself.
Example:
@@ -3714,18 +3719,19 @@ bool qunsetenv(const char *varName)
*/
/*!
- \macro QT_TRANSLATE_NOOP3(context, sourceText, comment)
+ \macro QT_TRANSLATE_NOOP3(context, sourceText, disambiguation)
\relates <QtGlobal>
\since 4.4
- Marks the string literal \a sourceText for dynamic translation in the
- given \a context and with \a comment, i.e the stored \a sourceText will
- not be altered. The \a context is typically a class and also needs to
- be specified as string literal. The string literal \a comment
- will be available for translators using e.g. Qt Linguist.
+ Marks the UTF-8 encoded string literal \a sourceText for delayed
+ translation in the given \a context with the given \a disambiguation.
+ The \a context is typically a class and also needs to be specified
+ as a string literal. The string literal \a disambiguation should be
+ a short semantic tag to tell apart otherwise identical strings.
- The macro expands to anonymous struct of the two string
- literals passed as \a sourceText and \a comment.
+ The macro tells lupdate to collect the string, and expands to an
+ anonymous struct of the two string literals passed as \a sourceText
+ and \a disambiguation.
Example:
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index e31d4d9ad7..3684c6b5de 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1062,7 +1062,7 @@ template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelpe
#define QT_TRANSLATE_NOOP3(scope, x, comment) {x, comment}
#define QT_TRANSLATE_NOOP3_UTF8(scope, x, comment) {x, comment}
-#ifndef QT_NO_TRANSLATION // ### This should enclose the NOOPs above
+#ifndef QT_NO_TRANSLATION // ### Qt6: This should enclose the NOOPs above
// Defined in qcoreapplication.cpp
// The better name qTrId() is reserved for an upcoming function which would
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 17002c4231..7444145e82 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -208,6 +208,7 @@ static bool isDefaultCategory(const char *category)
/*!
Returns true if writing to \c stderr is supported.
+ \internal
\sa stderrHasConsoleAttached()
*/
static bool systemHasStderr()
@@ -236,6 +237,7 @@ static bool systemHasStderr()
the output might still end up visible to the user. For this reason, we don't guard
the stderr output in the default message handler with stderrHasConsoleAttached().
+ \internal
\sa systemHasStderr()
*/
bool stderrHasConsoleAttached()
@@ -288,6 +290,7 @@ namespace QtPrivate {
This is normally the case if \c stderr has a console attached, but may be overridden
by the user by setting the QT_FORCE_STDERR_LOGGING environment variable to \c 1.
+ \internal
\sa stderrHasConsoleAttached()
*/
bool shouldLogToStderr()
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 11c431d015..0361fd6085 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -1329,7 +1329,14 @@
\omitvalue WA_WState_WindowOpacitySet
\omitvalue WA_WState_AcceptedTouchBeginEvent
\omitvalue WA_MacNoShadow
- \omitvalue WA_ContentsMarginsRespectsSafeArea
+ \value WA_ContentsMarginsRespectsSafeArea A QWidget respects the safe
+ area margins of a window by incorporating the margins into its contents'
+ margins by default. This means, that a QLayout will use the content area
+ of a widget for its layout, unless the Qt::WA_LayoutOnEntireRect attribute
+ is set. This along with a contents margin of 0 can be used on the actual
+ layout, to allow for example a background image to underlay the status bar and other
+ system areas on an iOS device, while still allowing child widgets of
+ that background to be inset based on the safe area.
*/
/*! \typedef Qt::HANDLE
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 0c38731052..5561ecbb6d 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -114,6 +114,8 @@ static int renameat2(int oldfd, const char *oldpath, int newfd, const char *newp
# if !QT_CONFIG(statx) && defined(SYS_statx)
static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struct statx *statxbuf)
{ return syscall(SYS_statx, dirfd, pathname, flag, mask, statxbuf); }
+# elif !QT_CONFIG(statx) && !defined(SYS_statx)
+# undef STATX_BASIC_STATS
# endif
# endif // !Q_OS_ANDROID
#endif
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
index 792ea387ac..0254d0f7a1 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.mm
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -377,7 +377,7 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
for (PathRefCounts::const_iterator i = watchingState.watchedPaths.begin(),
ei = watchingState.watchedPaths.end(); i != ei; ++i) {
- if (watchedPath.startsWith(i.key())) {
+ if (watchedPath.startsWith(i.key() % QDir::separator())) {
watchedPath = i.key();
break;
}
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index b029274329..a6c27d19c0 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -147,9 +147,15 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
Rules are evaluated in text order, from first to last. That is, if two rules
apply to a category/type, the rule that comes later is applied.
- Rules can be set via \l setFilterRules(). Since Qt 5.3, logging rules can also
- be set in the \c QT_LOGGING_RULES environment variable, and
- are automatically loaded from the \c [Rules] section of a logging
+ Rules can be set via \l setFilterRules():
+
+ \code
+ QLoggingCategory::setFilterRules("*.debug=false\n"
+ "driver.usb.debug=true");
+ \endcode
+
+ Since Qt 5.3, logging rules are also
+ automatically loaded from the \c [Rules] section of a logging
configuration file. Such configuration files are looked up in the QtProject
configuration directory, or explicitly set in a \c QT_LOGGING_CONF
environment variable:
@@ -160,19 +166,18 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
driver.usb.debug=true
\endcode
- Rules set by \l setFilterRules() take precedence over rules specified
- in the QtProject configuration directory, and can, in turn, be
- overwritten by rules from the configuration file specified by
- \c QT_LOGGING_CONF, and rules set by \c QT_LOGGING_RULES.
-
-
- Since Qt 5.6, \c QT_LOGGING_RULES may contain multiple rules separated
- by semicolons:
+ Since Qt 5.3, logging rules can also be specified in a \c QT_LOGGING_RULES
+ environment variable. And since Qt 5.6, multiple rules can also be
+ separated by semicolons:
\code
QT_LOGGING_RULES="*.debug=false;driver.usb.debug=true"
\endcode
+ Rules set by \l setFilterRules() take precedence over rules specified
+ in the QtProject configuration directory, and can, in turn, be
+ overwritten by rules from the configuration file specified by
+ \c QT_LOGGING_CONF, and rules set by \c QT_LOGGING_RULES.
Order of evaluation:
\list
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 68b7a8bf9b..a849519635 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -925,6 +925,8 @@ bool QProcessPrivate::startDetached(qint64 *pid)
closeChannel(&stdinChannel);
closeChannel(&stdoutChannel);
closeChannel(&stderrChannel);
+ qt_safe_close(pidPipe[0]);
+ qt_safe_close(pidPipe[1]);
qt_safe_close(startedPipe[0]);
qt_safe_close(startedPipe[1]);
return false;
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index 3a62a67e3b..b1ec2c560c 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -499,8 +499,13 @@ void QProcessPrivate::startProcess()
if (!openChannel(stdinChannel) ||
!openChannel(stdoutChannel) ||
- !openChannel(stderrChannel))
+ !openChannel(stderrChannel)) {
+ QString errorString = QProcess::tr("Process failed to start: %1").arg(qt_error_string());
+ cleanup();
+ setErrorAndEmit(QProcess::FailedToStart, errorString);
+ q->setProcessState(QProcess::NotRunning);
return;
+ }
const QString args = qt_create_commandline(program, arguments, nativeArguments);
QByteArray envlist;
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp
index 9af4fd9133..edb9bb9098 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.cpp
+++ b/src/corelib/itemmodels/qitemselectionmodel.cpp
@@ -1502,30 +1502,40 @@ bool QItemSelectionModel::isRowSelected(int row, const QModelIndex &parent) cons
&& d->currentSelection.at(i).intersected(d->ranges.at(j)).isValid())
return false;
}
+
+ auto isSelectable = [&](int row, int column) {
+ Qt::ItemFlags flags = d->model->index(row, column, parent).flags();
+ return (flags & Qt::ItemIsSelectable);
+ };
+
+ const int colCount = d->model->columnCount(parent);
+ int unselectable = 0;
// add ranges and currentSelection and check through them all
QList<QItemSelectionRange>::const_iterator it;
QList<QItemSelectionRange> joined = d->ranges;
if (d->currentSelection.count())
joined += d->currentSelection;
- int colCount = d->model->columnCount(parent);
for (int column = 0; column < colCount; ++column) {
+ if (!isSelectable(row, column)) {
+ ++unselectable;
+ continue;
+ }
+
for (it = joined.constBegin(); it != joined.constEnd(); ++it) {
if ((*it).contains(row, column, parent)) {
- bool selectable = false;
- for (int i = column; !selectable && i <= (*it).right(); ++i) {
- Qt::ItemFlags flags = d->model->index(row, i, parent).flags();
- selectable = flags & Qt::ItemIsSelectable;
- }
- if (selectable){
- column = qMax(column, (*it).right());
- break;
+ for (int i = column; i <= (*it).right(); ++i) {
+ if (!isSelectable(row, i))
+ ++unselectable;
}
+
+ column = qMax(column, (*it).right());
+ break;
}
}
if (it == joined.constEnd())
return false;
}
- return colCount > 0; // no columns means no selected items
+ return unselectable < colCount;
}
/*!
@@ -1568,26 +1578,39 @@ bool QItemSelectionModel::isColumnSelected(int column, const QModelIndex &parent
}
}
}
+
+ auto isSelectable = [&](int row, int column) {
+ Qt::ItemFlags flags = d->model->index(row, column, parent).flags();
+ return (flags & Qt::ItemIsSelectable);
+ };
+ const int rowCount = d->model->rowCount(parent);
+ int unselectable = 0;
+
// add ranges and currentSelection and check through them all
QList<QItemSelectionRange>::const_iterator it;
QList<QItemSelectionRange> joined = d->ranges;
if (d->currentSelection.count())
joined += d->currentSelection;
- int rowCount = d->model->rowCount(parent);
for (int row = 0; row < rowCount; ++row) {
- for (it = joined.constBegin(); it != joined.constEnd(); ++it) {
- if ((*it).contains(row, column, parent)) {
- Qt::ItemFlags flags = d->model->index(row, column, parent).flags();
- if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled)) {
- row = qMax(row, (*it).bottom());
- break;
- }
- }
- }
- if (it == joined.constEnd())
- return false;
+ if (!isSelectable(row, column)) {
+ ++unselectable;
+ continue;
+ }
+ for (it = joined.constBegin(); it != joined.constEnd(); ++it) {
+ if ((*it).contains(row, column, parent)) {
+ for (int i = row; i <= (*it).bottom(); ++i) {
+ if (!isSelectable(i, column)) {
+ ++unselectable;
+ }
+ }
+ row = qMax(row, (*it).bottom());
+ break;
+ }
+ }
+ if (it == joined.constEnd())
+ return false;
}
- return rowCount > 0; // no rows means no selected items
+ return unselectable < rowCount;
}
/*!
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 78093727b8..08279cb244 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -1910,7 +1910,10 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset()));
disconnect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset()));
- d->_q_sourceModelDestroyed();
+ // same as in _q_sourceReset()
+ d->invalidatePersistentIndexes();
+ d->_q_clearMapping();
+
QAbstractProxyModel::setSourceModel(sourceModel);
connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)),
diff --git a/src/corelib/kernel/qabstracteventdispatcher.h b/src/corelib/kernel/qabstracteventdispatcher.h
index 4775d3d47a..bd8da5c35d 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.h
+++ b/src/corelib/kernel/qabstracteventdispatcher.h
@@ -87,6 +87,7 @@ public:
QT_DEPRECATED inline void registerTimer(int timerId, int interval, QObject *object)
{ registerTimer(timerId, interval, Qt::CoarseTimer, object); }
#endif
+ // ### Qt6: change interval range to qint64 (or use QDeadlineTimer)
int registerTimer(int interval, Qt::TimerType timerType, QObject *object);
virtual void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) = 0;
virtual bool unregisterTimer(int timerId) = 0;
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm
index 5ecd86a30e..c29c4dfc14 100644
--- a/src/corelib/kernel/qcore_mac_objc.mm
+++ b/src/corelib/kernel/qcore_mac_objc.mm
@@ -161,6 +161,34 @@ QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool)
}
#endif // !QT_NO_DEBUG_STREAM
+bool qt_apple_isApplicationExtension()
+{
+ static bool isExtension = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSExtension"];
+ return isExtension;
+}
+
+#if !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WATCHOS)
+AppleApplication *qt_apple_sharedApplication()
+{
+ // Application extensions are not allowed to access the shared application
+ if (qt_apple_isApplicationExtension()) {
+ qWarning() << "accessing the shared" << [AppleApplication class]
+ << "is not allowed in application extensions";
+
+ // In practice the application is actually available, but the the App
+ // review process will likely catch uses of it, so we return nil just
+ // in case, unless we don't care about being App Store compliant.
+#if QT_CONFIG(appstore_compliant)
+ return nil;
+#endif
+ }
+
+ // We use performSelector so that building with -fapplication-extension will
+ // not mistakenly think we're using the shared application in extensions.
+ return [[AppleApplication class] performSelector:@selector(sharedApplication)];
+}
+#endif
+
#ifdef Q_OS_MACOS
/*
Ensure that Objective-C objects auto-released in main(), directly or indirectly,
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index 9c6cef68b2..9bd2e31bc9 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -158,6 +158,20 @@ QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool);
#endif
Q_CORE_EXPORT void qt_apple_check_os_version();
+Q_CORE_EXPORT bool qt_apple_isApplicationExtension();
+
+#if !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WATCHOS)
+QT_END_NAMESPACE
+# if defined(Q_OS_MACOS)
+Q_FORWARD_DECLARE_OBJC_CLASS(NSApplication);
+using AppleApplication = NSApplication;
+# else
+Q_FORWARD_DECLARE_OBJC_CLASS(UIApplication);
+using AppleApplication = UIApplication;
+# endif
+QT_BEGIN_NAMESPACE
+Q_CORE_EXPORT AppleApplication *qt_apple_sharedApplication();
+#endif
// --------------------------------------------------------------------------
diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm
index 8499b3fd57..503836d071 100644
--- a/src/corelib/kernel/qeventdispatcher_cf.mm
+++ b/src/corelib/kernel/qeventdispatcher_cf.mm
@@ -72,17 +72,12 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(RunLoopModeTracker);
if (self = [super init]) {
m_runLoopModes.push(kCFRunLoopDefaultMode);
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(receivedNotification:)
- name:nil
-#ifdef Q_OS_OSX
- object:[NSApplication sharedApplication]];
-#elif defined(Q_OS_WATCHOS)
- object:[WKExtension sharedExtension]];
-#else
- // Use performSelector so this can work in an App Extension
- object:[[UIApplication class] performSelector:@selector(sharedApplication)]];
+#if !defined(Q_OS_WATCHOS)
+ if (!qt_apple_isApplicationExtension()) {
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self selector:@selector(receivedNotification:)
+ name:nil object:qt_apple_sharedApplication()];
+ }
#endif
}
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 69d76915c9..016b67d790 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -4430,6 +4430,7 @@ QDebug operator<<(QDebug dbg, const QObject *o)
/*!
\macro Q_NAMESPACE
+ \relates QObject
\since 5.8
The Q_NAMESPACE macro can be used to add QMetaObject capabilities
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index 7d529372c4..68e3c8f10d 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -311,9 +311,9 @@ static inline bool isTextFile(const QByteArray &data)
if (data.startsWith(bigEndianBOM) || data.startsWith(littleEndianBOM))
return true;
- // Check the first 32 bytes (see shared-mime spec)
+ // Check the first 128 bytes (see shared-mime spec)
const char *p = data.constData();
- const char *e = p + qMin(32, data.size());
+ const char *e = p + qMin(128, data.size());
for ( ; p < e; ++p) {
if ((unsigned char)(*p) < 32 && *p != 9 && *p !=10 && *p != 13)
return false;
diff --git a/src/corelib/serialization/qjson.cpp b/src/corelib/serialization/qjson.cpp
index e4bca3bcd0..7912b5040c 100644
--- a/src/corelib/serialization/qjson.cpp
+++ b/src/corelib/serialization/qjson.cpp
@@ -326,40 +326,35 @@ int Value::usedStorage(const Base *b) const
return alignedSize(s);
}
+inline bool isValidValueOffset(uint offset, uint tableOffset)
+{
+ return offset >= sizeof(Base)
+ && offset + sizeof(uint) <= tableOffset;
+}
+
bool Value::isValid(const Base *b) const
{
- int offset = 0;
switch (type) {
+ case QJsonValue::Null:
+ case QJsonValue::Bool:
+ return true;
case QJsonValue::Double:
- if (latinOrIntValue)
- break;
- Q_FALLTHROUGH();
+ return latinOrIntValue || isValidValueOffset(value, b->tableOffset);
case QJsonValue::String:
+ if (!isValidValueOffset(value, b->tableOffset))
+ return false;
+ if (latinOrIntValue)
+ return asLatin1String(b).isValid(b->tableOffset - value);
+ return asString(b).isValid(b->tableOffset - value);
case QJsonValue::Array:
+ return isValidValueOffset(value, b->tableOffset)
+ && static_cast<Array *>(base(b))->isValid(b->tableOffset - value);
case QJsonValue::Object:
- offset = value;
- break;
- case QJsonValue::Null:
- case QJsonValue::Bool:
+ return isValidValueOffset(value, b->tableOffset)
+ && static_cast<Object *>(base(b))->isValid(b->tableOffset - value);
default:
- break;
- }
-
- if (!offset)
- return true;
- if (offset + sizeof(uint) > b->tableOffset)
return false;
-
- int s = usedStorage(b);
- if (!s)
- return true;
- if (s < 0 || s > (int)b->tableOffset - offset)
- return false;
- if (type == QJsonValue::Array)
- return static_cast<Array *>(base(b))->isValid(s);
- if (type == QJsonValue::Object)
- return static_cast<Object *>(base(b))->isValid(s);
- return true;
+ }
}
/*!
diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h
index 7743382806..dc56a49084 100644
--- a/src/corelib/serialization/qjson_p.h
+++ b/src/corelib/serialization/qjson_p.h
@@ -450,7 +450,7 @@ static inline void copyString(char *dest, const QString &str, bool compress)
/*
- Base is the base class for both Object and Array. Both classe work more or less the same way.
+ Base is the base class for both Object and Array. Both classes work more or less the same way.
The class starts with a header (defined by the struct below), then followed by data (the data for
values in the Array case and Entry's (see below) for objects.
diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp
index 9794bca60d..ab27b45fda 100644
--- a/src/corelib/serialization/qjsondocument.cpp
+++ b/src/corelib/serialization/qjsondocument.cpp
@@ -210,6 +210,9 @@ QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidat
return QJsonDocument();
}
+ if (size < (int)(sizeof(QJsonPrivate::Header) + sizeof(QJsonPrivate::Base)))
+ return QJsonDocument();
+
QJsonPrivate::Data *d = new QJsonPrivate::Data((char *)data, size);
d->ownsData = false;
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index d0f83d2b6a..7e1b43f9b1 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -65,7 +65,7 @@ struct QPodArrayOps
Q_ASSERT(newSize > uint(this->size));
Q_ASSERT(newSize <= this->alloc);
- ::memset(this->end(), 0, (newSize - this->size) * sizeof(T));
+ ::memset(static_cast<void *>(this->end()), 0, (newSize - this->size) * sizeof(T));
this->size = int(newSize);
}
@@ -121,8 +121,9 @@ struct QPodArrayOps
Q_ASSERT(e <= where || b > this->end()); // No overlap
Q_ASSERT(size_t(e - b) <= this->alloc - uint(this->size));
- ::memmove(where + (e - b), where, (static_cast<const T*>(this->end()) - where) * sizeof(T));
- ::memcpy(where, b, (e - b) * sizeof(T));
+ ::memmove(static_cast<void *>(where + (e - b)), static_cast<void *>(where),
+ (static_cast<const T*>(this->end()) - where) * sizeof(T));
+ ::memcpy(static_cast<void *>(where), static_cast<const void *>(b), (e - b) * sizeof(T));
this->size += (e - b);
}
@@ -133,7 +134,8 @@ struct QPodArrayOps
Q_ASSERT(b >= this->begin() && b < this->end());
Q_ASSERT(e > this->begin() && e < this->end());
- ::memmove(b, e, (static_cast<T *>(this->end()) - e) * sizeof(T));
+ ::memmove(static_cast<void *>(b), static_cast<void *>(e),
+ (static_cast<T *>(this->end()) - e) * sizeof(T));
this->size -= (e - b);
}
};
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 421e716d14..7c601e1336 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -238,7 +238,8 @@ qCalculateGrowingBlockSize(size_t elementCount, size_t elementSize, size_t heade
Returns a duplicate string.
Allocates space for a copy of \a src, copies it, and returns a
- pointer to the copy. If \a src is 0, it immediately returns 0.
+ pointer to the copy. If \a src is nullptr, it immediately returns
+ nullptr.
Ownership is passed to the caller, so the returned string must be
deleted using \c delete[].
@@ -247,7 +248,7 @@ qCalculateGrowingBlockSize(size_t elementCount, size_t elementSize, size_t heade
char *qstrdup(const char *src)
{
if (!src)
- return 0;
+ return nullptr;
char *dst = new char[strlen(src) + 1];
return qstrcpy(dst, src);
}
@@ -255,26 +256,28 @@ char *qstrdup(const char *src)
/*! \relates QByteArray
Copies all the characters up to and including the '\\0' from \a
- src into \a dst and returns a pointer to \a dst. If \a src is 0,
- it immediately returns 0.
+ src into \a dst and returns a pointer to \a dst. If \a src is
+ nullptr, it immediately returns nullptr.
This function assumes that \a dst is large enough to hold the
contents of \a src.
+ \note If \a dst and \a src overlap, the behavior is undefined.
+
\sa qstrncpy()
*/
char *qstrcpy(char *dst, const char *src)
{
if (!src)
- return 0;
+ return nullptr;
#ifdef Q_CC_MSVC
const int len = int(strlen(src));
// This is actually not secure!!! It will be fixed
// properly in a later release!
if (len >= 0 && strcpy_s(dst, len+1, src) == 0)
return dst;
- return 0;
+ return nullptr;
#else
return strcpy(dst, src);
#endif
@@ -287,11 +290,13 @@ char *qstrcpy(char *dst, const char *src)
Copies at most \a len bytes from \a src (stopping at \a len or the
terminating '\\0' whichever comes first) into \a dst and returns a
pointer to \a dst. Guarantees that \a dst is '\\0'-terminated. If
- \a src or \a dst is 0, returns 0 immediately.
+ \a src or \a dst is nullptr, returns nullptr immediately.
This function assumes that \a dst is at least \a len characters
long.
+ \note If \a dst and \a src overlap, the behavior is undefined.
+
\note When compiling with Visual C++ compiler version 14.00
(Visual C++ 2005) or later, internally the function strncpy_s
will be used.
@@ -302,7 +307,7 @@ char *qstrcpy(char *dst, const char *src)
char *qstrncpy(char *dst, const char *src, uint len)
{
if (!src || !dst)
- return 0;
+ return nullptr;
if (len > 0) {
#ifdef Q_CC_MSVC
strncpy_s(dst, len, src, len - 1);
@@ -320,7 +325,7 @@ char *qstrncpy(char *dst, const char *src, uint len)
A safe \c strlen() function.
Returns the number of characters that precede the terminating '\\0',
- or 0 if \a str is 0.
+ or 0 if \a str is nullptr.
\sa qstrnlen()
*/
@@ -332,7 +337,7 @@ char *qstrncpy(char *dst, const char *src, uint len)
A safe \c strnlen() function.
Returns the number of characters that precede the terminating '\\0', but
- at most \a maxlen. If \a str is 0, returns 0.
+ at most \a maxlen. If \a str is nullptr, returns 0.
\sa qstrlen()
*/
@@ -346,10 +351,10 @@ char *qstrncpy(char *dst, const char *src, uint len)
is less than \a str2, 0 if \a str1 is equal to \a str2 or a
positive value if \a str1 is greater than \a str2.
- Special case 1: Returns 0 if \a str1 and \a str2 are both 0.
+ Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr.
- Special case 2: Returns an arbitrary non-zero value if \a str1 is 0
- or \a str2 is 0 (but not both).
+ Special case 2: Returns an arbitrary non-zero value if \a str1 is
+ nullptr or \a str2 is nullptr (but not both).
\sa qstrncmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons}
*/
@@ -371,10 +376,10 @@ int qstrcmp(const char *str1, const char *str2)
str1 is equal to \a str2 or a positive value if \a str1 is greater
than \a str2.
- Special case 1: Returns 0 if \a str1 and \a str2 are both 0.
+ Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr.
- Special case 2: Returns a random non-zero value if \a str1 is 0
- or \a str2 is 0 (but not both).
+ Special case 2: Returns a random non-zero value if \a str1 is nullptr
+ or \a str2 is nullptr (but not both).
\sa qstrcmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons}
*/
@@ -390,10 +395,10 @@ int qstrcmp(const char *str1, const char *str2)
str1 is equal to \a str2 or a positive value if \a str1 is greater
than \a str2.
- Special case 1: Returns 0 if \a str1 and \a str2 are both 0.
+ Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr.
- Special case 2: Returns a random non-zero value if \a str1 is 0
- or \a str2 is 0 (but not both).
+ Special case 2: Returns a random non-zero value if \a str1 is nullptr
+ or \a str2 is nullptr (but not both).
\sa qstrcmp(), qstrncmp(), qstrnicmp(), {8-bit Character Comparisons}
*/
@@ -424,10 +429,10 @@ int qstricmp(const char *str1, const char *str2)
is equal to \a str2 or a positive value if \a str1 is greater than \a
str2.
- Special case 1: Returns 0 if \a str1 and \a str2 are both 0.
+ Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr.
- Special case 2: Returns a random non-zero value if \a str1 is 0
- or \a str2 is 0 (but not both).
+ Special case 2: Returns a random non-zero value if \a str1 is nullptr
+ or \a str2 is nullptr (but not both).
\sa qstrcmp(), qstrncmp(), qstricmp(), {8-bit Character Comparisons}
*/
@@ -777,19 +782,6 @@ QByteArray qUncompress(const uchar* data, int nbytes)
}
#endif
-static inline bool qIsUpper(char c)
-{
- return c >= 'A' && c <= 'Z';
-}
-
-static inline char qToLower(char c)
-{
- if (c >= 'A' && c <= 'Z')
- return c - 'A' + 'a';
- else
- return c;
-}
-
/*!
\class QByteArray
\inmodule QtCore
@@ -4131,9 +4123,10 @@ QByteArray &QByteArray::setNum(double n, char f, int prec)
QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
uint flags = QLocaleData::ZeroPadExponent;
- if (qIsUpper(f))
+ char lower = latin1_lowercased[uchar(f)];
+ if (f != lower)
flags |= QLocaleData::CapitalEorX;
- f = qToLower(f);
+ f = lower;
switch (f) {
case 'f':
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index 551e01e076..d03518e70d 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -44,7 +44,9 @@
#include "qset.h"
#include "qlocale.h"
#include "qdatetime.h"
+#if QT_CONFIG(timezone)
#include "qtimezone.h"
+#endif
#include "qregexp.h"
#include "qdebug.h"
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 33835e3d28..17aba8035b 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -408,15 +408,20 @@ void **QListData::erase(void **xi)
from strings.
QList stores a list of items. The default constructor creates an
- empty list. To insert items into the list, you can use
- operator<<():
+ empty list. You can use the initializer-list constructor to create
+ a list with elements:
- \snippet code/src_corelib_tools_qlistdata.cpp 1
+ \snippet code/src_corelib_tools_qlistdata.cpp 1a
QList provides these basic functions to add, move, and remove
items: insert(), replace(), removeAt(), move(), and swap(). In
addition, it provides the following convenience functions:
- append(), prepend(), removeFirst(), and removeLast().
+ append(), \l{operator<<()}, \l{operator+=()}, prepend(), removeFirst(),
+ and removeLast().
+
+ \l{operator<<()} allows to conveniently add multiple elements to a list:
+
+ \snippet code/src_corelib_tools_qlistdata.cpp 1b
QList uses 0-based indexes, just like C++ arrays. To access the
item at a particular index position, you can use operator[](). On
diff --git a/src/corelib/tools/qlocale_unix.cpp b/src/corelib/tools/qlocale_unix.cpp
index 095001e0a3..f202082213 100644
--- a/src/corelib/tools/qlocale_unix.cpp
+++ b/src/corelib/tools/qlocale_unix.cpp
@@ -107,27 +107,55 @@ Q_GLOBAL_STATIC(QSystemLocaleData, qSystemLocaleData)
#ifndef QT_NO_SYSTEMLOCALE
+static bool contradicts(const QString &maybe, const QString &known)
+{
+ if (maybe.isEmpty())
+ return false;
+
+ /*
+ If \a known (our current best shot at deciding which language to use)
+ provides more information (e.g. script, country) than \a maybe (a
+ candidate to replace \a known) and \a maybe agrees with \a known in what
+ it does provide, we keep \a known; this happens when \a maybe comes from
+ LANGUAGE (usually a simple language code) and LANG includes script and/or
+ country. A textual comparison won't do because, for example, bn (Bengali)
+ isn't a prefix of ben_IN, but the latter is a refinement of the former.
+ (Meanwhile, bn is a prefix of bnt, Bantu; and a prefix of ben is be,
+ Belarusian. There are many more such prefixings between two- and
+ three-letter codes.)
+ */
+ QLocale::Language langm, langk;
+ QLocale::Script scriptm, scriptk;
+ QLocale::Country landm, landk;
+ QLocalePrivate::getLangAndCountry(maybe, langm, scriptm, landm);
+ QLocalePrivate::getLangAndCountry(known, langk, scriptk, landk);
+ return (langm != QLocale::AnyLanguage && langm != langk)
+ || (scriptm != QLocale::AnyScript && scriptm != scriptk)
+ || (landm != QLocale::AnyCountry && landm != landk);
+}
+
QLocale QSystemLocale::fallbackUiLocale() const
{
- QByteArray lang = qgetenv("LC_ALL");
+ // See man 7 locale for precedence - LC_ALL beats LC_MESSAGES beats LANG:
+ QString lang = qEnvironmentVariable("LC_ALL");
if (lang.isEmpty())
- lang = qgetenv("LC_MESSAGES");
+ lang = qEnvironmentVariable("LC_MESSAGES");
if (lang.isEmpty())
- lang = qgetenv("LANG");
+ lang = qEnvironmentVariable("LANG");
// if the locale is the "C" locale, then we can return the language we found here:
- if (lang.isEmpty() || lang == QByteArray("C") || lang == QByteArray("POSIX"))
- return QLocale(QString::fromLatin1(lang));
+ if (lang.isEmpty() || lang == QLatin1String("C") || lang == QLatin1String("POSIX"))
+ return QLocale(lang);
- // if the locale is not the "C" locale and LANGUAGE is not empty, return
- // the first part of LANGUAGE if LANGUAGE is set and has a first part:
- QByteArray language = qgetenv("LANGUAGE");
+ // ... otherwise, if the first part of LANGUAGE says more than or
+ // contradicts what we have, use that:
+ QString language = qEnvironmentVariable("LANGUAGE");
if (!language.isEmpty()) {
- language = language.split(':').constFirst();
- if (!language.isEmpty())
- return QLocale(QString::fromLatin1(language));
+ language = language.split(QLatin1Char(':')).constFirst();
+ if (contradicts(language, lang))
+ return QLocale(language);
}
- return QLocale(QString::fromLatin1(lang));
+ return QLocale(lang);
}
QVariant QSystemLocale::query(QueryType type, QVariant in) const
diff --git a/src/corelib/tools/qpoint.h b/src/corelib/tools/qpoint.h
index 0f3e0c3517..ae46f0d39f 100644
--- a/src/corelib/tools/qpoint.h
+++ b/src/corelib/tools/qpoint.h
@@ -345,16 +345,24 @@ Q_DECL_RELAXED_CONSTEXPR inline QPointF &QPointF::operator*=(qreal c)
xp*=c; yp*=c; return *this;
}
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
+QT_WARNING_DISABLE_GCC("-Wfloat-equal")
+
Q_DECL_CONSTEXPR inline bool operator==(const QPointF &p1, const QPointF &p2)
{
- return qFuzzyIsNull(p1.xp - p2.xp) && qFuzzyIsNull(p1.yp - p2.yp);
+ return ((!p1.xp && !p1.yp) || (!p2.xp && !p2.yp))
+ ? (qFuzzyIsNull(p1.xp - p2.xp) && qFuzzyIsNull(p1.yp - p2.yp))
+ : (qFuzzyCompare(p1.xp, p2.xp) && qFuzzyCompare(p1.yp, p2.yp));
}
Q_DECL_CONSTEXPR inline bool operator!=(const QPointF &p1, const QPointF &p2)
{
- return !qFuzzyIsNull(p1.xp - p2.xp) || !qFuzzyIsNull(p1.yp - p2.yp);
+ return !(p1 == p2);
}
+QT_WARNING_POP
+
Q_DECL_CONSTEXPR inline const QPointF operator+(const QPointF &p1, const QPointF &p2)
{
return QPointF(p1.xp+p2.xp, p1.yp+p2.yp);
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index a0e408b94a..bccf8c5740 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -246,7 +246,8 @@ namespace QtSharedPointer {
struct ExternalRefCountWithContiguousData: public ExternalRefCountData
{
typedef ExternalRefCountData Parent;
- T data;
+ typedef typename std::remove_cv<T>::type NoCVType;
+ NoCVType data;
static void deleter(ExternalRefCountData *self)
{
@@ -262,7 +263,7 @@ namespace QtSharedPointer {
}
static void noDeleter(ExternalRefCountData *) { }
- static inline ExternalRefCountData *create(T **ptr, DestroyerFn destroy)
+ static inline ExternalRefCountData *create(NoCVType **ptr, DestroyerFn destroy)
{
ExternalRefCountWithContiguousData *d =
static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData)));
@@ -437,10 +438,12 @@ public:
# endif
typename Private::DestroyerFn noDestroy = &Private::noDeleter;
QSharedPointer result(Qt::Uninitialized);
- result.d = Private::create(&result.value, noDestroy);
+ typename std::remove_cv<T>::type *ptr;
+ result.d = Private::create(&ptr, noDestroy);
// now initialize the data
- new (result.data()) T(std::forward<Args>(arguments)...);
+ new (ptr) T(std::forward<Args>(arguments)...);
+ result.value = ptr;
result.d->destroyer = destroy;
result.d->setQObjectShared(result.value, true);
# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index eb56b31348..18684caefb 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -219,9 +219,8 @@
// AVX intrinsics
# if defined(__AVX__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC))
// AES, PCLMULQDQ instructions:
-// All processors that support AVX support AES, PCLMULQDQ
-// (but neither MSVC nor the Intel compiler define these macros)
-# define __AES__ 1
+// All processors that support AVX support PCLMULQDQ
+// (but neither MSVC nor the Intel compiler define this macro)
# define __PCLMUL__ 1
# endif
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index f6360f5504..a4b34263df 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -259,7 +259,7 @@ static bool simdTestMask(const char *&ptr, const char *end, quint32 maskval)
# if defined(__AVX2__)
// AVX2 implementation: test 32 bytes at a time
const __m256i mask256 = _mm256_broadcastd_epi32(_mm_cvtsi32_si128(maskval));
- while (ptr + 32 < end) {
+ while (ptr + 32 <= end) {
__m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(ptr));
if (!_mm256_testz_si256(mask256, data))
return false;
@@ -271,7 +271,7 @@ static bool simdTestMask(const char *&ptr, const char *end, quint32 maskval)
// SSE 4.1 implementation: test 32 bytes at a time (two 16-byte
// comparisons, unrolled)
const __m128i mask = _mm_set1_epi32(maskval);
- while (ptr + 32 < end) {
+ while (ptr + 32 <= end) {
__m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
__m128i data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr + 16));
if (!_mm_testz_si128(mask, data1))
@@ -283,7 +283,7 @@ static bool simdTestMask(const char *&ptr, const char *end, quint32 maskval)
# endif
# if defined(__SSE4_1__)
// AVX2 and SSE4.1: final 16-byte comparison
- if (ptr + 16 < end) {
+ if (ptr + 16 <= end) {
__m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
if (!_mm_testz_si128(mask, data1))
return false;
@@ -311,12 +311,19 @@ bool QtPrivate::isAscii(QLatin1String s) Q_DECL_NOTHROW
const char *ptr = s.begin();
const char *end = s.end();
-#if defined(__AVX2__)
- if (!simdTestMask(ptr, end, 0x80808080))
- return false;
-#elif defined(__SSE2__)
+#if defined(__SSE2__)
// Testing for the high bit can be done efficiently with just PMOVMSKB
- while (ptr + 16 < end) {
+# if defined(__AVX2__)
+ while (ptr + 32 <= end) {
+ __m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(ptr));
+ quint32 mask = _mm256_movemask_epi8(data);
+ if (mask)
+ return false;
+ ptr += 32;
+ }
+# endif
+
+ while (ptr + 16 <= end) {
__m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
quint32 mask = _mm_movemask_epi8(data);
if (mask)
@@ -325,7 +332,7 @@ bool QtPrivate::isAscii(QLatin1String s) Q_DECL_NOTHROW
}
#endif
- while (ptr + 4 < end) {
+ while (ptr + 4 <= end) {
quint32 data = qFromUnaligned<quint32>(ptr);
if (data & 0x80808080U)
return false;
@@ -646,30 +653,70 @@ static int ucstrncmp(const QChar *a, const QChar *b, size_t l)
}
#endif // __mips_dsp
#ifdef __SSE2__
- const char *ptr = reinterpret_cast<const char*>(a);
- qptrdiff distance = reinterpret_cast<const char*>(b) - ptr;
- a += l & ~7;
- b += l & ~7;
- l &= 7;
-
- // we're going to read ptr[0..15] (16 bytes)
- for ( ; ptr + 15 < reinterpret_cast<const char *>(a); ptr += 16) {
- __m128i a_data = _mm_loadu_si128((const __m128i*)ptr);
- __m128i b_data = _mm_loadu_si128((const __m128i*)(ptr + distance));
+ const QChar *end = a + l;
+ qptrdiff offset = 0;
+
+ // we're going to read a[0..15] and b[0..15] (32 bytes)
+ for ( ; a + offset + 16 <= end; offset += 16) {
+#ifdef __AVX2__
+ __m256i a_data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(a + offset));
+ __m256i b_data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(b + offset));
+ __m256i result = _mm256_cmpeq_epi16(a_data, b_data);
+ uint mask = _mm256_movemask_epi8(result);
+#else
+ __m128i a_data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(a + offset));
+ __m128i a_data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(a + offset + 8));
+ __m128i b_data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(b + offset));
+ __m128i b_data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(b + offset + 8));
+ __m128i result1 = _mm_cmpeq_epi16(a_data1, b_data1);
+ __m128i result2 = _mm_cmpeq_epi16(a_data2, b_data2);
+ uint mask = _mm_movemask_epi8(result1) | (_mm_movemask_epi8(result2) << 16);
+#endif
+ mask = ~mask;
+ if (mask) {
+ // found a different character
+ uint idx = qCountTrailingZeroBits(mask);
+ return a[offset + idx / 2].unicode() - b[offset + idx / 2].unicode();
+ }
+ }
+
+ // we're going to read a[0..7] and b[0..7] (16 bytes)
+ if (a + offset + 8 <= end) {
+ __m128i a_data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(a + offset));
+ __m128i b_data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(b + offset));
__m128i result = _mm_cmpeq_epi16(a_data, b_data);
uint mask = ~_mm_movemask_epi8(result);
if (ushort(mask)) {
- // found a different byte
+ // found a different character
+ uint idx = qCountTrailingZeroBits(mask);
+ return a[offset + idx / 2].unicode() - b[offset + idx / 2].unicode();
+ }
+
+ offset += 8;
+ }
+
+ // we're going to read a[0..3] and b[0..3] (8 bytes)
+ if (a + offset + 4 <= end) {
+ __m128i a_data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(a + offset));
+ __m128i b_data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(b + offset));
+ __m128i result = _mm_cmpeq_epi16(a_data, b_data);
+ uint mask = ~_mm_movemask_epi8(result);
+ if (uchar(mask)) {
+ // found a different character
uint idx = qCountTrailingZeroBits(mask);
- return reinterpret_cast<const QChar *>(ptr + idx)->unicode()
- - reinterpret_cast<const QChar *>(ptr + distance + idx)->unicode();
+ return a[offset + idx / 2].unicode() - b[offset + idx / 2].unicode();
}
+
+ offset += 4;
}
+
+ // reset l
+ l &= 3;
+
const auto lambda = [=](size_t i) -> int {
- return reinterpret_cast<const QChar *>(ptr)[i].unicode()
- - reinterpret_cast<const QChar *>(ptr + distance)[i].unicode();
+ return a[offset + i].unicode() - b[offset + i].unicode();
};
- return UnrollTailLoop<7>::exec(l, 0, lambda, lambda);
+ return UnrollTailLoop<3>::exec(l, 0, lambda, lambda);
#endif
#if defined(__ARM_NEON__) && defined(Q_PROCESSOR_ARM_64) // vaddv is only available on Aarch64
if (l >= 8) {
diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp
index d10d9ad9d0..c9db39a29f 100644
--- a/src/corelib/tools/qstringlist.cpp
+++ b/src/corelib/tools/qstringlist.cpp
@@ -98,14 +98,25 @@ QT_BEGIN_NAMESPACE
\tableofcontents
+ \section1 Initializing
+
+ The default constructor creates an empty list. You can use the
+ initializer-list constructor to create a list with elements:
+
+ \snippet qstringlist/main.cpp 0a
+
\section1 Adding Strings
Strings can be added to a list using the \l
+ {QList::insert()}{insert()} \l
{QList::append()}{append()}, \l
{QList::operator+=()}{operator+=()} and \l
- {QStringList::operator<<()}{operator<<()} functions. For example:
+ {operator<<()} functions.
+
+ \l{operator<<()} can be used to
+ conveniently add multiple elements to a list:
- \snippet qstringlist/main.cpp 0
+ \snippet qstringlist/main.cpp 0b
\section1 Iterating Over the Strings