Merge remote-tracking branch 'origin/5.8' into 5.9

Conflicts:
	src/corelib/global/qglobal.cpp

Change-Id: I375fa4afa662fa411a15f212ebd5f2f0dffdba7f
bb10
Liang Qi 2017-04-18 10:43:17 +02:00
commit 18934bcb0c
25 changed files with 175 additions and 64 deletions

View File

@ -29,8 +29,8 @@
\example richtext/syntaxhighlighter
\title Syntax Highlighter Example
\ingroup examples-richtext
\brief The Syntax Highligher example shows how to perform
simple syntax highlighing.
\brief The Syntax Highlighter example shows how to perform
simple syntax highlighting.
\brief The Syntax Highlighter example shows how to perform simple syntax
highlighting by subclassing the QSyntaxHighlighter class.
@ -64,8 +64,9 @@
and define your own highlighting rules.
We have chosen to store our highlighting rules using a private
struct: A rule consists of a QRegExp pattern and a QTextCharFormat
instance. The various rules are then stored using a QVector.
struct: A rule consists of a QRegularExpression pattern and a
QTextCharFormat instance. The various rules are then stored using a
QVector.
The QTextCharFormat class provides formatting information for
characters in a QTextDocument specifying the visual properties of
@ -78,7 +79,7 @@
When subclassing the QSyntaxHighlighter class you must pass the
parent parameter to the base class constructor. The parent is the
text document upon which the syntax highligning will be
text document upon which the syntax highlighting will be
applied. In this example, we have also chosen to define our
highlighting rules in the constructor:
@ -138,11 +139,11 @@
First we apply the syntax highlighting rules that we stored in the
\c highlightingRules vector. For each rule (i.e. for each
HighlightingRule object) we search for the pattern in the given
textblock using the QString::indexOf() function. When the first
text block using the QString::indexOf() function. When the first
occurrence of the pattern is found, we use the
QRegExp::matchedLength() function to determine the string that
will be formatted. QRegExp::matchedLength() returns the length of
the last matched string, or -1 if there was no match.
QRegularExpressionMatch::capturedLength() function to determine the string
that will be formatted. QRegularExpressionMatch::capturedLength() returns
the length of the last matched string, or 0 if there was no match.
To perform the actual formatting the QSyntaxHighlighter class
provides the \l {QSyntaxHighlighter::setFormat()}{setFormat()}

View File

