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

Conflicts:
	src/corelib/plugin/qlibrary_unix.cpp
	src/plugins/platforms/xcb/qxcbconnection.cpp
	tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp

Change-Id: I632c400d909f8c204f55743aadc7886af2f15dfb
This commit is contained in:
Liang Qi 2017-02-16 21:46:20 +01:00
commit c577f6edaf
48 changed files with 97004 additions and 279 deletions

View File

@ -239,9 +239,9 @@ private:
int i = data.indexOf("a href=\"?view=detail"); int i = data.indexOf("a href=\"?view=detail");
if (i > 0) { if (i > 0) {
QString href = data.mid(i, data.indexOf('\"', i + 8) - i + 1); QString href = data.mid(i, data.indexOf('\"', i + 8) - i + 1);
QRegExp regex("dpap=([A-Za-z0-9]+)"); QRegularExpression regex("dpap=([A-Za-z0-9]+)");
regex.indexIn(href); QRegularExpressionMatch match = regex.match(href);
QString airport = regex.cap(1); QString airport = match.captured(1);
QUrlQuery query(m_url); QUrlQuery query(m_url);
query.addQueryItem("dpap", airport); query.addQueryItem("dpap", airport);
m_url.setQuery(query); m_url.setQuery(query);

View File

@ -203,10 +203,11 @@ QSize MainWindow::getSize()
if (!ok) if (!ok)
return QSize(); return QSize();
QRegExp regExp(tr("([0-9]+) *x *([0-9]+)")); QRegularExpression regExp(tr("^([0-9]+) *x *([0-9]+)$"));
if (regExp.exactMatch(text)) { QRegularExpressionMatch match = regExp.match(text);
int width = regExp.cap(1).toInt(); if (match.hasMatch()) {
int height = regExp.cap(2).toInt(); int width = match.captured(1).toInt();
int height = match.captured(2).toInt();
if (width > 0 && width < 2048 && height > 0 && height < 2048) if (width > 0 && width < 2048 && height > 0 && height < 2048)
return QSize(width, height); return QSize(width, height);
} }

View File

@ -59,6 +59,7 @@
#include <QFile> #include <QFile>
#include <QTextBrowser> #include <QTextBrowser>
#include <QBoxLayout> #include <QBoxLayout>
#include <QRegularExpression>
extern QPixmap cached(const QString &img); extern QPixmap cached(const QString &img);
@ -339,14 +340,12 @@ void ArthurFrame::showSource()
foreach (QString keyword, ppKeywords) foreach (QString keyword, ppKeywords)
contents.replace(keyword, QLatin1String("<font color=navy>") + keyword + QLatin1String("</font>")); contents.replace(keyword, QLatin1String("<font color=navy>") + keyword + QLatin1String("</font>"));
contents.replace(QRegExp("(\\d\\d?)"), QLatin1String("<font color=navy>\\1</font>")); contents.replace(QRegularExpression("(\\d\\d?)"), QLatin1String("<font color=navy>\\1</font>"));
QRegExp commentRe("(//.+)\\n"); QRegularExpression commentRe("(//.+?)\\n");
commentRe.setMinimal(true);
contents.replace(commentRe, QLatin1String("<font color=red>\\1</font>\n")); contents.replace(commentRe, QLatin1String("<font color=red>\\1</font>\n"));
QRegExp stringLiteralRe("(\".+\")"); QRegularExpression stringLiteralRe("(\".+?\")");
stringLiteralRe.setMinimal(true);
contents.replace(stringLiteralRe, QLatin1String("<font color=green>\\1</font>")); contents.replace(stringLiteralRe, QLatin1String("<font color=green>\\1</font>"));
QString html = contents; QString html = contents;

View File

@ -138,7 +138,8 @@ void MainWindow::aboutToShowSaveAsMenu()
void MainWindow::findCodecs() void MainWindow::findCodecs()
{ {
QMap<QString, QTextCodec *> codecMap; QMap<QString, QTextCodec *> codecMap;
QRegExp iso8859RegExp("ISO[- ]8859-([0-9]+).*"); QRegularExpression iso8859RegExp("^ISO[- ]8859-([0-9]+).*$");
QRegularExpressionMatch match;
foreach (int mib, QTextCodec::availableMibs()) { foreach (int mib, QTextCodec::availableMibs()) {
QTextCodec *codec = QTextCodec::codecForMib(mib); QTextCodec *codec = QTextCodec::codecForMib(mib);
@ -150,8 +151,8 @@ void MainWindow::findCodecs()
rank = 1; rank = 1;
} else if (sortKey.startsWith(QLatin1String("UTF-16"))) { } else if (sortKey.startsWith(QLatin1String("UTF-16"))) {
rank = 2; rank = 2;
} else if (iso8859RegExp.exactMatch(sortKey)) { } else if ((match = iso8859RegExp.match(sortKey)).hasMatch()) {
if (iso8859RegExp.cap(1).size() == 1) if (match.captured(1).size() == 1)
rank = 3; rank = 3;
else else
rank = 4; rank = 4;

View File

@ -56,14 +56,14 @@ VariantDelegate::VariantDelegate(QObject *parent)
: QItemDelegate(parent) : QItemDelegate(parent)
{ {
boolExp.setPattern("true|false"); boolExp.setPattern("true|false");
boolExp.setCaseSensitivity(Qt::CaseInsensitive); boolExp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
byteArrayExp.setPattern("[\\x00-\\xff]*"); byteArrayExp.setPattern("[\\x00-\\xff]*");
charExp.setPattern("."); charExp.setPattern(".");
colorExp.setPattern("\\(([0-9]*),([0-9]*),([0-9]*),([0-9]*)\\)"); colorExp.setPattern("^\\(([0-9]*),([0-9]*),([0-9]*),([0-9]*)\\)$");
doubleExp.setPattern(""); doubleExp.setPattern("");
pointExp.setPattern("\\((-?[0-9]*),(-?[0-9]*)\\)"); pointExp.setPattern("^\\((-?[0-9]*),(-?[0-9]*)\\)$");
rectExp.setPattern("\\((-?[0-9]*),(-?[0-9]*),(-?[0-9]*),(-?[0-9]*)\\)"); rectExp.setPattern("^\\((-?[0-9]*),(-?[0-9]*),(-?[0-9]*),(-?[0-9]*)\\)$");
signedIntegerExp.setPattern("-?[0-9]*"); signedIntegerExp.setPattern("-?[0-9]*");
sizeExp = pointExp; sizeExp = pointExp;
unsignedIntegerExp.setPattern("[0-9]*"); unsignedIntegerExp.setPattern("[0-9]*");
@ -104,7 +104,7 @@ QWidget *VariantDelegate::createEditor(QWidget *parent,
QLineEdit *lineEdit = new QLineEdit(parent); QLineEdit *lineEdit = new QLineEdit(parent);
lineEdit->setFrame(false); lineEdit->setFrame(false);
QRegExp regExp; QRegularExpression regExp;
switch (originalValue.type()) { switch (originalValue.type()) {
case QVariant::Bool: case QVariant::Bool:
@ -152,8 +152,8 @@ QWidget *VariantDelegate::createEditor(QWidget *parent,
; ;
} }
if (!regExp.isEmpty()) { if (regExp.isValid()) {
QValidator *validator = new QRegExpValidator(regExp, lineEdit); QValidator *validator = new QRegularExpressionValidator(regExp, lineEdit);
lineEdit->setValidator(validator); lineEdit->setValidator(validator);
} }
@ -185,17 +185,18 @@ void VariantDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
QVariant originalValue = index.model()->data(index, Qt::UserRole); QVariant originalValue = index.model()->data(index, Qt::UserRole);
QVariant value; QVariant value;
QRegularExpressionMatch match;
switch (originalValue.type()) { switch (originalValue.type()) {
case QVariant::Char: case QVariant::Char:
value = text.at(0); value = text.at(0);
break; break;
case QVariant::Color: case QVariant::Color:
colorExp.exactMatch(text); match = colorExp.match(text);
value = QColor(qMin(colorExp.cap(1).toInt(), 255), value = QColor(qMin(match.captured(1).toInt(), 255),
qMin(colorExp.cap(2).toInt(), 255), qMin(match.captured(2).toInt(), 255),
qMin(colorExp.cap(3).toInt(), 255), qMin(match.captured(3).toInt(), 255),
qMin(colorExp.cap(4).toInt(), 255)); qMin(match.captured(4).toInt(), 255));
break; break;
case QVariant::Date: case QVariant::Date:
{ {
@ -214,17 +215,17 @@ void VariantDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
} }
break; break;
case QVariant::Point: case QVariant::Point:
pointExp.exactMatch(text); match = pointExp.match(text);
value = QPoint(pointExp.cap(1).toInt(), pointExp.cap(2).toInt()); value = QPoint(match.captured(1).toInt(), match.captured(2).toInt());
break; break;
case QVariant::Rect: case QVariant::Rect:
rectExp.exactMatch(text); match = rectExp.match(text);
value = QRect(rectExp.cap(1).toInt(), rectExp.cap(2).toInt(), value = QRect(match.captured(1).toInt(), match.captured(2).toInt(),
rectExp.cap(3).toInt(), rectExp.cap(4).toInt()); match.captured(3).toInt(), match.captured(4).toInt());
break; break;
case QVariant::Size: case QVariant::Size:
sizeExp.exactMatch(text); match = sizeExp.match(text);
value = QSize(sizeExp.cap(1).toInt(), sizeExp.cap(2).toInt()); value = QSize(match.captured(1).toInt(), match.captured(2).toInt());
break; break;
case QVariant::StringList: case QVariant::StringList:
value = text.split(','); value = text.split(',');

View File

@ -52,7 +52,7 @@
#define VARIANTDELEGATE_H #define VARIANTDELEGATE_H
#include <QItemDelegate> #include <QItemDelegate>
#include <QRegExp> #include <QRegularExpression>
class VariantDelegate : public QItemDelegate class VariantDelegate : public QItemDelegate
{ {
@ -73,19 +73,19 @@ public:
static QString displayText(const QVariant &value); static QString displayText(const QVariant &value);
private: private:
mutable QRegExp boolExp; mutable QRegularExpression boolExp;
mutable QRegExp byteArrayExp; mutable QRegularExpression byteArrayExp;
mutable QRegExp charExp; mutable QRegularExpression charExp;
mutable QRegExp colorExp; mutable QRegularExpression colorExp;
mutable QRegExp dateExp; mutable QRegularExpression dateExp;
mutable QRegExp dateTimeExp; mutable QRegularExpression dateTimeExp;
mutable QRegExp doubleExp; mutable QRegularExpression doubleExp;
mutable QRegExp pointExp; mutable QRegularExpression pointExp;
mutable QRegExp rectExp; mutable QRegularExpression rectExp;
mutable QRegExp signedIntegerExp; mutable QRegularExpression signedIntegerExp;
mutable QRegExp sizeExp; mutable QRegularExpression sizeExp;
mutable QRegExp timeExp; mutable QRegularExpression timeExp;
mutable QRegExp unsignedIntegerExp; mutable QRegularExpression unsignedIntegerExp;
}; };
#endif #endif

View File

@ -57,11 +57,12 @@ StyleSheetEditor::StyleSheetEditor(QWidget *parent)
{ {
ui.setupUi(this); ui.setupUi(this);
QRegExp regExp(".(.*)\\+?Style"); QRegularExpression regExp("^.(.*)\\+?Style$");
QString defaultStyle = QApplication::style()->metaObject()->className(); QString defaultStyle = QApplication::style()->metaObject()->className();
QRegularExpressionMatch match = regExp.match(defaultStyle);
if (regExp.exactMatch(defaultStyle)) if (match.hasMatch())
defaultStyle = regExp.cap(1); defaultStyle = match.captured(1);
ui.styleCombo->addItems(QStyleFactory::keys()); ui.styleCombo->addItems(QStyleFactory::keys());
ui.styleCombo->setCurrentIndex(ui.styleCombo->findText(defaultStyle, Qt::MatchContains)); ui.styleCombo->setCurrentIndex(ui.styleCombo->findText(defaultStyle, Qt::MatchContains));

View File

@ -1230,10 +1230,6 @@
This variable is also used to specify which additional files will be This variable is also used to specify which additional files will be
deployed to embedded devices. deployed to embedded devices.
For Windows CE, the default deployment target path is
\c{%CSIDL_PROGRAM_FILES%\target}, which usually gets expanded to
\c{\Program Files\target}.
\target LEXIMPLS \target LEXIMPLS
\section1 LEXIMPLS \section1 LEXIMPLS
@ -2354,16 +2350,6 @@
qmake or \l{#QMAKESPEC}{qmake.conf} and rarely qmake or \l{#QMAKESPEC}{qmake.conf} and rarely
needs to be modified. needs to be modified.
\target SIGNATURE_FILE
\section1 SIGNATURE_FILE
\note This variable is only used on Windows CE.
Specifies which signature file should be used to sign the project target.
\note This variable will overwrite the setting you have specified in configure,
with the \c -signature option.
\target SOURCES \target SOURCES
\section1 SOURCES \section1 SOURCES
@ -4483,8 +4469,8 @@
include the precompiled header file in \c HEADERS, as include the precompiled header file in \c HEADERS, as
qmake will do this if the configuration supports precompiled headers. qmake will do this if the configuration supports precompiled headers.
The MSVC and g++ specs targeting Windows (and Windows CE) enable The MSVC and g++ specs targeting Windows enable \c precompile_header
\c precompile_header by default. by default.
Using this option, you may trigger Using this option, you may trigger
conditional blocks in your project file to add settings when using conditional blocks in your project file to add settings when using

View File

@ -243,13 +243,24 @@ public class QtNative
} }
} }
private static void runPendingCppRunnablesOnUiThread() private static void runPendingCppRunnablesOnAndroidThread()
{ {
synchronized (m_mainActivityMutex) { synchronized (m_mainActivityMutex) {
if (!m_activityPaused && m_activity != null) if (m_activity != null) {
m_activity.runOnUiThread(runPendingCppRunnablesRunnable); if (!m_activityPaused)
else m_activity.runOnUiThread(runPendingCppRunnablesRunnable);
runAction(runPendingCppRunnablesRunnable); else
runAction(runPendingCppRunnablesRunnable);
} else {
final Looper mainLooper = Looper.getMainLooper();
final Thread looperThread = mainLooper.getThread();
if (looperThread.equals(Thread.currentThread())) {
runPendingCppRunnablesRunnable.run();
} else {
final Handler handler = new Handler(mainLooper);
handler.post(runPendingCppRunnablesRunnable);
}
}
} }
} }

View File

@ -211,8 +211,7 @@
}, },
"dlopen": { "dlopen": {
"label": "dlopen()", "label": "dlopen()",
"condition": "tests.dlopen || libs.libdl", "condition": "tests.dlopen || libs.libdl"
"output": [ { "type": "define", "negative": true, "name": "QT_NO_DYNAMIC_LIBRARY" } ]
}, },
"libdl": { "libdl": {
"label": "dlopen() in libdl", "label": "dlopen() in libdl",
@ -463,6 +462,7 @@
"label": "QLibrary", "label": "QLibrary",
"purpose": "Provides a wrapper for dynamically loaded libraries.", "purpose": "Provides a wrapper for dynamically loaded libraries.",
"section": "File I/O", "section": "File I/O",
"condition": "config.win32 || config.hpux || (!config.nacl && features.dlopen)",
"output": [ "publicFeature", "feature" ] "output": [ "publicFeature", "feature" ]
}, },
"settings": { "settings": {

View File

@ -87,15 +87,15 @@ public:
bool MyWidget::event(QEvent *event) bool MyWidget::event(QEvent *event)
{ {
if (event->type() == QEvent::KeyPress) { if (event->type() == QEvent::KeyPress) {
QKeyEvent *ke = static_cast<QKeyEvent *>(event); QKeyEvent *ke = static_cast<QKeyEvent *>(event);
if (ke->key() == Qt::Key_Tab) { if (ke->key() == Qt::Key_Tab) {
// special tab handling here // special tab handling here
return true; return true;
} }
} else if (event->type() == MyCustomEventType) { } else if (event->type() == MyCustomEventType) {
MyCustomEvent *myEvent = static_cast<MyCustomEvent *>(event); MyCustomEvent *myEvent = static_cast<MyCustomEvent *>(event);
// custom event handling here // custom event handling here
return true; return true;
} }
return QWidget::event(event); return QWidget::event(event);

View File

@ -2105,7 +2105,7 @@
On \macos, tool windows correspond to the On \macos, tool windows correspond to the
\l{http://developer.apple.com/documentation/Carbon/Conceptual/HandlingWindowsControls/hitb-wind_cont_concept/chapter_2_section_2.html}{Floating} \l{http://developer.apple.com/documentation/Carbon/Conceptual/HandlingWindowsControls/hitb-wind_cont_concept/chapter_2_section_2.html}{Floating}
class of windows. This means that the window lives on a class of windows. This means that the window lives on a
level above normal windows; it impossible to put a normal level above normal windows making it impossible to put a normal
window on top of it. By default, tool windows will disappear window on top of it. By default, tool windows will disappear
when the application is inactive. This can be controlled by when the application is inactive. This can be controlled by
the Qt::WA_MacAlwaysShowToolWindow attribute. the Qt::WA_MacAlwaysShowToolWindow attribute.

View File

@ -73,7 +73,7 @@ static jclass g_jNativeClass = Q_NULLPTR;
static jmethodID g_runPendingCppRunnablesMethodID = Q_NULLPTR; static jmethodID g_runPendingCppRunnablesMethodID = Q_NULLPTR;
static jmethodID g_hideSplashScreenMethodID = Q_NULLPTR; static jmethodID g_hideSplashScreenMethodID = Q_NULLPTR;
Q_GLOBAL_STATIC(std::deque<QtAndroidPrivate::Runnable>, g_pendingRunnables); Q_GLOBAL_STATIC(std::deque<QtAndroidPrivate::Runnable>, g_pendingRunnables);
Q_GLOBAL_STATIC(QMutex, g_pendingRunnablesMutex); static QBasicMutex g_pendingRunnablesMutex;
class PermissionsResultClass : public QObject class PermissionsResultClass : public QObject
{ {
@ -88,21 +88,24 @@ private:
typedef QHash<int, QSharedPointer<PermissionsResultClass>> PendingPermissionRequestsHash; typedef QHash<int, QSharedPointer<PermissionsResultClass>> PendingPermissionRequestsHash;
Q_GLOBAL_STATIC(PendingPermissionRequestsHash, g_pendingPermissionRequests); Q_GLOBAL_STATIC(PendingPermissionRequestsHash, g_pendingPermissionRequests);
Q_GLOBAL_STATIC(QMutex, g_pendingPermissionRequestsMutex); static QBasicMutex g_pendingPermissionRequestsMutex;
Q_GLOBAL_STATIC(QAtomicInt, g_requestPermissionsRequestCode); static int nextRequestCode()
{
static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(0);
return counter.fetchAndAddRelaxed(1);
}
// function called from Java from Android UI thread // function called from Java from Android UI thread
static void runPendingCppRunnables(JNIEnv */*env*/, jobject /*obj*/) static void runPendingCppRunnables(JNIEnv */*env*/, jobject /*obj*/)
{ {
for (;;) { // run all posted runnables for (;;) { // run all posted runnables
g_pendingRunnablesMutex->lock(); QMutexLocker locker(&g_pendingRunnablesMutex);
if (g_pendingRunnables->empty()) { if (g_pendingRunnables->empty()) {
g_pendingRunnablesMutex->unlock();
break; break;
} }
QtAndroidPrivate::Runnable runnable(std::move(g_pendingRunnables->front())); QtAndroidPrivate::Runnable runnable(std::move(g_pendingRunnables->front()));
g_pendingRunnables->pop_front(); g_pendingRunnables->pop_front();
g_pendingRunnablesMutex->unlock(); locker.unlock();
runnable(); // run it outside the sync block! runnable(); // run it outside the sync block!
} }
} }
@ -122,16 +125,17 @@ Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners)
static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requestCode, static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requestCode,
jobjectArray permissions, jintArray grantResults) jobjectArray permissions, jintArray grantResults)
{ {
g_pendingPermissionRequestsMutex->lock(); QMutexLocker locker(&g_pendingPermissionRequestsMutex);
auto it = g_pendingPermissionRequests->find(requestCode); auto it = g_pendingPermissionRequests->find(requestCode);
if (it == g_pendingPermissionRequests->end()) { if (it == g_pendingPermissionRequests->end()) {
g_pendingPermissionRequestsMutex->unlock();
// show an error or something ? // show an error or something ?
return; return;
} }
g_pendingPermissionRequestsMutex->unlock(); auto request = std::move(*it);
g_pendingPermissionRequests->erase(it);
locker.unlock();
Qt::ConnectionType connection = QThread::currentThread() == it.value()->thread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection; Qt::ConnectionType connection = QThread::currentThread() == request->thread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection;
QtAndroidPrivate::PermissionsHash hash; QtAndroidPrivate::PermissionsHash hash;
const int size = env->GetArrayLength(permissions); const int size = env->GetArrayLength(permissions);
std::unique_ptr<jint[]> results(new jint[size]); std::unique_ptr<jint[]> results(new jint[size]);
@ -143,10 +147,7 @@ static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requ
QtAndroidPrivate::PermissionsResult::Denied; QtAndroidPrivate::PermissionsResult::Denied;
hash[permission] = value; hash[permission] = value;
} }
QMetaObject::invokeMethod(it.value().data(), "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash)); QMetaObject::invokeMethod(request.data(), "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash));
g_pendingPermissionRequestsMutex->lock();
g_pendingPermissionRequests->erase(it);
g_pendingPermissionRequestsMutex->unlock();
} }
static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event) static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event)
@ -403,7 +404,7 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
return JNI_ERR; return JNI_ERR;
g_runPendingCppRunnablesMethodID = env->GetStaticMethodID(jQtNative, g_runPendingCppRunnablesMethodID = env->GetStaticMethodID(jQtNative,
"runPendingCppRunnablesOnUiThread", "runPendingCppRunnablesOnAndroidThread",
"()V"); "()V");
g_hideSplashScreenMethodID = env->GetStaticMethodID(jQtNative, "hideSplashScreen", "()V"); g_hideSplashScreenMethodID = env->GetStaticMethodID(jQtNative, "hideSplashScreen", "()V");
g_jNativeClass = static_cast<jclass>(env->NewGlobalRef(jQtNative)); g_jNativeClass = static_cast<jclass>(env->NewGlobalRef(jQtNative));
@ -459,10 +460,10 @@ void QtAndroidPrivate::runOnUiThread(QRunnable *runnable, JNIEnv *env)
void QtAndroidPrivate::runOnAndroidThread(const QtAndroidPrivate::Runnable &runnable, JNIEnv *env) void QtAndroidPrivate::runOnAndroidThread(const QtAndroidPrivate::Runnable &runnable, JNIEnv *env)
{ {
g_pendingRunnablesMutex->lock(); QMutexLocker locker(&g_pendingRunnablesMutex);
const bool triggerRun = g_pendingRunnables->empty(); const bool triggerRun = g_pendingRunnables->empty();
g_pendingRunnables->push_back(runnable); g_pendingRunnables->push_back(runnable);
g_pendingRunnablesMutex->unlock(); locker.unlock();
if (triggerRun) if (triggerRun)
env->CallStaticVoidMethod(g_jNativeClass, g_runPendingCppRunnablesMethodID); env->CallStaticVoidMethod(g_jNativeClass, g_runPendingCppRunnablesMethodID);
} }
@ -487,18 +488,16 @@ void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permis
return; return;
} }
// Check API 23+ permissions // Check API 23+ permissions
const int requestCode = (*g_requestPermissionsRequestCode)++; const int requestCode = nextRequestCode();
if (!directCall) { if (!directCall) {
g_pendingPermissionRequestsMutex->lock(); QMutexLocker locker(&g_pendingPermissionRequestsMutex);
(*g_pendingPermissionRequests)[requestCode] = QSharedPointer<PermissionsResultClass>::create(callbackFunc); (*g_pendingPermissionRequests)[requestCode] = QSharedPointer<PermissionsResultClass>::create(callbackFunc);
g_pendingPermissionRequestsMutex->unlock();
} }
runOnAndroidThread([permissions, callbackFunc, requestCode, directCall] { runOnAndroidThread([permissions, callbackFunc, requestCode, directCall] {
if (directCall) { if (directCall) {
g_pendingPermissionRequestsMutex->lock(); QMutexLocker locker(&g_pendingPermissionRequestsMutex);
(*g_pendingPermissionRequests)[requestCode] = QSharedPointer<PermissionsResultClass>::create(callbackFunc); (*g_pendingPermissionRequests)[requestCode] = QSharedPointer<PermissionsResultClass>::create(callbackFunc);
g_pendingPermissionRequestsMutex->unlock();
} }
QJNIEnvironmentPrivate env; QJNIEnvironmentPrivate env;
@ -519,8 +518,10 @@ QHash<QString, QtAndroidPrivate::PermissionsResult> QtAndroidPrivate::requestPer
*res = result; *res = result;
sem->release(); sem->release();
}, true); }, true);
sem->tryAcquire(1, timeoutMs); if (sem->tryAcquire(1, timeoutMs))
return *res; return std::move(*res);
else // mustn't touch *res
return QHash<QString, QtAndroidPrivate::PermissionsResult>();
} }
QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission) QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission)

View File

@ -834,38 +834,27 @@ void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
const char *QMetaType::typeName(int typeId) const char *QMetaType::typeName(int typeId)
{ {
const uint type = typeId; const uint type = typeId;
// In theory it can be filled during compilation time, but for some reason template code
// that is able to do it causes GCC 4.6 to generate additional 3K of executable code. Probably
// it is not worth of it.
static const char *namesCache[QMetaType::HighestInternalId + 1];
const char *result;
if (type <= QMetaType::HighestInternalId && ((result = namesCache[type])))
return result;
#define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \ #define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \
case QMetaType::MetaTypeName: result = #RealName; break; case QMetaType::MetaTypeName: return #RealName; break;
switch (QMetaType::Type(type)) { switch (QMetaType::Type(type)) {
QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_TYPEID_TYPENAME_CONVERTER) QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_TYPEID_TYPENAME_CONVERTER)
case QMetaType::UnknownType:
case QMetaType::User:
break;
}
default: { if (Q_UNLIKELY(type < QMetaType::User)) {
if (Q_UNLIKELY(type < QMetaType::User)) { return nullptr; // It can happen when someone cast int to QVariant::Type, we should not crash...
return 0; // It can happen when someone cast int to QVariant::Type, we should not crash...
} else {
const QVector<QCustomTypeInfo> * const ct = customTypes();
QReadLocker locker(customTypesLock());
return ct && uint(ct->count()) > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty()
? ct->at(type - QMetaType::User).typeName.constData()
: 0;
}
}
} }
const QVector<QCustomTypeInfo> * const ct = customTypes();
QReadLocker locker(customTypesLock());
return ct && uint(ct->count()) > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty()
? ct->at(type - QMetaType::User).typeName.constData()
: nullptr;
#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER #undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER
Q_ASSERT(type <= QMetaType::HighestInternalId);
namesCache[type] = result;
return result;
} }
/* /*

View File

@ -3708,7 +3708,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
continue; continue;
QObject * const receiver = c->receiver; QObject * const receiver = c->receiver;
const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId; const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId.load();
// determine if this connection should be sent immediately or // determine if this connection should be sent immediately or
// put into the event queue // put into the event queue

View File

@ -50,13 +50,9 @@
# include <private/qcore_mac_p.h> # include <private/qcore_mac_p.h>
#endif #endif
#if (defined(Q_OS_VXWORKS) && !defined(VXWORKS_RTP)) || defined (Q_OS_NACL)
#define QT_NO_DYNAMIC_LIBRARY
#endif
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#if !defined(QT_HPUX_LD) && !defined(QT_NO_DYNAMIC_LIBRARY) #if !defined(QT_HPUX_LD)
QT_BEGIN_INCLUDE_NAMESPACE QT_BEGIN_INCLUDE_NAMESPACE
#include <dlfcn.h> #include <dlfcn.h>
QT_END_INCLUDE_NAMESPACE QT_END_INCLUDE_NAMESPACE
@ -64,9 +60,7 @@ QT_END_INCLUDE_NAMESPACE
static QString qdlerror() static QString qdlerror()
{ {
#if defined(QT_NO_DYNAMIC_LIBRARY) #if !defined(QT_HPUX_LD)
const char *err = "This platform does not support dynamic libraries.";
#elif !defined(QT_HPUX_LD)
const char *err = dlerror(); const char *err = dlerror();
#else #else
const char *err = strerror(errno); const char *err = strerror(errno);
@ -131,7 +125,6 @@ QStringList QLibraryPrivate::prefixes_sys()
bool QLibraryPrivate::load_sys() bool QLibraryPrivate::load_sys()
{ {
QString attempt; QString attempt;
#if !defined(QT_NO_DYNAMIC_LIBRARY)
QFileSystemEntry fsEntry(fileName); QFileSystemEntry fsEntry(fileName);
QString path = fsEntry.path(); QString path = fsEntry.path();
@ -250,7 +243,6 @@ bool QLibraryPrivate::load_sys()
} }
} }
#endif #endif
#endif // QT_NO_DYNAMIC_LIBRARY
if (!pHnd) { if (!pHnd) {
errorString = QLibrary::tr("Cannot load library %1: %2").arg(fileName, qdlerror()); errorString = QLibrary::tr("Cannot load library %1: %2").arg(fileName, qdlerror());
} }
@ -263,29 +255,27 @@ bool QLibraryPrivate::load_sys()
bool QLibraryPrivate::unload_sys() bool QLibraryPrivate::unload_sys()
{ {
#if !defined(QT_NO_DYNAMIC_LIBRARY) #if defined(QT_HPUX_LD)
# if defined(QT_HPUX_LD)
if (shl_unload((shl_t)pHnd)) { if (shl_unload((shl_t)pHnd)) {
# else #else
if (dlclose(pHnd)) { if (dlclose(pHnd)) {
# endif #endif
# if defined (Q_OS_QNX) // Workaround until fixed in QNX; fixes crash in #if defined (Q_OS_QNX) // Workaround until fixed in QNX; fixes crash in
char *error = dlerror(); // QtDeclarative auto test "qqmlenginecleanup" for instance char *error = dlerror(); // QtDeclarative auto test "qqmlenginecleanup" for instance
if (!qstrcmp(error, "Shared objects still referenced")) // On QNX that's only "informative" if (!qstrcmp(error, "Shared objects still referenced")) // On QNX that's only "informative"
return true; return true;
errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName, errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName,
QLatin1String(error)); QLatin1String(error));
# else #else
errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName, qdlerror()); errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName, qdlerror());
# endif #endif
return false; return false;
} }
#endif
errorString.clear(); errorString.clear();
return true; return true;
} }
#if defined(Q_OS_LINUX) && !defined(QT_NO_DYNAMIC_LIBRARY) #if defined(Q_OS_LINUX)
Q_CORE_EXPORT QFunctionPointer qt_linux_find_symbol_sys(const char *symbol) Q_CORE_EXPORT QFunctionPointer qt_linux_find_symbol_sys(const char *symbol)
{ {
return QFunctionPointer(dlsym(RTLD_DEFAULT, symbol)); return QFunctionPointer(dlsym(RTLD_DEFAULT, symbol));
@ -305,8 +295,6 @@ QFunctionPointer QLibraryPrivate::resolve_sys(const char* symbol)
QFunctionPointer address = 0; QFunctionPointer address = 0;
if (shl_findsym((shl_t*)&pHnd, symbol, TYPE_UNDEFINED, &address) < 0) if (shl_findsym((shl_t*)&pHnd, symbol, TYPE_UNDEFINED, &address) < 0)
address = 0; address = 0;
#elif defined (QT_NO_DYNAMIC_LIBRARY)
QFunctionPointer address = 0;
#else #else
QFunctionPointer address = QFunctionPointer(dlsym(pHnd, symbol)); QFunctionPointer address = QFunctionPointer(dlsym(pHnd, symbol));
#endif #endif

View File

@ -107,8 +107,6 @@ QT_BEGIN_NAMESPACE
* waiting in the past. We then set the mutex to 0x0 and perform a FUTEX_WAKE. * waiting in the past. We then set the mutex to 0x0 and perform a FUTEX_WAKE.
*/ */
static QBasicAtomicInt futexFlagSupport = Q_BASIC_ATOMIC_INITIALIZER(-1);
static inline int _q_futex(void *addr, int op, int val, const struct timespec *timeout) Q_DECL_NOTHROW static inline int _q_futex(void *addr, int op, int val, const struct timespec *timeout) Q_DECL_NOTHROW
{ {
volatile int *int_addr = reinterpret_cast<volatile int *>(addr); volatile int *int_addr = reinterpret_cast<volatile int *>(addr);

View File

@ -74,7 +74,7 @@ public:
int writerCount; int writerCount;
int waitingReaders; int waitingReaders;
int waitingWriters; int waitingWriters;
bool recursive; const bool recursive;
//Called with the mutex locked //Called with the mutex locked
bool lockForWrite(int timeout); bool lockForWrite(int timeout);

View File

@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
*/ */
QThreadData::QThreadData(int initialRefCount) QThreadData::QThreadData(int initialRefCount)
: _ref(initialRefCount), loopLevel(0), scopeLevel(0), thread(0), threadId(0), : _ref(initialRefCount), loopLevel(0), scopeLevel(0),
eventDispatcher(0), eventDispatcher(0),
quitNow(false), canWait(true), isAdopted(false), requiresCoreApplication(true) quitNow(false), canWait(true), isAdopted(false), requiresCoreApplication(true)
{ {

View File

@ -284,7 +284,7 @@ public:
QStack<QEventLoop *> eventLoops; QStack<QEventLoop *> eventLoops;
QPostEventList postEventList; QPostEventList postEventList;
QAtomicPointer<QThread> thread; QAtomicPointer<QThread> thread;
Qt::HANDLE threadId; QAtomicPointer<void> threadId;
QAtomicPointer<QAbstractEventDispatcher> eventDispatcher; QAtomicPointer<QAbstractEventDispatcher> eventDispatcher;
QVector<void *> tls; QVector<void *> tls;
FlaggedDebugSignatures flaggedSignatures; FlaggedDebugSignatures flaggedSignatures;

View File

@ -255,7 +255,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
} }
data->deref(); data->deref();
data->isAdopted = true; data->isAdopted = true;
data->threadId = to_HANDLE(pthread_self()); data->threadId.store(to_HANDLE(pthread_self()));
if (!QCoreApplicationPrivate::theMainThread) if (!QCoreApplicationPrivate::theMainThread)
QCoreApplicationPrivate::theMainThread = data->thread.load(); QCoreApplicationPrivate::theMainThread = data->thread.load();
} }
@ -335,7 +335,7 @@ void *QThreadPrivate::start(void *arg)
thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag)); thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag));
} }
data->threadId = to_HANDLE(pthread_self()); data->threadId.store(to_HANDLE(pthread_self()));
set_thread_data(data); set_thread_data(data);
data->ref(); data->ref();
@ -352,7 +352,7 @@ void *QThreadPrivate::start(void *arg)
// sets the name of the current thread. // sets the name of the current thread.
QString objectName = thr->objectName(); QString objectName = thr->objectName();
pthread_t thread_id = from_HANDLE<pthread_t>(data->threadId); pthread_t thread_id = from_HANDLE<pthread_t>(data->threadId.load());
if (Q_LIKELY(objectName.isEmpty())) if (Q_LIKELY(objectName.isEmpty()))
setCurrentThreadName(thread_id, thr->metaObject()->className()); setCurrentThreadName(thread_id, thr->metaObject()->className());
else else
@ -651,7 +651,7 @@ void QThread::start(Priority priority)
#endif #endif
code = pthread_create(&threadId, &attr, QThreadPrivate::start, this); code = pthread_create(&threadId, &attr, QThreadPrivate::start, this);
} }
d->data->threadId = to_HANDLE(threadId); d->data->threadId.store(to_HANDLE(threadId));
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
@ -660,7 +660,7 @@ void QThread::start(Priority priority)
d->running = false; d->running = false;
d->finished = false; d->finished = false;
d->data->threadId = 0; d->data->threadId.store(nullptr);
} }
} }
@ -670,10 +670,10 @@ void QThread::terminate()
Q_D(QThread); Q_D(QThread);
QMutexLocker locker(&d->mutex); QMutexLocker locker(&d->mutex);
if (!d->data->threadId) if (!d->data->threadId.load())
return; return;
int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId)); int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId.load()));
if (code) { if (code) {
qWarning("QThread::start: Thread termination error: %s", qWarning("QThread::start: Thread termination error: %s",
qPrintable(qt_error_string((code)))); qPrintable(qt_error_string((code))));
@ -686,7 +686,7 @@ bool QThread::wait(unsigned long time)
Q_D(QThread); Q_D(QThread);
QMutexLocker locker(&d->mutex); QMutexLocker locker(&d->mutex);
if (from_HANDLE<pthread_t>(d->data->threadId) == pthread_self()) { if (from_HANDLE<pthread_t>(d->data->threadId.load()) == pthread_self()) {
qWarning("QThread::wait: Thread tried to wait on itself"); qWarning("QThread::wait: Thread tried to wait on itself");
return false; return false;
} }
@ -728,7 +728,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
int sched_policy; int sched_policy;
sched_param param; sched_param param;
if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, &param) != 0) { if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.load()), &sched_policy, &param) != 0) {
// failed to get the scheduling policy, don't bother setting // failed to get the scheduling policy, don't bother setting
// the priority // the priority
qWarning("QThread::setPriority: Cannot get scheduler parameters"); qWarning("QThread::setPriority: Cannot get scheduler parameters");
@ -744,15 +744,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
} }
param.sched_priority = prio; param.sched_priority = prio;
int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, &param); int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.load()), sched_policy, &param);
# ifdef SCHED_IDLE # ifdef SCHED_IDLE
// were we trying to set to idle priority and failed? // were we trying to set to idle priority and failed?
if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) { if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
// reset to lowest priority possible // reset to lowest priority possible
pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, &param); pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.load()), &sched_policy, &param);
param.sched_priority = sched_get_priority_min(sched_policy); param.sched_priority = sched_get_priority_min(sched_policy);
pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, &param); pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.load()), sched_policy, &param);
} }
# else # else
Q_UNUSED(status); Q_UNUSED(status);

