diff options
Diffstat (limited to 'tests')
39 files changed, 1073 insertions, 137 deletions
diff --git a/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro b/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro index 321420c2df..287ab30993 100644 --- a/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro +++ b/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro @@ -5,7 +5,6 @@ CONFIG += testcase QT = core core-private testlib SOURCES += tst_qloggingregistry.cpp -OTHER_FILES += qtlogging.ini TESTDATA += qtlogging.ini android { diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 470d5b6434..73672f3572 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -143,6 +143,8 @@ private slots: void hostFlags_data(); void hostFlags(); void setPort(); + void port_data(); + void port(); void toEncoded_data(); void toEncoded(); void setAuthority_data(); @@ -1742,6 +1744,9 @@ void tst_QUrl::symmetry() QUrl url(QString::fromUtf8("http://www.räksmörgås.se/pub?a=b&a=dø&a=f#vræl")); QCOMPARE(url.scheme(), QString::fromLatin1("http")); QCOMPARE(url.host(), QString::fromUtf8("www.räksmörgås.se")); + QCOMPARE(url.host(QUrl::EncodeSpaces), QString::fromUtf8("www.räksmörgås.se")); + QCOMPARE(url.host(QUrl::EncodeUnicode), QString::fromUtf8("www.xn--rksmrgs-5wao1o.se")); + QCOMPARE(url.host(QUrl::EncodeUnicode | QUrl::EncodeSpaces), QString::fromUtf8("www.xn--rksmrgs-5wao1o.se")); QCOMPARE(url.path(), QString::fromLatin1("/pub")); // this will be encoded ... QCOMPARE(url.encodedQuery().constData(), QString::fromLatin1("a=b&a=d%C3%B8&a=f").toLatin1().constData()); @@ -2200,8 +2205,6 @@ void tst_QUrl::strictParser_data() // FIXME: add some tests for prohibited BiDi (RFC 3454 section 6) // port errors happen in TolerantMode too - QTest::newRow("empty-port-1") << "http://example.com:" << "Port field was empty"; - QTest::newRow("empty-port-2") << "http://example.com:/" << "Port field was empty"; QTest::newRow("invalid-port-1") << "http://example.com:-1" << "Invalid port"; QTest::newRow("invalid-port-2") << "http://example.com:abc" << "Invalid port"; QTest::newRow("invalid-port-3") << "http://example.com:9a" << "Invalid port"; @@ -2778,6 +2781,31 @@ void tst_QUrl::setPort() } } +void tst_QUrl::port_data() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<int>("port"); + + QTest::newRow("no-port-1") << "http://example.com" << -1; + QTest::newRow("no-port-2") << "http://example.com/" << -1; + QTest::newRow("empty-port-1") << "http://example.com:" << -1; + QTest::newRow("empty-port-2") << "http://example.com:/" << -1; + QTest::newRow("zero-port-1") << "http://example.com:0" << 0; + QTest::newRow("zero-port-2") << "http://example.com:0/" << 0; + QTest::newRow("set-port-1") << "http://example.com:80" << 80; + QTest::newRow("set-port-2") << "http://example.com:80/" << 80; +} + +void tst_QUrl::port() +{ + QFETCH(QString, input); + QFETCH(int, port); + + QUrl url(input); + QVERIFY(url.isValid()); + QCOMPARE(url.port(), port); +} + void tst_QUrl::toEncoded_data() { QTest::addColumn<QByteArray>("url"); diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index 9af4345029..f5835ec5f4 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -998,7 +998,9 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8_data() QTest::addColumn<QString>("utf16"); extern void loadInvalidUtf8Rows(); + extern void loadNonCharactersRows(); loadInvalidUtf8Rows(); + loadNonCharactersRows(); QTest::newRow("utf8-mix-4") << QByteArray("\xE0.A2\x80"); QTest::newRow("utf8-mix-5") << QByteArray("\xE0\xA2.80"); diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index b4f0bd2b3a..5878d56a47 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -374,12 +374,13 @@ void tst_QtJson::testObjectSimple() QJsonObject object; object.insert("number", 999.); QCOMPARE(object.value("number").type(), QJsonValue::Double); - QCOMPARE(object.value("number").toDouble(), 999.); + QCOMPARE(object.value(QLatin1String("number")).toDouble(), 999.); object.insert("string", QString::fromLatin1("test")); QCOMPARE(object.value("string").type(), QJsonValue::String); - QCOMPARE(object.value("string").toString(), QString("test")); + QCOMPARE(object.value(QLatin1String("string")).toString(), QString("test")); object.insert("boolean", true); QCOMPARE(object.value("boolean").toBool(), true); + QCOMPARE(object.value(QLatin1String("boolean")).toBool(), true); QStringList keys = object.keys(); QVERIFY2(keys.contains("number"), "key number not found"); @@ -403,7 +404,7 @@ void tst_QtJson::testObjectSimple() QString before = object.value("string").toString(); object.insert("string", QString::fromLatin1("foo")); - QVERIFY2(object.value("string").toString() != before, "value should have been updated"); + QVERIFY2(object.value(QLatin1String("string")).toString() != before, "value should have been updated"); size = object.size(); QJsonObject subobject; @@ -678,7 +679,7 @@ void tst_QtJson::testValueRef() QCOMPARE(object.value(QLatin1String("null")), QJsonValue()); object[QLatin1String("null")] = 100.; QCOMPARE(object.value(QLatin1String("null")).type(), QJsonValue::Double); - QJsonValue val = object[QLatin1String("null")]; + QJsonValue val = qAsConst(object)[QLatin1String("null")]; QCOMPARE(val.toDouble(), 100.); QCOMPARE(object.size(), 2); @@ -843,13 +844,13 @@ void tst_QtJson::testObjectFind() QJsonObject::iterator it = object.find(QLatin1String("1")); QCOMPARE((*it).toDouble(), 1.); - it = object.find(QLatin1String("11")); + it = object.find(QString("11")); QCOMPARE((*it).type(), QJsonValue::Undefined); QCOMPARE(it, object.end()); QJsonObject::const_iterator cit = object.constFind(QLatin1String("1")); QCOMPARE((*cit).toDouble(), 1.); - cit = object.constFind(QLatin1String("11")); + cit = object.constFind(QString("11")); QCOMPARE((*it).type(), QJsonValue::Undefined); QCOMPARE(it, object.end()); } @@ -911,7 +912,7 @@ void tst_QtJson::testDocument() doc3.setObject(outer.value(QLatin1String("innter")).toObject()); QCOMPARE(doc3.isArray(), false); QCOMPARE(doc3.isObject(), true); - QVERIFY(doc3.object().contains(QLatin1String("innerKey"))); + QVERIFY(doc3.object().contains(QString("innerKey"))); QCOMPARE(doc3.object().value(QLatin1String("innerKey")), QJsonValue(42)); QJsonDocument doc4(outer.value(QLatin1String("innterArray")).toArray()); @@ -938,9 +939,9 @@ void tst_QtJson::nullValues() QJsonObject object; object.insert(QString("key"), QJsonValue()); - QCOMPARE(object.contains("key"), true); + QCOMPARE(object.contains(QLatin1String("key")), true); QCOMPARE(object.size(), 1); - QCOMPARE(object.value("key"), QJsonValue()); + QCOMPARE(object.value(QString("key")), QJsonValue()); } void tst_QtJson::nullArrays() diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 6898fa717e..d1d3738879 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -143,6 +143,7 @@ private slots: void exceptions(); void noDeclarativeParentChangedOnDestruction(); void deleteLaterInAboutToBlockHandler(); + void mutableFunctor(); }; struct QObjectCreatedOnShutdown @@ -6508,6 +6509,24 @@ void tst_QObject::noDeclarativeParentChangedOnDestruction() #endif } +struct MutableFunctor { + int count; + MutableFunctor() : count(0) {} + int operator()() { return ++count; } +}; + +void tst_QObject::mutableFunctor() +{ + ReturnValue o; + MutableFunctor functor; + QCOMPARE(functor.count, 0); + connect(&o, &ReturnValue::returnInt, functor); + QCOMPARE(emit o.returnInt(0), 1); + QCOMPARE(emit o.returnInt(0), 2); // each emit should increase the internal count + + QCOMPARE(functor.count, 0); // but the original object should have been copied at connect time +} + // Test for QtPrivate::HasQ_OBJECT_Macro Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value); Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value); diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index 5154d84a75..593706ac0d 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -513,6 +513,8 @@ void tst_QMimeDatabase::mimeTypeForUrl() QVERIFY(db.mimeTypeForUrl(QUrl::fromEncoded("http://foo/bar.png")).isDefault()); // HTTP can't know before downloading QCOMPARE(db.mimeTypeForUrl(QUrl::fromEncoded("ftp://foo/bar.png")).name(), QString::fromLatin1("image/png")); QCOMPARE(db.mimeTypeForUrl(QUrl::fromEncoded("ftp://foo/bar")).name(), QString::fromLatin1("application/octet-stream")); // unknown extension + QCOMPARE(db.mimeTypeForUrl(QUrl("mailto:something@example.com")).name(), QString::fromLatin1("application/octet-stream")); // unknown + QCOMPARE(db.mimeTypeForUrl(QUrl("mailto:something@polish.pl")).name(), QString::fromLatin1("application/octet-stream")); // unknown, NOT perl ;) } void tst_QMimeDatabase::mimeTypeForData_data() diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index cd2cdab11b..383f357206 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -640,22 +640,21 @@ void tst_QTimeLine::restart() void tst_QTimeLine::setPaused() { - QTimeLine timeLine(1000); + const int EndTime = 10000; + QTimeLine timeLine(EndTime); { QCOMPARE(timeLine.currentTime(), 0); timeLine.start(); - QTest::qWait(250); + QTRY_VERIFY(timeLine.currentTime() != 0); // wait for start timeLine.setPaused(true); int oldCurrentTime = timeLine.currentTime(); QVERIFY(oldCurrentTime > 0); - QVERIFY(oldCurrentTime < 1000); + QVERIFY(oldCurrentTime < EndTime); QTest::qWait(1000); timeLine.setPaused(false); - QTest::qWait(250); - int currentTime = timeLine.currentTime(); - QVERIFY(currentTime > 0); - QVERIFY(currentTime > oldCurrentTime); - QVERIFY(currentTime < 1000); + QTRY_VERIFY(timeLine.currentTime() > oldCurrentTime); + QVERIFY(timeLine.currentTime() > 0); + QVERIFY(timeLine.currentTime() < EndTime); timeLine.stop(); } } diff --git a/tests/auto/corelib/tools/qtimezone/BLACKLIST b/tests/auto/corelib/tools/qtimezone/BLACKLIST deleted file mode 100644 index d74ec33209..0000000000 --- a/tests/auto/corelib/tools/qtimezone/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -[tzTest] -opensuse-13.1 -opensuse-42.1 diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp index 077a6a20f1..9fd418742c 100644 --- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp @@ -762,16 +762,22 @@ void tst_QTimeZone::tzTest() // Warning: This could vary depending on age of TZ file! // Test low date uses first rule found + // Note: Depending on the OS in question, the database may be carrying the + // Local Mean Time. which for Berlin is 0:53:28 QTimeZonePrivate::Data dat = tzp.data(-9999999999999); QCOMPARE(dat.atMSecsSinceEpoch, (qint64)-9999999999999); - QCOMPARE(dat.standardTimeOffset, 3600); QCOMPARE(dat.daylightTimeOffset, 0); + if (dat.abbreviation == "LMT") { + QCOMPARE(dat.standardTimeOffset, 3208); + } else { + QCOMPARE(dat.standardTimeOffset, 3600); - // Test previous to low value is invalid - dat = tzp.previousTransition(-9999999999999); - QCOMPARE(dat.atMSecsSinceEpoch, std::numeric_limits<qint64>::min()); - QCOMPARE(dat.standardTimeOffset, std::numeric_limits<int>::min()); - QCOMPARE(dat.daylightTimeOffset, std::numeric_limits<int>::min()); + // Test previous to low value is invalid + dat = tzp.previousTransition(-9999999999999); + QCOMPARE(dat.atMSecsSinceEpoch, std::numeric_limits<qint64>::min()); + QCOMPARE(dat.standardTimeOffset, std::numeric_limits<int>::min()); + QCOMPARE(dat.daylightTimeOffset, std::numeric_limits<int>::min()); + } dat = tzp.nextTransition(-9999999999999); QCOMPARE(dat.atMSecsSinceEpoch, (qint64)-2422054408000); diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp index 3418a34c12..0163f44a36 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp @@ -1213,6 +1213,27 @@ void tst_QDBusConnection::callVirtualObjectLocal() QCOMPARE(obj.replyArguments, subPathReply.arguments()); } +void tst_QDBusConnection::pendingCallWhenDisconnected() +{ + if (!QCoreApplication::instance()) + QSKIP("Test requires a QCoreApplication"); + + QDBusServer *server = new QDBusServer; + QDBusConnection con = QDBusConnection::connectToPeer(server->address(), "disconnect"); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(con.isConnected()); + QDBusMessage message = QDBusMessage::createMethodCall("", "/", QString(), "method"); + QDBusPendingCall reply = con.asyncCall(message); + + delete server; + + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!con.isConnected()); + QVERIFY(reply.isFinished()); + QVERIFY(reply.isError()); + QVERIFY(reply.error().type() == QDBusError::Disconnected); +} + QString MyObject::path; QString MyObjectWithoutInterface::path; QString MyObjectWithoutInterface::interface; diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h index 0e2943b1c4..0402889c6e 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h @@ -116,6 +116,7 @@ private slots: void registerVirtualObject(); void callVirtualObject(); void callVirtualObjectLocal(); + void pendingCallWhenDisconnected(); public: QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; } diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 90b88d0992..bc48869f7d 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -3079,6 +3079,14 @@ void tst_QImage::pixelColor() QImage t = argb32.convertToFormat(QImage::Format_ARGB32_Premultiplied); QCOMPARE(t.pixel(0,0), argb32pm.pixel(0,0)); + + // Try specifying an invalid position. + QTest::ignoreMessage(QtWarningMsg, "QImage::setPixelColor: coordinate (-1,-1) out of range"); + argb32.setPixelColor(-1, -1, QColor(Qt::red)); + + // Try setting an invalid color. + QTest::ignoreMessage(QtWarningMsg, "QImage::setPixelColor: color is invalid"); + argb32.setPixelColor(0, 0, QColor()); } void tst_QImage::pixel() diff --git a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp index db0bfaf622..811a6d111f 100644 --- a/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp +++ b/tests/auto/gui/kernel/qkeyevent/tst_qkeyevent.cpp @@ -116,6 +116,23 @@ static bool orderByModifier(const QVector<int> &v1, const QVector<int> &v2) return true; } +static QByteArray modifiersTestRowName(const QString &keySequence) +{ + QByteArray result; + QTextStream str(&result); + for (int i = 0, size = keySequence.size(); i < size; ++i) { + const QChar &c = keySequence.at(i); + const ushort uc = c.unicode(); + if (uc > 32 && uc < 128) + str << '"' << c << '"'; + else + str << "U+" << hex << uc << dec; + if (i < size - 1) + str << ','; + } + return result; +} + void tst_QKeyEvent::modifiers_data() { struct Modifier @@ -155,7 +172,8 @@ void tst_QKeyEvent::modifiers_data() mods |= modifier.modifier; } QKeySequence keySequence(keys[0], keys[1], keys[2], keys[3]); - QTest::newRow(keySequence.toString(QKeySequence::NativeText).toUtf8().constData()) << mods; + QTest::newRow(modifiersTestRowName(keySequence.toString(QKeySequence::NativeText)).constData()) + << mods; } } diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp index ea2b6a12f7..b0f70d1a59 100644 --- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp @@ -183,6 +183,8 @@ private slots: void textCursorUsageWithinContentsChange(); void cssInheritance(); + + void lineHeightType(); private: void backgroundImage_checkExpectedHtml(const QTextDocument &doc); void buildRegExpData(); @@ -3204,7 +3206,7 @@ void tst_QTextDocument::cssInheritance() "<p style=\"line-height: 40px\">Foo</p><p>Bar</p><p>Baz</p></body></html>"); QTextBlock block = td.begin(); QTextBlockFormat fmt = block.blockFormat(); - QCOMPARE(fmt.lineHeightType(), int(QTextBlockFormat::FixedHeight)); + QCOMPARE(fmt.lineHeightType(), int(QTextBlockFormat::MinimumHeight)); QCOMPARE(fmt.lineHeight(), qreal(40)); block = block.next(); fmt = block.blockFormat(); @@ -3289,5 +3291,89 @@ void tst_QTextDocument::cssInheritance() } } +void tst_QTextDocument::lineHeightType() +{ + { + QTextDocument td; + td.setHtml("<html><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::SingleHeight)); + QCOMPARE(format.lineHeight(), 0.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { line-height: 40px; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::MinimumHeight)); + QCOMPARE(format.lineHeight(), 40.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { line-height: 200%; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::ProportionalHeight)); + QCOMPARE(format.lineHeight(), 200.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { line-height: 200%; -qt-line-height-type: single; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::SingleHeight)); + QCOMPARE(format.lineHeight(), 200.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { line-height: 40px; -qt-line-height-type: proportional; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::ProportionalHeight)); + QCOMPARE(format.lineHeight(), 40.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { line-height: 10; -qt-line-height-type: fixed; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::FixedHeight)); + QCOMPARE(format.lineHeight(), 10.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { line-height: 33; -qt-line-height-type: minimum; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::MinimumHeight)); + QCOMPARE(format.lineHeight(), 33.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { -qt-line-height-type: fixed; line-height: 200%; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::FixedHeight)); + QCOMPARE(format.lineHeight(), 200.0); + } + + { + QTextDocument td; + td.setHtml("<html><head><style type=\"text/css\">body { -qt-line-height-type: fixed; line-height: 200px; }</style></head><body>Foobar</body></html>"); + QTextBlock block = td.begin(); + QTextBlockFormat format = block.blockFormat(); + QCOMPARE(int(format.lineHeightType()), int(QTextBlockFormat::FixedHeight)); + QCOMPARE(format.lineHeight(), 200.0); + } +} + QTEST_MAIN(tst_QTextDocument) #include "tst_qtextdocument.moc" diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp index de29389796..36907b9258 100644 --- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp @@ -1075,8 +1075,6 @@ void tst_QTextScriptEngine::mirroredChars() void tst_QTextScriptEngine::controlInSyllable_qtbug14204() { - QSKIP("Result differs for HarfBuzz-NG, skip test."); - QFontDatabase db; if (!db.families().contains(QStringLiteral("Aparajita"))) QSKIP("couldn't find 'Aparajita' font"); @@ -1101,13 +1099,13 @@ void tst_QTextScriptEngine::controlInSyllable_qtbug14204() QCOMPARE(fe->fontDef.family, font.family()); e->shape(0); - QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(2)); + QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(3)); const ushort *log_clusters = e->logClusters(&e->layoutData->items[0]); QCOMPARE(log_clusters[0], ushort(0)); QCOMPARE(log_clusters[1], ushort(0)); - QCOMPARE(log_clusters[2], ushort(0)); - QCOMPARE(log_clusters[3], ushort(0)); + QCOMPARE(log_clusters[2], ushort(1)); + QCOMPARE(log_clusters[3], ushort(2)); } void tst_QTextScriptEngine::combiningMarks_qtbug15675_data() @@ -1225,29 +1223,21 @@ void tst_QTextScriptEngine::thaiWithZWJ() QTextLayout layout(s, font); QTextEngine *e = layout.engine(); e->itemize(); - QCOMPARE(e->layoutData->items.size(), 11); + QCOMPARE(e->layoutData->items.size(), 3); for (int item = 0; item < e->layoutData->items.size(); ++item) e->shape(item); - QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(7)); // Thai: The ZWJ and ZWNJ characters are inherited, so should be part of the thai script - QCOMPARE(e->layoutData->items[1].num_glyphs, ushort(1)); // Common: The smart quotes cannot be handled by thai, so should be a separate item - QCOMPARE(e->layoutData->items[2].num_glyphs, ushort(1)); // Thai: Thai character - QCOMPARE(e->layoutData->items[3].num_glyphs, ushort(1)); // Common: Ellipsis - QCOMPARE(e->layoutData->items[4].num_glyphs, ushort(1)); // Thai: Thai character - QCOMPARE(e->layoutData->items[5].num_glyphs, ushort(1)); // Common: Smart quote - QCOMPARE(e->layoutData->items[6].num_glyphs, ushort(1)); // Thai: Thai character - QCOMPARE(e->layoutData->items[7].num_glyphs, ushort(1)); // Common: \xA0 = non-breaking space. Could be useful to have in thai, but not currently implemented - QCOMPARE(e->layoutData->items[8].num_glyphs, ushort(1)); // Thai: Thai character - QCOMPARE(e->layoutData->items[9].num_glyphs, ushort(1)); // Japanese: Kanji for tree - QCOMPARE(e->layoutData->items[10].num_glyphs, ushort(2)); // Thai: Thai character followed by superscript "a" which is of inherited type + QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(15)); // Thai, Inherited and Common + QCOMPARE(e->layoutData->items[1].num_glyphs, ushort(1)); // Japanese: Kanji for tree + QCOMPARE(e->layoutData->items[2].num_glyphs, ushort(2)); // Thai: Thai character followed by superscript "a" which is of inherited type //A quick sanity check - check all the characters are individual clusters unsigned short *logClusters = e->layoutData->logClustersPtr; - for (int i = 0; i < 7; i++) + for (int i = 0; i < 15; i++) QCOMPARE(logClusters[i], ushort(i)); - for (int i = 0; i < 10; i++) - QCOMPARE(logClusters[i+7], ushort(0)); + for (int i = 0; i < 3; i++) + QCOMPARE(logClusters[i+15], ushort(0)); // A thai implementation could either remove the ZWJ and ZWNJ characters, or hide them. // The current implementation hides them, so we test for that. diff --git a/tests/auto/network-settings.h b/tests/auto/network-settings.h index d6b63c6100..16966ced4e 100644 --- a/tests/auto/network-settings.h +++ b/tests/auto/network-settings.h @@ -29,6 +29,8 @@ #include <QString> #ifdef QT_NETWORK_LIB #include <QtNetwork/QHostInfo> +#include <QtNetwork/QHostAddress> +#include <QtNetwork/QAbstractSocket> #endif #ifdef Q_OS_UNIX @@ -134,5 +136,21 @@ public: } return true; } -#endif + + // Helper function for usage with QVERIFY2 on sockets. + static QByteArray msgSocketError(const QAbstractSocket &s) + { + QString result; + QDebug debug(&result); + debug.nospace(); + debug.noquote(); + if (!s.localAddress().isNull()) + debug << "local=" << s.localAddress().toString() << ':' << s.localPort(); + if (!s.peerAddress().isNull()) + debug << ", peer=" << s.peerAddress().toString() << ':' << s.peerPort(); + debug << ", type=" << s.socketType() << ", state=" << s.state() + << ", error=" << s.error() << ": " << s.errorString(); + return result.toLocal8Bit(); + } +#endif // QT_NETWORK_LIB }; diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index 3112d7d62b..00e01094a4 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -31,6 +31,7 @@ #include <QtTest/QtTest> #include <qtextstream.h> +#include <qdatastream.h> #include <QtNetwork/qlocalsocket.h> #include <QtNetwork/qlocalserver.h> @@ -73,6 +74,9 @@ private slots: void readBufferOverflow(); + void simpleCommandProtocol1(); + void simpleCommandProtocol2(); + void fullPath(); void hitMaximumConnections_data(); @@ -622,6 +626,110 @@ void tst_QLocalSocket::readBufferOverflow() QCOMPARE(client.bytesAvailable(), 0); } +static qint64 writeCommand(const QVariant &command, QIODevice *device, int commandCounter) +{ + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out << qint64(0); + out << commandCounter; + out << command; + out.device()->seek(0); + out << qint64(block.size() - sizeof(qint64)); + return device->write(block); +} + +static QVariant readCommand(QIODevice *ioDevice, int *readCommandCounter, bool readSize = true) +{ + QDataStream in(ioDevice); + qint64 blockSize; + int commandCounter; + if (readSize) + in >> blockSize; + in >> commandCounter; + *readCommandCounter = commandCounter; + + QVariant command; + in >> command; + + return command; +} + +void tst_QLocalSocket::simpleCommandProtocol1() +{ + QLocalServer server; + server.listen(QStringLiteral("simpleProtocol")); + + QLocalSocket localSocketWrite; + localSocketWrite.connectToServer(server.serverName()); + QVERIFY(server.waitForNewConnection()); + QLocalSocket *localSocketRead = server.nextPendingConnection(); + QVERIFY(localSocketRead); + + int readCounter = 0; + for (int i = 0; i < 2000; ++i) { + const QVariant command(QRect(readCounter, i, 10, 10)); + const qint64 blockSize = writeCommand(command, &localSocketWrite, i); + while (localSocketWrite.bytesToWrite()) + QVERIFY(localSocketWrite.waitForBytesWritten()); + while (localSocketRead->bytesAvailable() < blockSize) { + QVERIFY(localSocketRead->waitForReadyRead(1000)); + } + const QVariant variant = readCommand(localSocketRead, &readCounter); + QCOMPARE(readCounter, i); + QCOMPARE(variant, command); + } +} + +void tst_QLocalSocket::simpleCommandProtocol2() +{ + QLocalServer server; + server.listen(QStringLiteral("simpleProtocol")); + + QLocalSocket localSocketWrite; + localSocketWrite.connectToServer(server.serverName()); + QVERIFY(server.waitForNewConnection()); + QLocalSocket* localSocketRead = server.nextPendingConnection(); + QVERIFY(localSocketRead); + + int readCounter = 0; + qint64 writtenBlockSize = 0; + qint64 blockSize = 0; + + QObject::connect(localSocketRead, &QLocalSocket::readyRead, [&] { + forever { + if (localSocketRead->bytesAvailable() < sizeof(qint64)) + return; + + if (blockSize == 0) { + QDataStream in(localSocketRead); + in >> blockSize; + } + + if (localSocketRead->bytesAvailable() < blockSize) + return; + + int commandNumber = 0; + const QVariant variant = readCommand(localSocketRead, &commandNumber, false); + QCOMPARE(writtenBlockSize, blockSize); + QCOMPARE(readCounter, commandNumber); + QCOMPARE(variant.userType(), (int)QMetaType::QRect); + + readCounter++; + blockSize = 0; + } + }); + + for (int i = 0; i < 500; ++i) { + const QVariant command(QRect(readCounter, i, 10, 10)); + writtenBlockSize = writeCommand(command, &localSocketWrite, i) - sizeof(qint64); + if (i % 10 == 0) + QTest::qWait(1); + } + + localSocketWrite.abort(); + QVERIFY(localSocketRead->waitForDisconnected(1000)); +} + // QLocalSocket/Server can take a name or path, check that it works as expected void tst_QLocalSocket::fullPath() { diff --git a/tests/auto/network/socket/qtcpserver/crashingServer/main.cpp b/tests/auto/network/socket/qtcpserver/crashingServer/main.cpp index 15e9228a04..1a8e7920d3 100644 --- a/tests/auto/network/socket/qtcpserver/crashingServer/main.cpp +++ b/tests/auto/network/socket/qtcpserver/crashingServer/main.cpp @@ -29,9 +29,16 @@ #include <QtCore> #include <QtNetwork> +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) && defined(Q_CC_MSVC) +# include <crtdbg.h> +#endif int main(int argc, char *argv[]) { + // Windows: Suppress crash notification dialog. +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) && defined(Q_CC_MSVC) + _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); +#endif QCoreApplication app(argc, argv); QTcpServer server; diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 7565097942..382fbf08a8 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -671,8 +671,10 @@ void tst_QTcpSocket::bindThenResolveHost() dummySocket.close(); - socket->connectToHost(hostName, 80); - QVERIFY2(socket->waitForConnected(), "Network timeout"); + const quint16 port = 80; + socket->connectToHost(hostName, port); + QVERIFY2(socket->waitForConnected(), (hostName.toLocal8Bit() + ": " + QByteArray::number(port) + ' ' + + QtNetworkSettings::msgSocketError(*socket)).constData()); QCOMPARE(socket->localPort(), boundPort); QCOMPARE(socket->socketDescriptor(), fd); diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 8c9d0d1b9f..942a074c87 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -33,6 +33,7 @@ #include <qcoreapplication.h> #include <qfileinfo.h> #include <qdatastream.h> +#include <qdebug.h> #include <qudpsocket.h> #include <qhostaddress.h> #include <qhostinfo.h> @@ -246,7 +247,7 @@ void tst_QUdpSocket::unconnectedServerAndClientTest() char buf[1024]; QHostAddress host; quint16 port; - QVERIFY(serverSocket.waitForReadyRead(5000)); + QVERIFY2(serverSocket.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(serverSocket).constData()); QCOMPARE(int(serverSocket.readDatagram(buf, sizeof(buf), &host, &port)), int(strlen(message[i]))); buf[strlen(message[i])] = '\0'; @@ -378,8 +379,8 @@ void tst_QUdpSocket::loop() QCOMPARE(paul.writeDatagram(paulMessage.data(), paulMessage.length(), peterAddress, peter.localPort()), qint64(paulMessage.length())); - QVERIFY(peter.waitForReadyRead(9000)); - QVERIFY(paul.waitForReadyRead(9000)); + QVERIFY2(peter.waitForReadyRead(9000), QtNetworkSettings::msgSocketError(peter).constData()); + QVERIFY2(paul.waitForReadyRead(9000), QtNetworkSettings::msgSocketError(paul).constData()); char peterBuffer[16*1024]; char paulBuffer[16*1024]; if (success) { @@ -466,7 +467,7 @@ void tst_QUdpSocket::dualStack() QByteArray buffer; //test v4 -> dual QCOMPARE((int)v4Sock.writeDatagram(v4Data.constData(), v4Data.length(), QHostAddress(QHostAddress::LocalHost), dualSock.localPort()), v4Data.length()); - QVERIFY(dualSock.waitForReadyRead(5000)); + QVERIFY2(dualSock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(dualSock).constData()); buffer.reserve(100); qint64 size = dualSock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, v4Data.length()); @@ -480,7 +481,7 @@ void tst_QUdpSocket::dualStack() //test v6 -> dual QCOMPARE((int)v6Sock.writeDatagram(v6Data.constData(), v6Data.length(), QHostAddress(QHostAddress::LocalHostIPv6), dualSock.localPort()), v6Data.length()); - QVERIFY(dualSock.waitForReadyRead(5000)); + QVERIFY2(dualSock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(dualSock).constData()); buffer.reserve(100); size = dualSock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, v6Data.length()); @@ -489,7 +490,7 @@ void tst_QUdpSocket::dualStack() //test dual -> v6 QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); - QVERIFY(v6Sock.waitForReadyRead(5000)); + QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData()); buffer.reserve(100); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -499,7 +500,7 @@ void tst_QUdpSocket::dualStack() //test dual -> v4 QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); - QVERIFY(v4Sock.waitForReadyRead(5000)); + QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData()); buffer.reserve(100); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -531,7 +532,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QUdpSocket dualSock; QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); - QVERIFY(v4Sock.waitForReadyRead(5000)); + QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData()); buffer.reserve(100); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -539,7 +540,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QCOMPARE(buffer, dualData); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); - QVERIFY(v6Sock.waitForReadyRead(5000)); + QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData()); buffer.reserve(100); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -552,7 +553,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QUdpSocket dualSock; QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); - QVERIFY(v6Sock.waitForReadyRead(5000)); + QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData()); buffer.reserve(100); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -560,7 +561,7 @@ void tst_QUdpSocket::dualStackAutoBinding() QCOMPARE(buffer, dualData); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); - QVERIFY(v4Sock.waitForReadyRead(5000)); + QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData()); buffer.reserve(100); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); QCOMPARE((int)size, dualData.length()); @@ -665,7 +666,7 @@ void tst_QUdpSocket::pendingDatagramSize() QVERIFY(client.writeDatagram("3 messages", 10, serverAddress, server.localPort()) == 10); char c = 0; - QVERIFY(server.waitForReadyRead()); + QVERIFY2(server.waitForReadyRead(), QtNetworkSettings::msgSocketError(server).constData()); if (server.hasPendingDatagrams()) { #if defined Q_OS_HPUX && defined __ia64 QEXPECT_FAIL("", "HP-UX 11i v2 can't determine the datagram size correctly.", Abort); @@ -1071,7 +1072,7 @@ void tst_QUdpSocket::zeroLengthDatagram() #endif QCOMPARE(sender.writeDatagram(QByteArray(), QHostAddress::LocalHost, receiver.localPort()), qint64(0)); - QVERIFY(receiver.waitForReadyRead(1000)); + QVERIFY2(receiver.waitForReadyRead(1000), QtNetworkSettings::msgSocketError(receiver).constData()); QVERIFY(receiver.hasPendingDatagrams()); char buf; @@ -1350,8 +1351,7 @@ void tst_QUdpSocket::multicast() int(datagram.size())); } - QVERIFY2(receiver.waitForReadyRead(), - qPrintable(receiver.errorString())); + QVERIFY2(receiver.waitForReadyRead(), QtNetworkSettings::msgSocketError(receiver).constData()); QVERIFY(receiver.hasPendingDatagrams()); QList<QByteArray> receivedDatagrams; while (receiver.hasPendingDatagrams()) { @@ -1417,7 +1417,7 @@ void tst_QUdpSocket::echo() qDebug() << "packets in" << successes << "out" << i; QTest::qWait(50); //choke to avoid triggering flood/DDoS protections on echo service } - QVERIFY(successes >= 9); + QVERIFY2(successes >= 9, QByteArray::number(successes).constData()); } void tst_QUdpSocket::linkLocalIPv6() @@ -1538,7 +1538,7 @@ void tst_QUdpSocket::linkLocalIPv4() QByteArray receiveBuffer("xxxxx"); foreach (QUdpSocket *s, sockets) { QVERIFY(s->writeDatagram(testData, s->localAddress(), neutral.localPort())); - QVERIFY(neutral.waitForReadyRead(10000)); + QVERIFY2(neutral.waitForReadyRead(10000), QtNetworkSettings::msgSocketError(neutral).constData()); QHostAddress from; quint16 fromPort; QCOMPARE((int)neutral.readDatagram(receiveBuffer.data(), receiveBuffer.length(), &from, &fromPort), testData.length()); @@ -1547,7 +1547,7 @@ void tst_QUdpSocket::linkLocalIPv4() QCOMPARE(receiveBuffer, testData); QVERIFY(neutral.writeDatagram(testData, s->localAddress(), s->localPort())); - QVERIFY(s->waitForReadyRead(10000)); + QVERIFY2(s->waitForReadyRead(10000), QtNetworkSettings::msgSocketError(*s).constData()); QCOMPARE((int)s->readDatagram(receiveBuffer.data(), receiveBuffer.length(), &from, &fromPort), testData.length()); QCOMPARE(receiveBuffer, testData); diff --git a/tests/auto/network/socket/qudpsocket/udpServer/main.cpp b/tests/auto/network/socket/qudpsocket/udpServer/main.cpp index e19e93dc18..a5986c29c7 100644 --- a/tests/auto/network/socket/qudpsocket/udpServer/main.cpp +++ b/tests/auto/network/socket/qudpsocket/udpServer/main.cpp @@ -31,18 +31,21 @@ class Server : public QObject { Q_OBJECT public: - Server(int port) + + Server() { connect(&serverSocket, &QIODevice::readyRead, this, &Server::sendEcho); } + + bool bind(quint16 port) { - connect(&serverSocket, SIGNAL(readyRead()), - this, SLOT(sendEcho())); - if (serverSocket.bind(QHostAddress::Any, port, - QUdpSocket::ReuseAddressHint - | QUdpSocket::ShareAddress)) { + const bool result = serverSocket.bind(QHostAddress::Any, port, + QUdpSocket::ReuseAddressHint + | QUdpSocket::ShareAddress); + if (result) { printf("OK\n"); } else { - printf("FAILED\n"); + printf("FAILED: %s\n", qPrintable(serverSocket.errorString())); } fflush(stdout); + return result; } private slots: @@ -68,8 +71,19 @@ private: int main(int argc, char **argv) { QCoreApplication app(argc, argv); + QStringList arguments = QCoreApplication::arguments(); + arguments.pop_front(); + quint16 port = 0; + if (!arguments.isEmpty()) + port = arguments.constFirst().toUShort(); + if (!port) { + printf("Specify port number\n"); + return -1; + } - Server server(app.arguments().at(1).toInt()); + Server server; + if (!server.bind(port)) + return -2; return app.exec(); } diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp index d554a50c8d..50cfe48cdf 100644 --- a/tests/auto/other/compiler/tst_compiler.cpp +++ b/tests/auto/other/compiler/tst_compiler.cpp @@ -679,25 +679,105 @@ void tst_Compiler::cxx11_atomics() #endif } +QT_WARNING_PUSH +QT_WARNING_DISABLE_CLANG("-Wignored-attributes") +QT_WARNING_DISABLE_CLANG("-Wunused-local-typedefs") +QT_WARNING_DISABLE_GCC("-Wattributes") +QT_WARNING_DISABLE_GCC("-Wunused-local-typedefs") + +#ifndef __has_cpp_attribute +# define __has_cpp_attribute(x) 0 +#endif +#ifdef Q_COMPILER_ATTRIBUTES +[[noreturn]] void attribute_f1(); +void attribute_f2 [[noreturn]] (); +# if (defined(__cpp_namespace_attributes) && __cpp_namespace_attributes >= 201411) && __has_cpp_attribute(deprecated) +namespace NS [[deprecated]] { } +# endif +#endif + void tst_Compiler::cxx11_attributes() { #ifndef Q_COMPILER_ATTRIBUTES QSKIP("Compiler does not support C++11 feature"); #else - struct [[deprecated]] C {}; + // Attributes in function parameters and using clauses cause MSVC 2015 to crash + // https://connect.microsoft.com/VisualStudio/feedback/details/2011594 +# if (!defined(Q_CC_MSVC) || _MSC_FULL_VER >= 190023811) && !defined(Q_CC_INTEL) + void f([[ ]] int); + [[ ]] using namespace QtPrivate; + [[ ]] try { + } catch ([[]] int) { + } +# endif + + struct [[ ]] A { }; + struct B : A { + [[ ]] int m_i : 32; + [[noreturn]] void f() const { ::exit(0); } + +# ifdef Q_COMPILER_DEFAULT_DELETE_MEMBERS + [[ ]] ~B() = default; + [[ ]] B(const B &) = delete; +# endif + }; +# if __has_cpp_attribute(deprecated) + struct [[deprecated]] C { }; +# endif + enum [[ ]] E { }; + [[ ]] void [[ ]] * [[ ]] * [[ ]] ptr = 0; + int B::* [[ ]] pmm = 0; + +# if __has_cpp_attribute(deprecated) + enum [[deprecated]] E2 { +# if defined(__cpp_enumerator_attributes) && __cpp_enumerator_attributes >= 201411 + value [[deprecated]] = 0 +# endif + }; +# endif +# ifdef Q_COMPILER_LAMBDA + []()[[ ]] {}(); +# endif +# ifdef Q_COMPILER_TEMPLATE_ALIAS + using B2 [[ ]] = B; +# endif + + [[ ]] goto end; +# ifdef Q_CC_GNU + // Attributes in gnu:: namespace + [[gnu::unused]] end: + ; [[gnu::unused]] struct D {} d; - [[noreturn]] void f(); struct D e [[gnu::used, gnu::unused]]; - [[gnu::aligned(8)]] int i; + [[gnu::aligned(8)]] int i [[ ]]; + int array[][[]] = { 1 }; +# else + // Non GNU, so use an empty attribute + [[ ]] end: + ; + [[ ]] struct D {} d; + struct D e [[ ]]; + [[ ]] int i [[ ]]; + int array[][[]] = { 1 }; +# endif -[[gnu::unused]] end: - ; + int & [[ ]] lref = i; + int && [[ ]] rref = 1; + [[ ]] (void)1; + [[ ]] for (i = 0; i < 2; ++i) + ; + Q_UNUSED(ptr); + Q_UNUSED(pmm); Q_UNUSED(d); Q_UNUSED(e); Q_UNUSED(i); + Q_UNUSED(array); + Q_UNUSED(lref); + Q_UNUSED(rref); #endif } +QT_WARNING_POP #ifdef Q_COMPILER_AUTO_FUNCTION auto autoFunction() -> unsigned diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index f0241997bf..53d7cae837 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -657,6 +657,7 @@ void tst_QFileSystemModel::nameFilters() } void tst_QFileSystemModel::setData_data() { + QTest::addColumn<QString>("subdirName"); QTest::addColumn<QStringList>("files"); QTest::addColumn<QString>("oldFileName"); QTest::addColumn<QString>("newFileName"); @@ -666,7 +667,15 @@ void tst_QFileSystemModel::setData_data() << QDir::temp().absolutePath() + '/' + "a" << false; */ - QTest::newRow("in current dir") << (QStringList() << "a" << "b" << "c") + QTest::newRow("in current dir") + << QString() + << (QStringList() << "a" << "b" << "c") + << "a" + << "d" + << true; + QTest::newRow("in subdir") + << "s" + << (QStringList() << "a" << "b" << "c") << "a" << "d" << true; @@ -675,15 +684,25 @@ void tst_QFileSystemModel::setData_data() void tst_QFileSystemModel::setData() { QSignalSpy spy(model, SIGNAL(fileRenamed(QString,QString,QString))); - QString tmp = flatDirTestPath; + QFETCH(QString, subdirName); QFETCH(QStringList, files); QFETCH(QString, oldFileName); QFETCH(QString, newFileName); QFETCH(bool, success); + QString tmp = flatDirTestPath; + if (!subdirName.isEmpty()) { + QDir dir(tmp); + QVERIFY(dir.mkdir(subdirName)); + tmp.append('/' + subdirName); + } QVERIFY(createFiles(tmp, files)); - QModelIndex root = model->setRootPath(tmp); - QTRY_COMPARE(model->rowCount(root), files.count()); + QModelIndex tmpIdx = model->setRootPath(flatDirTestPath); + if (!subdirName.isEmpty()) { + tmpIdx = model->index(tmp); + model->fetchMore(tmpIdx); + } + QTRY_COMPARE(model->rowCount(tmpIdx), files.count()); QModelIndex idx = model->index(tmp + '/' + oldFileName); QCOMPARE(idx.isValid(), true); @@ -691,16 +710,21 @@ void tst_QFileSystemModel::setData() model->setReadOnly(false); QCOMPARE(model->setData(idx, newFileName), success); + model->setReadOnly(true); if (success) { QCOMPARE(spy.count(), 1); QList<QVariant> arguments = spy.takeFirst(); QCOMPARE(model->data(idx, QFileSystemModel::FileNameRole).toString(), newFileName); + QCOMPARE(model->fileInfo(idx).filePath(), tmp + '/' + newFileName); QCOMPARE(model->index(arguments.at(0).toString()), model->index(tmp)); QCOMPARE(arguments.at(1).toString(), oldFileName); QCOMPARE(arguments.at(2).toString(), newFileName); QCOMPARE(QFile::rename(tmp + '/' + newFileName, tmp + '/' + oldFileName), true); } - QTRY_COMPARE(model->rowCount(root), files.count()); + QTRY_COMPARE(model->rowCount(tmpIdx), files.count()); + // cleanup + if (!subdirName.isEmpty()) + QVERIFY(QDir(tmp).removeRecursively()); } void tst_QFileSystemModel::sortPersistentIndex() diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 99ec37fe2e..bc8b08997f 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -73,6 +73,7 @@ public: void testEvent(); void testhorizontalOffset(); void testverticalOffset(); + void testVisualRegionForSelection(); friend class tst_QHeaderView; }; @@ -204,6 +205,7 @@ private slots: void QTBUG8650_crashOnInsertSections(); void QTBUG12268_hiddenMovedSectionSorting(); void QTBUG14242_hideSectionAutoSize(); + void QTBUG50171_visualRegionForSwappedItems(); void ensureNoIndexAtLength(); void offsetConsistent(); @@ -2258,6 +2260,24 @@ void tst_QHeaderView::QTBUG14242_hideSectionAutoSize() QCOMPARE(calced_length, afterlength); } +void tst_QHeaderView::QTBUG50171_visualRegionForSwappedItems() +{ + protected_QHeaderView headerView(Qt::Horizontal); + QtTestModel model; + model.rows = 2; + model.cols = 3; + headerView.setModel(&model); + headerView.swapSections(1, 2); + headerView.hideSection(0); + headerView.testVisualRegionForSelection(); +} + +void protected_QHeaderView::testVisualRegionForSelection() +{ + QRegion r = visualRegionForSelection(QItemSelection(model()->index(1, 0), model()->index(1, 2))); + QCOMPARE(r.boundingRect().contains(QRect(1, 1, length() - 2, 1)), true); +} + void tst_QHeaderView::ensureNoIndexAtLength() { QTableView qtv; diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index afc9e29864..701dbd9f1f 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -67,7 +67,7 @@ #include <QtGui/qwindow.h> #include <qtimer.h> -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) #include "tst_qwidget_mac_helpers.h" // Abstract the ObjC stuff out so not everyone must run an ObjC++ compile. #endif @@ -97,7 +97,7 @@ static HWND winHandleOf(const QWidget *w) # define Q_CHECK_PAINTEVENTS #endif -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX #include <Security/AuthSession.h> bool macHasAccessToWindowsServer() { @@ -222,7 +222,7 @@ private slots: void restoreVersion1Geometry(); void widgetAt(); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void sheetOpacity(); void setMask(); #endif @@ -255,7 +255,7 @@ private slots: void update(); void isOpaque(); -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX void scroll(); void scrollNativeChildren(); #endif @@ -382,7 +382,7 @@ private slots: void taskQTBUG_7532_tabOrderWithFocusProxy(); void movedAndResizedAttributes(); void childAt(); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void childAt_unifiedToolBar(); void taskQTBUG_11373(); #endif @@ -418,6 +418,7 @@ private: const QString m_platform; QSize m_testWidgetSize; QPoint m_availableTopLeft; + QPoint m_safeCursorPos; const bool m_windowsAnimationsEnabled; }; @@ -575,6 +576,7 @@ void tst_QWidget::getSetCheck() tst_QWidget::tst_QWidget() : m_platform(QGuiApplication::platformName().toLower()) + , m_safeCursorPos(0, 0) , m_windowsAnimationsEnabled(windowsAnimationsEnabled()) { if (m_windowsAnimationsEnabled) // Disable animations which can interfere with screen grabbing in moveChild(), showAndMoveChild() @@ -614,7 +616,13 @@ void tst_QWidget::initTestCase() // to avoid Windows warnings about minimum size for decorated windows. int width = 200; const QScreen *screen = QGuiApplication::primaryScreen(); - m_availableTopLeft = screen->availableGeometry().topLeft(); + const QRect availableGeometry = screen->availableGeometry(); + m_availableTopLeft = availableGeometry.topLeft(); + // XCB: Determine "safe" cursor position at bottom/right corner of screen. + // Pushing the mouse rapidly to the top left corner can trigger KDE / KWin's + // "Present all Windows" (Ctrl+F9) feature also programmatically. + if (m_platform == QLatin1String("xcb")) + m_safeCursorPos = availableGeometry.bottomRight() - QPoint(40, 40); const int screenWidth = screen->geometry().width(); if (screenWidth > 2000) width = 100 * ((screenWidth + 500) / 1000); @@ -2306,12 +2314,12 @@ void tst_QWidget::showMinimizedKeepsFocus() window.showNormal(); qApp->setActiveWindow(&window); QVERIFY(QTest::qWaitForWindowActive(&window)); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (!macHasAccessToWindowsServer()) QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue); #endif QTRY_COMPARE(window.focusWidget(), firstchild); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (!macHasAccessToWindowsServer()) QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue); #endif @@ -2644,7 +2652,7 @@ public: void tst_QWidget::lostUpdatesOnHide() { -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX UpdateWidget widget; widget.setAttribute(Qt::WA_DontShowOnScreen); widget.show(); @@ -2686,7 +2694,7 @@ void tst_QWidget::raise() QVERIFY(QTest::qWaitForWindowExposed(parentPtr.data())); QTest::qWait(10); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (child1->internalWinId()) { QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events."); } @@ -2866,7 +2874,7 @@ void tst_QWidget::stackUnder() foreach (UpdateWidget *child, allChildren) { int expectedPaintEvents = child == child4 ? 1 : 0; -#if defined(Q_OS_WIN) || defined(Q_OS_MAC) +#if defined(Q_OS_WIN) || defined(Q_OS_OSX) if (expectedPaintEvents == 1 && child->numPaintEvents == 2) QEXPECT_FAIL(0, "Mac and Windows issues double repaints for Z-Order change", Continue); #endif @@ -2902,7 +2910,7 @@ void tst_QWidget::stackUnder() foreach (UpdateWidget *child, allChildren) { int expectedZOrderChangeEvents = child == child1 ? 1 : 0; if (child == child3) { -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX QEXPECT_FAIL(0, "See QTBUG-493", Continue); #endif QCOMPARE(child->numPaintEvents, 0); @@ -2959,8 +2967,23 @@ protected: QSize sizeHint() const { return QSize(500, 500); } }; +// Scale to remove devicePixelRatio should scaling be active. +static QPixmap grabFromWidget(QWidget *w, const QRect &rect) +{ + QPixmap pixmap = w->grab(rect); + const qreal devicePixelRatio = pixmap.devicePixelRatioF(); + if (!qFuzzyCompare(devicePixelRatio, qreal(1))) { + pixmap = pixmap.scaled((QSizeF(pixmap.size()) / devicePixelRatio).toSize(), + Qt::KeepAspectRatio, Qt::SmoothTransformation); + pixmap.setDevicePixelRatio(1); + } + return pixmap; +} + void tst_QWidget::testContentsPropagation() { + if (!qFuzzyCompare(qApp->devicePixelRatio(), qreal(1))) + QSKIP("This test does not work with scaling."); ContentsPropagationWidget widget; widget.setFixedSize(500, 500); widget.setContentsPropagation(false); @@ -3418,7 +3441,7 @@ void tst_QWidget::testDeletionInEventHandlers() delete w; } -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void tst_QWidget::sheetOpacity() { QWidget tmpWindow; @@ -4207,7 +4230,7 @@ void tst_QWidget::update() QCOMPARE(sibling.numPaintEvents, 1); QCOMPARE(sibling.paintedRegion, sibling.visibleRegion()); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX if (child.internalWinId()) // child is native QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue); #endif @@ -4233,7 +4256,7 @@ static inline bool isOpaque(QWidget *widget) void tst_QWidget::isOpaque() { -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX QWidget w; QVERIFY(::isOpaque(&w)); @@ -4305,7 +4328,7 @@ void tst_QWidget::isOpaque() #endif } -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX /* Test that scrolling of a widget invalidates the correct regions */ @@ -4752,7 +4775,7 @@ void tst_QWidget::windowMoveResize() widget.move(r.topLeft()); widget.resize(r.size()); QApplication::processEvents(); -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) if (r.width() == 0 && r.height() > 0) { widget.move(r.topLeft()); widget.resize(r.size()); @@ -4823,7 +4846,7 @@ void tst_QWidget::windowMoveResize() widget.move(r.topLeft()); widget.resize(r.size()); QApplication::processEvents(); -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) if (r.width() == 0 && r.height() > 0) { widget.move(r.topLeft()); widget.resize(r.size()); @@ -5009,7 +5032,7 @@ void tst_QWidget::moveChild() QTRY_COMPARE(pos, child.pos()); QCOMPARE(parent.r, QRegion(oldGeometry) - child.geometry()); -#if !defined(Q_OS_MAC) +#if !defined(Q_OS_OSX) // should be scrolled in backingstore QCOMPARE(child.r, QRegion()); #endif @@ -5564,7 +5587,7 @@ void tst_QWidget::setToolTip() QCOMPARE(spy.count(), 2); for (int pass = 0; pass < 2; ++pass) { - QCursor::setPos(0, 0); + QCursor::setPos(m_safeCursorPos); QScopedPointer<QWidget> popup(new QWidget(0, Qt::Popup)); popup->setObjectName(QLatin1String("tst_qwidget setToolTip #") + QString::number(pass)); popup->setWindowTitle(popup->objectName()); @@ -5748,7 +5771,7 @@ public: startTimer(1000); } - void timerEvent(QTimerEvent *) + void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE { switch (state++) { case 0: @@ -5771,7 +5794,7 @@ public: return false; } - bool nativeEvent(const QByteArray &eventType, void *message, long *) + bool nativeEvent(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE { if (isMapNotify(eventType, message)) gotExpectedMapNotify = true; @@ -5779,7 +5802,7 @@ public: } // QAbstractNativeEventFilter interface - virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE + bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE { if (isMapNotify(eventType, message)) gotExpectedGlobalEvent = true; @@ -5914,7 +5937,7 @@ void tst_QWidget::childEvents() // Move away the cursor; otherwise it might result in an enter event if it's // inside the widget when the widget is shown. - QCursor::setPos(qApp->desktop()->availableGeometry().bottomRight()); + QCursor::setPos(m_safeCursorPos); QTest::qWait(100); { @@ -6796,7 +6819,7 @@ void tst_QWidget::render_systemClip() // rrrrrrrrrr // ... -#ifndef Q_OS_MAC +#ifndef Q_OS_OSX for (int i = 0; i < image.height(); ++i) { for (int j = 0; j < image.width(); ++j) { if (i < 50 && j < i) @@ -7783,7 +7806,7 @@ void tst_QWidget::sendUpdateRequestImmediately() void tst_QWidget::doubleRepaint() { -#if defined(Q_OS_MAC) +#if defined(Q_OS_OSX) if (!macHasAccessToWindowsServer()) QSKIP("Not having window server access causes the wrong number of repaints to be issues"); #endif @@ -8493,7 +8516,7 @@ void tst_QWidget::setClearAndResizeMask() QTRY_COMPARE(child.mask(), childMask); QTest::qWait(50); // and ensure that the child widget doesn't get any update. -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QCOMPARE(child.numPaintEvents, 1); @@ -8516,7 +8539,7 @@ void tst_QWidget::setClearAndResizeMask() // and ensure that that the child widget gets an update for the area outside the old mask. QTRY_COMPARE(child.numPaintEvents, 1); outsideOldMask = child.rect(); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (!child.internalWinId()) #endif @@ -8531,7 +8554,7 @@ void tst_QWidget::setClearAndResizeMask() // Mask child widget with a mask that is bigger than the rect child.setMask(QRegion(0, 0, 1000, 1000)); QTest::qWait(100); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(child.numPaintEvents, 1); @@ -8544,7 +8567,7 @@ void tst_QWidget::setClearAndResizeMask() // ...and the same applies when clearing the mask. child.clearMask(); QTest::qWait(100); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_VERIFY(child.numPaintEvents > 0); @@ -8574,7 +8597,7 @@ void tst_QWidget::setClearAndResizeMask() QTimer::singleShot(100, &resizeChild, SLOT(shrinkMask())); QTest::qWait(200); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); @@ -8586,7 +8609,7 @@ void tst_QWidget::setClearAndResizeMask() const QRegion oldMask = resizeChild.mask(); QTimer::singleShot(0, &resizeChild, SLOT(enlargeMask())); QTest::qWait(100); -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX // Mac always issues a full update when calling setMask, and we cannot force it to not do so. if (child.internalWinId()) QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); @@ -8758,7 +8781,7 @@ void tst_QWidget::syntheticEnterLeave() int numLeaveEvents; }; - QCursor::setPos(QPoint(0,0)); + QCursor::setPos(m_safeCursorPos); MyWidget window; window.setWindowFlags(Qt::WindowStaysOnTopHint); @@ -8878,7 +8901,7 @@ void tst_QWidget::taskQTBUG_4055_sendSyntheticEnterLeave() int numEnterEvents, numMouseMoveEvents; }; - QCursor::setPos(QPoint(0,0)); + QCursor::setPos(m_safeCursorPos); SELParent parent; parent.move(200, 200); @@ -9097,7 +9120,7 @@ void tst_QWidget::rectOutsideCoordinatesLimit_task144779() QPixmap correct(main.size()); correct.fill(Qt::green); - const QPixmap mainPixmap = main.grab(QRect(QPoint(0, 0), QSize(-1, -1))); + const QPixmap mainPixmap = grabFromWidget(&main, QRect(QPoint(0, 0), QSize(-1, -1))); QTRY_COMPARE(mainPixmap.toImage().convertToFormat(QImage::Format_RGB32), correct.toImage().convertToFormat(QImage::Format_RGB32)); @@ -9297,7 +9320,7 @@ void tst_QWidget::taskQTBUG_7532_tabOrderWithFocusProxy() void tst_QWidget::movedAndResizedAttributes() { -#if defined (Q_OS_MAC) +#if defined (Q_OS_OSX) QEXPECT_FAIL("", "FixMe, QTBUG-8941 and QTBUG-8977", Abort); QVERIFY(false); #else @@ -9404,7 +9427,7 @@ void tst_QWidget::childAt() QCOMPARE(parent.childAt(120, 120), grandChild); } -#ifdef Q_OS_MAC +#ifdef Q_OS_OSX void tst_QWidget::childAt_unifiedToolBar() { QLabel *label = new QLabel(QLatin1String("foo")); @@ -9560,10 +9583,10 @@ void tst_QWidget::grab() p.drawTiledPixmap(0, 0, 128, 128, pal.brush(QPalette::Window).texture(), 0, 0); p.end(); - QPixmap actual = widget.grab(QRect(64, 64, 64, 64)); + QPixmap actual = grabFromWidget(&widget, QRect(64, 64, 64, 64)); QVERIFY(lenientCompare(actual, expected)); - actual = widget.grab(QRect(64, 64, -1, -1)); + actual = grabFromWidget(&widget, QRect(64, 64, -1, -1)); QVERIFY(lenientCompare(actual, expected)); // Make sure a widget that is not yet shown is grabbed correctly. @@ -10052,7 +10075,7 @@ void tst_QWidget::destroyedSignal() void tst_QWidget::underMouse() { // Move the mouse cursor to a safe location - QCursor::setPos(0,0); + QCursor::setPos(m_safeCursorPos); ColorWidget topLevelWidget(0, Qt::FramelessWindowHint, Qt::blue); ColorWidget childWidget1(&topLevelWidget, Qt::Widget, Qt::yellow); @@ -10308,7 +10331,7 @@ public: void tst_QWidget::taskQTBUG_27643_enterEvents() { // Move the mouse cursor to a safe location so it won't interfere - QCursor::setPos(0,0); + QCursor::setPos(m_safeCursorPos); EnterTestMainDialog dialog; QPushButton button(&dialog); diff --git a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp index d4b221a4a7..e68463a00e 100644 --- a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp +++ b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp @@ -77,6 +77,8 @@ private slots: #ifndef QT_NO_WHEELEVENT void wheelEvent_data(); void wheelEvent(); + void fineGrainedWheelEvent_data(); + void fineGrainedWheelEvent(); #endif void sliderPressedReleased_data(); void sliderPressedReleased(); @@ -892,6 +894,55 @@ void tst_QAbstractSlider::wheelEvent() if (expectedSignalCount) QVERIFY(actionTriggeredTimeStamp < valueChangedTimeStamp); } + +void tst_QAbstractSlider::fineGrainedWheelEvent_data() +{ + QTest::addColumn<bool>("invertedControls"); + QTest::newRow("invertedControls=false") << false; + QTest::newRow("invertedControls=true") << true; +} + +void tst_QAbstractSlider::fineGrainedWheelEvent() +{ + QFETCH(bool, invertedControls); + + QCoreApplication *applicationInstance = QCoreApplication::instance(); + QVERIFY(applicationInstance != 0); + QApplication::setWheelScrollLines(3); + + slider->setRange(0, 10); + slider->setSingleStep(1); + slider->setPageStep(10); + slider->setInvertedControls(invertedControls); + slider->setOrientation(Qt::Vertical); + slider->setSliderPosition(0); + + const int singleStepDelta = invertedControls ? (-WHEEL_DELTA / 3) : (WHEEL_DELTA / 3); + + QWheelEvent eventDown(slider->rect().bottomRight(), singleStepDelta / 2, + Qt::NoButton, Qt::NoModifier, Qt::Vertical); + QVERIFY(applicationInstance->sendEvent(slider,&eventDown)); + QCOMPARE(slider->sliderPosition(), 0); + QVERIFY(applicationInstance->sendEvent(slider,&eventDown)); + QCOMPARE(slider->sliderPosition(), 1); + + QWheelEvent eventUp(slider->rect().bottomRight(), -singleStepDelta / 2, + Qt::NoButton, Qt::NoModifier, Qt::Vertical); + QVERIFY(applicationInstance->sendEvent(slider,&eventUp)); + QCOMPARE(slider->sliderPosition(), 1); + QVERIFY(applicationInstance->sendEvent(slider,&eventUp)); + QCOMPARE(slider->sliderPosition(), 0); + QVERIFY(applicationInstance->sendEvent(slider,&eventUp)); + QCOMPARE(slider->sliderPosition(), 0); + QVERIFY(applicationInstance->sendEvent(slider,&eventUp)); + QCOMPARE(slider->sliderPosition(), 0); + + QVERIFY(applicationInstance->sendEvent(slider,&eventDown)); + QCOMPARE(slider->sliderPosition(), 0); + QVERIFY(applicationInstance->sendEvent(slider,&eventDown)); + QCOMPARE(slider->sliderPosition(), 1); +} + #endif // !QT_NO_WHEELEVENT void tst_QAbstractSlider::sliderPressedReleased_data() diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index db7edb346d..a5a94f109a 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -484,6 +484,7 @@ void tst_QMdiArea::subWindowActivated2() spy.clear(); mdiArea.show(); + mdiArea.activateWindow(); QVERIFY(QTest::qWaitForWindowActive(&mdiArea)); QTRY_COMPARE(spy.count(), 1); QVERIFY(mdiArea.currentSubWindow()); diff --git a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp index 7b49b89709..e0f69bee11 100644 --- a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp +++ b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp @@ -233,12 +233,19 @@ void tst_QImageConversion::convertGeneric_data() QTest::addColumn<QImage::Format>("outputFormat"); QImage rgb32 = generateImageRgb32(1000, 1000); QImage argb32 = generateImageArgb32(1000, 1000); + QImage i8 = argb32.convertToFormat(QImage::Format_Indexed8); QImage rgba32 = argb32.convertToFormat(QImage::Format_RGBA8888); QImage bgr30 = rgb32.convertToFormat(QImage::Format_BGR30); QImage a2rgb30 = argb32.convertToFormat(QImage::Format_A2RGB30_Premultiplied); QImage rgb666 = rgb32.convertToFormat(QImage::Format_RGB666); QImage argb4444 = argb32.convertToFormat(QImage::Format_ARGB4444_Premultiplied); + QTest::newRow("indexed8 -> rgb32") << i8 << QImage::Format_RGB32; + QTest::newRow("indexed8 -> argb32") << i8 << QImage::Format_ARGB32; + QTest::newRow("indexed8 -> argb32pm") << i8 << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("indexed8 -> rgbx8888") << i8 << QImage::Format_RGBX8888; + QTest::newRow("indexed8 -> rgb16") << i8 << QImage::Format_RGB16; + QTest::newRow("rgba8888 -> rgb32") << rgba32 << QImage::Format_RGB32; QTest::newRow("rgba8888 -> argb32") << rgba32 << QImage::Format_ARGB32; QTest::newRow("rgba8888 -> argb32pm") << rgba32 << QImage::Format_ARGB32_Premultiplied; diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 05988c2160..fd42411a1d 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -31,6 +31,7 @@ qsysinfo \ qtabletevent \ qtexteditlist \ qtbug-8933 \ +qtbug-52641 \ qtouchevent \ touch \ qwidget_zorder \ diff --git a/tests/manual/qcursor/qcursorhighdpi/main.cpp b/tests/manual/qcursor/qcursorhighdpi/main.cpp index 13c414fbbb..4a7646c39d 100644 --- a/tests/manual/qcursor/qcursorhighdpi/main.cpp +++ b/tests/manual/qcursor/qcursorhighdpi/main.cpp @@ -39,10 +39,12 @@ #include <QBitmap> #include <QCursor> +#include <QDrag> #include <QPainter> #include <QPixmap> #include <QDebug> +#include <QMimeData> #include <QStringList> #include <QTextStream> @@ -63,6 +65,14 @@ #include <algorithm> #include <iterator> +#if QT_VERSION < 0x050000 +QDebug operator<<(QDebug d, const QPixmap &p) +{ + d.nospace() << "QPixmap(" << p.size() << ')'; + return d; +} +#endif // Qt 4 + // High DPI cursor test for testing cursor sizes in multi-screen setups. // It creates one widget per screen with a grid of standard cursors, // pixmap / bitmap cursors and pixmap / bitmap cursors with device pixel ratio 2. @@ -154,6 +164,49 @@ static QCursor bitmapCursorDevicePixelRatio(int size, int dpr) } #endif // Qt 5 +// A label from which a pixmap can be dragged for testing drag with pixmaps/DPR. +class DraggableLabel : public QLabel { +public: + explicit DraggableLabel(const QPixmap &p, const QString &text, QWidget *parent = Q_NULLPTR) + : QLabel(text, parent), m_pixmap(p) + { + setToolTip(QLatin1String("Click to drag away the pixmap. Press Shift to set a circular mask.")); + } + +protected: + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +private: + const QPixmap m_pixmap; +}; + +void DraggableLabel::mousePressEvent(QMouseEvent *) +{ + QMimeData *mimeData = new QMimeData; + mimeData->setImageData(qVariantFromValue(m_pixmap)); + QDrag *drag = new QDrag(this); + QPixmap pixmap = m_pixmap; + if (QApplication::keyboardModifiers() & Qt::ShiftModifier) { + QBitmap mask(pixmap.width(), pixmap.height()); + mask.clear(); + QPainter painter(&mask); + painter.setBrush(Qt::color1); + const int hx = pixmap.width() / 2; + const int hy = pixmap.width() / 2; + painter.drawEllipse(QPoint(hx, hy), hx, hy); + pixmap.setMask(mask); + } + drag->setMimeData(mimeData); + drag->setPixmap(pixmap); + QPoint sizeP = QPoint(m_pixmap.width(), m_pixmap.height()); +#if QT_VERSION > 0x050000 + sizeP /= int(m_pixmap.devicePixelRatio()); +#endif // Qt 5 + drag->setHotSpot(sizeP / 2); + qDebug() << "Dragging:" << m_pixmap; + drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction); +} + // Vertical ruler widget with 10 px marks class VerticalRuler : public QWidget { public: @@ -205,8 +258,15 @@ static QLabel *createCursorLabel(const QCursor &cursor, const QString &additiona #endif // Qt 5 if (!additionalText.isEmpty()) labelText += ' ' + additionalText; - QLabel *result = new QLabel(labelText); - result->setFrameShape(QFrame::Box); + const QPixmap cursorPixmap = cursor.pixmap(); + QLabel *result = Q_NULLPTR; + if (cursorPixmap.size().isEmpty()) { + result = new QLabel(labelText); + result->setFrameShape(QFrame::Box); + } else { + result = new DraggableLabel(cursor.pixmap(), labelText); + result->setFrameShape(QFrame::StyledPanel); + } result->setCursor(cursor); return result; } @@ -299,7 +359,10 @@ int main(int argc, char *argv[]) QDesktopWidget *desktopWidget = app.desktop(); - for (int s = desktopWidget->screenCount() - 1; s >= 0; --s) { + const int lastScreen = arguments.contains("-p") + ? 0 // Primary screen only + : desktopWidget->screenCount() - 1; // All screens + for (int s = lastScreen; s >= 0; --s) { MainWindowPtr window(new MainWindow(desktopWidget->screen(s))); const QPoint pos = desktopWidget->screenGeometry(s).center() - QPoint(200, 100); window->move(pos); diff --git a/tests/manual/qtabletevent/device_information/tabletwidget.cpp b/tests/manual/qtabletevent/device_information/tabletwidget.cpp index a30e32b6d9..b4273bde8e 100644 --- a/tests/manual/qtabletevent/device_information/tabletwidget.cpp +++ b/tests/manual/qtabletevent/device_information/tabletwidget.cpp @@ -33,7 +33,7 @@ #include <QMetaObject> #include <QMetaEnum> -TabletWidget::TabletWidget(bool mouseToo) : mMouseToo(mouseToo) +TabletWidget::TabletWidget(bool mouseToo) : mMouseToo(mouseToo), mWheelEventCount(0) { QPalette newPalette = palette(); newPalette.setColor(QPalette::Window, Qt::white); @@ -82,6 +82,10 @@ bool TabletWidget::eventFilter(QObject *, QEvent *ev) mGPos = event->globalPos(); mTimestamp = event->timestamp(); } + break; + case QEvent::Wheel: + ++mWheelEventCount; + break; default: break; } @@ -176,6 +180,8 @@ void TabletWidget::paintEvent(QPaintEvent *) eventInfo << QString("z: %1").arg(QString::number(mZ)); eventInfo << QString("Unique Id: %1").arg(QString::number(mUnique)); + + eventInfo << QString("Total wheel events: %1").arg(QString::number(mWheelEventCount)); } QString text = eventInfo.join("\n"); diff --git a/tests/manual/qtabletevent/device_information/tabletwidget.h b/tests/manual/qtabletevent/device_information/tabletwidget.h index 4e6520e4cc..2b014a213a 100644 --- a/tests/manual/qtabletevent/device_information/tabletwidget.h +++ b/tests/manual/qtabletevent/device_information/tabletwidget.h @@ -61,6 +61,7 @@ private: qint64 mUnique; bool mMouseToo; ulong mTimestamp; + int mWheelEventCount; }; #endif // TABLETWIDGET_H diff --git a/tests/manual/qtbug-52641/main.cpp b/tests/manual/qtbug-52641/main.cpp new file mode 100644 index 0000000000..33ebd8584c --- /dev/null +++ b/tests/manual/qtbug-52641/main.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Kai Pastor +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QApplication> +#include <QFileDialog> +#include <QPainter> +#include <QPdfWriter> + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + QString filepath = QFileDialog::getSaveFileName(nullptr, "Save File", "", + "PDF files (*.pdf)"); + if (filepath.isEmpty()) + return 1; + QPdfWriter writer(filepath); + writer.setPageSize(QPageSize(QPageSize::A4)); + writer.setResolution(300); + + QPainterPath path; + path.moveTo(0,0); + path.lineTo(1000,0); + path.lineTo(1000,1000); + path.lineTo(0,800); + path.lineTo(500,100); + path.lineTo(800,900); + path.lineTo(300,600); + + QPen pen; + pen.setWidth(30); + pen.setJoinStyle(Qt::MiterJoin); + + // The black path on the first page must always be visible in the PDF viewer. + QPainter p(&writer); + pen.setMiterLimit(6.0); + p.setPen(pen); + p.drawPath(path); + + // If a miter limit below 1.0 is written to the PDF, + // broken PDF viewers may not show the red path on the second page. + writer.newPage(); + pen.setMiterLimit(0.6); + pen.setColor(Qt::red); + p.setPen(pen); + p.drawPath(path); + + p.end(); + return 0; +} diff --git a/tests/manual/qtbug-52641/qtbug-52641.pro b/tests/manual/qtbug-52641/qtbug-52641.pro new file mode 100644 index 0000000000..5a9ff6df52 --- /dev/null +++ b/tests/manual/qtbug-52641/qtbug-52641.pro @@ -0,0 +1,5 @@ +TARGET = qtbug-52641 +TEMPLATE = app +QT = core gui widgets +SOURCES = main.cpp + diff --git a/tests/manual/textrendering/glyphshaping/glyphshaping.pro b/tests/manual/textrendering/glyphshaping/glyphshaping.pro index 6500814423..f4e0b45734 100644 --- a/tests/manual/textrendering/glyphshaping/glyphshaping.pro +++ b/tests/manual/textrendering/glyphshaping/glyphshaping.pro @@ -1,6 +1,5 @@ QT += widgets SOURCES = main.cpp -OTHER_FILES = glyphshaping_data.xml glyphshaping_data.path = . glyphshaping_data.files = $$PWD/glyphshaping_data.xml DEPLOYMENT += glyphshaping_data diff --git a/tests/manual/touch/main.cpp b/tests/manual/touch/main.cpp index fb0c8559f9..66ad02f78b 100644 --- a/tests/manual/touch/main.cpp +++ b/tests/manual/touch/main.cpp @@ -256,6 +256,9 @@ QColor Point::color() const case Qt::MouseEventSynthesizedByQt: globalColor = Qt::blue; break; + case Qt::MouseEventSynthesizedByApplication: + globalColor = Qt::green; + break; case Qt::MouseEventNotSynthesized: break; } diff --git a/tests/manual/widgets/styles/main.cpp b/tests/manual/widgets/styles/main.cpp new file mode 100644 index 0000000000..add9afd5b2 --- /dev/null +++ b/tests/manual/widgets/styles/main.cpp @@ -0,0 +1,232 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QAction> +#include <QApplication> +#include <QDebug> +#include <QGridLayout> +#include <QLabel> +#include <QMainWindow> +#include <QMenu> +#include <QMenuBar> +#include <QPalette> +#include <QPixmap> +#include <QPlainTextEdit> +#include <QStyle> +#include <QTabWidget> +#include <QTextStream> +#include <QVBoxLayout> +#include <QWindow> +#include <QScreen> + +// Format enumeration value and strip off the class name +// added by QDebug: "QStyle::StandardPixmap(SP_Icon)" -> "SP_Icon". +template <typename Enum> +static inline QString formatEnumValue(Enum value) +{ + QString result; + QDebug(&result) << value; + int index = result.indexOf(QLatin1Char('(')); + if (index > 0) { // "QStyle::StandardPixmap(..)". + result.remove(0, index + 1); + index = result.lastIndexOf(QLatin1Char(')')); + if (index > 0) + result.truncate(index); + } + return result; +} + +static QString pixmapDescription(QStyle::StandardPixmap sp, const QPixmap &pixmap) +{ + QString description = formatEnumValue(sp); + QTextStream str(&description); + str << '(' << int(sp) << ") "; + if (pixmap.isNull()) { + str << "(null)"; + } else { + const qreal dpr = pixmap.devicePixelRatioF(); + str << ' ' << pixmap.width() << 'x' << pixmap.height(); + if (!qFuzzyCompare(dpr, qreal(1))) + str << " DPR=" << dpr; + } + return description; +} + +// Display pixmaps returned by QStyle::standardPixmap() in a grid. +static QWidget *createStandardPixmapPage(QWidget *parent) +{ + QWidget *result = new QWidget(parent); + QGridLayout *grid = new QGridLayout(result); + int row = 0; + int column = 0; + const int maxColumns = 6; + for (int i = 0; i <= int(QStyle::SP_LineEditClearButton); ++i) { + const QStyle::StandardPixmap sp = static_cast<QStyle::StandardPixmap>(i); + QPixmap pixmap = result->style()->standardPixmap(sp, Q_NULLPTR, result); + QLabel *descriptionLabel = new QLabel(pixmapDescription(sp, pixmap)); + grid->addWidget(descriptionLabel, row, column++); + QLabel *displayLabel = new QLabel; + displayLabel->setPixmap(pixmap); + displayLabel->setFrameShape(QFrame::Box); + grid->addWidget(displayLabel, row, column++); + if (column >= maxColumns) { + ++row; + column = 0; + } + } + return result; +} + +// Display values returned by QStyle::pixelMetric(). +static QWidget *createMetricsPage(QWidget *parent) +{ + QPlainTextEdit *result = new QPlainTextEdit(parent); + QString text; + QTextStream str(&text); + for (int i = 0; i <= int(QStyle::PM_HeaderDefaultSectionSizeVertical); ++i) { + const QStyle::PixelMetric m = static_cast<QStyle::PixelMetric>(i); + str << formatEnumValue(m) << '(' << int(m) << ")=" + << result->style()->pixelMetric(m, Q_NULLPTR, result) << '\n'; + } + result->setPlainText(text); + return result; +} + +// Display values returned by QStyle::styleHint() +static QWidget *createHintsPage(QWidget *parent) +{ + QPlainTextEdit *result = new QPlainTextEdit(parent); + QString text; + QTextStream str(&text); + for (int i = 0; i <= int(QStyle::SH_Menu_SubMenuDontStartSloppyOnLeave); ++i) { + const QStyle::StyleHint h = static_cast<QStyle::StyleHint>(i); + str << formatEnumValue(h) << '(' << int(h) << ")=" + << result->style()->styleHint(h, Q_NULLPTR, result) << '\n'; + } + result->setPlainText(text); + return result; +} + +// Display palette colors +static QWidget *createColorsPage(QWidget *parent) +{ + QWidget *result = new QWidget(parent); + QGridLayout *grid = new QGridLayout; + const QPalette palette = QGuiApplication::palette(); + int row = 0; + for (int r = 0; r < int(QPalette::NColorRoles); ++r) { + const QPalette::ColorRole role = static_cast<QPalette::ColorRole>(r); + const QColor color = palette.color(QPalette::Active, role); + if (color.isValid()) { + const QString description = + formatEnumValue(role) + QLatin1Char('(') + QString::number(r) + + QLatin1String(") ") + color.name(QColor::HexArgb); + grid->addWidget(new QLabel(description), row, 0); + QLabel *displayLabel = new QLabel; + QPixmap pixmap(20, 20); + pixmap.fill(color); + displayLabel->setPixmap(pixmap); + displayLabel->setFrameShape(QFrame::Box); + grid->addWidget(displayLabel, row, 1); + ++row; + } + } + QHBoxLayout *hBox = new QHBoxLayout; + hBox->addLayout(grid); + hBox->addStretch(); + QVBoxLayout *vBox = new QVBoxLayout(result); + vBox->addLayout(hBox); + vBox->addStretch(); + return result; +} + +class MainWindow : public QMainWindow { + Q_OBJECT +public: + MainWindow(); + +public slots: + void updateDescription(); + +private: + QTabWidget *m_tabWidget; + QLabel *m_descriptionLabel; +}; + +MainWindow::MainWindow() + : m_tabWidget(new QTabWidget) + , m_descriptionLabel(new QLabel) +{ + QMenu *fileMenu = menuBar()->addMenu("&File"); + QAction *a = fileMenu->addAction("Quit", this, &QWidget::close); + a->setShortcut(Qt::CTRL + Qt::Key_Q); + + QWidget *central = new QWidget; + QVBoxLayout *mainLayout = new QVBoxLayout(central); + mainLayout->addWidget(m_descriptionLabel); + mainLayout->addWidget(m_tabWidget); + m_tabWidget->addTab(createStandardPixmapPage(m_tabWidget), "Standard Pixmaps"); + m_tabWidget->addTab(createHintsPage(m_tabWidget), "Hints"); + m_tabWidget->addTab(createMetricsPage(m_tabWidget), "Pixel Metrics"); + m_tabWidget->addTab(createColorsPage(m_tabWidget), "Colors"); + setCentralWidget(central); + + setWindowTitle(QLatin1String("Style Tester (Qt") + QLatin1String(QT_VERSION_STR) + + QLatin1String(", ") + style()->objectName() + QLatin1Char(')')); +} + +void MainWindow::updateDescription() +{ + QString text; + QTextStream str(&text); + str << "Qt " << QT_VERSION_STR << ", platform: " << QGuiApplication::platformName() + << ", Style: \"" << style()->objectName() << "\", DPR=" << devicePixelRatioF() + << ' ' << logicalDpiX() << ',' << logicalDpiY() << "DPI"; + if (const QWindow *w = windowHandle()) + str << ", Screen: \"" << w->screen()->name() << '"'; + m_descriptionLabel->setText(text); +} + +int main(int argc, char *argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + QApplication app(argc, argv); + MainWindow mw; + mw.show(); + mw.updateDescription(); + QObject::connect(mw.windowHandle(), &QWindow::screenChanged, + &mw, &MainWindow::updateDescription); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/widgets/styles/styles.pro b/tests/manual/widgets/styles/styles.pro new file mode 100644 index 0000000000..ef8217a9a3 --- /dev/null +++ b/tests/manual/widgets/styles/styles.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +QT = widgets +CONFIG += console +CONFIG -= app_bundle +CONFIG += c++11 + +SOURCES += main.cpp diff --git a/tests/manual/widgets/widgets.pro b/tests/manual/widgets/widgets.pro index e9dcdf39e7..3a128581cf 100644 --- a/tests/manual/widgets/widgets.pro +++ b/tests/manual/widgets/widgets.pro @@ -1,3 +1,3 @@ TEMPLATE = subdirs SUBDIRS = itemviews qgraphicsview kernel - +greaterThan(QT_MAJOR_VERSION, 4): SUBDIRS += styles |