@ -68,9 +68,9 @@ Highlighter::Highlighter(QTextDocument *parent)
<< "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b"
<< "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b"
<< "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b"
<< "\\bvoid\\b" << "\\bvolatile\\b";
<< "\\bvoid\\b" << "\\bvolatile\\b" << "\\bbool\\b";
foreach (const QString &pattern, keywordPatterns) {
rule.pattern = QRegExp(pattern);
rule.pattern = QRegularExpression(pattern);
rule.format = keywordFormat;
highlightingRules.append(rule);
//! [0] //! [1]
@ -80,14 +80,14 @@ Highlighter::Highlighter(QTextDocument *parent)
//! [2]
classFormat.setFontWeight(QFont::Bold);
classFormat.setForeground(Qt::darkMagenta);
rule.pattern = QRegExp("\\bQ[A-Za-z]+\\b");
rule.pattern = QRegularExpression("\\bQ[A-Za-z]+\\b");
rule.format = classFormat;
highlightingRules.append(rule);
//! [2]
//! [3]
singleLineCommentFormat.setForeground(Qt::red);
rule.pattern = QRegExp("//[^\n]*");
rule.pattern = QRegularExpression("//[^\n]*");
rule.format = singleLineCommentFormat;
highlightingRules.append(rule);
@ -96,7 +96,7 @@ Highlighter::Highlighter(QTextDocument *parent)
//! [4]
quotationFormat.setForeground(Qt::darkGreen);
rule.pattern = QRegExp("\".*\"");
rule.pattern = QRegularExpression("\".*\"");
rule.format = quotationFormat;
highlightingRules.append(rule);
//! [4]
@ -104,14 +104,14 @@ Highlighter::Highlighter(QTextDocument *parent)
//! [5]
functionFormat.setFontItalic(true);
functionFormat.setForeground(Qt::blue);
rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()");
rule.pattern = QRegularExpression("\\b[A-Za-z0-9_]+(?=\\()");
rule.format = functionFormat;
highlightingRules.append(rule);
//! [5]
//! [6]
commentStartExpression = QRegExp("/\\*");
commentEndExpression = QRegExp("\\*/");
commentStartExpression = QRegularExpression("/\\*");
commentEndExpression = QRegularExpression("\\*/");
}
//! [6]
@ -119,12 +119,10 @@ Highlighter::Highlighter(QTextDocument *parent)
void Highlighter::highlightBlock(const QString &text)
{
foreach (const HighlightingRule &rule, highlightingRules) {
QRegExp expression(rule.pattern);
int index = expression.indexIn(text);
while (index >= 0) {
int length = expression.matchedLength();
setFormat(index, length, rule.format);
index = expression.indexIn(text, index + length);
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
while (matchIterator.hasNext()) {
QRegularExpressionMatch match = matchIterator.next();
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
}
}
//! [7] //! [8]
@ -134,22 +132,23 @@ void Highlighter::highlightBlock(const QString &text)
//! [9]
int startIndex = 0;
if (previousBlockState() != 1)
startIndex = commentStartExpression.indexIn(text);
startIndex = text.indexOf(commentStartExpression);
//! [9] //! [10]
while (startIndex >= 0) {
//! [10] //! [11]
int endIndex = commentEndExpression.indexIn(text, startIndex);
int commentLength;
QRegularExpressionMatch match = commentEndExpression.match(text, startIndex);
int endIndex = match.capturedStart();
int commentLength = 0;
if (endIndex == -1) {
setCurrentBlockState(1);
commentLength = text.length() - startIndex;
} else {
commentLength = endIndex - startIndex
+ commentEndExpression.matchedLength();
+ match.capturedLength();
}
setFormat(startIndex, commentLength, multiLineCommentFormat);
startIndex = commentStartExpression.indexIn(text, startIndex + commentLength);
startIndex = text.indexOf(commentStartExpression, startIndex + commentLength);
}
}
//! [11]

View File

@ -53,6 +53,7 @@
#include <QSyntaxHighlighter>
#include <QTextCharFormat>
#include <QRegularExpression>
QT_BEGIN_NAMESPACE
class QTextDocument;
@ -72,13 +73,13 @@ protected:
private:
struct HighlightingRule
{
QRegExp pattern;
QRegularExpression pattern;
QTextCharFormat format;
};
QVector<HighlightingRule> highlightingRules;
QRegExp commentStartExpression;
QRegExp commentEndExpression;
QRegularExpression commentStartExpression;
QRegularExpression commentEndExpression;
QTextCharFormat keywordFormat;
QTextCharFormat classFormat;

View File

@ -2628,12 +2628,14 @@ QString QSysInfo::kernelVersion()
to determine the distribution name and returns that. If determining the
distribution name failed, it returns "unknown".
\b{Darwin, \macos, iOS, tvOS, and watchOS note}: this function returns
"macos" for \macos systems, "ios" for iOS systems, "tvos" for tvOS systems,
"watchos" for watchOS systems, and "darwin" in case the system could not
be determined.
\b{\macos note}: this function returns "osx" for all \macos systems,
regardless of Apple naming convention. The returned string will be updated
for Qt 6. Note that this function erroneously returned "macos" for \macos
10.12 in Qt versions 5.6.2, 5.7.1, and 5.8.0.
\b{OS X note}: this function returns "osx" for versions of \macos prior to 10.12.
\b{Darwin, iOS, tvOS, and watchOS note}: this function returns "ios" for
iOS systems, "tvos" for tvOS systems, "watchos" for watchOS systems, and
"darwin" in case the system could not be determined.
\b{FreeBSD note}: this function returns "debian" for Debian/kFreeBSD and
"unknown" otherwise.
@ -2666,10 +2668,12 @@ QString QSysInfo::productType()
#elif defined(Q_OS_WATCHOS)
return QStringLiteral("watchos");
#elif defined(Q_OS_MACOS)
const auto version = QOperatingSystemVersion::current();
if (version.majorVersion() == 10 && version.minorVersion() < 12)
return QStringLiteral("osx");
// ### Qt6: remove fallback
# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
return QStringLiteral("macos");
# else
return QStringLiteral("osx");
# endif
#elif defined(Q_OS_DARWIN)
return QStringLiteral("darwin");

View File

@ -363,6 +363,7 @@ void QFileSelectorPrivate::updateSelectors()
QStringList QFileSelectorPrivate::platformSelectors()
{
// similar, but not identical to QSysInfo::osType
// ### Qt6: remove macOS fallbacks to "mac" and the future compatibility
QStringList ret;
#if defined(Q_OS_WIN)
ret << QStringLiteral("windows");
@ -380,12 +381,11 @@ QStringList QFileSelectorPrivate::platformSelectors()
# endif
# endif
QString productName = QSysInfo::productType();
# ifdef Q_OS_MACOS
if (productName != QLatin1String("osx"))
ret << QStringLiteral("osx"); // compatibility
# endif
if (productName != QLatin1String("unknown"))
ret << productName; // "opensuse", "fedora", "macos", "ios", "android"
ret << productName; // "opensuse", "fedora", "osx", "ios", "android"
# if defined(Q_OS_MACOS)
ret << QStringLiteral("macos"); // future compatibility
# endif
#endif
return ret;
}

View File

@ -38,13 +38,13 @@
**
****************************************************************************/
#include "qglobal.h"
#if !defined(QWS) && defined(Q_OS_MAC)
# include "private/qcore_mac_p.h"
# include <CoreFoundation/CoreFoundation.h>
#endif
#include "qglobal.h"
#include "qplatformdefs.h"
#include "qdatastream.h"

View File

@ -260,6 +260,7 @@ namespace QtSharedPointer {
internalSafetyCheckRemove(self);
deleter(self);
}
static void noDeleter(ExternalRefCountData *) { }
static inline ExternalRefCountData *create(T **ptr, DestroyerFn destroy)
{
@ -433,11 +434,13 @@ public:
# else
typename Private::DestroyerFn destroy = &Private::deleter;
# endif
typename Private::DestroyerFn noDestroy = &Private::noDeleter;
QSharedPointer result(Qt::Uninitialized);
result.d = Private::create(&result.value, destroy);
result.d = Private::create(&result.value, noDestroy);
// now initialize the data
new (result.data()) T(std::forward<Args>(arguments)...);
result.d->destroyer = destroy;
result.d->setQObjectShared(result.value, true);
# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
internalSafetyCheckAdd(result.d, result.value);

View File

@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
\reentrant
\since 4.6
\brief The QStringBuilder class is a template class that provides a facility to build up QStrings from smaller chunks.
\brief The QStringBuilder class is a template class that provides a facility to build up QStrings and QByteArrays from smaller chunks.
\ingroup tools
\ingroup shared
@ -58,22 +58,34 @@ QT_BEGIN_NAMESPACE
To build a QString by multiple concatenations, QString::operator+()
is typically used. This causes \e{n - 1} reallocations when building
a string from \e{n} chunks.
is typically used. This causes \e{n - 1} allocations when building
a string from \e{n} chunks. The same is true for QByteArray.
QStringBuilder uses expression templates to collect the individual
chunks, compute the total size, allocate the required amount of
memory for the final QString object, and copy the chunks into the
memory for the final string object, and copy the chunks into the
allocated memory.
The QStringBuilder class is not to be used explicitly in user
code. Instances of the class are created as return values of the
operator%() function, acting on objects of type QString,
QLatin1String, QStringRef, QChar, QCharRef,
QLatin1Char, and \c char.
operator%() function, acting on objects of the following types:
For building QStrings:
\li QString, QStringRef,
\li QChar, QCharRef, QLatin1Char,
\li QLatin1String,
\li QByteArray, \c char, \c{const char[]}.
The types in the last list point are only available when
QT_NO_CAST_FROM_ASCII is not defined.
For building QByteArrays:
\li QByteArray, \c char, \c{const char[]}.
Concatenating strings with operator%() generally yields better
performance then using \c QString::operator+() on the same chunks
performance than using \c QString::operator+() on the same chunks
if there are three or more of them, and performs equally well in other
cases.

View File

@ -423,8 +423,9 @@ inline QMatrix4x4& QMatrix4x4::operator-=(const QMatrix4x4& other)
return *this;
}
inline QMatrix4x4& QMatrix4x4::operator*=(const QMatrix4x4& other)
inline QMatrix4x4& QMatrix4x4::operator*=(const QMatrix4x4& o)
{
const QMatrix4x4 other = o; // prevent aliasing when &o == this ### Qt 6: take o by value
flagBits |= other.flagBits;
if (flagBits < Rotation2D) {

View File

@ -292,7 +292,7 @@ void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block)
/*!
Constructs a QSyntaxHighlighter with the given \a parent.
If the parent is a QTextEdit, it installs the syntaxhighlighter on the
If the parent is a QTextEdit, it installs the syntax highlighter on the
parents document. The specified QTextEdit also becomes the owner of
the QSyntaxHighlighter.
*/

View File

@ -901,7 +901,13 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef
bool forcedAntialiasSetting = !antialias;
const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
bool useXftConf = (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY"));
bool useXftConf = false;
if (services) {
const QList<QByteArray> desktopEnv = services->desktopEnvironment().split(':');
useXftConf = desktopEnv.contains("GNOME") || desktopEnv.contains("UNITY");
}
if (useXftConf && !forcedAntialiasSetting) {
void *antialiasResource =
QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled",

View File

@ -667,6 +667,7 @@ void QMenuSloppyState::reset()
m_enabled = false;
m_first_mouse = true;
m_init_guard = false;
m_use_reset_action = true;
m_uni_dir_discarded_count = 0;
m_time.stop();
m_reset_action = Q_NULLPTR;
@ -719,6 +720,7 @@ void QMenuSloppyState::setSubMenuPopup(const QRect &actionRect, QAction *resetAc
{
m_enabled = true;
m_init_guard = true;
m_use_reset_action = true;
m_time.stop();
m_action_rect = actionRect;
m_sub_menu = subMenu;
@ -779,10 +781,12 @@ void QMenuSloppyState::timeout()
if (m_sub_menu)
menu_priv->hideMenu(m_sub_menu);
if (reallyHasMouse)
menu_priv->setCurrentAction(m_reset_action,0);
else
if (reallyHasMouse) {
if (m_use_reset_action)
menu_priv->setCurrentAction(m_reset_action, 0);
} else {
menu_priv->setCurrentAction(Q_NULLPTR, 0);
}
}
//return the top causedPopup.widget that is not a QMenu

View File

@ -95,6 +95,7 @@ public:
, m_select_other_actions(false)
, m_first_mouse(true)
, m_init_guard(false)
, m_use_reset_action(true)
, m_uni_dir_discarded_count(0)
, m_uni_dir_fail_at_count(0)
, m_timeout(0)
@ -182,9 +183,17 @@ public:
QSetValueOnDestroy<bool> setFirstMouse(m_first_mouse, false);
QSetValueOnDestroy<QPointF> setPreviousPoint(m_previous_point, mousePos);
if (resetAction && resetAction->isSeparator())
if (resetAction && resetAction->isSeparator()) {
m_reset_action = Q_NULLPTR;
else {
m_use_reset_action = true;
} else if (m_reset_action != resetAction) {
if (m_use_reset_action && resetAction) {
const QList<QAction *> actions = m_menu->actions();
const int resetIdx = actions.indexOf(resetAction);
const int originIdx = actions.indexOf(m_origin_action);
if (resetIdx > -1 && originIdx > -1 && qAbs(resetIdx - originIdx) > 1)
m_use_reset_action = false;
}
m_reset_action = resetAction;
}
@ -249,6 +258,7 @@ private:
bool m_init_guard;
bool m_discard_state_when_entering_parent;
bool m_dont_start_time_on_leave;
bool m_use_reset_action;
short m_uni_dir_discarded_count;
short m_uni_dir_fail_at_count;
short m_timeout;

View File

@ -15,6 +15,7 @@
<file>platforms/test</file>
<file>platforms/+unix/+android/test</file>
<file>platforms/+unix/+darwin/+mac/+ios/test</file>
<file>platforms/+unix/+darwin/+mac/+osx/+macos/test</file>
<file>platforms/+unix/+darwin/+mac/+osx/test</file>
<file>platforms/+unix/+darwin/+mac/test</file>
<file>platforms/+unix/+darwin/test</file>
@ -27,6 +28,7 @@
<file>platforms/+windows/test</file>
<file>platforms/+android/test</file>
<file>platforms/+ios/test</file>
<file>platforms/+macos/test</file>
<file>platforms/+osx/test</file>
<file>platforms/+darwin/test</file>
<file>platforms/+mac/test</file>
@ -39,7 +41,7 @@
<file>platforms/test2</file>
<file>platforms/+android/test2</file>
<file>platforms/+ios/test2</file>
<file>platforms/+osx/test2</file>
<file>platforms/+macos/test2</file>
<file>platforms/+haiku/test2</file>
<file>platforms/+linux/test2</file>
<file>platforms/+wince/test2</file>
@ -50,5 +52,11 @@
<file>platforms/test3</file>
<file>platforms/+windows/test3</file>
<file>platforms/+unix/test3</file>
<!-- platforms/test4 and 5: special cases for macOS -->
<file>platforms/test4</file>
<file>platforms/+osx/test4</file>
<file>platforms/test5</file>
<file>platforms/+mac/test5</file>
</qresource>
</RCC>

View File

@ -126,6 +126,14 @@ void tst_QFileSelector::basicTest_data()
QTest::newRow("platform3") << QString(":/platforms/test3") << QStringList()
<< expectedPlatform3File;
#ifdef Q_OS_MACOS
// special case for compatibility code
QTest::newRow("osx-compat") << QString(":/platforms/test4") << QStringList()
<< ":/platforms/+osx/test4";
QTest::newRow("mac-compat") << QString(":/platforms/test5") << QStringList()
<< ":/platforms/+mac/test5";
#endif
QString resourceTestPath(":/extras/test");
QString custom1("custom1");
QTest::newRow("custom1-noselector") << resourceTestPath << QStringList()

View File

@ -97,6 +97,8 @@ private slots:
void qvariantCast();
void sharedFromThis();
void constructorThrow();
void threadStressTest_data();
void threadStressTest();
void validConstructs();
@ -2594,6 +2596,54 @@ void tst_QSharedPointer::sharedFromThis()
QCOMPARE(Data::destructorCounter, destructions + 6);
}
#ifndef QT_NO_EXCEPTIONS
class ThrowData: public Data
{
public:
static int childDestructorCounter;
static int childGenerationCounter;
ThrowData()
{
childGenerationCounter++;
throw QStringLiteral("Dummy exception");
}
~ThrowData()
{
childDestructorCounter++;
}
};
int ThrowData::childDestructorCounter = 0;
int ThrowData::childGenerationCounter = 0;
#endif // !QT_NO_EXCEPTIONS
void tst_QSharedPointer::constructorThrow()
{
#ifndef QT_NO_EXCEPTIONS
int generation = Data::generationCounter;
int destructorCounter = Data::destructorCounter;
int childGeneration = ThrowData::childGenerationCounter;
int childDestructorCounter = ThrowData::childDestructorCounter;
QSharedPointer<ThrowData> ptr;
QVERIFY_EXCEPTION_THROWN(ptr = QSharedPointer<ThrowData>::create(), QString);
QVERIFY(ptr.isNull());
QCOMPARE(ThrowData::childGenerationCounter, childGeneration + 1);
// destructor should never be called, if a constructor throws
// an exception
QCOMPARE(ThrowData::childDestructorCounter, childDestructorCounter);
QCOMPARE(Data::generationCounter, generation + 1);
// but base class constructor doesn't throw, so base class destructor
// should be called
QCOMPARE(Data::destructorCounter, destructorCounter + 1);
#else
QSKIP("Needs exceptions");
#endif // !QT_NO_EXCEPTIONS
}
namespace ReentrancyWhileDestructing {
struct IB
{

View File

@ -1227,6 +1227,10 @@ void tst_QMatrixNxN::multiply4x4()
QMatrix4x4 m5;
m5 = m1 * m2;
QVERIFY(isSame(m5, (const float *)m3Values));
QMatrix4x4 m1xm1 = m1 * m1;
m1 *= m1;
QCOMPARE(m1, m1xm1);
}
// Test matrix multiplication for 4x3 matrices.