View File

@ -137,7 +137,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
} }
threadData->deref(); threadData->deref();
threadData->isAdopted = true; threadData->isAdopted = true;
threadData->threadId = reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())); threadData->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
if (!QCoreApplicationPrivate::theMainThread) { if (!QCoreApplicationPrivate::theMainThread) {
QCoreApplicationPrivate::theMainThread = threadData->thread.load(); QCoreApplicationPrivate::theMainThread = threadData->thread.load();
@ -351,7 +351,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
qt_create_tls(); qt_create_tls();
TlsSetValue(qt_current_thread_data_tls_index, data); TlsSetValue(qt_current_thread_data_tls_index, data);
data->threadId = reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())); data->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())));
QThread::setTerminationEnabled(false); QThread::setTerminationEnabled(false);

View File

@ -60,14 +60,13 @@ void MyHighlighter::highlightBlock(const QString &text)
QTextCharFormat myClassFormat; QTextCharFormat myClassFormat;
myClassFormat.setFontWeight(QFont::Bold); myClassFormat.setFontWeight(QFont::Bold);
myClassFormat.setForeground(Qt::darkMagenta); myClassFormat.setForeground(Qt::darkMagenta);
QString pattern = "\\bMy[A-Za-z]+\\b";
QRegExp expression(pattern); QRegularExpression expression("\\bMy[A-Za-z]+\\b");
int index = text.indexOf(expression); QRegularExpressionMatchIterator i = expression.globalMatch(text);
while (index >= 0) { while (i.hasNext())
int length = expression.matchedLength(); {
setFormat(index, length, myClassFormat); QRegularExpressionMatch match = i.next();
index = text.indexOf(expression, index + length); setFormat(match.capturedStart(), match.capturedLength(), myClassFormat);
} }
} }
//! [1] //! [1]
@ -77,8 +76,8 @@ void MyHighlighter::highlightBlock(const QString &text)
QTextCharFormat multiLineCommentFormat; QTextCharFormat multiLineCommentFormat;
multiLineCommentFormat.setForeground(Qt::red); multiLineCommentFormat.setForeground(Qt::red);
QRegExp startExpression("/\\*"); QRegularExpression startExpression("/\\*");
QRegExp endExpression("\\*/"); QRegularExpression endExpression("\\*/");
setCurrentBlockState(0); setCurrentBlockState(0);
@ -87,14 +86,15 @@ if (previousBlockState() != 1)
startIndex = text.indexOf(startExpression); startIndex = text.indexOf(startExpression);
while (startIndex >= 0) { while (startIndex >= 0) {
int endIndex = text.indexOf(endExpression, startIndex); QRegularExpressionMatch endMatch;
int endIndex = text.indexOf(endExpression, startIndex, &endMatch);
int commentLength; int commentLength;
if (endIndex == -1) { if (endIndex == -1) {
setCurrentBlockState(1); setCurrentBlockState(1);
commentLength = text.length() - startIndex; commentLength = text.length() - startIndex;
} else { } else {
commentLength = endIndex - startIndex commentLength = endIndex - startIndex
+ endExpression.matchedLength(); + endMatch.capturedLength();
} }
setFormat(startIndex, commentLength, multiLineCommentFormat); setFormat(startIndex, commentLength, multiLineCommentFormat);
startIndex = text.indexOf(startExpression, startIndex = text.indexOf(startExpression,
@ -104,25 +104,6 @@ while (startIndex >= 0) {
//! [3] //! [3]
void MyHighlighter::highlightBlock(const QString &text)
{
QTextCharFormat myClassFormat;
myClassFormat.setFontWeight(QFont::Bold);
myClassFormat.setForeground(Qt::darkMagenta);
QString pattern = "\\bMy[A-Za-z]+\\b";
QRegExp expression(pattern);
int index = text.indexOf(expression);
while (index >= 0) {
int length = expression.matchedLength();
setFormat(index, length, myClassFormat);
index = text.indexOf(expression, index + length);
}
}
//! [3]
//! [4]
struct ParenthesisInfo struct ParenthesisInfo
{ {
QChar char; QChar char;
@ -133,4 +114,4 @@ struct BlockData : public QTextBlockUserData
{ {
QVector<ParenthesisInfo> parentheses; QVector<ParenthesisInfo> parentheses;
}; };
//! [4] //! [3]

View File

@ -75,6 +75,10 @@ QT_END_NAMESPACE
#if defined(Q_OS_INTEGRITY) #if defined(Q_OS_INTEGRITY)
# undef Value # undef Value
#endif #endif
// Hurd has #define TILDE 0x00080000 from <sys/ioctl.h>
#if defined(TILDE)
# undef TILDE
#endif
#define QT_CSS_DECLARE_TYPEINFO(Class, Type) \ #define QT_CSS_DECLARE_TYPEINFO(Class, Type) \
} /* namespace QCss */ \ } /* namespace QCss */ \

View File

@ -243,6 +243,8 @@ void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block)
\snippet code/src_gui_text_qsyntaxhighlighter.cpp 1 \snippet code/src_gui_text_qsyntaxhighlighter.cpp 1
\target QSyntaxHighlighter multiblock
Some syntaxes can have constructs that span several text Some syntaxes can have constructs that span several text
blocks. For example, a C++ syntax highlighter should be able to blocks. For example, a C++ syntax highlighter should be able to
cope with \c{/}\c{*...*}\c{/} multiline comments. To deal with cope with \c{/}\c{*...*}\c{/} multiline comments. To deal with
@ -267,12 +269,12 @@ void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block)
\snippet code/src_gui_text_qsyntaxhighlighter.cpp 2 \snippet code/src_gui_text_qsyntaxhighlighter.cpp 2
In the example above, we first set the current block state to In the example above, we first set the current block state to
0. Then, if the previous block ended within a comment, we higlight 0. Then, if the previous block ended within a comment, we highlight
from the beginning of the current block (\c {startIndex = from the beginning of the current block (\c {startIndex =
0}). Otherwise, we search for the given start expression. If the 0}). Otherwise, we search for the given start expression. If the
specified end expression cannot be found in the text block, we specified end expression cannot be found in the text block, we
change the current block state by calling setCurrentBlockState(), change the current block state by calling setCurrentBlockState(),
and make sure that the rest of the block is higlighted. and make sure that the rest of the block is highlighted.
In addition you can query the current formatting and user data In addition you can query the current formatting and user data
using the format() and currentBlockUserData() functions using the format() and currentBlockUserData() functions
@ -411,33 +413,12 @@ void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block)
setFormat() as often as necessary to apply any font and color setFormat() as often as necessary to apply any font and color
changes that you require. For example: changes that you require. For example:
\snippet code/src_gui_text_qsyntaxhighlighter.cpp 3 \snippet code/src_gui_text_qsyntaxhighlighter.cpp 1
Some syntaxes can have constructs that span several text See the \l{QSyntaxHighlighter multiblock}{Detailed Description} for
blocks. For example, a C++ syntax highlighter should be able to examples of using setCurrentBlockState(), currentBlockState()
cope with \c{/}\c{*...*}\c{/} multiline comments. To deal with and previousBlockState() to handle syntaxes with constructs that
these cases it is necessary to know the end state of the previous span several text blocks
text block (e.g. "in comment").
Inside your highlightBlock() implementation you can query the end
state of the previous text block using the previousBlockState()
function. After parsing the block you can save the last state
using setCurrentBlockState().
The currentBlockState() and previousBlockState() functions return
an int value. If no state is set, the returned value is -1. You
can designate any other value to identify any given state using
the setCurrentBlockState() function. Once the state is set the
QTextBlock keeps that value until it is set set again or until the
corresponding paragraph of text gets deleted.
For example, if you're writing a simple C++ syntax highlighter,
you might designate 1 to signify "in comment". For a text block
that ended in the middle of a comment you'd set 1 using
setCurrentBlockState, and for other paragraphs you'd set 0.
In your parsing code if the return value of previousBlockState()
is 1, you would highlight the text as a C++ comment until you
reached the closing \c{*}\c{/}.
\sa previousBlockState(), setFormat(), setCurrentBlockState() \sa previousBlockState(), setFormat(), setCurrentBlockState()
*/ */
@ -581,7 +562,7 @@ void QSyntaxHighlighter::setCurrentBlockState(int newState)
and store their relative position and the actual QChar in a simple and store their relative position and the actual QChar in a simple
class derived from QTextBlockUserData: class derived from QTextBlockUserData:
\snippet code/src_gui_text_qsyntaxhighlighter.cpp 4 \snippet code/src_gui_text_qsyntaxhighlighter.cpp 3
During cursor navigation in the associated editor, you can ask the During cursor navigation in the associated editor, you can ask the
current QTextBlock (retrieved using the QTextCursor::block() current QTextBlock (retrieved using the QTextCursor::block()

View File

@ -252,6 +252,10 @@ QT_BEGIN_NAMESPACE
QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig, QObject *parent) QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig, QObject *parent)
: QObject(parent), d(0) : QObject(parent), d(0)
{ {
qRegisterMetaType<QNetworkSession::State>();
qRegisterMetaType<QNetworkSession::SessionError>();
qRegisterMetaType<QNetworkSession::UsagePolicies>();
// invalid configuration // invalid configuration
if (!connectionConfig.identifier().isEmpty()) { if (!connectionConfig.identifier().isEmpty()) {
const auto engines = qNetworkConfigurationManagerPrivate()->engines(); const auto engines = qNetworkConfigurationManagerPrivate()->engines();
@ -277,10 +281,6 @@ QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig,
} }
} }
} }
qRegisterMetaType<QNetworkSession::State>();
qRegisterMetaType<QNetworkSession::SessionError>();
qRegisterMetaType<QNetworkSession::UsagePolicies>();
} }
/*! /*!

View File

@ -48,6 +48,7 @@
#include <vector> #include <vector>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifndef QT_NO_OPENGL
class QDebug; class QDebug;
@ -227,7 +228,7 @@ private:
GLenum (APIENTRY * m_getGraphicsResetStatus)(); GLenum (APIENTRY * m_getGraphicsResetStatus)();
bool m_lost; bool m_lost;
}; };
#endif
QT_END_NAMESPACE QT_END_NAMESPACE
#endif // QWINDOWSGLCONTEXT_H #endif // QWINDOWSGLCONTEXT_H

View File

@ -605,7 +605,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeXRender(); initializeXRender();
#if defined(XCB_USE_XINPUT2) #if defined(XCB_USE_XINPUT2)
initializeXInput2(); if (!qEnvironmentVariableIsSet("QT_XCB_NO_XI2"))
initializeXInput2();
#endif #endif
initializeXShape(); initializeXShape();
initializeXKB(); initializeXKB();

View File

@ -58,7 +58,7 @@ namespace QTest
{ {
Q_ASSERT(QCoreApplication::instance()); Q_ASSERT(QCoreApplication::instance());
QDeadlineTimer timer(ms); QDeadlineTimer timer(ms, Qt::PreciseTimer);
int remaining = ms; int remaining = ms;
do { do {
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
@ -74,7 +74,7 @@ namespace QTest
#ifdef QT_GUI_LIB #ifdef QT_GUI_LIB
inline static bool qWaitForWindowActive(QWindow *window, int timeout = 5000) inline static bool qWaitForWindowActive(QWindow *window, int timeout = 5000)
{ {
QDeadlineTimer timer(timeout); QDeadlineTimer timer(timeout, Qt::PreciseTimer);
int remaining = timeout; int remaining = timeout;
while (!window->isActive() && remaining > 0) { while (!window->isActive() && remaining > 0) {
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
@ -101,7 +101,7 @@ namespace QTest
inline static bool qWaitForWindowExposed(QWindow *window, int timeout = 5000) inline static bool qWaitForWindowExposed(QWindow *window, int timeout = 5000)
{ {
QDeadlineTimer timer(timeout); QDeadlineTimer timer(timeout, Qt::PreciseTimer);
int remaining = timeout; int remaining = timeout;
while (!window->isExposed() && remaining > 0) { while (!window->isExposed() && remaining > 0) {
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);

View File

@ -1153,6 +1153,7 @@ void WriteInitialization::writeProperties(const QString &varName,
DomPropertyMap properties = propertyMap(lst); DomPropertyMap properties = propertyMap(lst);
if (properties.contains(QLatin1String("control"))) { if (properties.contains(QLatin1String("control"))) {
DomProperty *p = properties.value(QLatin1String("control")); DomProperty *p = properties.value(QLatin1String("control"));
Q_ASSERT( p );
m_output << m_indent << varName << "->setControl(" m_output << m_indent << varName << "->setControl("
<< writeString(toString(p->elementString()), m_dindent) << ");\n"; << writeString(toString(p->elementString()), m_dindent) << ");\n";
} }

View File

@ -656,7 +656,7 @@ void QFileDialogPrivate::retranslateStrings()
/* WIDGETS */ /* WIDGETS */
if (options->useDefaultNameFilters()) if (options->useDefaultNameFilters())
q->setNameFilter(QFileDialogOptions::defaultNameFilterString()); q->setNameFilter(QFileDialogOptions::defaultNameFilterString());
if (nativeDialogInUse) if (!usingWidgets())
return; return;
QList<QAction*> actions = qFileDialogUi->treeView->header()->actions(); QList<QAction*> actions = qFileDialogUi->treeView->header()->actions();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@
#include <QtCore/QElapsedTimer> #include <QtCore/QElapsedTimer>
#include <QtTest/QtTest> #include <QtTest/QtTest>
static const int minResolution = 50; // the minimum resolution for the tests static const int minResolution = 100; // the minimum resolution for the tests
QDebug operator<<(QDebug s, const QElapsedTimer &t) QDebug operator<<(QDebug s, const QElapsedTimer &t)
{ {
@ -107,7 +107,7 @@ void tst_QElapsedTimer::elapsed()
QElapsedTimer t1; QElapsedTimer t1;
t1.start(); t1.start();
QTest::qSleep(4*minResolution); QTest::qSleep(2*minResolution);
QElapsedTimer t2; QElapsedTimer t2;
t2.start(); t2.start();
@ -128,8 +128,8 @@ void tst_QElapsedTimer::elapsed()
QVERIFY(!t2.hasExpired(-1)); QVERIFY(!t2.hasExpired(-1));
qint64 elapsed = t1.restart(); qint64 elapsed = t1.restart();
QVERIFY(elapsed > 3*minResolution); QVERIFY(elapsed > minResolution);
QVERIFY(elapsed < 5*minResolution); QVERIFY(elapsed < 3*minResolution);
qint64 diff = t2.msecsTo(t1); qint64 diff = t2.msecsTo(t1);
QVERIFY(diff < minResolution); QVERIFY(diff < minResolution);
} }

View File

@ -0,0 +1,3 @@
[remainingTime]
windows
osx

View File

@ -858,6 +858,11 @@ void tst_QMimeDatabase::fromThreads()
} }
#ifndef QT_NO_PROCESS #ifndef QT_NO_PROCESS
enum {
UpdateMimeDatabaseTimeout = 120 * 1000 // 2min
};
static bool runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDatabase method? static bool runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDatabase method?
{ {
const QString umdCommand = QString::fromLatin1("update-mime-database"); const QString umdCommand = QString::fromLatin1("update-mime-database");
@ -878,7 +883,7 @@ static bool runUpdateMimeDatabase(const QString &path) // TODO make it a QMimeDa
qPrintable(umd), qPrintable(proc.errorString())); qPrintable(umd), qPrintable(proc.errorString()));
return false; return false;
} }
const bool success = proc.waitForFinished(); const bool success = proc.waitForFinished(UpdateMimeDatabaseTimeout);
qDebug().noquote() << "runUpdateMimeDatabase: done," qDebug().noquote() << "runUpdateMimeDatabase: done,"
<< success << timer.elapsed() << "ms"; << success << timer.elapsed() << "ms";
return true; return true;

View File

@ -367,16 +367,18 @@ public:
void run(); void run();
}; };
static const int Timeout = 60 * 1000; // 1min
void Producer::run() void Producer::run()
{ {
for (int i = 0; i < DataSize; ++i) { for (int i = 0; i < DataSize; ++i) {
freeSpace.acquire(); QVERIFY(freeSpace.tryAcquire(1, Timeout));
buffer[i % BufferSize] = alphabet[i % AlphabetSize]; buffer[i % BufferSize] = alphabet[i % AlphabetSize];
usedSpace.release(); usedSpace.release();
} }
for (int i = 0; i < DataSize; ++i) { for (int i = 0; i < DataSize; ++i) {
if ((i % ProducerChunkSize) == 0) if ((i % ProducerChunkSize) == 0)
freeSpace.acquire(ProducerChunkSize); QVERIFY(freeSpace.tryAcquire(ProducerChunkSize, Timeout));
buffer[i % BufferSize] = alphabet[i % AlphabetSize]; buffer[i % BufferSize] = alphabet[i % AlphabetSize];
if ((i % ProducerChunkSize) == (ProducerChunkSize - 1)) if ((i % ProducerChunkSize) == (ProducerChunkSize - 1))
usedSpace.release(ProducerChunkSize); usedSpace.release(ProducerChunkSize);

View File

@ -958,51 +958,88 @@ void tst_QThreadPool::clear()
void tst_QThreadPool::cancel() void tst_QThreadPool::cancel()
{ {
QSemaphore sem(0); QSemaphore sem(0);
QSemaphore startedThreads(0);
class SemaphoreReleaser
{
QSemaphore &sem;
int n;
Q_DISABLE_COPY(SemaphoreReleaser)
public:
explicit SemaphoreReleaser(QSemaphore &sem, int n)
: sem(sem), n(n) {}
~SemaphoreReleaser()
{
sem.release(n);
}
};
class BlockingRunnable : public QRunnable class BlockingRunnable : public QRunnable
{ {
public: public:
QSemaphore & sem; QSemaphore & sem;
int & dtorCounter; QSemaphore &startedThreads;
int & runCounter; QAtomicInt &dtorCounter;
QAtomicInt &runCounter;
int dummy; int dummy;
BlockingRunnable(QSemaphore & s, int & c, int & r) : sem(s), dtorCounter(c), runCounter(r){}
~BlockingRunnable(){dtorCounter++;} explicit BlockingRunnable(QSemaphore &s, QSemaphore &started, QAtomicInt &c, QAtomicInt &r)
: sem(s), startedThreads(started), dtorCounter(c), runCounter(r){}
~BlockingRunnable()
{
dtorCounter.fetchAndAddRelaxed(1);
}
void run() void run()
{ {
runCounter++; startedThreads.release();
runCounter.fetchAndAddRelaxed(1);
sem.acquire(); sem.acquire();
count.ref(); count.ref();
} }
}; };
typedef BlockingRunnable* BlockingRunnablePtr;
enum {
MaxThreadCount = 3,
OverProvisioning = 2,
runs = MaxThreadCount * OverProvisioning
};
QThreadPool threadPool; QThreadPool threadPool;
threadPool.setMaxThreadCount(3); threadPool.setMaxThreadCount(MaxThreadCount);
int runs = 2 * threadPool.maxThreadCount(); BlockingRunnable *runnables[runs];
BlockingRunnablePtr* runnables = new BlockingRunnablePtr[runs];
// ensure that the QThreadPool doesn't deadlock if any of the checks fail
// and cause an early return:
const SemaphoreReleaser semReleaser(sem, runs);
count.store(0); count.store(0);
int dtorCounter = 0; QAtomicInt dtorCounter = 0;
int runCounter = 0; QAtomicInt runCounter = 0;
for (int i = 0; i < runs; i++) { for (int i = 0; i < runs; i++) {
runnables[i] = new BlockingRunnable(sem, dtorCounter, runCounter); runnables[i] = new BlockingRunnable(sem, startedThreads, dtorCounter, runCounter);
runnables[i]->setAutoDelete(i != 0 && i != (runs-1)); //one which will run and one which will not runnables[i]->setAutoDelete(i != 0 && i != (runs-1)); //one which will run and one which will not
threadPool.cancel(runnables[i]); //verify NOOP for jobs not in the queue threadPool.cancel(runnables[i]); //verify NOOP for jobs not in the queue
threadPool.start(runnables[i]); threadPool.start(runnables[i]);
} }
// wait for all worker threads to have started up:
QVERIFY(startedThreads.tryAcquire(MaxThreadCount, 60*1000 /* 1min */));
for (int i = 0; i < runs; i++) { for (int i = 0; i < runs; i++) {
threadPool.cancel(runnables[i]); threadPool.cancel(runnables[i]);
} }
runnables[0]->dummy = 0; //valgrind will catch this if cancel() is crazy enough to delete currently running jobs runnables[0]->dummy = 0; //valgrind will catch this if cancel() is crazy enough to delete currently running jobs
runnables[runs-1]->dummy = 0; runnables[runs-1]->dummy = 0;
QCOMPARE(dtorCounter, runs-threadPool.maxThreadCount()-1); QCOMPARE(dtorCounter.load(), runs - threadPool.maxThreadCount() - 1);
sem.release(threadPool.maxThreadCount()); sem.release(threadPool.maxThreadCount());
threadPool.waitForDone(); threadPool.waitForDone();
QCOMPARE(runCounter, threadPool.maxThreadCount()); QCOMPARE(runCounter.load(), threadPool.maxThreadCount());
QCOMPARE(count.load(), threadPool.maxThreadCount()); QCOMPARE(count.load(), threadPool.maxThreadCount());
QCOMPARE(dtorCounter, runs-2); QCOMPARE(dtorCounter.load(), runs - 2);
delete runnables[0]; //if the pool deletes them then we'll get double-free crash delete runnables[0]; //if the pool deletes them then we'll get double-free crash
delete runnables[runs-1]; delete runnables[runs-1];
delete[] runnables;
} }
void tst_QThreadPool::destroyingWaitsForTasksToFinish() void tst_QThreadPool::destroyingWaitsForTasksToFinish()

View File

@ -155,6 +155,29 @@ private:
QDateTime invalidDateTime() const { return QDateTime(invalidDate(), invalidTime()); } QDateTime invalidDateTime() const { return QDateTime(invalidDate(), invalidTime()); }
QDate invalidDate() const { return QDate(); } QDate invalidDate() const { return QDate(); }
QTime invalidTime() const { return QTime(-1, -1, -1); } QTime invalidTime() const { return QTime(-1, -1, -1); }
class TimeZoneRollback
{
const QByteArray prior;
public:
// Save the previous timezone so we can restore it afterwards, otherwise
// later tests may break:
explicit TimeZoneRollback(const QByteArray &zone) : prior(qgetenv("TZ"))
{ reset(zone); }
void reset(const QByteArray &zone)
{
qputenv("TZ", zone.constData());
tzset();
}
~TimeZoneRollback()
{
if (prior.isNull())
qunsetenv("TZ");
else
qputenv("TZ", prior.constData());
tzset();
}
};
}; };
Q_DECLARE_METATYPE(Qt::TimeSpec) Q_DECLARE_METATYPE(Qt::TimeSpec)
@ -1953,12 +1976,8 @@ void tst_QDateTime::operator_insert_extract()
QFETCH(QString, deserialiseAs); QFETCH(QString, deserialiseAs);
QFETCH(QDataStream::Version, dataStreamVersion); QFETCH(QDataStream::Version, dataStreamVersion);
// Save the previous timezone so we can restore it afterwards, otherwise later tests will break
QByteArray previousTimeZone = qgetenv("TZ");
// Start off in a certain timezone. // Start off in a certain timezone.
qputenv("TZ", serialiseAs.toLocal8Bit().constData()); TimeZoneRollback useZone(serialiseAs.toLocal8Bit());
tzset();
QDateTime dateTimeAsUTC(dateTime.toUTC()); QDateTime dateTimeAsUTC(dateTime.toUTC());
QByteArray byteArray; QByteArray byteArray;
@ -1983,8 +2002,7 @@ void tst_QDateTime::operator_insert_extract()
// Ensure that a change in timezone between serialisation and deserialisation // Ensure that a change in timezone between serialisation and deserialisation
// still results in identical UTC-converted datetimes. // still results in identical UTC-converted datetimes.
qputenv("TZ", deserialiseAs.toLocal8Bit().constData()); useZone.reset(deserialiseAs.toLocal8Bit());
tzset();
QDateTime expectedLocalTime(dateTimeAsUTC.toLocalTime()); QDateTime expectedLocalTime(dateTimeAsUTC.toLocalTime());
{ {
// Deserialise whole QDateTime at once. // Deserialise whole QDateTime at once.
@ -2035,12 +2053,6 @@ void tst_QDateTime::operator_insert_extract()
QCOMPARE(localDeserialized, dateTime); QCOMPARE(localDeserialized, dateTime);
} }
} }
if (previousTimeZone.isNull())
qunsetenv("TZ");
else
qputenv("TZ", previousTimeZone.constData());
tzset();
} }
void tst_QDateTime::toString_strformat() void tst_QDateTime::toString_strformat()