summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-08-27 09:45:52 +0200
committerLiang Qi <liang.qi@qt.io>2019-08-27 09:45:52 +0200
commit0f1f7fb97fd0dd572ad61a0ebaef68c2bba72e57 (patch)
treee1f3f1b58aa69904e6bc629e88ed68fca858f83a
parente8c70fb07f01b492b721451c00496f860eb40be0 (diff)
parent5bb178c479a247720fbc3fbb7f06a32b725193ac (diff)
Merge remote-tracking branch 'origin/dev' into 5.14
Conflicts: src/widgets/kernel/qwidget.cpp src/widgets/kernel/qwidget_p.h src/widgets/kernel/qwidgetrepaintmanager.cpp src/widgets/kernel/qwidgetwindow.cpp tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp Change-Id: Ifae457d0427be8e2465e474b055722e11b3b1e5c
-rw-r--r--config.tests/arch/write_info.pri3
-rw-r--r--examples/corelib/threads/doc/src/mandelbrot.qdoc4
-rw-r--r--examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp2
-rw-r--r--examples/widgets/graphicsview/chip/view.cpp2
-rw-r--r--examples/widgets/graphicsview/elasticnodes/graphwidget.cpp2
-rw-r--r--examples/widgets/painting/affine/xform.cpp2
-rw-r--r--examples/widgets/widgets/mousebuttons/buttontester.cpp11
-rw-r--r--mkspecs/android-clang/qmake.conf113
-rw-r--r--mkspecs/android-g++/qmake.conf35
-rw-r--r--mkspecs/android-g++/qplatformdefs.h177
-rw-r--r--mkspecs/common/android-base-head.conf72
-rw-r--r--mkspecs/common/android-base-tail.conf90
-rw-r--r--mkspecs/features/android/android.prf25
-rw-r--r--mkspecs/features/android/android_deployment_settings.prf36
-rw-r--r--mkspecs/features/android/default_pre.prf76
-rw-r--r--mkspecs/features/android/resolve_config.prf10
-rw-r--r--mkspecs/features/exclusive_builds_post.prf2
-rw-r--r--mkspecs/features/qmake_use.prf6
-rw-r--r--mkspecs/features/qt_android_deps.prf6
-rw-r--r--mkspecs/features/qt_configure.prf2
-rw-r--r--mkspecs/features/qt_functions.prf3
-rw-r--r--mkspecs/features/qt_helper_lib.prf33
-rw-r--r--mkspecs/features/qt_module.prf2
-rw-r--r--mkspecs/features/qt_module_pris.prf27
-rw-r--r--qmake/generators/makefile.cpp14
-rw-r--r--qmake/generators/makefiledeps.cpp164
-rw-r--r--qmake/generators/makefiledeps.h9
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.cpp15
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp22
-rw-r--r--src/3rdparty/forkfd/forkfd.c186
-rw-r--r--src/3rdparty/forkfd/forkfd.h5
-rw-r--r--src/3rdparty/forkfd/forkfd_atomic.h39
-rw-r--r--src/3rdparty/forkfd/forkfd_c11.h64
-rw-r--r--src/3rdparty/forkfd/forkfd_freebsd.c101
-rw-r--r--src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--src/android/jar/jar.pro1
-rw-r--r--src/android/java/java.pro2
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java77
-rw-r--r--src/android/templates/AndroidManifest.xml5
-rw-r--r--src/android/templates/build.gradle2
-rw-r--r--src/android/templates/res/values/libs.xml9
-rw-r--r--src/android/templates/templates.pro2
-rw-r--r--src/corelib/codecs/qicucodec.cpp2
-rw-r--r--src/corelib/corelib.pro1
-rw-r--r--src/corelib/io/forkfd_qt.cpp29
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp15
-rw-r--r--src/corelib/kernel/qobject.cpp22
-rw-r--r--src/corelib/kernel/qobject_p.h6
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp21
-rw-r--r--src/corelib/serialization/qcborvalue.cpp16
-rw-r--r--src/corelib/serialization/qcborvalue.h3
-rw-r--r--src/corelib/serialization/qcborvalue_p.h56
-rw-r--r--src/corelib/text/qstring.h9
-rw-r--r--src/corelib/thread/qthread_unix.cpp23
-rw-r--r--src/corelib/tools/qsize.cpp18
-rw-r--r--src/corelib/tools/qsize.h11
-rw-r--r--src/gui/doc/qtgui.qdocconf3
-rw-r--r--src/gui/doc/src/includes/qt-colors.qdocinc86
-rw-r--r--src/gui/doc/src/includes/svg-colors.qdocinc594
-rw-r--r--src/gui/image/image.pri19
-rw-r--r--src/gui/image/qimage.cpp15
-rw-r--r--src/gui/image/qimage.h1
-rw-r--r--src/gui/image/qimage_conversions.cpp222
-rw-r--r--src/gui/image/qimage_p.h1
-rw-r--r--src/gui/image/qimage_ssse3.cpp7
-rw-r--r--src/gui/image/qpixmap_win.cpp3
-rw-r--r--src/gui/image/qpnghandler.cpp2
-rw-r--r--src/gui/kernel/qevent.cpp56
-rw-r--r--src/gui/opengl/qopengltextureuploader.cpp18
-rw-r--r--src/gui/painting/painting.pri42
-rw-r--r--src/gui/painting/qbezier.cpp16
-rw-r--r--src/gui/painting/qbezier_p.h37
-rw-r--r--src/gui/painting/qcolor.cpp81
-rw-r--r--src/gui/painting/qcolor.h187
-rw-r--r--src/gui/painting/qdrawhelper.cpp28
-rw-r--r--src/gui/painting/qpainterpath.cpp21
-rw-r--r--src/gui/platform/wasm/qwasmlocalfileaccess.cpp37
-rw-r--r--src/gui/platform/wasm/qwasmlocalfileaccess_p.h2
-rw-r--r--src/gui/text/qcssparser.cpp13
-rw-r--r--src/gui/text/qcssparser_p.h2
-rw-r--r--src/gui/text/qfont.cpp8
-rw-r--r--src/gui/text/qfont_p.h10
-rw-r--r--src/gui/text/qfontmetrics.cpp8
-rw-r--r--src/gui/text/qtextdocument.cpp80
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp26
-rw-r--r--src/gui/text/qtexthtmlparser.cpp34
-rw-r--r--src/gui/text/qtexthtmlparser_p.h8
-rw-r--r--src/network/access/access.pri6
-rw-r--r--src/network/access/http2/hpack.cpp5
-rw-r--r--src/network/access/http2/hpack_p.h1
-rw-r--r--src/network/access/http2/http2frames.cpp4
-rw-r--r--src/network/access/http2/http2protocol.cpp116
-rw-r--r--src/network/access/http2/http2protocol_p.h64
-rw-r--r--src/network/access/qhttp2configuration.cpp312
-rw-r--r--src/network/access/qhttp2configuration.h100
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp45
-rw-r--r--src/network/access/qhttp2protocolhandler_p.h25
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp11
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h8
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp6
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp4
-rw-r--r--src/network/access/qhttpthreaddelegate_p.h3
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp3
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp64
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h2
-rw-r--r--src/network/access/qnetworkrequest.cpp71
-rw-r--r--src/network/access/qnetworkrequest.h5
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice.cpp2
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice_p.h1
-rw-r--r--src/plugins/bearer/android/jar/jar.pro2
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp29
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp3
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp2
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.cpp2
-rw-r--r--src/tools/androiddeployqt/main.cpp922
-rw-r--r--src/tools/androidtestrunner/main.cpp4
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp45
-rw-r--r--src/widgets/dialogs/qfiledialog.h1
-rw-r--r--src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp5
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp12
-rw-r--r--src/widgets/kernel/qapplication.cpp4
-rw-r--r--src/widgets/kernel/qshortcut.cpp2
-rw-r--r--src/widgets/kernel/qwidget.cpp30
-rw-r--r--src/widgets/kernel/qwidget_p.h4
-rw-r--r--src/widgets/widgets/qdockarealayout.cpp21
-rw-r--r--src/widgets/widgets/qdockwidget.cpp7
-rw-r--r--tests/auto/corelib/animation/qpauseanimation/BLACKLIST8
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST4
-rw-r--r--tests/auto/corelib/io/qprocess/BLACKLIST1
-rw-r--r--tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp2
-rw-r--r--tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp83
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp30
-rw-r--r--tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST3
-rw-r--r--tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST3
-rw-r--r--tests/auto/corelib/kernel/qtimer/BLACKLIST9
-rw-r--r--tests/auto/corelib/serialization/qtextstream/BLACKLIST3
-rw-r--r--tests/auto/corelib/thread/qsemaphore/BLACKLIST3
-rw-r--r--tests/auto/corelib/thread/qthread/BLACKLIST4
-rw-r--r--tests/auto/corelib/thread/qthreadpool/BLACKLIST7
-rw-r--r--tests/auto/corelib/tools/qsize/tst_qsize.cpp44
-rw-r--r--tests/auto/corelib/tools/qsizef/tst_qsizef.cpp44
-rw-r--r--tests/auto/corelib/tools/qtimeline/BLACKLIST4
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp24
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp8
-rw-r--r--tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp5
-rw-r--r--tests/auto/gui/kernel/qguitimer/BLACKLIST8
-rw-r--r--tests/auto/gui/kernel/qwindow/BLACKLIST15
-rw-r--r--tests/auto/gui/painting/qcolor/tst_qcolor.cpp189
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp1
-rw-r--r--tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp29
-rw-r--r--tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp134
-rw-r--r--tests/auto/gui/text/qtexttable/tst_qtexttable.cpp108
-rw-r--r--tests/auto/network/access/http2/http2srv.cpp10
-rw-r--r--tests/auto/network/access/http2/http2srv.h12
-rw-r--r--tests/auto/network/access/http2/tst_http2.cpp138
-rw-r--r--tests/auto/network/access/qabstractnetworkcache/BLACKLIST2
-rw-r--r--tests/auto/network/access/qftp/BLACKLIST9
-rw-r--r--tests/auto/network/access/qnetworkreply/BLACKLIST191
-rw-r--r--tests/auto/network/access/spdy/BLACKLIST3
-rw-r--r--tests/auto/network/kernel/qdnslookup/BLACKLIST12
-rw-r--r--tests/auto/network/socket/qsocks5socketengine/BLACKLIST3
-rw-r--r--tests/auto/network/socket/qtcpserver/BLACKLIST14
-rw-r--r--tests/auto/network/socket/qtcpsocket/BLACKLIST3
-rw-r--r--tests/auto/network/socket/qudpsocket/BLACKLIST6
-rw-r--r--tests/auto/network/ssl/qsslkey/BLACKLIST17
-rw-r--r--tests/auto/network/ssl/qsslsocket/BLACKLIST4
-rw-r--r--tests/auto/other/networkselftest/BLACKLIST3
-rw-r--r--tests/auto/other/qfocusevent/BLACKLIST3
-rw-r--r--tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST3
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST11
-rw-r--r--tests/auto/widgets/dialogs/qmessagebox/BLACKLIST6
-rw-r--r--tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp4
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp11
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp744
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST12
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/BLACKLIST1
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp9
-rw-r--r--tests/auto/widgets/kernel/qapplication/BLACKLIST3
-rw-r--r--tests/auto/widgets/kernel/qwidget/BLACKLIST10
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/button.pngbin1785 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/combobox.pngbin1808 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/lineedit.pngbin953 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/mdi.pngbin3092 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/menu.pngbin1139 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/radiobutton.pngbin1498 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/slider.pngbin1074 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/mac/spinbox.pngbin1299 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/button.pngbin722 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/combobox.pngbin809 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/lineedit.pngbin530 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/menu.pngbin646 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/radiobutton.pngbin844 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/slider.pngbin575 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/images/vista/spinbox.pngbin583 -> 0 bytes
-rw-r--r--tests/auto/widgets/styles/qstyle/qstyle.pro5
-rw-r--r--tests/auto/widgets/styles/qstyle/testdata.qrc19
-rw-r--r--tests/auto/widgets/styles/qstyle/tst_qstyle.cpp127
-rw-r--r--tests/auto/widgets/widgets/qframe/tst_qframe.cpp4
-rw-r--r--tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp3
-rw-r--r--tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp22
-rw-r--r--tests/benchmarks/gui/image/qimagereader/qimagereader.pro2
-rw-r--r--tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp17
203 files changed, 4675 insertions, 2855 deletions
diff --git a/config.tests/arch/write_info.pri b/config.tests/arch/write_info.pri
index 79f980c873..666b9e5cbb 100644
--- a/config.tests/arch/write_info.pri
+++ b/config.tests/arch/write_info.pri
@@ -3,9 +3,6 @@ targetinfofile ~= s/pro$/target.txt/
win32 {
ext = .exe
-} else:android {
- file_prefix = lib
- ext = .so
} else:wasm {
equals(WASM_OBJECT_FILES, 1): \
ext = .o
diff --git a/examples/corelib/threads/doc/src/mandelbrot.qdoc b/examples/corelib/threads/doc/src/mandelbrot.qdoc
index 274874632e..9e3fdc1dfe 100644
--- a/examples/corelib/threads/doc/src/mandelbrot.qdoc
+++ b/examples/corelib/threads/doc/src/mandelbrot.qdoc
@@ -304,8 +304,8 @@
\snippet threads/mandelbrot/mandelbrotwidget.cpp 12
The wheel event handler is reimplemented to make the mouse wheel
- control the zoom level. QWheelEvent::delta() returns the angle of
- the wheel mouse movement, in eights of a degree. For most mice,
+ control the zoom level. QWheelEvent::angleDelta() returns the angle
+ of the wheel mouse movement, in eighths of a degree. For most mice,
one wheel step corresponds to 15 degrees. We find out how many
mouse steps we have and determine the resulting zoom factor.
For example, if we have two wheel steps in the positive direction
diff --git a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp
index 71d0abb09f..822791533b 100644
--- a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp
+++ b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp
@@ -176,7 +176,7 @@ void MandelbrotWidget::keyPressEvent(QKeyEvent *event)
//! [12]
void MandelbrotWidget::wheelEvent(QWheelEvent *event)
{
- int numDegrees = event->delta() / 8;
+ int numDegrees = event->angleDelta().y() / 8;
double numSteps = numDegrees / 15.0f;
zoom(pow(ZoomInFactor, numSteps));
}
diff --git a/examples/widgets/graphicsview/chip/view.cpp b/examples/widgets/graphicsview/chip/view.cpp
index 9676c13ff7..7d5fd699a4 100644
--- a/examples/widgets/graphicsview/chip/view.cpp
+++ b/examples/widgets/graphicsview/chip/view.cpp
@@ -68,7 +68,7 @@
void GraphicsView::wheelEvent(QWheelEvent *e)
{
if (e->modifiers() & Qt::ControlModifier) {
- if (e->delta() > 0)
+ if (e->angleDelta().y() > 0)
view->zoomIn(6);
else
view->zoomOut(6);
diff --git a/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp b/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp
index 6b817b2a21..9341d77f8d 100644
--- a/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp
+++ b/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp
@@ -190,7 +190,7 @@ void GraphWidget::timerEvent(QTimerEvent *event)
//! [5]
void GraphWidget::wheelEvent(QWheelEvent *event)
{
- scaleView(pow((double)2, -event->delta() / 240.0));
+ scaleView(pow((double)2, -event->angleDelta().y() / 240.0));
}
//! [5]
#endif
diff --git a/examples/widgets/painting/affine/xform.cpp b/examples/widgets/painting/affine/xform.cpp
index 482e0f3268..50acf0f814 100644
--- a/examples/widgets/painting/affine/xform.cpp
+++ b/examples/widgets/painting/affine/xform.cpp
@@ -260,7 +260,7 @@ void XFormView::timerEvent(QTimerEvent *e)
#if QT_CONFIG(wheelevent)
void XFormView::wheelEvent(QWheelEvent *e)
{
- m_scale += e->delta() / qreal(600);
+ m_scale += e->angleDelta().y() / qreal(600);
m_scale = qMax(qreal(0.1), qMin(qreal(4), m_scale));
emit scaleChanged(int(m_scale*1000));
}
diff --git a/examples/widgets/widgets/mousebuttons/buttontester.cpp b/examples/widgets/widgets/mousebuttons/buttontester.cpp
index 6653221698..88dbbeda45 100644
--- a/examples/widgets/widgets/mousebuttons/buttontester.cpp
+++ b/examples/widgets/widgets/mousebuttons/buttontester.cpp
@@ -93,15 +93,16 @@ void ButtonTester::mouseDoubleClickEvent(QMouseEvent *e)
void ButtonTester::wheelEvent (QWheelEvent *e)
{
QString result;
- if (e->delta() > 0) {
-
- if (e->orientation() == Qt::Vertical) {
+ const bool vertical = qAbs(e->angleDelta().y()) >= qAbs(e->angleDelta().x());
+ const int delta = vertical ? e->angleDelta().y() : e->angleDelta().x();
+ if (delta > 0) {
+ if (vertical) {
result = "Mouse Wheel Event: UP";
} else {
result = "Mouse Wheel Event: LEFT";
}
- } else if (e->delta() < 0) {
- if (e->orientation() == Qt::Vertical) {
+ } else if (delta < 0) {
+ if (vertical) {
result = "Mouse Wheel Event: DOWN";
} else {
result = "Mouse Wheel Event: RIGHT";
diff --git a/mkspecs/android-clang/qmake.conf b/mkspecs/android-clang/qmake.conf
index 8569c08348..8252f400a1 100644
--- a/mkspecs/android-clang/qmake.conf
+++ b/mkspecs/android-clang/qmake.conf
@@ -8,43 +8,102 @@ CONFIG += android_install unversioned_soname unversioned_libname
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/clang.conf)
-include(../common/android-base-head.conf)
+
+load(device_config)
+
+# In early configure setup; nothing useful to be done here.
+isEmpty(DEFAULT_ANDROID_NDK_ROOT): return()
+
+NDK_ROOT = $$(ANDROID_NDK_ROOT)
+isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
+
+!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.")
+
+NDK_HOST = $$(ANDROID_NDK_HOST)
+isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST
+
+ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM)
+isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM
+
+ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT)
+isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT
+
+ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION)
+isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) {
+ SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*)
+ for (REVISION, SDK_BUILD_TOOLS_REVISIONS) {
+ BASENAME = $$basename(REVISION)
+ greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME
+ }
+}
+
+ALL_ANDROID_ABIS = arm64-v8a armeabi-v7a x86_64 x86
+
+CONFIG += $$ANDROID_PLATFORM
+
+QMAKE_PCH_OUTPUT_EXT = .gch
+
+QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
+QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE}
+QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
+QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
NDK_LLVM_PATH = $$NDK_ROOT/toolchains/llvm/prebuilt/$$NDK_HOST
QMAKE_CC = $$NDK_LLVM_PATH/bin/clang
QMAKE_CXX = $$NDK_LLVM_PATH/bin/clang++
+QMAKE_LINK = $$QMAKE_CXX
-equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
- QMAKE_CFLAGS += -target armv7-none-linux-androideabi
-else: equals(ANDROID_TARGET_ARCH, armeabi): \
- QMAKE_CFLAGS += -target armv5te-none-linux-androideabi
-else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \
- QMAKE_CFLAGS += -target aarch64-none-linux-android
-else: equals(ANDROID_TARGET_ARCH, x86): \
- QMAKE_CFLAGS += -target i686-none-linux-android -mstackrealign
-else: equals(ANDROID_TARGET_ARCH, x86_64): \
- QMAKE_CFLAGS += -target x86_64-none-linux-android
+QMAKE_CFLAGS_OPTIMIZE = -Oz
+QMAKE_CFLAGS_OPTIMIZE_FULL = -Oz
-QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH -fno-limit-debug-info
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
+QMAKE_CFLAGS_NEON = -mfpu=neon
-QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++
-equals(ANDROID_TARGET_ARCH, armeabi-v7a): QMAKE_LINK += -Wl,--exclude-libs,libunwind.a
+QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared
+QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
+QMAKE_LFLAGS_RPATH = -Wl,-rpath=
+QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link=
-QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \
- -isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX \
- -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include \
- -isystem $$NDK_ROOT/sources/android/support/include \
- -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include
+QMAKE_LIBS_X11 =
+QMAKE_LIBS_THREAD =
+QMAKE_LIBS_OPENGL =
+QMAKE_INCDIR_POST =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
-ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH
+ANDROID_USE_LLVM = true
-ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so
+armeabi-v7a.sdk = armeabi-v7a
+armeabi-v7a.target = armeabi-v7a
+armeabi-v7a.dir_affix = armeabi-v7a
+armeabi-v7a.CONFIG = armeabi-v7a
+armeabi-v7a.deployment_identifier = armeabi-v7a
-ANDROID_USE_LLVM = true
+arm64-v8a.sdk = arm64-v8a
+arm64-v8a.target = arm64-v8a
+arm64-v8a.dir_affix = arm64-v8a
+arm64-v8a.CONFIG = arm64-v8a
+arm64-v8a.deployment_identifier = arm64-v8a
+
+x86.sdk = x86
+x86.target = x86
+x86.dir_affix = x86
+x86.CONFIG = x86
+x86.deployment_identifier = x86
-exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \
- ANDROID_CXX_STL_LIBS = -lc++
-else: \
- ANDROID_CXX_STL_LIBS = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so.$$replace(ANDROID_PLATFORM, "android-", "")
+x86_64.sdk = x86_64
+x86_64.target = x86_64
+x86_64.dir_affix = x86_64
+x86_64.CONFIG = x86_64
+x86_64.deployment_identifier = x86_64
-include(../common/android-base-tail.conf)
+load(qt_config)
diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf
deleted file mode 100644
index 0cb3558f96..0000000000
--- a/mkspecs/android-g++/qmake.conf
+++ /dev/null
@@ -1,35 +0,0 @@
-# qmake configuration for building with android-g++
-MAKEFILE_GENERATOR = UNIX
-QMAKE_PLATFORM = android
-QMAKE_COMPILER = gcc
-
-CONFIG += android_install unversioned_soname unversioned_libname plugin_with_soname android_deployment_settings
-
-include(../common/linux.conf)
-include(../common/gcc-base-unix.conf)
-include(../common/android-base-head.conf)
-
-QMAKE_CC = $${CROSS_COMPILE}gcc
-QMAKE_CXX = $${CROSS_COMPILE}g++
-QMAKE_LINK = $$QMAKE_CXX
-
-ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/libs/$$ANDROID_TARGET_ARCH
-ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libgnustl_shared.so
-ANDROID_CXX_STL_LIBS = -lgnustl_shared -lgcc
-ANDROID_USE_LLVM = false
-
-exists($$NDK_ROOT/sysroot/usr/include): \
- QMAKE_CFLAGS += --sysroot=$$NDK_ROOT/sysroot \
- -isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX
-else: QMAKE_CFLAGS += --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
-
-QMAKE_CFLAGS += -isystem $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/include \
- -isystem $$ANDROID_SOURCES_CXX_STL_LIBDIR/include
-
-equals(ANDROID_TARGET_ARCH, armeabi)|equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
- LIBGCC_PATH_FULL = $$system("$$QMAKE_CXX -mthumb-interwork -print-libgcc-file-name")
-else: \
- LIBGCC_PATH_FULL = $$system("$$QMAKE_CXX -print-libgcc-file-name")
-ANDROID_SOURCES_CXX_STL_LIBDIR += $$dirname(LIBGCC_PATH_FULL)
-
-include(../common/android-base-tail.conf)
diff --git a/mkspecs/android-g++/qplatformdefs.h b/mkspecs/android-g++/qplatformdefs.h
deleted file mode 100644
index 0b92709dd5..0000000000
--- a/mkspecs/android-g++/qplatformdefs.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the qmake spec of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://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 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPLATFORMDEFS_H
-#define QPLATFORMDEFS_H
-
-// Get Qt defines/settings
-
-#include "qglobal.h"
-
-// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
-
-// 1) need to reset default environment if _BSD_SOURCE is defined
-// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0
-// 3) it seems older glibc need this to include the X/Open stuff
-
-#include <unistd.h>
-
-// We are hot - unistd.h should have turned on the specific APIs we requested
-
-#include <features.h>
-#include <pthread.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <pwd.h>
-#include <signal.h>
-#include <dlfcn.h>
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/ipc.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-#ifdef QT_LARGEFILE_SUPPORT
-#define QT_STATBUF struct stat64
-#define QT_STATBUF4TSTAT struct stat64
-#define QT_STAT ::stat64
-#define QT_FSTAT ::fstat64
-#define QT_LSTAT ::lstat64
-#define QT_OPEN ::open64
-#define QT_TRUNCATE ::truncate64
-#define QT_FTRUNCATE ::ftruncate64
-#define QT_LSEEK ::lseek64
-#else
-#define QT_STATBUF struct stat
-#define QT_STATBUF4TSTAT struct stat
-#define QT_STAT ::stat
-#define QT_FSTAT ::fstat
-#define QT_LSTAT ::lstat
-#define QT_OPEN ::open
-#define QT_TRUNCATE ::truncate
-#define QT_FTRUNCATE ::ftruncate
-#define QT_LSEEK ::lseek
-#endif
-
-#ifdef QT_LARGEFILE_SUPPORT
-#define QT_FOPEN ::fopen64
-#define QT_FSEEK ::fseeko64
-#define QT_FTELL ::ftello64
-#define QT_FGETPOS ::fgetpos64
-#define QT_FSETPOS ::fsetpos64
-#define QT_MMAP ::mmap64
-#define QT_FPOS_T fpos64_t
-#define QT_OFF_T off64_t
-#else
-#define QT_FOPEN ::fopen
-#define QT_FSEEK ::fseek
-#define QT_FTELL ::ftell
-#define QT_FGETPOS ::fgetpos
-#define QT_FSETPOS ::fsetpos
-#define QT_MMAP ::mmap
-#define QT_FPOS_T fpos_t
-#define QT_OFF_T long
-#endif
-
-#define QT_STAT_REG S_IFREG
-#define QT_STAT_DIR S_IFDIR
-#define QT_STAT_MASK S_IFMT
-#define QT_STAT_LNK S_IFLNK
-#define QT_SOCKET_CONNECT ::connect
-#define QT_SOCKET_BIND ::bind
-#define QT_FILENO fileno
-#define QT_CLOSE ::close
-#define QT_READ ::read
-#define QT_WRITE ::write
-#define QT_ACCESS ::access
-#define QT_GETCWD ::getcwd
-#define QT_CHDIR ::chdir
-#define QT_MKDIR ::mkdir
-#define QT_RMDIR ::rmdir
-#define QT_OPEN_LARGEFILE O_LARGEFILE
-#define QT_OPEN_RDONLY O_RDONLY
-#define QT_OPEN_WRONLY O_WRONLY
-#define QT_OPEN_RDWR O_RDWR
-#define QT_OPEN_CREAT O_CREAT
-#define QT_OPEN_TRUNC O_TRUNC
-#define QT_OPEN_APPEND O_APPEND
-#define QT_OPEN_EXCL O_EXCL
-
-// Directory iteration
-#define QT_DIR DIR
-
-#define QT_OPENDIR ::opendir
-#define QT_CLOSEDIR ::closedir
-
-#if defined(QT_LARGEFILE_SUPPORT) \
- && defined(QT_USE_XOPEN_LFS_EXTENSIONS) \
- && !defined(QT_NO_READDIR64)
-#define QT_DIRENT struct dirent64
-#define QT_READDIR ::readdir64
-#define QT_READDIR_R ::readdir64_r
-#else
-#define QT_DIRENT struct dirent
-#define QT_READDIR ::readdir
-#define QT_READDIR_R ::readdir_r
-#endif
-
-#define QT_SOCKET_CONNECT ::connect
-#define QT_SOCKET_BIND ::bind
-
-
-#define QT_SIGNAL_RETTYPE void
-#define QT_SIGNAL_ARGS int
-#define QT_SIGNAL_IGNORE SIG_IGN
-
-#define QT_SOCKLEN_T socklen_t
-
-#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
-#endif
-
-#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/common/android-base-head.conf b/mkspecs/common/android-base-head.conf
deleted file mode 100644
index ba90ad5f17..0000000000
--- a/mkspecs/common/android-base-head.conf
+++ /dev/null
@@ -1,72 +0,0 @@
-load(device_config)
-
-# In early configure setup; nothing useful to be done here.
-isEmpty(DEFAULT_ANDROID_NDK_ROOT): return()
-
-NDK_ROOT = $$(ANDROID_NDK_ROOT)
-isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
-
-NDK_HOST = $$(ANDROID_NDK_HOST)
-isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST
-
-ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM)
-isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM
-
-ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH)
-isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH
-
-NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX)
-isEmpty(NDK_TOOLCHAIN_PREFIX) {
- equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86
- else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64
- else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android
- else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi
-}
-
-NDK_TOOLS_PREFIX = $$(ANDROID_NDK_TOOLS_PREFIX)
-isEmpty(NDK_TOOLS_PREFIX) {
- equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLS_PREFIX = i686-linux-android
- else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLS_PREFIX = x86_64-linux-android
- else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLS_PREFIX = aarch64-linux-android
- else: NDK_TOOLS_PREFIX = arm-linux-androideabi
-}
-
-NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION)
-isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION
-
-equals(ANDROID_TARGET_ARCH, x86): ANDROID_ARCHITECTURE = x86
-else: equals(ANDROID_TARGET_ARCH, x86_64): ANDROID_ARCHITECTURE = x86_64
-else: equals(ANDROID_TARGET_ARCH, arm64-v8a): ANDROID_ARCHITECTURE = arm64
-else: ANDROID_ARCHITECTURE = arm
-
-!equals(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION
-
-NDK_TOOLCHAIN = $$NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION
-NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST
-
-
-ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT)
-isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT
-
-ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION)
-isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) {
- SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*)
- for (REVISION, SDK_BUILD_TOOLS_REVISIONS) {
- BASENAME = $$basename(REVISION)
- greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME
- }
-}
-
-CONFIG += $$ANDROID_PLATFORM
-QMAKE_CFLAGS = -D__ANDROID_API__=$$replace(ANDROID_PLATFORM, "android-", "")
-
-ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/
-
-CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-
-
-QMAKE_PCH_OUTPUT_EXT = .gch
-
-QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
-QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE}
-QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
-QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
diff --git a/mkspecs/common/android-base-tail.conf b/mkspecs/common/android-base-tail.conf
deleted file mode 100644
index edc255d08e..0000000000
--- a/mkspecs/common/android-base-tail.conf
+++ /dev/null
@@ -1,90 +0,0 @@
-# In early configure setup; nothing useful to be done here.
-isEmpty(DEFAULT_ANDROID_NDK_ROOT): return()
-
-# -fstack-protector-strong offers good protection against stack smashing attacks.
-# It is (currently) enabled only on Android because we know for sure that Andoroid compilers supports it
-QMAKE_CFLAGS += -fstack-protector-strong -DANDROID
-
-equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
- QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove
-else: equals(ANDROID_TARGET_ARCH, armeabi): \
- QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float -fno-builtin-memmove
-# -fno-builtin-memmove is used to workaround https://code.google.com/p/android/issues/detail?id=81692
-
-QMAKE_CFLAGS_WARN_ON = -Wall -W
-QMAKE_CFLAGS_WARN_OFF =
-equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) {
- CONFIG += optimize_size
- QMAKE_CFLAGS_DEBUG = -g -marm -O0
- equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) {
- DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND
- } else {
- QMAKE_CFLAGS_RELEASE += -mthumb
- QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb
- }
-}
-
-QMAKE_CFLAGS_SHLIB = -fPIC
-QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
-QMAKE_CFLAGS_THREAD = -D_REENTRANT
-QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
-QMAKE_CFLAGS_NEON = -mfpu=neon
-
-QMAKE_CFLAGS_GNUC99 = -std=gnu99
-QMAKE_CFLAGS_GNUC11 = -std=gnu11
-QMAKE_CXXFLAGS_CXX11 = -std=c++11
-QMAKE_CXXFLAGS_CXX14 = -std=c++14
-QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
-QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11
-QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++14
-QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z
-
-QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
-QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
-QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
-QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE
-QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
-QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG
-QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
-QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
-QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
-QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
-
-# modifications to linux.conf
-QMAKE_AR = $${CROSS_COMPILE}ar cqs
-QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
-QMAKE_NM = $${CROSS_COMPILE}nm -P
-
-QMAKE_STRIP =
-#$${CROSS_COMPILE}strip
-
-QMAKE_RANLIB = $${CROSS_COMPILE}ranlib
-
-QMAKE_INCDIR_POST =
-QMAKE_LIBDIR_POST = $$ANDROID_SOURCES_CXX_STL_LIBDIR
-QMAKE_INCDIR_X11 =
-QMAKE_LIBDIR_X11 =
-QMAKE_INCDIR_OPENGL =
-QMAKE_LIBDIR_OPENGL =
-
-QMAKE_LINK_SHLIB = $$QMAKE_LINK
-QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
-equals(ANDROID_TARGET_ARCH, x86_64) QMAKE_LFLAGS += -L$$ANDROID_PLATFORM_ROOT_PATH/usr/lib64
-QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared
-QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
-QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
-QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
-QMAKE_LFLAGS_RPATH = -Wl,-rpath=
-QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link=
-
-QMAKE_LIBS_PRIVATE = $$ANDROID_CXX_STL_LIBS -llog -lz -lm -ldl -lc
-QMAKE_LIBS_X11 =
-QMAKE_LIBS_THREAD =
-QMAKE_LIBS_EGL = -lEGL
-QMAKE_LIBS_OPENGL =
-QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
-
-
-!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.")
-
-load(qt_config)
diff --git a/mkspecs/features/android/android.prf b/mkspecs/features/android/android.prf
index 0e6f4a4592..a12c17c4ed 100644
--- a/mkspecs/features/android/android.prf
+++ b/mkspecs/features/android/android.prf
@@ -16,17 +16,22 @@ APK_PATH = $$shell_path($$OUT_PWD/android-build/$${TARGET}.apk)
}
QMAKE_EXTRA_TARGETS *= apk apk_install_target
-contains(TEMPLATE, ".*app") {
- !android_app {
- !contains(TARGET, ".so"): TARGET = lib$${TARGET}.so
- QMAKE_LFLAGS += -Wl,-soname,$$shell_quote($$TARGET)
+build_pass {
+ contains(TEMPLATE, ".*app") {
+ !android_app {
+ !contains(TARGET, ".so") {
+ single_arch:TARGET = lib$${TARGET}.so
+ else:TARGET = lib$${TARGET}_$${QT_ARCH}.so
+ }
+ QMAKE_LFLAGS += -Wl,-soname,$$shell_quote($$TARGET)
- android_install {
- target.path=/libs/$$ANDROID_TARGET_ARCH/
- INSTALLS *= target
+ android_install {
+ target.path=/libs/$$ANDROID_TARGET_ARCH/
+ INSTALLS *= target
+ }
}
+ } else: contains(TEMPLATE, "lib"):!static:!QTDIR_build:android_install {
+ target.path = /libs/$$ANDROID_TARGET_ARCH/
+ INSTALLS *= target
}
-} else: contains(TEMPLATE, "lib"):!static:!QTDIR_build:android_install {
- target.path = /libs/$$ANDROID_TARGET_ARCH/
- INSTALLS *= target
}
diff --git a/mkspecs/features/android/android_deployment_settings.prf b/mkspecs/features/android/android_deployment_settings.prf
index 48943fa0f4..998a985bb5 100644
--- a/mkspecs/features/android/android_deployment_settings.prf
+++ b/mkspecs/features/android/android_deployment_settings.prf
@@ -17,32 +17,21 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-embedded {
isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
FILE_CONTENT += " \"ndk\": $$emitString($$NDK_ROOT),"
- equals(ANDROID_USE_LLVM, true) {
- FILE_CONTENT += " \"toolchain-prefix\": \"llvm\","
- FILE_CONTENT += " \"tool-prefix\": \"llvm\","
- } else {
- NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX)
- isEmpty(NDK_TOOLCHAIN_PREFIX) {
- equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86
- else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64
- else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android
- else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi
- }
- FILE_CONTENT += " \"toolchain-prefix\": $$emitString($$NDK_TOOLCHAIN_PREFIX),"
- FILE_CONTENT += " \"tool-prefix\": $$emitString($$NDK_TOOLS_PREFIX),"
- }
-
- NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION)
- isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION
- FILE_CONTENT += " \"toolchain-version\": $$emitString($$NDK_TOOLCHAIN_VERSION),"
+ FILE_CONTENT += " \"toolchain-prefix\": \"llvm\","
+ FILE_CONTENT += " \"tool-prefix\": \"llvm\","
NDK_HOST = $$(ANDROID_NDK_HOST)
isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST
FILE_CONTENT += " \"ndk-host\": $$emitString($$NDK_HOST),"
- ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH)
- isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH
- FILE_CONTENT += " \"target-architecture\": $$emitString($$ANDROID_TARGET_ARCH),"
+ for (arch, ANDROID_ABIS) {
+ equals(arch, x86): libs_arch = i686-linux-android
+ else: equals(arch, x86_64): libs_arch = x86_64-linux-android
+ else: equals(arch, arm64-v8a): libs_arch = aarch64-linux-android
+ else: libs_arch = arm-linux-androideabi
+ ARCHS += "$$emitString($$arch):$$emitString($$libs_arch)"
+ }
+ FILE_CONTENT += " \"architectures\": {$$join(ARCHS,", ")},"
# Explicitly set qt dependencies of application for deployment
!isEmpty(ANDROID_DEPLOYMENT_DEPENDENCIES): \
@@ -74,9 +63,8 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-embedded {
QML_ROOT_PATH = $$_PRO_FILE_PWD_
FILE_CONTENT += " \"qml-root-path\": $$emitString($$QML_ROOT_PATH),"
FILE_CONTENT += " \"stdcpp-path\": $$emitString($$ANDROID_STDCPP_PATH),"
- FILE_CONTENT += " \"useLLVM\": $$ANDROID_USE_LLVM,"
-
- FILE_CONTENT += " \"application-binary\": $$emitString($$absolute_path($$DESTDIR, $$OUT_PWD)/$$TARGET)"
+ FILE_CONTENT += ""
+ FILE_CONTENT += " \"application-binary\": $$emitString($$TARGET)"
FILE_CONTENT += "}"
isEmpty(ANDROID_DEPLOYMENT_SETTINGS_FILE): ANDROID_DEPLOYMENT_SETTINGS_FILE = $$OUT_PWD/android-$$TARGET-deployment-settings.json
diff --git a/mkspecs/features/android/default_pre.prf b/mkspecs/features/android/default_pre.prf
new file mode 100644
index 0000000000..d4f84a8fcc
--- /dev/null
+++ b/mkspecs/features/android/default_pre.prf
@@ -0,0 +1,76 @@
+load(default_pre)
+
+build_pass:armeabi-v7a {
+ QT_ARCH = armeabi-v7a
+} else:build_pass:arm64-v8a {
+ QT_ARCH = arm64-v8a
+} else:build_pass:x86 {
+ QT_ARCH = x86
+} else:build_pass:x86_64 {
+ QT_ARCH = x86_64
+} else {
+ # default architecture
+ QT_ARCH = arm64-v8a
+}
+
+DEFAULT_ANDROID_TARGET_ARCH=$${QT_ARCH}
+
+ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH)
+isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH
+
+# Follow https://android.googlesource.com/platform/ndk/+/ndk-release-r20/docs/BuildSystemMaintainers.md
+
+equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
+ QMAKE_CFLAGS = -target armv7a-linux-androideabi$$replace(ANDROID_PLATFORM, "android-", "")
+else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \
+ QMAKE_CFLAGS = -target aarch64-linux-android$$replace(ANDROID_PLATFORM, "android-", "")
+else: equals(ANDROID_TARGET_ARCH, x86): \
+ QMAKE_CFLAGS = -target i686-linux-android$$replace(ANDROID_PLATFORM, "android-", "") -mstackrealign
+else: equals(ANDROID_TARGET_ARCH, x86_64): \
+ QMAKE_CFLAGS = -target x86_64-linux-android$$replace(ANDROID_PLATFORM, "android-", "")
+
+QMAKE_CFLAGS += -fno-limit-debug-info
+
+QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS
+
+ANDROID_STDCPP_PATH = $$NDK_LLVM_PATH/sysroot/usr/lib/
+
+# -fstack-protector-strong offers good protection against stack smashing attacks.
+# It is (currently) enabled only on Android because we know for sure that Android compilers supports it
+QMAKE_CFLAGS += -fPIC -fstack-protector-strong -DANDROID
+
+
+equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) {
+ CONFIG += optimize_size
+ QMAKE_CFLAGS_DEBUG = -g -marm -O0
+ QMAKE_CFLAGS_RELEASE += -mthumb
+ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb
+}
+
+QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
+
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_LIBS_EGL = -lEGL
+QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
+
+# modifications to linux.conf
+QMAKE_AR = $${CROSS_COMPILE}ar cqs
+QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
+QMAKE_NM = $${CROSS_COMPILE}nm -P
+
+QMAKE_STRIP =
+#$${CROSS_COMPILE}strip
+
+QMAKE_RANLIB = $${CROSS_COMPILE}ranlib
+QMAKE_LINK_SHLIB = $$QMAKE_LINK
+QMAKE_LFLAGS =
+
+QMAKE_LIBS_PRIVATE = -llog -lz -lm -ldl -lc
diff --git a/mkspecs/features/android/resolve_config.prf b/mkspecs/features/android/resolve_config.prf
new file mode 100644
index 0000000000..c542017e31
--- /dev/null
+++ b/mkspecs/features/android/resolve_config.prf
@@ -0,0 +1,10 @@
+load(resolve_config)
+
+!host_build:!single_arch:!java:android {
+ isEmpty(ANDROID_ABIS): ANDROID_ABIS = $$ALL_ANDROID_ABIS
+
+ ALL_ABIS = $$join(ANDROID_ABIS, _and_)
+ CONFIG += $$ALL_ABIS build_all
+ addExclusiveBuildsProper($$ALL_ABIS, $$ANDROID_ABIS)
+ unset(ALL_ABIS)
+}
diff --git a/mkspecs/features/exclusive_builds_post.prf b/mkspecs/features/exclusive_builds_post.prf
index 936085af0b..a9c341a2d7 100644
--- a/mkspecs/features/exclusive_builds_post.prf
+++ b/mkspecs/features/exclusive_builds_post.prf
@@ -1,4 +1,6 @@
+load(qt_functions)
+
contains(TEMPLATE, subdirs) {
for(build, QMAKE_EXCLUSIVE_BUILDS) {
prepareRecursiveTarget($$build)
diff --git a/mkspecs/features/qmake_use.prf b/mkspecs/features/qmake_use.prf
index 64faa4f215..ecb4f7ed41 100644
--- a/mkspecs/features/qmake_use.prf
+++ b/mkspecs/features/qmake_use.prf
@@ -22,7 +22,11 @@ for(ever) {
!defined(QMAKE_LIBS_$$nu, var): \
error("Library '$$lower($$replace(nu, _, -))' is not defined.")
- debug: \
+ android {
+ ABI_LIBS = $$eval(QMAKE_LIBS_$${nu}_$${QT_ARCH})
+ isEmpty(ABI_LIBS): ABI_LIBS = $$eval(QMAKE_LIBS_$${nu})
+ LIBS$${suffix} += $$ABI_LIBS
+ } else: debug: \
LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu)
else: \
LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_RELEASE) $$eval(QMAKE_LIBS_$$nu)
diff --git a/mkspecs/features/qt_android_deps.prf b/mkspecs/features/qt_android_deps.prf
index c172ca8c4e..e50c24b966 100644
--- a/mkspecs/features/qt_android_deps.prf
+++ b/mkspecs/features/qt_android_deps.prf
@@ -16,7 +16,7 @@
ANDROID_DEPENDS_DIR = $$MODULE_BASE_OUTDIR/lib/
DEPENDENCY_FILE = $$ANDROID_DEPENDS_DIR$$TARGET-android-dependencies.xml
-!build_pass {
+build_pass:!isEmpty(QT_ARCH): {
!isEmpty(MODULE_PLUGIN_TYPES) {
for(PLUGIN_TYPE, MODULE_PLUGIN_TYPES) {
ANDROID_BUNDLED_FILES += "plugins/$$PLUGIN_TYPE"
@@ -46,6 +46,8 @@ DEPENDENCY_FILE = $$ANDROID_DEPENDS_DIR$$TARGET-android-dependencies.xml
EXTENDS = $$section(LIB_FILE, ":", 1, 1)
!isEmpty(EXTENDS): EXTENDS = "extends=\"$$EXTENDS\""
LIB_FILE = $$section(LIB_FILE, ":", 0, 0)
+ LIB_FILE = $$replace(LIB_FILE,".so", "_$${QT_ARCH}.so")
+ !isEmpty(EXTENDS): EXTENDS = $$replace(EXTENDS,".so", "_$${QT_ARCH}.so")
FILE_CONTENT += "<lib file=\"$$LIB_FILE\" $$EXTENDS />"
}
}
@@ -54,12 +56,14 @@ DEPENDENCY_FILE = $$ANDROID_DEPENDS_DIR$$TARGET-android-dependencies.xml
for(REPLACEMENT, ANDROID_LIB_DEPENDENCY_REPLACEMENTS) {
REPLACEMENT_FILE = $$section(REPLACEMENT, ":", 0, 0)
LIB_FILE = $$section(REPLACEMENT, ":", 1, 1)
+ REPLACEMENT_FILE = $$replace(REPLACEMENT_FILE,".so", "_$${QT_ARCH}.so")
FILE_CONTENT += "<lib file=\"$$LIB_FILE\" replaces=\"$$REPLACEMENT_FILE\" />"
}
}
!isEmpty(ANDROID_BUNDLED_FILES) {
for (BUNDLED_FILE, ANDROID_BUNDLED_FILES) {
+ BUNDLED_FILE = $$replace(BUNDLED_FILE,".so", "_$${QT_ARCH}.so")
FILE_CONTENT += "<bundled file=\"$$BUNDLED_FILE\" />"
}
}
diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf
index 2b86caebd0..1219fe1443 100644
--- a/mkspecs/features/qt_configure.prf
+++ b/mkspecs/features/qt_configure.prf
@@ -560,7 +560,7 @@ defineTest(qtConfResolveLibs) {
} else {
paths += $$lp
}
- } else: contains(l, "^-l.*") {
+ } else: !android: contains(l, "^-l.*") {
lib = $$replace(l, "^-l", )
lcan =
integrity:contains(lib, "^.*\\.a") {
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 1903e509c8..ede494eec1 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -1,7 +1,8 @@
defineReplace(qtPlatformTargetSuffix) {
suffix =
- CONFIG(debug, debug|release) {
+ android: return($${suffix}_$${QT_ARCH})
+ else: CONFIG(debug, debug|release) {
!debug_and_release|build_pass {
mac: return($${suffix}_debug)
win32: return($${suffix}d)
diff --git a/mkspecs/features/qt_helper_lib.prf b/mkspecs/features/qt_helper_lib.prf
index 2cb54fc547..216c24c7aa 100644
--- a/mkspecs/features/qt_helper_lib.prf
+++ b/mkspecs/features/qt_helper_lib.prf
@@ -29,19 +29,19 @@ DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin
THE_TARGET = $$qt5LibraryTarget($$TARGET)
-!build_pass {
- MODULE = $$replace(TARGET, ^qt, )
- MODULE ~= s,-,_,
- MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_ext_$${MODULE}.pri
- ucmodule = $$upper($$MODULE)
+MODULE = $$replace(TARGET, ^qt, )
+MODULE ~= s,-,_,
+MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_ext_$${MODULE}.pri
+ucmodule = $$upper($$MODULE)
+win32|CONFIG(static, static|shared) {
+ prefix = $$QMAKE_PREFIX_STATICLIB
+ suffix = $$QMAKE_EXTENSION_STATICLIB
+} else {
+ prefix = $$QMAKE_PREFIX_SHLIB
+ suffix = $$QMAKE_EXTENSION_SHLIB
+}
- win32|CONFIG(static, static|shared) {
- prefix = $$QMAKE_PREFIX_STATICLIB
- suffix = $$QMAKE_EXTENSION_STATICLIB
- } else {
- prefix = $$QMAKE_PREFIX_SHLIB
- suffix = $$QMAKE_EXTENSION_SHLIB
- }
+!build_pass {
CC_USES =
LD_USES =
for (use, QMAKE_USE) {
@@ -58,7 +58,9 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET)
"QMAKE_DEPENDS_$${ucmodule}_LD =$$join(LD_USES, " ", " ")" \
"QMAKE_INCDIR_$${ucmodule} = $$val_escape(MODULE_INCLUDEPATH)" \
"QMAKE_DEFINES_$${ucmodule} = $$val_escape(MODULE_DEFINES)"
- debug_and_release {
+ android {
+ MODULE_PRI_CONT += "QMAKE_LIBS_$${ucmodule} ="
+ } else: debug_and_release {
win32: \
MODULE_DEBUG_LIBS = $$DESTDIR/$$prefix$${TARGET}d.$$suffix
else: darwin: \
@@ -76,6 +78,11 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET)
"QMAKE_LIBS_$${ucmodule} = $$val_escape(MODULE_LIBS)"
}
write_file($$MODULE_PRI, MODULE_PRI_CONT)|error()
+} else: android {
+ ABI_TARGET = $$qt5LibraryTarget($$TARGET)
+ ABI_MODULE_LIBS = $$DESTDIR/$$prefix$${ABI_TARGET}.$$suffix
+ MODULE_PRI_CONT = "QMAKE_LIBS_$${ucmodule}_$${QT_ARCH} = $$val_escape(ABI_MODULE_LIBS)"
+ write_file($$MODULE_PRI, MODULE_PRI_CONT, append)|error()
}
TARGET = $$THE_TARGET
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
index 169d91c746..828a9621b9 100644
--- a/mkspecs/features/qt_module.prf
+++ b/mkspecs/features/qt_module.prf
@@ -93,7 +93,7 @@ header_module {
DESTDIR = $$MODULE_BASE_OUTDIR/lib
DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin
-CONFIG += qmake_cache target_qt
+CONFIG += target_qt
QMAKE_DOCS_TARGETDIR = qt$${MODULE}
diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf
index e892f83432..719caf3d4a 100644
--- a/mkspecs/features/qt_module_pris.prf
+++ b/mkspecs/features/qt_module_pris.prf
@@ -51,13 +51,12 @@ defineReplace(qtGetExportsForModule) {
return($$result)
}
-defineReplace(qtExportLibsForModule) {
+defineReplace(qtExportDepsForModule) {
result =
for (lib, QT.$${1}.libraries) {
NAME = $$upper($$lib)
vars = \
QMAKE_DEPENDS_$${NAME}_CC QMAKE_DEPENDS_$${NAME}_LD \
- QMAKE_LIBS_$$NAME QMAKE_LIBS_$${NAME}_DEBUG QMAKE_LIBS_$${NAME}_RELEASE \
QMAKE_DEFINES_$$NAME QMAKE_INCDIR_$$NAME
for (var, vars) {
expvar = $$var
@@ -71,6 +70,24 @@ defineReplace(qtExportLibsForModule) {
return($$result)
}
+defineReplace(qtExportLibsForModule) {
+ result =
+ for (lib, QT.$${1}.libraries) {
+ NAME = $$upper($$lib)
+ vars = \
+ QMAKE_LIBS_$$NAME QMAKE_LIBS_$${NAME}_DEBUG QMAKE_LIBS_$${NAME}_RELEASE
+ for (var, vars) {
+ expvar = $$var
+ expvar ~= s/^QMAKE_/QMAKE_EXPORT_/
+ defined($$expvar, var):equals($$expvar, -): next()
+ !defined($$expvar, var): expvar = $$var
+ defined($$expvar, var): \
+ result += "$$var$${2} = $$val_escape($$expvar)"
+ }
+ }
+ return($$result)
+}
+
!build_pass {
# Create a module .pri file
@@ -160,6 +177,7 @@ defineReplace(qtExportLibsForModule) {
"QT.$${MODULE}_private.module_config =$$join(module_build_type, " ", " ")" \
$$qtGetFeaturesForModule($${MODULE}_private) \
"" \
+ $$qtExportDepsForModule($${MODULE}_private) \
$$qtExportLibsForModule($${MODULE}_private)
write_file($$MODULE_PRIVATE_PRI, MODULE_PRIVATE_PRI_CONT)|error()
}
@@ -220,7 +238,10 @@ defineReplace(qtExportLibsForModule) {
}
cache(QT_MODULES, transient)
-} # !build_pass
+} else:android:!no_private_module:!internal_module {
+ MODULE_PRIVATE_PRI_CONT = $$qtExportLibsForModule($${MODULE}_private, _$${QT_ARCH})
+ write_file($$MODULE_PRIVATE_PRI, MODULE_PRIVATE_PRI_CONT, append)|error()
+}
# Schedule the regular .pri file for installation
CONFIG += qt_install_module
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index ec73ccfe54..94e9259c68 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -771,20 +771,6 @@ MakefileGenerator::init()
QMakeSourceFileInfo::setDependencyPaths(deplist);
debug_msg(1, "Dependency Directories: %s",
incDirs.join(QString(" :: ")).toLatin1().constData());
- //cache info
- if(project->isActiveConfig("qmake_cache")) {
- QString cache_file;
- if(!project->isEmpty("QMAKE_INTERNAL_CACHE_FILE")) {
- cache_file = QDir::fromNativeSeparators(project->first("QMAKE_INTERNAL_CACHE_FILE").toQString());
- } else {
- cache_file = ".qmake.internal.cache";
- if(project->isActiveConfig("build_pass"))
- cache_file += ".BUILD." + project->first("BUILD_PASS");
- }
- if(cache_file.indexOf('/') == -1)
- cache_file.prepend(Option::output_dir + '/');
- QMakeSourceFileInfo::setCacheFile(cache_file);
- }
//add to dependency engine
for(x = 0; x < compilers.count(); ++x) {
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp
index 10fcc1493c..d68539814e 100644
--- a/qmake/generators/makefiledeps.cpp
+++ b/qmake/generators/makefiledeps.cpp
@@ -60,8 +60,6 @@ QT_BEGIN_NAMESPACE
inline bool qmake_endOfLine(const char &c) { return (c == '\r' || c == '\n'); }
#endif
-//#define QMAKE_USE_CACHE
-
QMakeLocalFileName::QMakeLocalFileName(const QString &name) : is_null(name.isNull())
{
if(!name.isEmpty()) {
@@ -265,19 +263,10 @@ QMakeSourceFileInfo::QMakeSourceFileInfo(const QString &cf)
//buffer
spare_buffer = nullptr;
spare_buffer_size = 0;
-
- //cache
- cachefile = cf;
- if(!cachefile.isEmpty())
- loadCache(cachefile);
}
QMakeSourceFileInfo::~QMakeSourceFileInfo()
{
- //cache
- if(!cachefile.isEmpty() /*&& files_changed*/)
- saveCache(cachefile);
-
//buffer
if(spare_buffer) {
free(spare_buffer);
@@ -290,12 +279,6 @@ QMakeSourceFileInfo::~QMakeSourceFileInfo()
delete includes;
}
-void QMakeSourceFileInfo::setCacheFile(const QString &cf)
-{
- cachefile = cf;
- loadCache(cachefile);
-}
-
void QMakeSourceFileInfo::addSourceFiles(const ProStringList &l, uchar seek,
QMakeSourceFileInfo::SourceFileType type)
{
@@ -1054,151 +1037,4 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file)
return true;
}
-
-void QMakeSourceFileInfo::saveCache(const QString &cf)
-{
-#ifdef QMAKE_USE_CACHE
- if(cf.isEmpty())
- return;
-
- QFile file(QMakeLocalFileName(cf).local());
- if(file.open(QIODevice::WriteOnly)) {
- QTextStream stream(&file);
- stream << QMAKE_VERSION_STR << endl << endl; //version
- { //cache verification
- QMap<QString, QStringList> verify = getCacheVerification();
- stream << verify.count() << endl;
- for(QMap<QString, QStringList>::iterator it = verify.begin();
- it != verify.end(); ++it) {
- stream << it.key() << endl << it.value().join(';') << endl;
- }
- stream << endl;
- }
- if(files->nodes) {
- for(int file = 0; file < files->num_nodes; ++file) {
- for(SourceFiles::SourceFileNode *node = files->nodes[file]; node; node = node->next) {
- stream << node->file->file.local() << endl; //source
- stream << node->file->type << endl; //type
-
- //depends
- stream << ";";
- if(node->file->deps) {
- for(int depend = 0; depend < node->file->deps->used_nodes; ++depend) {
- if(depend)
- stream << ";";
- stream << node->file->deps->children[depend]->file.local();
- }
- }
- stream << endl;
-
- stream << node->file->mocable << endl; //mocable
- stream << endl; //just for human readability
- }
- }
- }
- stream.flush();
- file.close();
- }
-#else
- Q_UNUSED(cf);
-#endif
-}
-
-void QMakeSourceFileInfo::loadCache(const QString &cf)
-{
- if(cf.isEmpty())
- return;
-
-#ifdef QMAKE_USE_CACHE
- QMakeLocalFileName cache_file(cf);
- int fd = open(QMakeLocalFileName(cf).local().toLatin1(), O_RDONLY);
- if(fd == -1)
- return;
- QFileInfo cache_fi = findFileInfo(cache_file);
- if(!cache_fi.exists() || cache_fi.isDir())
- return;
-
- QFile file;
- if (!file.open(fd, QIODevice::ReadOnly))
- return;
- QTextStream stream(&file);
-
- if (stream.readLine() == QMAKE_VERSION_STR) { //version check
- stream.skipWhiteSpace();
-
- bool verified = true;
- { //cache verification
- QMap<QString, QStringList> verify;
- int len = stream.readLine().toInt();
- for(int i = 0; i < len; ++i) {
- QString var = stream.readLine();
- QString val = stream.readLine();
- verify.insert(var, val.split(';', QString::SkipEmptyParts));
- }
- verified = verifyCache(verify);
- }
- if(verified) {
- stream.skipWhiteSpace();
- if(!files)
- files = new SourceFiles;
- while(!stream.atEnd()) {
- QString source = stream.readLine();
- QString type = stream.readLine();
- QString depends = stream.readLine();
- QString mocable = stream.readLine();
- stream.skipWhiteSpace();
-
- QMakeLocalFileName fn(source);
- QFileInfo fi = findFileInfo(fn);
-
- SourceFile *file = files->lookupFile(fn);
- if(!file) {
- file = new SourceFile;
- file->file = fn;
- files->addFile(file);
- file->type = (SourceFileType)type.toInt();
- file->exists = fi.exists();
- }
- if(fi.exists() && fi.lastModified() < cache_fi.lastModified()) {
- if(!file->dep_checked) { //get depends
- if(!file->deps)
- file->deps = new SourceDependChildren;
- file->dep_checked = true;
- QStringList depend_list = depends.split(";", QString::SkipEmptyParts);
- for(int depend = 0; depend < depend_list.size(); ++depend) {
- QMakeLocalFileName dep_fn(depend_list.at(depend));
- QFileInfo dep_fi(findFileInfo(dep_fn));
- SourceFile *dep = files->lookupFile(dep_fn);
- if(!dep) {
- dep = new SourceFile;
- dep->file = dep_fn;
- dep->exists = dep_fi.exists();
- dep->type = QMakeSourceFileInfo::TYPE_UNKNOWN;
- files->addFile(dep);
- }
- dep->included_count++;
- file->deps->addChild(dep);
- }
- }
- if(!file->moc_checked) { //get mocs
- file->moc_checked = true;
- file->mocable = mocable.toInt();
- }
- }
- }
- }
- }
-#endif
-}
-
-QMap<QString, QStringList> QMakeSourceFileInfo::getCacheVerification()
-{
- return QMap<QString, QStringList>();
-}
-
-bool QMakeSourceFileInfo::verifyCache(const QMap<QString, QStringList> &v)
-{
- return v == getCacheVerification();
-}
-
QT_END_NAMESPACE
diff --git a/qmake/generators/makefiledeps.h b/qmake/generators/makefiledeps.h
index b91a3e0a0f..66b87bf470 100644
--- a/qmake/generators/makefiledeps.h
+++ b/qmake/generators/makefiledeps.h
@@ -79,9 +79,6 @@ private:
bool findDeps(SourceFile *);
void dependTreeWalker(SourceFile *, SourceDependChildren *);
- //cache
- QString cachefile;
-
protected:
virtual QMakeLocalFileName fixPathForFile(const QMakeLocalFileName &, bool forOpen=false);
virtual QMakeLocalFileName findFileForDep(const QMakeLocalFileName &, const QMakeLocalFileName &);
@@ -114,12 +111,6 @@ public:
bool mocable(const QString &file);
- virtual QMap<QString, QStringList> getCacheVerification();
- virtual bool verifyCache(const QMap<QString, QStringList> &);
- void setCacheFile(const QString &cachefile); //auto caching
- void loadCache(const QString &cf);
- void saveCache(const QString &cf);
-
private:
DependencyMode dep_mode;
};
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp
index 3116238aa0..0515c7404f 100644
--- a/qmake/generators/win32/msbuild_objectmodel.cpp
+++ b/qmake/generators/win32/msbuild_objectmodel.cpp
@@ -300,14 +300,17 @@ inline XmlOutput::xml_output valueTagT( const triState v)
return valueTag(v == _True ? "true" : "false");
}
-static QString vcxCommandSeparator()
+static QString commandLinesForOutput(QStringList commands)
{
// MSBuild puts the contents of the custom commands into a batch file and calls it.
// As we want every sub-command to be error-checked (as is done by makefile-based
// backends), we insert the checks ourselves, using the undocumented jump target.
- static QString cmdSep =
- QLatin1String("&#x000D;&#x000A;if errorlevel 1 goto VCEnd&#x000D;&#x000A;");
- return cmdSep;
+ static QString errchk = QStringLiteral("if errorlevel 1 goto VCEnd");
+ for (int i = commands.count() - 2; i >= 0; --i) {
+ if (!commands.at(i).startsWith("rem", Qt::CaseInsensitive))
+ commands.insert(i + 1, errchk);
+ }
+ return commands.join('\n');
}
static QString unquote(const QString &value)
@@ -1658,7 +1661,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCCustomBuildTool &tool)
{
xml << tag("Command")
<< attrTag("Condition", condition)
- << valueTag(tool.CommandLine.join(vcxCommandSeparator()));
+ << valueTag(commandLinesForOutput(tool.CommandLine));
}
if ( !tool.Description.isEmpty() )
@@ -1712,7 +1715,7 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCEventTool &tool)
{
xml
<< tag(tool.EventName)
- << tag(_Command) << valueTag(tool.CommandLine.join(vcxCommandSeparator()))
+ << tag(_Command) << valueTag(commandLinesForOutput(tool.CommandLine))
<< tag(_Message) << valueTag(tool.Description)
<< closetag(tool.EventName);
}
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index b6f7f20564..b74448ce94 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -209,7 +209,9 @@ bool VcprojGenerator::writeProjectMakefile()
struct VcsolutionDepend {
QString uuid;
- QString vcprojFile, orig_target, target;
+ QString vcprojFile;
+ QString projectName;
+ QString target;
Target targetType;
QStringList dependencies;
};
@@ -433,7 +435,8 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt
Option::qmake_mode = old_mode;
// We assume project filename is [QMAKE_PROJECT_NAME].vcproj
- QString vcproj = tmp_vcproj.project->first("QMAKE_PROJECT_NAME") + project->first("VCPROJ_EXTENSION");
+ const ProString projectName = tmp_vcproj.project->first("QMAKE_PROJECT_NAME");
+ const QString vcproj = projectName + project->first("VCPROJ_EXTENSION");
QString vcprojDir = Option::output_dir;
// If file doesn't exsist, then maybe the users configuration
@@ -445,14 +448,14 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt
VcsolutionDepend *newDep = new VcsolutionDepend;
newDep->vcprojFile = vcprojDir + Option::dir_sep + vcproj;
- newDep->orig_target = tmp_proj.first("QMAKE_ORIG_TARGET").toQString();
+ newDep->projectName = projectName.toQString();
newDep->target = tmp_proj.first("MSVCPROJ_TARGET").toQString().section(Option::dir_sep, -1);
newDep->targetType = tmp_vcproj.projectTarget;
newDep->uuid = tmp_proj.isEmpty("QMAKE_UUID") ? getProjectUUID(Option::fixPathToLocalOS(vcprojDir + QDir::separator() + vcproj)).toString().toUpper(): tmp_proj.first("QMAKE_UUID").toQString();
// We want to store it as the .lib name.
if (newDep->target.endsWith(".dll"))
newDep->target = newDep->target.left(newDep->target.length()-3) + "lib";
- projGuids.insert(newDep->orig_target, newDep->target);
+ projGuids.insert(newDep->projectName, newDep->target);
if (tmpList.size()) {
const ProStringList depends = tmpList;
@@ -591,7 +594,7 @@ void VcprojGenerator::writeSubDirs(QTextStream &t)
for (QList<VcsolutionDepend*>::Iterator it = solution_cleanup.begin(); it != solution_cleanup.end(); ++it) {
// ### quoting rules?
t << _slnProjectBeg << _slnMSVCvcprojGUID << _slnProjectMid
- << "\"" << (*it)->orig_target << "\", \"" << (*it)->vcprojFile
+ << "\"" << (*it)->projectName << "\", \"" << (*it)->vcprojFile
<< "\", \"" << (*it)->uuid << "\"";
debug_msg(1, "Project %s has dependencies: %s", (*it)->target.toLatin1().constData(), (*it)->dependencies.join(" ").toLatin1().constData());
@@ -937,6 +940,15 @@ void VcprojGenerator::initProject()
vcProject.SccProjectName = project->first("SCCPROJECTNAME").toQString();
vcProject.SccLocalPath = project->first("SCCLOCALPATH").toQString();
vcProject.flat_files = project->isActiveConfig("flat");
+
+ // Set up the full target path for target conflict checking.
+ const QChar slash = QLatin1Char('/');
+ QString destdir = QDir::fromNativeSeparators(var("DESTDIR"));
+ if (!destdir.endsWith(slash))
+ destdir.append(slash);
+ project->values("DEST_TARGET") = ProStringList(destdir
+ + project->first("TARGET")
+ + project->first("TARGET_EXT"));
}
void VcprojGenerator::initConfiguration()
diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c
index 12537b6199..e4f3bd85de 100644
--- a/src/3rdparty/forkfd/forkfd.c
+++ b/src/3rdparty/forkfd/forkfd.c
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -59,9 +59,6 @@
# define HAVE_PIPE2 1
# endif
#endif
-#if defined(__FreeBSD__) && __FreeBSD__ >= 9
-# include <sys/procdesc.h>
-#endif
#if _POSIX_VERSION-0 >= 200809L || _XOPEN_VERSION-0 >= 500
# define HAVE_WAITID 1
@@ -93,9 +90,11 @@
# endif
#endif
-#ifndef FFD_ATOMIC_RELAXED
-# include "forkfd_gcc.h"
-#endif
+#include "forkfd_atomic.h"
+
+static int system_has_forkfd(void);
+static int system_forkfd(int flags, pid_t *ppid, int *system);
+static int system_forkfd_wait(int ffd, struct forkfd_info *info, struct rusage *rusage);
#define CHILDREN_IN_SMALL_ARRAY 16
#define CHILDREN_IN_BIG_ARRAY 256
@@ -448,6 +447,37 @@ static void ignore_sigpipe()
#endif
}
+#if defined(__GNUC__) && (!defined(__FreeBSD__) || __FreeBSD__ < 10)
+__attribute((destructor, unused)) static void cleanup();
+#endif
+
+static void cleanup()
+{
+ BigArray *array;
+ /* This function is not thread-safe!
+ * It must only be called when the process is shutting down.
+ * At shutdown, we expect no one to be calling forkfd(), so we don't
+ * need to be thread-safe with what is done there.
+ *
+ * But SIGCHLD might be delivered to any thread, including this one.
+ * There's no way to prevent that. The correct solution would be to
+ * cooperatively delete. We don't do that.
+ */
+ if (ffd_atomic_load(&forkfd_status, FFD_ATOMIC_RELAXED) == 0)
+ return;
+
+ /* notify the handler that we're no longer in operation */
+ ffd_atomic_store(&forkfd_status, 0, FFD_ATOMIC_RELAXED);
+
+ /* free any arrays we might have */
+ array = ffd_atomic_load(&children.header.nextArray, FFD_ATOMIC_ACQUIRE);
+ while (array != NULL) {
+ BigArray *next = ffd_atomic_load(&array->header.nextArray, FFD_ATOMIC_ACQUIRE);
+ free(array);
+ array = next;
+ }
+}
+
static void forkfd_initialize()
{
#if defined(HAVE_BROKEN_WAITID)
@@ -489,44 +519,15 @@ static void forkfd_initialize()
ignore_sigpipe();
#endif
-#ifndef __GNUC__
+#ifdef __GNUC__
+ (void) cleanup; /* suppress unused static function warning */
+#else
atexit(cleanup);
#endif
ffd_atomic_store(&forkfd_status, 1, FFD_ATOMIC_RELAXED);
}
-#ifdef __GNUC__
-__attribute((destructor, unused)) static void cleanup();
-#endif
-
-static void cleanup()
-{
- BigArray *array;
- /* This function is not thread-safe!
- * It must only be called when the process is shutting down.
- * At shutdown, we expect no one to be calling forkfd(), so we don't
- * need to be thread-safe with what is done there.
- *
- * But SIGCHLD might be delivered to any thread, including this one.
- * There's no way to prevent that. The correct solution would be to
- * cooperatively delete. We don't do that.
- */
- if (ffd_atomic_load(&forkfd_status, FFD_ATOMIC_RELAXED) == 0)
- return;
-
- /* notify the handler that we're no longer in operation */
- ffd_atomic_store(&forkfd_status, 0, FFD_ATOMIC_RELAXED);
-
- /* free any arrays we might have */
- array = ffd_atomic_load(&children.header.nextArray, FFD_ATOMIC_ACQUIRE);
- while (array != NULL) {
- BigArray *next = ffd_atomic_load(&array->header.nextArray, FFD_ATOMIC_ACQUIRE);
- free(array);
- array = next;
- }
-}
-
static int create_pipe(int filedes[], int flags)
{
int ret = -1;
@@ -565,55 +566,6 @@ static int create_pipe(int filedes[], int flags)
return ret;
}
-#if defined(FORKFD_NO_SPAWNFD) && defined(__FreeBSD__) && __FreeBSD__ >= 9
-# if __FreeBSD__ == 9
-/* PROCDESC is an optional feature in the kernel and wasn't enabled
- * by default on FreeBSD 9. So we need to check for it at runtime. */
-static ffd_atomic_int system_has_forkfd = FFD_ATOMIC_INIT(1);
-# else
-/* On FreeBSD 10, PROCDESC was enabled by default. On v11, it's not an option
- * anymore and can't be disabled. */
-static const int system_has_forkfd = 1;
-# endif
-
-static int system_forkfd(int flags, pid_t *ppid)
-{
- int ret;
- pid_t pid;
- pid = pdfork(&ret, PD_DAEMON);
- if (__builtin_expect(pid == -1, 0)) {
-# if __FreeBSD__ == 9
- if (errno == ENOSYS) {
- /* PROCDESC wasn't compiled into the kernel: don't try it again. */
- ffd_atomic_store(&system_has_forkfd, 0, FFD_ATOMIC_RELAXED);
- }
-# endif
- return -1;
- }
- if (pid == 0) {
- /* child process */
- return FFD_CHILD_PROCESS;
- }
-
- /* parent process */
- if (flags & FFD_CLOEXEC)
- fcntl(ret, F_SETFD, FD_CLOEXEC);
- if (flags & FFD_NONBLOCK)
- fcntl(ret, F_SETFL, fcntl(ret, F_GETFL) | O_NONBLOCK);
- if (ppid)
- *ppid = pid;
- return ret;
-}
-#else
-static const int system_has_forkfd = 0;
-static int system_forkfd(int flags, pid_t *ppid)
-{
- (void)flags;
- (void)ppid;
- return -1;
-}
-#endif
-
#ifndef FORKFD_NO_FORKFD
/**
* @brief forkfd returns a file descriptor representing a child process
@@ -661,11 +613,9 @@ int forkfd(int flags, pid_t *ppid)
int efd;
#endif
- if (system_has_forkfd) {
- ret = system_forkfd(flags, ppid);
- if (system_has_forkfd)
- return ret;
- }
+ fd = system_forkfd(flags, ppid, &ret);
+ if (ret)
+ return fd;
(void) pthread_once(&forkfd_initialization, forkfd_initialize);
@@ -790,7 +740,7 @@ int spawnfd(int flags, pid_t *ppid, const char *path, const posix_spawn_file_act
/* we can only do work if we have a way to start the child in stopped mode;
* otherwise, we have a major race condition. */
- assert(!system_has_forkfd);
+ assert(!system_has_forkfd());
(void) pthread_once(&forkfd_initialization, forkfd_initialize);
@@ -843,30 +793,13 @@ out:
#endif // _POSIX_SPAWN && !FORKFD_NO_SPAWNFD
-int forkfd_wait(int ffd, forkfd_info *info, struct rusage *rusage)
+int forkfd_wait(int ffd, struct forkfd_info *info, struct rusage *rusage)
{
struct pipe_payload payload;
int ret;
- if (system_has_forkfd) {
-#if defined(__FreeBSD__) && __FreeBSD__ >= 9
- pid_t pid;
- int status;
- int options = WEXITED;
-
- ret = pdgetpid(ffd, &pid);
- if (ret == -1)
- return ret;
- ret = fcntl(ffd, F_GETFL);
- if (ret == -1)
- return ret;
- options |= (ret & O_NONBLOCK) ? WNOHANG : 0;
- ret = wait4(pid, &status, options, rusage);
- if (ret != -1 && info)
- convertStatusToForkfdInfo(status, info);
- return ret == -1 ? -1 : 0;
-#endif
- }
+ if (system_has_forkfd())
+ return system_forkfd_wait(ffd, info, rusage);
ret = read(ffd, &payload, sizeof(payload));
if (ret == -1)
@@ -886,3 +819,28 @@ int forkfd_close(int ffd)
{
return close(ffd);
}
+
+#if defined(__FreeBSD__) && __FreeBSD__ >= 9
+# include "forkfd_freebsd.c"
+#else
+int system_has_forkfd()
+{
+ return 0;
+}
+
+int system_forkfd(int flags, pid_t *ppid, int *system)
+{
+ (void)flags;
+ (void)ppid;
+ *system = 0;
+ return -1;
+}
+
+int system_forkfd_wait(int ffd, struct forkfd_info *info, struct rusage *rusage)
+{
+ (void)ffd;
+ (void)info;
+ (void)rusage;
+ return -1;
+}
+#endif
diff --git a/src/3rdparty/forkfd/forkfd.h b/src/3rdparty/forkfd/forkfd.h
index 958321c299..eb121de593 100644
--- a/src/3rdparty/forkfd/forkfd.h
+++ b/src/3rdparty/forkfd/forkfd.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
@@ -27,6 +27,7 @@
#include <fcntl.h>
#include <stdint.h>
+#include <sys/wait.h>
#include <unistd.h> // to get the POSIX flags
#if _POSIX_SPAWN > 0
@@ -48,7 +49,7 @@ struct forkfd_info {
};
int forkfd(int flags, pid_t *ppid);
-int forkfd_wait(int ffd, forkfd_info *info, struct rusage *rusage);
+int forkfd_wait(int ffd, struct forkfd_info *info, struct rusage *rusage);
int forkfd_close(int ffd);
#if _POSIX_SPAWN > 0
diff --git a/src/3rdparty/forkfd/forkfd_atomic.h b/src/3rdparty/forkfd/forkfd_atomic.h
new file mode 100644
index 0000000000..394e30d26c
--- /dev/null
+++ b/src/3rdparty/forkfd/forkfd_atomic.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Intel Corporation.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#if !defined(FFD_ATOMIC_H) & !defined(FFD_ATOMIC_RELAXED)
+#define FFD_ATOMIC_H
+
+#if defined(__cplusplus) && __cplusplus >= 201103L
+# include "forkfd_c11.h"
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+# include "forkfd_c11.h"
+#elif defined(__GNUC__)
+# include "forkfd_gcc.h"
+#endif
+
+#endif /* FFD_ATOMIC_h && FFD_ATOMIC_RELAXED */
+#ifndef FFD_ATOMIC_RELAXED
+# error "Could not determine atomics for this platform"
+#endif
diff --git a/src/3rdparty/forkfd/forkfd_c11.h b/src/3rdparty/forkfd/forkfd_c11.h
new file mode 100644
index 0000000000..f3dc2b5357
--- /dev/null
+++ b/src/3rdparty/forkfd/forkfd_c11.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Intel Corporation.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#ifndef FFD_ATOMIC_C11_H
+#define FFD_ATOMIC_C11_H
+
+/* atomics */
+/* Using the C11 <stdatomic.h> header or C++11's <atomic>
+ */
+
+#if defined(__cplusplus)
+# include <atomic>
+# define ffd_atomic_pointer(type) std::atomic<type*>
+# define FFD_ATOMIC_RELAXED std::memory_order_relaxed
+# define FFD_ATOMIC_ACQUIRE std::memory_order_acquire
+# define FFD_ATOMIC_RELEASE std::memory_order_release
+// acq_rel & cst not necessary
+typedef std::atomic_int ffd_atomic_int;
+#else
+# include <stdatomic.h>
+# define ffd_atomic_pointer(type) _Atomic(type*)
+# define FFD_ATOMIC_RELAXED memory_order_relaxed
+# define FFD_ATOMIC_ACQUIRE memory_order_acquire
+# define FFD_ATOMIC_RELEASE memory_order_release
+// acq_rel & cst not necessary
+
+typedef atomic_int ffd_atomic_int;
+#endif
+
+#define FFD_ATOMIC_INIT(val) ATOMIC_VAR_INIT(val)
+
+#define ffd_atomic_load(ptr, order) \
+ atomic_load_explicit(ptr, order)
+#define ffd_atomic_store(ptr, val, order) \
+ atomic_store_explicit(ptr, val, order)
+#define ffd_atomic_exchange(ptr,val,order) \
+ atomic_exchange_explicit(ptr, val, order)
+#define ffd_atomic_compare_exchange(ptr, expected, desired, order1, order2) \
+ atomic_compare_exchange_strong_explicit(ptr, expected, desired, order1, order2)
+#define ffd_atomic_add_fetch(ptr, val, order) \
+ (atomic_fetch_add_explicit(ptr, val, order) + (val))
+
+#endif
diff --git a/src/3rdparty/forkfd/forkfd_freebsd.c b/src/3rdparty/forkfd/forkfd_freebsd.c
new file mode 100644
index 0000000000..77ce3fcfad
--- /dev/null
+++ b/src/3rdparty/forkfd/forkfd_freebsd.c
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Intel Corporation.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and associated documentation files (the "Software"), to deal
+** in the Software without restriction, including without limitation the rights
+** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+** copies of the Software, and to permit persons to whom the Software is
+** furnished to do so, subject to the following conditions:
+**
+** The above copyright notice and this permission notice shall be included in
+** all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+** THE SOFTWARE.
+**
+****************************************************************************/
+
+#include "forkfd.h"
+
+#include <sys/types.h>
+#include <sys/procdesc.h>
+
+#include "forkfd_atomic.h"
+
+#if __FreeBSD__ >= 10
+/* On FreeBSD 10, PROCDESC was enabled by default. On v11, it's not an option
+ * anymore and can't be disabled. */
+static ffd_atomic_int system_forkfd_state = FFD_ATOMIC_INIT(1);
+#else
+static ffd_atomic_int system_forkfd_state = FFD_ATOMIC_INIT(0);
+#endif
+
+int system_has_forkfd()
+{
+ return ffd_atomic_load(&system_forkfd_state, FFD_ATOMIC_RELAXED) > 0;
+}
+
+int system_forkfd(int flags, pid_t *ppid, int *system)
+{
+ int ret;
+ pid_t pid;
+
+ int state = ffd_atomic_load(&system_forkfd_state, FFD_ATOMIC_RELAXED);
+ *system = 0;
+ if (state < 0)
+ return -1;
+
+ pid = pdfork(&ret, PD_DAEMON);
+# if __FreeBSD__ == 9
+ if (state == 0 && pid != 0) {
+ /* Parent process: remember whether PROCDESC was compiled into the kernel */
+ state = (pid == -1 && errno == ENOSYS) ? -1 : 1;
+ ffd_atomic_store(&system_forkfd_state, state, FFD_ATOMIC_RELAXED);
+ }
+ if (state < 0)
+ return -1;
+# endif
+ *system = 1;
+ if (__builtin_expect(pid == -1, 0))
+ return -1;
+
+ if (pid == 0) {
+ /* child process */
+ return FFD_CHILD_PROCESS;
+ }
+
+ /* parent process */
+ if (flags & FFD_CLOEXEC)
+ fcntl(ret, F_SETFD, FD_CLOEXEC);
+ if (flags & FFD_NONBLOCK)
+ fcntl(ret, F_SETFL, fcntl(ret, F_GETFL) | O_NONBLOCK);
+ if (ppid)
+ *ppid = pid;
+ return ret;
+}
+
+int system_forkfd_wait(int ffd, struct forkfd_info *info, struct rusage *rusage)
+{
+ pid_t pid;
+ int status;
+ int options = WEXITED;
+
+ int ret = pdgetpid(ffd, &pid);
+ if (ret == -1)
+ return ret;
+ ret = fcntl(ffd, F_GETFL);
+ if (ret == -1)
+ return ret;
+ options |= (ret & O_NONBLOCK) ? WNOHANG : 0;
+ ret = wait4(pid, &status, options, rusage);
+ if (ret != -1 && info)
+ convertStatusToForkfdInfo(status, info);
+ return ret == -1 ? -1 : 0;
+}
diff --git a/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties b/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties
index bf3de21830..4b7e1f3d38 100644
--- a/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties
+++ b/src/3rdparty/gradle/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/src/android/jar/jar.pro b/src/android/jar/jar.pro
index ac6fc79968..24a83d56a1 100644
--- a/src/android/jar/jar.pro
+++ b/src/android/jar/jar.pro
@@ -1,6 +1,7 @@
TARGET = QtAndroid
CONFIG += java
+
DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar
PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/
diff --git a/src/android/java/java.pro b/src/android/java/java.pro
index 9d37eb1026..7f0dfa8a1b 100644
--- a/src/android/java/java.pro
+++ b/src/android/java/java.pro
@@ -1,3 +1,5 @@
+CONFIG += single_arch
+
CONFIG -= qt android_install
javaresources.files = \
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
index d3b0600b2f..45941e8ed8 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2016, BogDan Vatra <bogdan@kde.org>
+ Copyright (c) 2019, BogDan Vatra <bogdan@kde.org>
Contact: http://www.qt.io/licensing/
Commercial License Usage
@@ -63,9 +63,12 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
import dalvik.system.DexClassLoader;
@@ -85,7 +88,6 @@ public abstract class QtLoader {
public static final String ENVIRONMENT_VARIABLES_KEY = "environment.variables";
public static final String APPLICATION_PARAMETERS_KEY = "application.parameters";
public static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries";
- public static final String QT_LIBS_RESOURCE_ID_KEY = "android.app.qt_libs_resource_id";
public static final String BUNDLED_IN_LIB_RESOURCE_ID_KEY = "android.app.bundled_in_lib_resource_id";
public static final String BUNDLED_IN_ASSETS_RESOURCE_ID_KEY = "android.app.bundled_in_assets_resource_id";
public static final String MAIN_LIBRARY_KEY = "main.library";
@@ -153,7 +155,7 @@ public abstract class QtLoader {
// this repository is used to push a new release, and should be used to test your application.
// * unstable - unstable repository, DO NOT use this repository in production,
// this repository is used to push Qt snapshots.
- public String[] m_qtLibs = null; // required qt libs
+ public ArrayList<String> m_qtLibs = null; // required qt libs
public int m_displayDensity = -1;
private ContextWrapper m_context;
protected ComponentInfo m_contextInfo;
@@ -191,6 +193,36 @@ public abstract class QtLoader {
}
// Implement in subclass
+ private final List<String> supportedAbis = Arrays.asList(Build.SUPPORTED_ABIS);
+ private String preferredAbi = null;
+
+ private ArrayList<String> prefferedAbiLibs(String []libs)
+ {
+ HashMap<String, ArrayList<String>> abisLibs = new HashMap<>();
+ for (String lib : libs) {
+ String[] archLib = lib.split(";", 2);
+ if (preferredAbi != null && !archLib[0].equals(preferredAbi))
+ continue;
+ if (!abisLibs.containsKey(archLib[0]))
+ abisLibs.put(archLib[0], new ArrayList<String>());
+ abisLibs.get(archLib[0]).add(archLib[1]);
+ }
+
+ if (preferredAbi != null) {
+ if (abisLibs.containsKey(preferredAbi)) {
+ return abisLibs.get(preferredAbi);
+ }
+ return new ArrayList<String>();
+ }
+
+ for (String abi: supportedAbis) {
+ if (abisLibs.containsKey(abi)) {
+ preferredAbi = abi;
+ return abisLibs.get(abi);
+ }
+ }
+ return new ArrayList<String>();
+ }
// this function is used to load and start the loader
private void loadApplication(Bundle loaderParams)
@@ -218,12 +250,14 @@ public abstract class QtLoader {
// add all bundled Qt libs to loader params
ArrayList<String> libs = new ArrayList<String>();
- if (m_contextInfo.metaData.containsKey("android.app.bundled_libs_resource_id"))
- libs.addAll(Arrays.asList(m_context.getResources().getStringArray(m_contextInfo.metaData.getInt("android.app.bundled_libs_resource_id"))));
+ if (m_contextInfo.metaData.containsKey("android.app.bundled_libs_resource_id")) {
+ int resourceId = m_contextInfo.metaData.getInt("android.app.bundled_libs_resource_id");
+ libs.addAll(prefferedAbiLibs(m_context.getResources().getStringArray(resourceId)));
+ }
String libName = null;
if (m_contextInfo.metaData.containsKey("android.app.lib_name")) {
- libName = m_contextInfo.metaData.getString("android.app.lib_name");
+ libName = m_contextInfo.metaData.getString("android.app.lib_name") + "_" + preferredAbi;
loaderParams.putString(MAIN_LIBRARY_KEY, libName); //main library contains main() function
}
@@ -278,7 +312,7 @@ public abstract class QtLoader {
try {
if (m_service != null) {
Bundle parameters = new Bundle();
- parameters.putStringArray(REQUIRED_MODULES_KEY, m_qtLibs);
+ parameters.putStringArray(REQUIRED_MODULES_KEY, (String[]) m_qtLibs.toArray());
parameters.putString(APPLICATION_TITLE_KEY, getTitle());
parameters.putInt(MINIMUM_MINISTRO_API_KEY, MINISTRO_API_LEVEL);
parameters.putInt(MINIMUM_QT_VERSION_KEY, QT_VERSION);
@@ -464,7 +498,8 @@ public abstract class QtLoader {
// why can't we load the plugins directly from libs ?!?!
String key = BUNDLED_IN_LIB_RESOURCE_ID_KEY;
if (m_contextInfo.metaData.containsKey(key)) {
- String[] list = m_context.getResources().getStringArray(m_contextInfo.metaData.getInt(key));
+ int resourceId = m_contextInfo.metaData.getInt(key);
+ ArrayList<String> list = prefferedAbiLibs(m_context.getResources().getStringArray(resourceId));
for (String bundledImportBinary : list) {
String[] split = bundledImportBinary.split(":");
@@ -603,7 +638,7 @@ public abstract class QtLoader {
if (m_contextInfo.metaData.containsKey("android.app.qt_libs_resource_id")) {
int resourceId = m_contextInfo.metaData.getInt("android.app.qt_libs_resource_id");
- m_qtLibs = m_context.getResources().getStringArray(resourceId);
+ m_qtLibs = prefferedAbiLibs(m_context.getResources().getStringArray(resourceId));
}
if (m_contextInfo.metaData.containsKey("android.app.use_local_qt_libs")
@@ -617,6 +652,7 @@ public abstract class QtLoader {
apkDeployFromSystem = true;
String libsDir = null;
+ String bundledLibsDir = null;
if (apkDeployFromSystem) {
String systemLibsPrefix = SYSTEM_LIB_PATH;
if (m_contextInfo.metaData.containsKey("android.app.system_libs_prefix")) {
@@ -633,8 +669,11 @@ public abstract class QtLoader {
} else {
String nativeLibraryPrefix = m_context.getApplicationInfo().nativeLibraryDir + "/";
File nativeLibraryDir = new File(nativeLibraryPrefix);
- if (nativeLibraryDir.exists() && nativeLibraryDir.isDirectory() && nativeLibraryDir.list().length > 0)
+ if (nativeLibraryDir.exists() && nativeLibraryDir.isDirectory() && nativeLibraryDir.list().length > 0) {
libsDir = nativeLibraryPrefix;
+ bundledLibsDir = nativeLibraryPrefix;
+ }
+
}
if (apkDeployFromSystem && libsDir == null)
@@ -643,8 +682,8 @@ public abstract class QtLoader {
if (m_qtLibs != null) {
String libPrefix = libsDir + "lib";
- for (int i = 0; i < m_qtLibs.length; i++)
- libraryList.add(libPrefix + m_qtLibs[i] + ".so");
+ for (String lib : m_qtLibs)
+ libraryList.add(libPrefix + lib + ".so");
}
if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs")
@@ -654,22 +693,26 @@ public abstract class QtLoader {
String pluginsPrefix = dataPath + "qt-reserved-files/";
if (libsDir == null)
- throw new Exception("");
+ throw new Exception("Invalid libsDir");
cleanOldCacheIfNecessary(dataPath, pluginsPrefix);
extractBundledPluginsAndImports(pluginsPrefix, libsDir);
if (m_contextInfo.metaData.containsKey(BUNDLED_IN_LIB_RESOURCE_ID_KEY)) {
- String[] extraLibs = m_contextInfo.metaData.getString("android.app.load_local_libs").split(":");
- for (String lib : extraLibs) {
- if (!lib.isEmpty())
- libraryList.add(pluginsPrefix + lib);
+ int resourceId = m_contextInfo.metaData.getInt("android.app.load_local_libs_resource_id");
+ for (String libs : prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))) {
+ for (String lib : libs.split(":")) {
+ if (!lib.isEmpty())
+ libraryList.add(libsDir + lib);
+ }
}
}
ENVIRONMENT_VARIABLES += "\tQML2_IMPORT_PATH=" + pluginsPrefix + "/qml"
+ "\tQML_IMPORT_PATH=" + pluginsPrefix + "/imports"
+ "\tQT_PLUGIN_PATH=" + pluginsPrefix + "/plugins";
+ if (bundledLibsDir != null)
+ ENVIRONMENT_VARIABLES += "\tQT_BUNDLED_LIBS_PATH=" + bundledLibsDir;
}
Bundle loaderParams = new Bundle();
diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml
index aed8a3c888..75da314c2b 100644
--- a/src/android/templates/AndroidManifest.xml
+++ b/src/android/templates/AndroidManifest.xml
@@ -12,7 +12,7 @@
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
- <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --">
+ <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --" android:extractNativeLibs="true">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
android:name="org.qtproject.qt5.android.bindings.QtActivity"
android:label="-- %%INSERT_APP_NAME%% --"
@@ -36,10 +36,11 @@
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
+
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
- <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
+ <meta-data android:name="android.app.load_local_libs_resource_id" android:resource="@array/load_local_libs"/>
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Used to specify custom system library path to run with local system libs -->
diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle
index 8d4aa63153..d2da115936 100644
--- a/src/android/templates/build.gradle
+++ b/src/android/templates/build.gradle
@@ -5,7 +5,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.2.0'
+ classpath 'com.android.tools.build:gradle:3.5.0'
}
}
diff --git a/src/android/templates/res/values/libs.xml b/src/android/templates/res/values/libs.xml
index 4009a7785a..db777bf433 100644
--- a/src/android/templates/res/values/libs.xml
+++ b/src/android/templates/res/values/libs.xml
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<array name="qt_sources">
- <item>https://download.qt.io/ministro/android/qt5/qt-5.9</item>
+ <item>https://download.qt.io/ministro/android/qt5/qt-5.14</item>
</array>
<!-- The following is handled automatically by the deployment tool. It should
@@ -12,12 +12,17 @@
</array>
<array name="qt_libs">
- <!-- %%INSERT_QT_LIBS%% -->
+ <!-- %%INSERT_QT_LIBS%% -->
</array>
<array name="bundled_in_lib">
<!-- %%INSERT_BUNDLED_IN_LIB%% -->
</array>
+
+ <array name="load_local_libs">
+ <!-- %%INSERT_LOCAL_LIBS%% -->
+ </array>
+
<array name="bundled_in_assets">
<!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
</array>
diff --git a/src/android/templates/templates.pro b/src/android/templates/templates.pro
index 55387f3af7..9a64251ee3 100644
--- a/src/android/templates/templates.pro
+++ b/src/android/templates/templates.pro
@@ -1,3 +1,5 @@
+CONFIG += single_arch
+
CONFIG -= qt android_install
templates.files = \
diff --git a/src/corelib/codecs/qicucodec.cpp b/src/corelib/codecs/qicucodec.cpp
index 101c3a3278..b9f1a814fa 100644
--- a/src/corelib/codecs/qicucodec.cpp
+++ b/src/corelib/codecs/qicucodec.cpp
@@ -42,8 +42,10 @@
#include "qtextcodec_p.h"
#include "qutfcodec_p.h"
#include "qlatincodec_p.h"
+#if QT_CONFIG(codecs)
#include "qtsciicodec_p.h"
#include "qisciicodec_p.h"
+#endif
#include "qsimplecodec_p.h"
#include "private/qcoreglobaldata_p.h"
#include "qdebug.h"
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index b9bcc70e17..121db51eb5 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -12,6 +12,7 @@ CONFIG += qt_tracepoints
CONFIG += $$MODULE_CONFIG
DEFINES += $$MODULE_DEFINES
+android: DEFINES += LIBS_SUFFIX='\\"_$${QT_ARCH}.so\\"'
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x67000000
diff --git a/src/corelib/io/forkfd_qt.cpp b/src/corelib/io/forkfd_qt.cpp
index 80d1cd54d7..cf44874153 100644
--- a/src/corelib/io/forkfd_qt.cpp
+++ b/src/corelib/io/forkfd_qt.cpp
@@ -37,37 +37,12 @@
**
****************************************************************************/
-// these might be defined via precompiled headers
-#include <QtCore/qatomic.h>
+#include <QtCore/qglobal.h>
#define FORKFD_NO_SPAWNFD
-
#if defined(QT_NO_DEBUG) && !defined(NDEBUG)
# define NDEBUG
#endif
-typedef QT_PREPEND_NAMESPACE(QBasicAtomicInt) ffd_atomic_int;
-#define ffd_atomic_pointer(type) QT_PREPEND_NAMESPACE(QBasicAtomicPointer<type>)
-
-QT_BEGIN_NAMESPACE
-
-#define FFD_ATOMIC_INIT(val) Q_BASIC_ATOMIC_INITIALIZER(val)
-
-#define FFD_ATOMIC_RELAXED Relaxed
-#define FFD_ATOMIC_ACQUIRE Acquire
-#define FFD_ATOMIC_RELEASE Release
-
-#define FFD_CONCAT(x, y) x ## y
-
-#define ffd_atomic_load(ptr,order) (ptr)->FFD_CONCAT(load, order)()
-#define ffd_atomic_store(ptr,val,order) (ptr)->FFD_CONCAT(store, order)(val)
-#define ffd_atomic_exchange(ptr,val,order) (ptr)->FFD_CONCAT(fetchAndStore, order)(val)
-#define ffd_atomic_compare_exchange(ptr,expected,desired,order1,order2) \
- (ptr)->FFD_CONCAT(testAndSet, order1)(*expected, desired, *expected)
-#define ffd_atomic_add_fetch(ptr,val,order) ((ptr)->FFD_CONCAT(fetchAndAdd, order)(val) + val)
-
-QT_END_NAMESPACE
-
-extern "C" {
+#include <forkfd.h>
#include "../../3rdparty/forkfd/forkfd.c"
-}
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index c5fb5b9fc5..6e97c2fd39 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -1898,10 +1898,17 @@ bool QAbstractItemModel::clearItemData(const QModelIndex &index)
*/
bool QAbstractItemModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
{
- bool b = true;
- for (QMap<int, QVariant>::ConstIterator it = roles.begin(); it != roles.end(); ++it)
- b = b && setData(index, it.value(), it.key());
- return b;
+ // ### Qt 6: Consider change the semantics of this function,
+ // or deprecating/removing it altogether.
+ //
+ // For instance, it should try setting *all* the data
+ // in \a roles, and not bail out at the first setData that returns
+ // false. It should also have a transactional approach.
+ for (auto it = roles.begin(), e = roles.end(); it != e; ++it) {
+ if (!setData(index, it.value(), it.key()))
+ return false;
+ }
+ return true;
}
/*!
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 4a26e9cdc0..9251a3c05f 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -527,28 +527,6 @@ inline void QMetaCallEvent::allocArgs()
/*!
\internal
- Only used by QtDeclarative - to be removed when migrated.
- */
-QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative,
- QObjectPrivate::StaticMetaCallFunction callFunction,
- const QObject *sender, int signalId,
- int nargs, int *types_, void **args_)
- : QAbstractMetaCallEvent(sender, signalId),
- d({nullptr, nullptr, callFunction, nargs, method_offset, method_relative}),
- prealloc_()
-{
- allocArgs();
- for (int arg = 0; arg < nargs; ++arg) {
- types()[arg] = types_[arg];
- args()[arg] = args_[arg];
- }
- free(types_);
- free(args_);
-}
-
-/*!
- \internal
-
Used for blocking queued connections, just passes \a args through without
allocating any memory.
*/
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 5d0b3a8399..feafcaf323 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -509,12 +509,6 @@ private:
class Q_CORE_EXPORT QMetaCallEvent : public QAbstractMetaCallEvent
{
public:
- // kept for compatibility until QtDeclarative has moved over
- QMetaCallEvent(ushort method_offset, ushort method_relative,
- QObjectPrivate::StaticMetaCallFunction callFunction,
- const QObject *sender, int signalId,
- int nargs, int *types, void **args);
-
// blocking queued with semaphore - args always owned by caller
QMetaCallEvent(ushort method_offset, ushort method_relative,
QObjectPrivate::StaticMetaCallFunction callFunction,
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 84fcc53d52..44d5513163 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -52,6 +52,10 @@
# include <private/qcore_mac_p.h>
#endif
+#ifdef Q_OS_ANDROID
+# include <private/qjnihelpers_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
static QString qdlerror()
@@ -96,6 +100,9 @@ QStringList QLibraryPrivate::suffixes_sys(const QString& fullVersion)
suffixes << QLatin1String(".so.%1").arg(fullVersion);
} else {
suffixes << QLatin1String(".so");
+# ifdef Q_OS_ANDROID
+ suffixes << QStringLiteral(LIBS_SUFFIX);
+# endif
}
#endif
# ifdef Q_OS_MAC
@@ -157,9 +164,12 @@ bool QLibraryPrivate::load_sys()
// Do not unload the library during dlclose(). Consequently, the
// library's specific static variables are not reinitialized if the
// library is reloaded with dlopen() at a later time.
-#if defined(RTLD_NODELETE) && !defined(Q_OS_ANDROID)
+#if defined(RTLD_NODELETE)
if (loadHints & QLibrary::PreventUnloadHint) {
- dlFlags |= RTLD_NODELETE;
+# ifdef Q_OS_ANDROID // RTLD_NODELETE flag is supported by Android 23+
+ if (QtAndroidPrivate::androidSdkVersion() > 22)
+# endif
+ dlFlags |= RTLD_NODELETE;
}
#endif
@@ -219,7 +229,14 @@ bool QLibraryPrivate::load_sys()
} else {
attempt = path + prefixes.at(prefix) + name + suffixes.at(suffix);
}
+
pHnd = dlopen(QFile::encodeName(attempt), dlFlags);
+#ifdef Q_OS_ANDROID
+ if (!pHnd) {
+ auto attemptFromBundle = attempt;
+ pHnd = dlopen(QFile::encodeName(attemptFromBundle.replace(QLatin1Char('/'), QLatin1Char('_'))), dlFlags);
+ }
+#endif
if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
// We only want to continue if dlopen failed due to that the shared library did not exist.
diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp
index ba616c0a7d..9053618014 100644
--- a/src/corelib/serialization/qcborvalue.cpp
+++ b/src/corelib/serialization/qcborvalue.cpp
@@ -915,7 +915,7 @@ void QCborContainerPrivate::replaceAt_complex(Element &e, const QCborValue &valu
// in qstring.cpp
void qt_to_latin1_unchecked(uchar *dst, const ushort *uc, qsizetype len);
-Q_NEVER_INLINE void QCborContainerPrivate::appendAsciiString(const QString &s)
+Q_NEVER_INLINE void QCborContainerPrivate::appendAsciiString(QStringView s)
{
qsizetype len = s.size();
QtCbor::Element e;
@@ -926,7 +926,7 @@ Q_NEVER_INLINE void QCborContainerPrivate::appendAsciiString(const QString &s)
char *ptr = data.data() + e.value + sizeof(ByteData);
uchar *l = reinterpret_cast<uchar *>(ptr);
- const ushort *uc = (const ushort *)s.unicode();
+ const ushort *uc = (const ushort *)s.utf16();
qt_to_latin1_unchecked(l, uc, len);
}
@@ -1646,13 +1646,23 @@ QCborValue::QCborValue(const QByteArray &ba)
container->ref.storeRelaxed(1);
}
+#if QT_STRINGVIEW_LEVEL < 2
/*!
Creates a QCborValue with string value \a s. The value can later be
retrieved using toString().
\sa toString(), isString(), isByteArray()
*/
-QCborValue::QCborValue(const QString &s)
+QCborValue::QCborValue(const QString &s) : QCborValue(qToStringViewIgnoringNull(s)) {}
+#endif
+
+/*!
+ Creates a QCborValue with string value \a s. The value can later be
+ retrieved using toString().
+
+ \sa toString(), isString(), isByteArray()
+*/
+QCborValue::QCborValue(QStringView s)
: n(0), container(new QCborContainerPrivate), t(String)
{
container->append(s);
diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h
index f542e44c47..f79fc572c4 100644
--- a/src/corelib/serialization/qcborvalue.h
+++ b/src/corelib/serialization/qcborvalue.h
@@ -143,7 +143,10 @@ public:
QCborValue(QCborSimpleType st) : t(type_helper(st)) {}
QCborValue(const QByteArray &ba);
+#if QT_STRINGVIEW_LEVEL < 2
QCborValue(const QString &s);
+#endif
+ QCborValue(QStringView s);
QCborValue(QLatin1String s);
#ifndef QT_NO_CAST_FROM_ASCII
QT_ASCII_CAST_WARN QCborValue(const char *s) : QCborValue(QString::fromUtf8(s)) {}
diff --git a/src/corelib/serialization/qcborvalue_p.h b/src/corelib/serialization/qcborvalue_p.h
index 4050d18fa9..590c2d6e05 100644
--- a/src/corelib/serialization/qcborvalue_p.h
+++ b/src/corelib/serialization/qcborvalue_p.h
@@ -245,13 +245,21 @@ public:
appendByteData(s.latin1(), s.size(), QCborValue::String,
QtCbor::Element::StringIsAscii);
}
- void appendAsciiString(const QString &s);
+ void appendAsciiString(QStringView s);
+
+#if QT_STRINGVIEW_LEVEL < 2
void append(const QString &s)
{
+ append(qToStringViewIgnoringNull(s));
+ }
+#endif
+
+ void append(QStringView s)
+ {
if (QtPrivate::isAscii(s))
appendAsciiString(s);
else
- appendByteData(reinterpret_cast<const char *>(s.constData()), s.size() * 2,
+ appendByteData(reinterpret_cast<const char *>(s.utf16()), s.size() * 2,
QCborValue::String, QtCbor::Element::StringIsUtf16);
}
void append(const QCborValue &v)
@@ -345,33 +353,41 @@ public:
return e;
}
- bool stringEqualsElement(qsizetype idx, QLatin1String s) const
+ static int compareUtf8(const QtCbor::ByteData *b, const QLatin1String &s)
{
- const auto &e = elements.at(idx);
- if (e.type != QCborValue::String)
- return false;
-
- const QtCbor::ByteData *b = byteData(idx);
- if (!b)
- return s.isEmpty();
+ return QUtf8::compareUtf8(b->byte(), b->len, s);
+ }
- if (e.flags & QtCbor::Element::StringIsUtf16)
- return QtPrivate::compareStrings(b->asStringView(), s) == 0;
- return QUtf8::compareUtf8(b->byte(), b->len, s) == 0;
+ static int compareUtf8(const QtCbor::ByteData *b, QStringView s)
+ {
+ return QUtf8::compareUtf8(b->byte(), b->len, s.data(), s.size());
}
- bool stringEqualsElement(qsizetype idx, const QString &s) const
+
+ template<typename String>
+ int stringCompareElement(const QtCbor::Element &e, String s) const
{
- const auto &e = elements.at(idx);
if (e.type != QCborValue::String)
- return false;
+ return int(e.type) - int(QCborValue::String);
- const QtCbor::ByteData *b = byteData(idx);
+ const QtCbor::ByteData *b = byteData(e);
if (!b)
- return s.isEmpty();
+ return s.isEmpty() ? 0 : -1;
if (e.flags & QtCbor::Element::StringIsUtf16)
- return QtPrivate::compareStrings(b->asStringView(), s) == 0;
- return QUtf8::compareUtf8(b->byte(), b->len, s.data(), s.size()) == 0;
+ return QtPrivate::compareStrings(b->asStringView(), s);
+ return compareUtf8(b, s);
+ }
+
+ template<typename String>
+ bool stringEqualsElement(const QtCbor::Element &e, String s) const
+ {
+ return stringCompareElement(e, s) == 0;
+ }
+
+ template<typename String>
+ bool stringEqualsElement(qsizetype idx, String s) const
+ {
+ return stringEqualsElement(elements.at(idx), s);
}
static int compareElement_helper(const QCborContainerPrivate *c1, QtCbor::Element e1,
diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h
index 88286b902a..7b1351666d 100644
--- a/src/corelib/text/qstring.h
+++ b/src/corelib/text/qstring.h
@@ -57,15 +57,6 @@
#include <string>
#include <iterator>
-#if defined(Q_OS_ANDROID) && !defined(ANDROID_HAS_WSTRING)
-// std::wstring is disabled on android's glibc, as bionic lacks certain features
-// that libstdc++ checks for (like mbcslen).
-namespace std
-{
- typedef basic_string<wchar_t> wstring;
-}
-#endif
-
#include <stdarg.h>
#ifdef truncate
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 38e9c1c3ec..cb3c0d6bb1 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -108,20 +108,8 @@ Q_STATIC_ASSERT(sizeof(pthread_t) <= sizeof(Qt::HANDLE));
enum { ThreadPriorityResetFlag = 0x80000000 };
-#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) && !defined(QT_LINUXBASE)
-/* LSB doesn't have __thread, https://lsbbugs.linuxfoundation.org/show_bug.cgi?id=993 */
-#define HAVE_TLS
-#endif
-#if defined(Q_CC_XLC) || defined (Q_CC_SUN)
-#define HAVE_TLS
-#endif
-#if defined(Q_OS_RTEMS)
-#define HAVE_TLS
-#endif
-#ifdef HAVE_TLS
-static __thread QThreadData *currentThreadData = 0;
-#endif
+static thread_local QThreadData *currentThreadData = 0;
static pthread_once_t current_thread_data_once = PTHREAD_ONCE_INIT;
static pthread_key_t current_thread_data_key;
@@ -182,28 +170,19 @@ Q_DESTRUCTOR_FUNCTION(destroy_current_thread_data_key)
// Utility functions for getting, setting and clearing thread specific data.
static QThreadData *get_thread_data()
{
-#ifdef HAVE_TLS
return currentThreadData;
-#else
- pthread_once(&current_thread_data_once, create_current_thread_data_key);
- return reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key));
-#endif
}
static void set_thread_data(QThreadData *data)
{
-#ifdef HAVE_TLS
currentThreadData = data;
-#endif
pthread_once(&current_thread_data_once, create_current_thread_data_key);
pthread_setspecific(current_thread_data_key, data);
}
static void clear_thread_data()
{
-#ifdef HAVE_TLS
currentThreadData = 0;
-#endif
pthread_setspecific(current_thread_data_key, 0);
}
diff --git a/src/corelib/tools/qsize.cpp b/src/corelib/tools/qsize.cpp
index fe508ad459..2cbaae117d 100644
--- a/src/corelib/tools/qsize.cpp
+++ b/src/corelib/tools/qsize.cpp
@@ -390,7 +390,25 @@ QSize QSize::scaled(const QSize &s, Qt::AspectRatioMode mode) const noexcept
\sa expandedTo(), scale()
*/
+/*!
+ \fn QSize QSize::grownBy(QMargins margins) const
+ \fn QSizeF QSizeF::grownBy(QMarginsF margins) const
+ \since 5.14
+
+ Returns the size that results from growing this size by \a margins.
+
+ \sa shrunkBy()
+*/
+/*!
+ \fn QSize QSize::shrunkBy(QMargins margins) const
+ \fn QSizeF QSizeF::shrunkBy(QMarginsF margins) const
+ \since 5.14
+
+ Returns the size that results from shrinking this size by \a margins.
+
+ \sa grownBy()
+*/
/*****************************************************************************
QSize stream functions
diff --git a/src/corelib/tools/qsize.h b/src/corelib/tools/qsize.h
index 4114609856..06de1cd63f 100644
--- a/src/corelib/tools/qsize.h
+++ b/src/corelib/tools/qsize.h
@@ -41,6 +41,7 @@
#define QSIZE_H
#include <QtCore/qnamespace.h>
+#include <QtCore/qmargins.h>
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
struct CGSize;
@@ -74,6 +75,11 @@ public:
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QSize expandedTo(const QSize &) const noexcept;
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QSize boundedTo(const QSize &) const noexcept;
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QSize grownBy(QMargins m) const noexcept
+ { return {width() + m.left() + m.right(), height() + m.top() + m.bottom()}; }
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QSize shrunkBy(QMargins m) const noexcept
+ { return {width() - m.left() - m.right(), height() - m.top() - m.bottom()}; }
+
Q_DECL_RELAXED_CONSTEXPR inline int &rwidth() noexcept;
Q_DECL_RELAXED_CONSTEXPR inline int &rheight() noexcept;
@@ -238,6 +244,11 @@ public:
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QSizeF expandedTo(const QSizeF &) const noexcept;
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline QSizeF boundedTo(const QSizeF &) const noexcept;
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QSizeF grownBy(QMarginsF m) const noexcept
+ { return {width() + m.left() + m.right(), height() + m.top() + m.bottom()}; }
+ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QSizeF shrunkBy(QMarginsF m) const noexcept
+ { return {width() - m.left() - m.right(), height() - m.top() - m.bottom()}; }
+
Q_DECL_RELAXED_CONSTEXPR inline qreal &rwidth() noexcept;
Q_DECL_RELAXED_CONSTEXPR inline qreal &rheight() noexcept;
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index 049b9ef179..76dd6d7ea1 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -67,3 +67,6 @@ navigation.cppclassespage = "Qt GUI C++ Classes"
# Ignore warnings about undocumented enum values for the QGradient presets
spurious += "Undocumented enum item '.*' in QGradient::Preset"
+
+# \svgcolor {#ffdead}
+macro.svgcolor.HTML = "<div style=\"padding:10px;color:#fff;background:\1;\"></div>"
diff --git a/src/gui/doc/src/includes/qt-colors.qdocinc b/src/gui/doc/src/includes/qt-colors.qdocinc
new file mode 100644
index 0000000000..4c082323b6
--- /dev/null
+++ b/src/gui/doc/src/includes/qt-colors.qdocinc
@@ -0,0 +1,86 @@
+\table
+\header
+ \li Name
+ \li Hex
+ \li Color
+\row
+ \li Color0
+ \li #000000
+ \li \svgcolor {#000000}
+\row
+ \li Color1
+ \li #ffffff
+ \li \svgcolor {#ffffff}
+\row
+ \li Black
+ \li #000000
+ \li \svgcolor {#000000}
+\row
+ \li White
+ \li #ffffff
+ \li \svgcolor {#ffffff}
+\row
+ \li DarkGray
+ \li #808080
+ \li \svgcolor {#808080}
+\row
+ \li Gray
+ \li #a0a0a4
+ \li \svgcolor {#a0a0a4}
+\row
+ \li LightGray
+ \li #c0c0c0
+ \li \svgcolor {#c0c0c0}
+\row
+ \li Red
+ \li #ff0000
+ \li \svgcolor {#ff0000}
+\row
+ \li Green
+ \li #00ff00
+ \li \svgcolor {#00ff00}
+\row
+ \li Blue
+ \li #0000ff
+ \li \svgcolor {#0000ff}
+\row
+ \li Cyan
+ \li #00ffff
+ \li \svgcolor {#00ffff}
+\row
+ \li Magenta
+ \li #ff00ff
+ \li \svgcolor {#ff00ff}
+\row
+ \li Yellow
+ \li #ffff00
+ \li \svgcolor {#ffff00}
+\row
+ \li DarkRed
+ \li #800000
+ \li \svgcolor {#800000}
+\row
+ \li DarkGreen
+ \li #008000
+ \li \svgcolor {#008000}
+\row
+ \li DarkBlue
+ \li #000080
+ \li \svgcolor {#000080}
+\row
+ \li DarkCyan
+ \li #008080
+ \li \svgcolor {#008080}
+\row
+ \li DarkMagenta
+ \li #800080
+ \li \svgcolor {#800080}
+\row
+ \li DarkYellow
+ \li #808000
+ \li \svgcolor {#808000}
+\row
+ \li Transparent
+ \li #00000000
+ \li (transparent)
+\endtable
diff --git a/src/gui/doc/src/includes/svg-colors.qdocinc b/src/gui/doc/src/includes/svg-colors.qdocinc
new file mode 100644
index 0000000000..4e5fb56d5e
--- /dev/null
+++ b/src/gui/doc/src/includes/svg-colors.qdocinc
@@ -0,0 +1,594 @@
+\table
+\header
+ \li Name
+ \li Hex
+ \li Color
+\row
+ \li aliceblue
+ \li #f0f8ff
+ \li \svgcolor {#f0f8ff}
+\row
+ \li antiquewhite
+ \li #faebd7
+ \li \svgcolor {#faebd7}
+\row
+ \li aqua
+ \li #00ffff
+ \li \svgcolor {#00ffff}
+\row
+ \li aquamarine
+ \li #7fffd4
+ \li \svgcolor {#7fffd4}
+\row
+ \li azure
+ \li #f0ffff
+ \li \svgcolor {#f0ffff}
+\row
+ \li beige
+ \li #f5f5dc
+ \li \svgcolor {#f5f5dc}
+\row
+ \li bisque
+ \li #ffe4c4
+ \li \svgcolor {#ffe4c4}
+\row
+ \li black
+ \li #000000
+ \li \svgcolor {#000000}
+\row
+ \li blanchedalmond
+ \li #ffebcd
+ \li \svgcolor {#ffebcd}
+\row
+ \li blue
+ \li #0000ff
+ \li \svgcolor {#0000ff}
+\row
+ \li blueviolet
+ \li #8a2be2
+ \li \svgcolor {#8a2be2}
+\row
+ \li brown
+ \li #a52a2a
+ \li \svgcolor {#a52a2a}
+\row
+ \li burlywood
+ \li #deb887
+ \li \svgcolor {#deb887}
+\row
+ \li cadetblue
+ \li #5f9ea0
+ \li \svgcolor {#5f9ea0}
+\row
+ \li chartreuse
+ \li #7fff00
+ \li \svgcolor {#7fff00}
+\row
+ \li chocolate
+ \li #d2691e
+ \li \svgcolor {#d2691e}
+\row
+ \li coral
+ \li #ff7f50
+ \li \svgcolor {#ff7f50}
+\row
+ \li cornflowerblue
+ \li #6495ed
+ \li \svgcolor {#6495ed}
+\row
+ \li cornsilk
+ \li #fff8dc
+ \li \svgcolor {#fff8dc}
+\row
+ \li crimson
+ \li #dc143c
+ \li \svgcolor {#dc143c}
+\row
+ \li cyan
+ \li #00ffff
+ \li \svgcolor {#00ffff}
+\row
+ \li darkblue
+ \li #00008b
+ \li \svgcolor {#00008b}
+\row
+ \li darkcyan
+ \li #008b8b
+ \li \svgcolor {#008b8b}
+\row
+ \li darkgoldenrod
+ \li #b8860b
+ \li \svgcolor {#b8860b}
+\row
+ \li darkgray
+ \li #a9a9a9
+ \li \svgcolor {#a9a9a9}
+\row
+ \li darkgreen
+ \li #006400
+ \li \svgcolor {#006400}
+\row
+ \li darkgrey
+ \li #a9a9a9
+ \li \svgcolor {#a9a9a9}
+\row
+ \li darkkhaki
+ \li #bdb76b
+ \li \svgcolor {#bdb76b}
+\row
+ \li darkmagenta
+ \li #8b008b
+ \li \svgcolor {#8b008b}
+\row
+ \li darkolivegreen
+ \li #556b2f
+ \li \svgcolor {#556b2f}
+\row
+ \li darkorange
+ \li #ff8c00
+ \li \svgcolor {#ff8c00}
+\row
+ \li darkorchid
+ \li #9932cc
+ \li \svgcolor {#9932cc}
+\row
+ \li darkred
+ \li #8b0000
+ \li \svgcolor {#8b0000}
+\row
+ \li darksalmon
+ \li #e9967a
+ \li \svgcolor {#e9967a}
+\row
+ \li darkseagreen
+ \li #8fbc8f
+ \li \svgcolor {#8fbc8f}
+\row
+ \li darkslateblue
+ \li #483d8b
+ \li \svgcolor {#483d8b}
+\row
+ \li darkslategray
+ \li #2f4f4f
+ \li \svgcolor {#2f4f4f}
+\row
+ \li darkslategrey
+ \li #2f4f4f
+ \li \svgcolor {#2f4f4f}
+\row
+ \li darkturquoise
+ \li #00ced1
+ \li \svgcolor {#00ced1}
+\row
+ \li darkviolet
+ \li #9400d3
+ \li \svgcolor {#9400d3}
+\row
+ \li deeppink
+ \li #ff1493
+ \li \svgcolor {#ff1493}
+\row
+ \li deepskyblue
+ \li #00bfff
+ \li \svgcolor {#00bfff}
+\row
+ \li dimgray
+ \li #696969
+ \li \svgcolor {#696969}
+\row
+ \li dimgrey
+ \li #696969
+ \li \svgcolor {#696969}
+\row
+ \li dodgerblue
+ \li #1e90ff
+ \li \svgcolor {#1e90ff}
+\row
+ \li firebrick
+ \li #b22222
+ \li \svgcolor {#b22222}
+\row
+ \li floralwhite
+ \li #fffaf0
+ \li \svgcolor {#fffaf0}
+\row
+ \li forestgreen
+ \li #228b22
+ \li \svgcolor {#228b22}
+\row
+ \li fuchsia
+ \li #ff00ff
+ \li \svgcolor {#ff00ff}
+\row
+ \li gainsboro
+ \li #dcdcdc
+ \li \svgcolor {#dcdcdc}
+\row
+ \li ghostwhite
+ \li #f8f8ff
+ \li \svgcolor {#f8f8ff}
+\row
+ \li gold
+ \li #ffd700
+ \li \svgcolor {#ffd700}
+\row
+ \li goldenrod
+ \li #daa520
+ \li \svgcolor {#daa520}
+\row
+ \li gray
+ \li #808080
+ \li \svgcolor {#808080}
+\row
+ \li grey
+ \li #808080
+ \li \svgcolor {#808080}
+\row
+ \li green
+ \li #008000
+ \li \svgcolor {#008000}
+\row
+ \li greenyellow
+ \li #adff2f
+ \li \svgcolor {#adff2f}
+\row
+ \li honeydew
+ \li #f0fff0
+ \li \svgcolor {#f0fff0}
+\row
+ \li hotpink
+ \li #ff69b4
+ \li \svgcolor {#ff69b4}
+\row
+ \li indianred
+ \li #cd5c5c
+ \li \svgcolor {#cd5c5c}
+\row
+ \li indigo
+ \li #4b0082
+ \li \svgcolor {#4b0082}
+\row
+ \li ivory
+ \li #fffff0
+ \li \svgcolor {#fffff0}
+\row
+ \li khaki
+ \li #f0e68c
+ \li \svgcolor {#f0e68c}
+\row
+ \li lavender
+ \li #e6e6fa
+ \li \svgcolor {#e6e6fa}
+\row
+ \li lavenderblush
+ \li #fff0f5
+ \li \svgcolor {#fff0f5}
+\row
+ \li lawngreen
+ \li #7cfc00
+ \li \svgcolor {#7cfc00}
+\row
+ \li lemonchiffon
+ \li #fffacd
+ \li \svgcolor {#fffacd}
+\row
+ \li lightblue
+ \li #add8e6
+ \li \svgcolor {#add8e6}
+\row
+ \li lightcoral
+ \li #f08080
+ \li \svgcolor {#f08080}
+\row
+ \li lightcyan
+ \li #e0ffff
+ \li \svgcolor {#e0ffff}
+\row
+ \li lightgoldenrodyellow
+ \li #fafad2
+ \li \svgcolor {#fafad2}
+\row
+ \li lightgray
+ \li #d3d3d3
+ \li \svgcolor {#d3d3d3}
+\row
+ \li lightgreen
+ \li #90ee90
+ \li \svgcolor {#90ee90}
+\row
+ \li lightgrey
+ \li #d3d3d3
+ \li \svgcolor {#d3d3d3}
+\row
+ \li lightpink
+ \li #ffb6c1
+ \li \svgcolor {#ffb6c1}
+\row
+ \li lightsalmon
+ \li #ffa07a
+ \li \svgcolor {#ffa07a}
+\row
+ \li lightseagreen
+ \li #20b2aa
+ \li \svgcolor {#20b2aa}
+\row
+ \li lightskyblue
+ \li #87cefa
+ \li \svgcolor {#87cefa}
+\row
+ \li lightslategray
+ \li #778899
+ \li \svgcolor {#778899}
+\row
+ \li lightslategrey
+ \li #778899
+ \li \svgcolor {#778899}
+\row
+ \li lightsteelblue
+ \li #b0c4de
+ \li \svgcolor {#b0c4de}
+\row
+ \li lightyellow
+ \li #ffffe0
+ \li \svgcolor {#ffffe0}
+\row
+ \li lime
+ \li #00ff00
+ \li \svgcolor {#00ff00}
+\row
+ \li limegreen
+ \li #32cd32
+ \li \svgcolor {#32cd32}
+\row
+ \li linen
+ \li #faf0e6
+ \li \svgcolor {#faf0e6}
+\row
+ \li magenta
+ \li #ff00ff
+ \li \svgcolor {#ff00ff}
+\row
+ \li maroon
+ \li #800000
+ \li \svgcolor {#800000}
+\row
+ \li mediumaquamarine
+ \li #66cdaa
+ \li \svgcolor {#66cdaa}
+\row
+ \li mediumblue
+ \li #0000cd
+ \li \svgcolor {#0000cd}
+\row
+ \li mediumorchid
+ \li #ba55d3
+ \li \svgcolor {#ba55d3}
+\row
+ \li mediumpurple
+ \li #9370db
+ \li \svgcolor {#9370db}
+\row
+ \li mediumseagreen
+ \li #3cb371
+ \li \svgcolor {#3cb371}
+\row
+ \li mediumslateblue
+ \li #7b68ee
+ \li \svgcolor {#7b68ee}
+\row
+ \li mediumspringgreen
+ \li #00fa9a
+ \li \svgcolor {#00fa9a}
+\row
+ \li mediumturquoise
+ \li #48d1cc
+ \li \svgcolor {#48d1cc}
+\row
+ \li mediumvioletred
+ \li #c71585
+ \li \svgcolor {#c71585}
+\row
+ \li midnightblue
+ \li #191970
+ \li \svgcolor {#191970}
+\row
+ \li mintcream
+ \li #f5fffa
+ \li \svgcolor {#f5fffa}
+\row
+ \li mistyrose
+ \li #ffe4e1
+ \li \svgcolor {#ffe4e1}
+\row
+ \li moccasin
+ \li #ffe4b5
+ \li \svgcolor {#ffe4b5}
+\row
+ \li navajowhite
+ \li #ffdead
+ \li \svgcolor {#ffdead}
+\row
+ \li navy
+ \li #000080
+ \li \svgcolor {#000080}
+\row
+ \li oldlace
+ \li #fdf5e6
+ \li \svgcolor {#fdf5e6}
+\row
+ \li olive
+ \li #808000
+ \li \svgcolor {#808000}
+\row
+ \li olivedrab
+ \li #6b8e23
+ \li \svgcolor {#6b8e23}
+\row
+ \li orange
+ \li #ffa500
+ \li \svgcolor {#ffa500}
+\row
+ \li orangered
+ \li #ff4500
+ \li \svgcolor {#ff4500}
+\row
+ \li orchid
+ \li #da70d6
+ \li \svgcolor {#da70d6}
+\row
+ \li palegoldenrod
+ \li #eee8aa
+ \li \svgcolor {#eee8aa}
+\row
+ \li palegreen
+ \li #98fb98
+ \li \svgcolor {#98fb98}
+\row
+ \li paleturquoise
+ \li #afeeee
+ \li \svgcolor {#afeeee}
+\row
+ \li palevioletred
+ \li #db7093
+ \li \svgcolor {#db7093}
+\row
+ \li papayawhip
+ \li #ffefd5
+ \li \svgcolor {#ffefd5}
+\row
+ \li peachpuff
+ \li #ffdab9
+ \li \svgcolor {#ffdab9}
+\row
+ \li peru
+ \li #cd853f
+ \li \svgcolor {#cd853f}
+\row
+ \li pink
+ \li #ffc0cb
+ \li \svgcolor {#ffc0cb}
+\row
+ \li plum
+ \li #dda0dd
+ \li \svgcolor {#dda0dd}
+\row
+ \li powderblue
+ \li #b0e0e6
+ \li \svgcolor {#b0e0e6}
+\row
+ \li purple
+ \li #800080
+ \li \svgcolor {#800080}
+\row
+ \li red
+ \li #ff0000
+ \li \svgcolor {#ff0000}
+\row
+ \li rosybrown
+ \li #bc8f8f
+ \li \svgcolor {#bc8f8f}
+\row
+ \li royalblue
+ \li #4169e1
+ \li \svgcolor {#4169e1}
+\row
+ \li saddlebrown
+ \li #8b4513
+ \li \svgcolor {#8b4513}
+\row
+ \li salmon
+ \li #fa8072
+ \li \svgcolor {#fa8072}
+\row
+ \li sandybrown
+ \li #f4a460
+ \li \svgcolor {#f4a460}
+\row
+ \li seagreen
+ \li #2e8b57
+ \li \svgcolor {#2e8b57}
+\row
+ \li seashell
+ \li #fff5ee
+ \li \svgcolor {#fff5ee}
+\row
+ \li sienna
+ \li #a0522d
+ \li \svgcolor {#a0522d}
+\row
+ \li silver
+ \li #c0c0c0
+ \li \svgcolor {#c0c0c0}
+\row
+ \li skyblue
+ \li #87ceeb
+ \li \svgcolor {#87ceeb}
+\row
+ \li slateblue
+ \li #6a5acd
+ \li \svgcolor {#6a5acd}
+\row
+ \li slategray
+ \li #708090
+ \li \svgcolor {#708090}
+\row
+ \li slategrey
+ \li #708090
+ \li \svgcolor {#708090}
+\row
+ \li snow
+ \li #fffafa
+ \li \svgcolor {#fffafa}
+\row
+ \li springgreen
+ \li #00ff7f
+ \li \svgcolor {#00ff7f}
+\row
+ \li steelblue
+ \li #4682b4
+ \li \svgcolor {#4682b4}
+\row
+ \li tan
+ \li #d2b48c
+ \li \svgcolor {#d2b48c}
+\row
+ \li teal
+ \li #008080
+ \li \svgcolor {#008080}
+\row
+ \li thistle
+ \li #d8bfd8
+ \li \svgcolor {#d8bfd8}
+\row
+ \li tomato
+ \li #ff6347
+ \li \svgcolor {#ff6347}
+\row
+ \li turquoise
+ \li #40e0d0
+ \li \svgcolor {#40e0d0}
+\row
+ \li violet
+ \li #ee82ee
+ \li \svgcolor {#ee82ee}
+\row
+ \li wheat
+ \li #f5deb3
+ \li \svgcolor {#f5deb3}
+\row
+ \li white
+ \li #ffffff
+ \li \svgcolor {#ffffff}
+\row
+ \li whitesmoke
+ \li #f5f5f5
+ \li \svgcolor {#f5f5f5}
+\row
+ \li yellow
+ \li #ffff00
+ \li \svgcolor {#ffff00}
+\row
+ \li yellowgreen
+ \li #9acd32
+ \li \svgcolor {#9acd32}
+\endtable
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index 70fccbc378..3b2ced3f58 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -82,7 +82,18 @@ qtConfig(png) {
}
# SIMD
-SSSE3_SOURCES += image/qimage_ssse3.cpp
-NEON_SOURCES += image/qimage_neon.cpp
-MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp
-MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S
+!android {
+ SSSE3_SOURCES += image/qimage_ssse3.cpp
+ NEON_SOURCES += image/qimage_neon.cpp
+ MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp
+ MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S
+} else {
+ # see https://developer.android.com/ndk/guides/abis
+ arm64-v8a {
+ SOURCES += image/qimage_neon.cpp
+ }
+ x86 | x86_64 {
+ DEFINES += QT_COMPILER_SUPPORTS_SSE2 QT_COMPILER_SUPPORTS_SSE3 QT_COMPILER_SUPPORTS_SSSE3
+ SOURCES += image/qimage_ssse3.cpp
+ }
+}
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 8e0bbb6907..b7f67cd7ef 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -287,6 +287,7 @@ bool QImageData::checkForAlphaPixels() const
case QImage::Format_RGB555:
case QImage::Format_RGB666:
case QImage::Format_RGB888:
+ case QImage::Format_BGR888:
case QImage::Format_RGBX8888:
case QImage::Format_BGR30:
case QImage::Format_RGB30:
@@ -720,6 +721,7 @@ bool QImageData::checkForAlphaPixels() const
\value Format_RGBA64 The image is stored using a 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12)
\value Format_RGBA64_Premultiplied The image is stored using a premultiplied 64-bit halfword-ordered
RGBA format (16-16-16-16). (added in Qt 5.12)
+ \value Format_BGR888 The image is stored using a 24-bit BGR format. (added in Qt 5.14)
\note Drawing into a QImage with QImage::Format_Indexed8 is not
supported.
@@ -5550,6 +5552,19 @@ static Q_CONSTEXPR QPixelFormat pixelformats[] = {
/*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
/*INTERPRETATION*/ QPixelFormat::UnsignedShort,
/*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
+ //QImage::Format_BGR888:
+ QPixelFormat(QPixelFormat::BGR,
+ /*RED*/ 8,
+ /*GREEN*/ 8,
+ /*BLUE*/ 8,
+ /*FOURTH*/ 0,
+ /*FIFTH*/ 0,
+ /*ALPHA*/ 0,
+ /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
+ /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
+ /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
+ /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
+ /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
};
Q_STATIC_ASSERT(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats);
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 7c68168be8..7544ccca05 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -131,6 +131,7 @@ public:
Format_RGBA64,
Format_RGBA64_Premultiplied,
Format_Grayscale16,
+ Format_BGR888,
#ifndef Q_QDOC
NImageFormats
#endif
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 837ac88470..539bac222a 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -429,8 +429,8 @@ typedef void (QT_FASTCALL *Rgb888ToRgbConverter)(quint32 *dst, const uchar *src,
template <bool rgbx>
static void convert_RGB888_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
- Q_ASSERT(src->format == QImage::Format_RGB888);
- if (rgbx)
+ Q_ASSERT(src->format == QImage::Format_RGB888 || src->format == QImage::Format_BGR888);
+ if (rgbx ^ (src->format == QImage::Format_BGR888))
Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
else
Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
@@ -1421,6 +1421,69 @@ static void convert_RGBA64_to_gray16(QImageData *dest, const QImageData *src, Qt
}
}
+static void convert_RGB888_to_BGR888(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGB888 || src->format == QImage::Format_BGR888);
+ Q_ASSERT(dest->format == QImage::Format_RGB888 || dest->format == QImage::Format_BGR888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const qsizetype sbpl = src->bytes_per_line;
+ const qsizetype dbpl = dest->bytes_per_line;
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ int pixel = 0;
+ // Handle 4 pixels (12 bytes) at a time
+ for (; pixel + 3 < src->width; pixel += 4) {
+ const uchar *src = src_data + pixel * 3;
+ quint32 *dest_packed = (quint32 *) (dest_data + pixel * 3);
+ dest_packed[0] = (src[5] << 24) | (src[0] << 16) | (src[1] << 8) | (src[2] << 0);
+ dest_packed[1] = (src[7] << 24) | (src[8] << 16) | (src[3] << 8) | (src[4] << 0);
+ dest_packed[2] = (src[9] << 24) | (src[10] << 16) | (src[11] << 8) | (src[6] << 0);
+ }
+
+ // epilog: handle left over pixels
+ for (; pixel < src->width; ++pixel) {
+ dest_data[pixel * 3 + 0] = src_data[pixel * 3 + 2];
+ dest_data[pixel * 3 + 1] = src_data[pixel * 3 + 1];
+ dest_data[pixel * 3 + 2] = src_data[pixel * 3 + 0];
+ }
+
+ src_data += sbpl;
+ dest_data += dbpl;
+ }
+}
+
+static bool convert_RGB888_to_BGR888_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGB888 || data->format == QImage::Format_BGR888);
+
+ const qsizetype bpl = data->bytes_per_line;
+ uchar *line_data = data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ for (int j = 0; j < data->width; ++j)
+ qSwap(line_data[j * 3 + 0], line_data[j * 3 + 2]);
+ line_data += bpl;
+ }
+
+ switch (data->format) {
+ case QImage::Format_RGB888:
+ data->format = QImage::Format_BGR888;
+ break;
+ case QImage::Format_BGR888:
+ data->format = QImage::Format_RGB888;
+ break;
+ default:
+ Q_UNREACHABLE();
+ data->format = QImage::Format_Invalid;
+ return false;
+ }
+ return true;
+}
+
static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
{
QVector<QRgb> colorTable = ctbl;
@@ -2265,7 +2328,7 @@ static bool convert_Grayscale8_to_Indexed8_inplace(QImageData *data, Qt::ImageCo
Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
{
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
{
0,
@@ -2286,7 +2349,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Mono
{
@@ -2308,7 +2371,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_MonoLSB
{
@@ -2333,7 +2396,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0, 0, 0, 0, 0,
convert_Indexed8_to_Alpha8,
convert_Indexed8_to_Grayscale8,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_Indexed8
{
@@ -2361,7 +2424,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGB_to_RGB30<PixelOrderRGB, false>,
0,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_RGB32
{
@@ -2391,7 +2454,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0, 0,
0,
convert_ARGB32_to_RGBA64<false>,
- 0, 0
+ 0, 0, 0
}, // Format_ARGB32
{
@@ -2416,7 +2479,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_ARGB_to_RGBA,
0, 0, 0, 0,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_ARGB32_Premultiplied
{
@@ -2438,7 +2501,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB16
{
@@ -2460,7 +2523,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8565_Premultiplied
{
@@ -2482,7 +2545,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB666
{
@@ -2504,7 +2567,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB6666_Premultiplied
{
@@ -2526,7 +2589,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB555
{
@@ -2548,7 +2611,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8555_Premultiplied
{
@@ -2565,13 +2628,14 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0,
+ 0, // self
0,
0,
convert_RGB888_to_RGB<true>,
convert_RGB888_to_RGB<true>,
convert_RGB888_to_RGB<true>,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ convert_RGB888_to_BGR888,
}, // Format_RGB888
{
@@ -2593,7 +2657,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB444
{
@@ -2614,7 +2678,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB4444_Premultiplied
{
0,
@@ -2641,7 +2705,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGB_to_RGB30<PixelOrderRGB, true>,
0,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_RGBX8888
{
0,
@@ -2670,7 +2734,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0, 0,
0,
convert_ARGB32_to_RGBA64<true>,
- 0, 0
+ 0, 0, 0
}, // Format_RGBA8888
{
@@ -2692,7 +2756,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGBA8888_Premultiplied
{
@@ -2720,7 +2784,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_BGR30_to_RGB30,
convert_BGR30_to_RGB30,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_BGR30
{
0,
@@ -2747,7 +2811,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_RGB30<true>,
convert_BGR30_to_RGB30,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_A2BGR30_Premultiplied
{
0,
@@ -2773,7 +2837,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_BGR30_to_RGB30,
0,
convert_passthrough,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB30
{
0,
@@ -2800,7 +2864,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_A2RGB30_PM_to_RGB30<false>,
0,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_A2RGB30_Premultiplied
{
0,
@@ -2820,7 +2884,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Alpha8
{
0,
@@ -2840,14 +2904,15 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Grayscale8
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, // self
convert_passthrough,
convert_passthrough,
- convert_RGBA64_to_gray16
+ convert_RGBA64_to_gray16,
+ 0
}, // Format_RGBX64
{
0,
@@ -2874,6 +2939,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGBA64_to_RGBx64,
0, // self
convert_RGBA64_to_RGBA64PM,
+ 0,
0
}, // Format_RGBA64
{
@@ -2901,7 +2967,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_RGBA64PM_to_RGBA64<true>,
convert_RGBA64PM_to_RGBA64<false>,
0, // self
- convert_RGBA64_to_gray16
+ convert_RGBA64_to_gray16,
+ 0
}, // Format_RGBA64_Premultiplied
{
0,
@@ -2931,20 +2998,46 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
convert_gray16_to_RGBA64,
convert_gray16_to_RGBA64,
convert_gray16_to_RGBA64,
- 0 // self
+ 0, // self
+ 0
}, // Format_Grayscale16
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, 0, 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGB888_to_BGR888,
+ 0,
+ 0,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ convert_RGB888_to_RGB<false>,
+ convert_RGB888_to_RGB<false>,
+ convert_RGB888_to_RGB<false>,
+#else
+ 0, 0, 0,
+#endif
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, // self
+ }, // Format_BGR888
};
InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
{
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
},
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Mono
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_MonoLSB
{
0,
@@ -2968,7 +3061,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0, 0, 0, 0, 0,
convert_Indexed8_to_Alpha8_inplace,
convert_Indexed8_to_Grayscale8_inplace,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_Indexed8
{
0,
@@ -2995,7 +3088,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_RGB_to_RGB30_inplace<PixelOrderRGB, false>,
0,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_RGB32
{
0,
@@ -3022,7 +3115,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_RGB_to_RGB30_inplace<PixelOrderRGB, false>,
0,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_ARGB32
{
0,
@@ -3046,34 +3139,35 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_ARGB_to_RGBA_inplace<QImage::Format_RGBA8888_Premultiplied>,
0, 0, 0, 0,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_ARGB32_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB16
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8565_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB666
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB6666_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB555
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB8555_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ convert_RGB888_to_BGR888_inplace
}, // Format_RGB888
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB444
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_ARGB4444_Premultiplied
{
0,
@@ -3100,7 +3194,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_RGB_to_RGB30_inplace<PixelOrderRGB, true>,
0,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_RGBX8888
{
0,
@@ -3127,7 +3221,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_RGB_to_RGB30_inplace<PixelOrderRGB, true>,
0,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_RGBA8888
{
0,
@@ -3149,7 +3243,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_RGBA8888_Premultiplied
{
0,
@@ -3176,7 +3270,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_BGR30_to_RGB30_inplace,
convert_BGR30_to_A2RGB30_inplace,
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_BGR30
{
0,
@@ -3202,7 +3296,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0, // self
convert_A2RGB30_PM_to_RGB30_inplace<true>,
convert_BGR30_to_RGB30_inplace,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_A2BGR30_Premultiplied
{
0,
@@ -3228,7 +3322,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_BGR30_to_A2RGB30_inplace,
0, // self
convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0
}, // Format_RGB30
{
0,
@@ -3255,7 +3349,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
convert_A2RGB30_PM_to_RGB30_inplace<false>,
0, // self
0, 0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_A2RGB30_Premultiplied
{
0,
@@ -3280,7 +3374,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0, 0, 0, 0,
0, // self
0,
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_Alpha8
{
0,
@@ -3305,32 +3399,37 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0, 0, 0, 0,
0,
0, // self
- 0, 0, 0, 0
+ 0, 0, 0, 0, 0
}, // Format_Grayscale8
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, // self
convert_passthrough_inplace<QImage::Format_RGBA64>,
convert_passthrough_inplace<QImage::Format_RGBA64_Premultiplied>,
- 0
+ 0, 0
}, // Format_RGBX64
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
convert_RGBA64_to_RGBx64_inplace,
0, // self
convert_RGBA64_to_RGBA64PM_inplace,
- 0
+ 0, 0
}, // Format_RGBA64
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
convert_RGBA64PM_to_RGBA64_inplace<true>,
convert_RGBA64PM_to_RGBA64_inplace<false>,
0, // self
- 0
+ 0, 0
}, // Format_RGBA64_Premultiplied
{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, // Format_Grayscale16
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ convert_RGB888_to_BGR888_inplace,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_BGR888
};
static void qInitImageConversions()
@@ -3341,6 +3440,9 @@ static void qInitImageConversions()
qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
+ qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBX8888] = convert_RGB888_to_RGB32_ssse3;
+ qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBA8888] = convert_RGB888_to_RGB32_ssse3;
+ qimage_converter_map[QImage::Format_BGR888][QImage::Format_RGBA8888_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
}
#endif
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 9da6acd0a7..9e2d9c86bb 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -207,6 +207,7 @@ inline int qt_depthForFormat(QImage::Format format)
case QImage::Format_ARGB8565_Premultiplied:
case QImage::Format_ARGB8555_Premultiplied:
case QImage::Format_RGB888:
+ case QImage::Format_BGR888:
depth = 24;
break;
case QImage::Format_RGBX64:
diff --git a/src/gui/image/qimage_ssse3.cpp b/src/gui/image/qimage_ssse3.cpp
index 9cdfba20e3..fb81a1a6c3 100644
--- a/src/gui/image/qimage_ssse3.cpp
+++ b/src/gui/image/qimage_ssse3.cpp
@@ -121,8 +121,11 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, con
void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
- Q_ASSERT(src->format == QImage::Format_RGB888);
- Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->format == QImage::Format_RGB888 || src->format == QImage::Format_BGR888);
+ if (src->format == QImage::Format_BGR888)
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ else
+ Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
Q_ASSERT(src->width == dest->width);
Q_ASSERT(src->height == dest->height);
diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp
index 3a2db74098..8aad77b991 100644
--- a/src/gui/image/qpixmap_win.cpp
+++ b/src/gui/image/qpixmap_win.cpp
@@ -281,6 +281,7 @@ Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &imageIn, int hbitmapForm
}
break;
case QImage::Format_RGB888:
+ case QImage::Format_BGR888:
compression = BI_RGB;
bitCount = 24u;
break;
@@ -368,7 +369,7 @@ static QImage::Format imageFromWinHBITMAP_Format(const BITMAPINFOHEADER &header,
? QImage::Format_RGB32 : QImage::Format_ARGB32_Premultiplied;
break;
case 24:
- result = QImage::Format_RGB888;
+ result = QImage::Format_BGR888;
break;
case 16:
result = QImage::Format_RGB555;
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 16d6c25b8b..4ab45337b0 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -1079,6 +1079,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i
if (color_type == PNG_COLOR_TYPE_RGB) {
switch (image.format()) {
case QImage::Format_RGB888:
+ case QImage::Format_BGR888:
break;
case QImage::Format_RGBX8888:
case QImage::Format_RGBX64:
@@ -1131,6 +1132,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_RGB888:
+ case QImage::Format_BGR888:
case QImage::Format_RGBX8888:
case QImage::Format_RGBA8888:
case QImage::Format_RGBX64:
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index ec52791010..616cca1422 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -535,13 +535,6 @@ Qt::MouseEventFlags QMouseEvent::flags() const
*/
/*!
- \fn QPointF QMouseEvent::posF() const
- \obsolete
-
- Use localPos() instead.
-*/
-
-/*!
\class QHoverEvent
\ingroup events
\inmodule QtGui
@@ -750,12 +743,14 @@ QHoverEvent::~QHoverEvent()
\l inverted always returns false.
*/
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\fn Qt::Orientation QWheelEvent::orientation() const
\obsolete
Use angleDelta() instead.
*/
+#endif
#if QT_CONFIG(wheelevent)
#if QT_DEPRECATED_SINCE(5, 15)
@@ -936,6 +931,7 @@ QWheelEvent::~QWheelEvent()
\endlist
*/
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\fn int QWheelEvent::delta() const
\obsolete
@@ -999,6 +995,7 @@ QWheelEvent::~QWheelEvent()
This function has been deprecated, use globalPosition() instead.
*/
+#endif
/*!
\fn Qt::ScrollPhase QWheelEvent::phase() const
@@ -1102,16 +1099,6 @@ QKeyEvent::~QKeyEvent()
}
/*!
- \fn QKeyEvent *QKeyEvent::createExtendedKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString& text, bool autorep, ushort count)
- \internal
-*/
-
-/*!
- \fn bool QKeyEvent::hasExtendedInfo() const
- \internal
-*/
-
-/*!
\fn quint32 QKeyEvent::nativeScanCode() const
\since 4.2
@@ -2539,7 +2526,7 @@ Qt::MouseButtons QTabletEvent::buttons() const
globalPos() can differ significantly from the current position
QCursor::pos().
- \sa globalX(), globalY(), hiResGlobalPos()
+ \sa globalX(), globalY()
*/
/*!
@@ -2584,15 +2571,6 @@ Qt::MouseButtons QTabletEvent::buttons() const
*/
/*!
- \fn const QPointF &QTabletEvent::hiResGlobalPos() const
-
- The high precision coordinates delivered from the tablet expressed.
- Sub pixeling information is in the fractional part of the QPointF.
-
- \sa globalPos(), hiResGlobalX(), hiResGlobalY()
-*/
-
-/*!
\fn qreal &QTabletEvent::hiResGlobalX() const
The high precision x position of the tablet device.
@@ -2674,10 +2652,10 @@ Qt::MouseButtons QTabletEvent::buttons() const
\sa Qt::NativeGestureType, QGestureEvent
*/
+#if QT_DEPRECATED_SINCE(5, 10)
/*!
\deprecated The QTouchDevice parameter is now required
*/
-#if QT_DEPRECATED_SINCE(5, 10)
QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos,
const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue)
: QInputEvent(QEvent::NativeGesture), mGestureType(type),
@@ -4290,18 +4268,6 @@ QWindowStateChangeEvent::~QWindowStateChangeEvent()
QGraphicsItem::acceptTouchEvents()
*/
-/*! \enum QTouchEvent::DeviceType
- \obsolete
-
- This enum represents the type of device that generated a QTouchEvent.
-
- This enum has been deprecated. Use QTouchDevice::DeviceType instead.
- \omitvalue TouchPad
- \omitvalue TouchScreen
-
- \sa QTouchDevice::DeviceType, QTouchDevice::type(), QTouchEvent::device()
-*/
-
/*!
Constructs a QTouchEvent with the given \a eventType, \a device, and
\a touchPoints. The \a touchPointStates and \a modifiers
@@ -4341,16 +4307,6 @@ QTouchEvent::~QTouchEvent()
This is typically a QWidget or a QQuickItem. May be 0 when no specific target is available.
*/
-/*! \fn QTouchEvent::DeviceType QTouchEvent::deviceType() const
- \obsolete
-
- Returns the touch device Type, which is of type \l {QTouchEvent::DeviceType} {DeviceType}.
-
- This function has been deprecated. Use QTouchDevice::type() instead.
-
- \sa QTouchDevice::type(), QTouchEvent::device()
-*/
-
/*! \fn QTouchEvent::TouchPoint::TouchPoint(TouchPoint &&other)
Move-constructs a TouchPoint instance, making it point to the same
diff --git a/src/gui/opengl/qopengltextureuploader.cpp b/src/gui/opengl/qopengltextureuploader.cpp
index d9d5403cf3..9e393bc47a 100644
--- a/src/gui/opengl/qopengltextureuploader.cpp
+++ b/src/gui/opengl/qopengltextureuploader.cpp
@@ -65,6 +65,10 @@
#define GL_RGBA16 0x805B
#endif
+#ifndef GL_BGR
+#define GL_BGR 0x80E0
+#endif
+
#ifndef GL_BGRA
#define GL_BGRA 0x80E1
#endif
@@ -202,6 +206,20 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag
pixelType = GL_UNSIGNED_BYTE;
targetFormat = QImage::Format_RGB888;
break;
+ case QImage::Format_BGR888:
+ if (isOpenGL12orBetter) {
+ externalFormat = GL_BGR;
+ internalFormat = GL_RGB;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = QImage::Format_BGR888;
+ } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) {
+ funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
+ funcs->glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
+ externalFormat = internalFormat = GL_RGB;
+ pixelType = GL_UNSIGNED_BYTE;
+ targetFormat = QImage::Format_BGR888;
+ }
+ break;
case QImage::Format_RGBX8888:
case QImage::Format_RGBA8888:
case QImage::Format_RGBA8888_Premultiplied:
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 972cf387ff..fcf6488edd 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -135,23 +135,41 @@ gcc:equals(QT_GCC_MAJOR_VERSION, 5) {
NO_PCH_SOURCES += painting/qdrawhelper.cpp
}
-SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
-SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
-SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \
- painting/qimagescale_sse4.cpp
-ARCH_HASWELL_SOURCES += painting/qdrawhelper_avx2.cpp
+!android {
+ SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
+ SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
+ SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \
+ painting/qimagescale_sse4.cpp
+ ARCH_HASWELL_SOURCES += painting/qdrawhelper_avx2.cpp
-NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
-NEON_HEADERS += painting/qdrawhelper_neon_p.h
+ NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
+ NEON_HEADERS += painting/qdrawhelper_neon_p.h
+}
!uikit:!win32:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as
-!uikit:!win32:!integrity:!contains(QT_ARCH, "arm64") {
+!android:!uikit:!win32:!integrity:!contains(QT_ARCH, "arm64") {
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
DEFINES += ENABLE_PIXMAN_DRAWHELPERS
}
-MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
-MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h
-MIPS_DSP_ASM += painting/qdrawhelper_mips_dsp_asm.S
-MIPS_DSPR2_ASM += painting/qdrawhelper_mips_dspr2_asm.S
+!android {
+ MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
+ MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h
+ MIPS_DSP_ASM += painting/qdrawhelper_mips_dsp_asm.S
+ MIPS_DSPR2_ASM += painting/qdrawhelper_mips_dspr2_asm.S
+} else {
+ # see https://developer.android.com/ndk/guides/abis
+ x86 | x86_64 {
+ DEFINES += QT_COMPILER_SUPPORTS_SSE2 QT_COMPILER_SUPPORTS_SSE3 QT_COMPILER_SUPPORTS_SSSE3
+ SOURCES += painting/qdrawhelper_sse2.cpp painting/qdrawhelper_ssse3.cpp
+ }
+ x86_64 {
+ DEFINES += QT_COMPILER_SUPPORTS_SSE4_1 QT_COMPILER_SUPPORTS_SSE4_2
+ SOURCES += painting/qdrawhelper_sse4.cpp painting/qimagescale_sse4.cpp
+ }
+ arm64-v8a {
+ SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
+ HEADERS += painting/qdrawhelper_neon_p.h
+ }
+}
include($$PWD/../../3rdparty/zlib_dependency.pri)
diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp
index daf19fffe1..9861fffff3 100644
--- a/src/gui/painting/qbezier.cpp
+++ b/src/gui/painting/qbezier.cpp
@@ -47,6 +47,8 @@
#include <private/qnumeric_p.h>
+#include <tuple> // for std::tie()
+
QT_BEGIN_NAMESPACE
//#define QDEBUG_BEZIER
@@ -128,7 +130,7 @@ void QBezier::addToPolygon(QPolygonF *polygon, qreal bezier_flattening_threshold
--lvl;
} else {
// split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
+ std::tie(b[1], b[0]) = b->split();
lvl[1] = --lvl[0];
++b;
++lvl;
@@ -166,7 +168,7 @@ void QBezier::addToPolygon(QDataBuffer<QPointF> &polygon, qreal bezier_flattenin
--lvl;
} else {
// split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
+ std::tie(b[1], b[0]) = b->split();
lvl[1] = --lvl[0];
++b;
++lvl;
@@ -422,7 +424,7 @@ redo:
o += 2;
--b;
} else {
- b->split(b+1, b);
+ std::tie(b[1], b[0]) = b->split();
++b;
}
}
@@ -464,8 +466,6 @@ qreal QBezier::length(qreal error) const
void QBezier::addIfClose(qreal *length, qreal error) const
{
- QBezier left, right; /* bez poly splits */
-
qreal len = qreal(0.0); /* arc length */
qreal chord; /* chord length */
@@ -476,9 +476,9 @@ void QBezier::addIfClose(qreal *length, qreal error) const
chord = QLineF(QPointF(x1, y1),QPointF(x4, y4)).length();
if((len-chord) > error) {
- split(&left, &right); /* split in two */
- left.addIfClose(length, error); /* try left side */
- right.addIfClose(length, error); /* try right side */
+ const auto halves = split(); /* split in two */
+ halves.first.addIfClose(length, error); /* try left side */
+ halves.second.addIfClose(length, error); /* try right side */
return;
}
diff --git a/src/gui/painting/qbezier_p.h b/src/gui/painting/qbezier_p.h
index f88e3b35b3..1c49f82416 100644
--- a/src/gui/painting/qbezier_p.h
+++ b/src/gui/painting/qbezier_p.h
@@ -107,7 +107,7 @@ public:
inline QLineF endTangent() const;
inline void parameterSplitLeft(qreal t, QBezier *left);
- inline void split(QBezier *firstHalf, QBezier *secondHalf) const;
+ inline std::pair<QBezier, QBezier> split() const;
int shifted(QBezier *curveSegments, int maxSegmets,
qreal offset, float threshold) const;
@@ -223,28 +223,21 @@ inline QPointF QBezier::secondDerivedAt(qreal t) const
a * y1 + b * y2 + c * y3 + d * y4);
}
-inline void QBezier::split(QBezier *firstHalf, QBezier *secondHalf) const
+std::pair<QBezier, QBezier> QBezier::split() const
{
- Q_ASSERT(firstHalf);
- Q_ASSERT(secondHalf);
-
- qreal c = (x2 + x3)*.5;
- firstHalf->x2 = (x1 + x2)*.5;
- secondHalf->x3 = (x3 + x4)*.5;
- firstHalf->x1 = x1;
- secondHalf->x4 = x4;
- firstHalf->x3 = (firstHalf->x2 + c)*.5;
- secondHalf->x2 = (secondHalf->x3 + c)*.5;
- firstHalf->x4 = secondHalf->x1 = (firstHalf->x3 + secondHalf->x2)*.5;
-
- c = (y2 + y3)/2;
- firstHalf->y2 = (y1 + y2)*.5;
- secondHalf->y3 = (y3 + y4)*.5;
- firstHalf->y1 = y1;
- secondHalf->y4 = y4;
- firstHalf->y3 = (firstHalf->y2 + c)*.5;
- secondHalf->y2 = (secondHalf->y3 + c)*.5;
- firstHalf->y4 = secondHalf->y1 = (firstHalf->y3 + secondHalf->y2)*.5;
+ const auto mid = [](QPointF lhs, QPointF rhs) { return (lhs + rhs) * .5; };
+
+ const QPointF mid_12 = mid(pt1(), pt2());
+ const QPointF mid_23 = mid(pt2(), pt3());
+ const QPointF mid_34 = mid(pt3(), pt4());
+ const QPointF mid_12_23 = mid(mid_12, mid_23);
+ const QPointF mid_23_34 = mid(mid_23, mid_34);
+ const QPointF mid_12_23__23_34 = mid(mid_12_23, mid_23_34);
+
+ return {
+ fromPoints(pt1(), mid_12, mid_12_23, mid_12_23__23_34),
+ fromPoints(mid_12_23__23_34, mid_23_34, mid_34, pt4()),
+ };
}
inline void QBezier::parameterSplitLeft(qreal t, QBezier *left)
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 6cbc30e79a..8780cce223 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -147,6 +147,7 @@ static bool get_hex_rgb(const QChar *str, size_t len, QRgba64 *rgb)
#endif
#define rgb(r,g,b) (0xff000000 | (r << 16) | (g << 8) | b)
+// keep this is in sync with QColorConstants
static const struct RGBData {
const char name[21];
uint value;
@@ -475,25 +476,35 @@ static QStringList get_colornames()
\section1 Predefined Colors
- There are 20 predefined QColors described by the Qt::GlobalColor enum,
- including black, white, primary and secondary colors, darker versions
- of these colors and three shades of gray. QColor also recognizes a
- variety of color names; the static colorNames() function returns a
- QStringList color names that QColor knows about.
+ There are 20 predefined QColor objects in the \c{QColorConstants}
+ namespace, including black, white, primary and secondary colors,
+ darker versions of these colors, and three shades of gray.
+ Furthermore, the \c{QColorConstants::Svg} namespace defines QColor
+ objects for the standard \l{https://www.w3.org/TR/SVG11/types.html#ColorKeywords}{SVG color keyword names}.
\image qt-colors.png Qt Colors
- Additionally, the Qt::color0, Qt::color1 and Qt::transparent colors
- are used for special purposes.
+ The \c{QColorConstants::Color0}, \c{QColorConstants::Color1} and
+ \c{QColorConstants::Transparent} colors are used for special
+ purposes.
- Qt::color0 (zero pixel value) and Qt::color1 (non-zero pixel value)
- are special colors for drawing in QBitmaps. Painting with Qt::color0
- sets the bitmap bits to 0 (transparent; i.e., background), and painting
- with Qt::color1 sets the bits to 1 (opaque; i.e., foreground).
+ \c{QColorConstants::Color0} (zero pixel value) and
+ \c{QColorConstants::Color1} (non-zero pixel value) are special
+ colors for drawing in QBitmaps. Painting with
+ \c{QColorConstants::Color0} sets the bitmap bits to 0 (transparent;
+ i.e., background), and painting with c{QColorConstants::Color1}
+ sets the bits to 1 (opaque; i.e., foreground).
- Qt::transparent is used to indicate a transparent pixel. When painting
- with this value, a pixel value will be used that is appropriate for the
- underlying pixel format in use.
+ \c{QColorConstants::Transparent} is used to indicate a transparent
+ pixel. When painting with this value, a pixel value will be used
+ that is appropriate for the underlying pixel format in use.
+
+ For historical reasons, the 20 predefined colors are also available
+ in the Qt::GlobalColor enumeration.
+
+ Finally, QColor recognizes a variety of color names (as strings);
+ the static colorNames() function returns a QStringList color names
+ that QColor knows about.
\section1 The Extended RGB Color Model
@@ -586,7 +597,7 @@ static QStringList get_colornames()
alpha-channel to feature \l {QColor#Alpha-Blended
Drawing}{alpha-blended drawing}.
- \sa QPalette, QBrush
+ \sa QPalette, QBrush, QColorConstants
*/
#define QCOLOR_INT_RANGE_CHECK(fn, var) \
@@ -886,7 +897,8 @@ QString QColor::name(NameFormat format) const
\li #AARRGGBB (Since 5.2)
\li #RRRGGGBBB
\li #RRRRGGGGBBBB
- \li A name from the list of colors defined in the list of \l{http://www.w3.org/TR/SVG/types.html#ColorKeywords}{SVG color keyword names}
+ \li A name from the list of colors defined in the list of
+ \l{https://www.w3.org/TR/SVG11/types.html#ColorKeywords}{SVG color keyword names}
provided by the World Wide Web Consortium; for example, "steelblue" or "gainsboro".
These color names work on all platforms. Note that these color names are \e not the
same as defined by the Qt::GlobalColor enums, e.g. "green" and Qt::green does not
@@ -3249,4 +3261,41 @@ const uint qt_inv_premul_factor[256] = {
\sa QColor::rgb(), QColor::rgba()
*/
+/*!
+ \namespace QColorConstants
+ \inmodule QtGui
+
+ \brief The QColorConstants namespace contains QColor predefined constants.
+
+ These constants are usable everywhere a QColor object is expected:
+
+ \code
+ painter.setBrush(QColorConstants::Svg::lightblue);
+ \endcode
+
+ Their usage is much cheaper than e.g. passing a string to QColor's constructor,
+ as they don't require any parsing of the string, and always result in a valid
+ QColor object:
+
+ \badcode
+ object.setColor(QColor("lightblue")); // expensive
+ \endcode
+
+ \section1 Qt Colors
+
+ The following colors are defined in the \c{QColorConstants} namespace:
+
+ \include qt-colors.qdocinc
+
+ \section1 SVG Colors
+
+ The following table lists the available
+ \l {http://www.w3.org/TR/SVG/types.html#ColorKeywords}{SVG colors}.
+ They are available in the \c{QColorConstants::Svg} inner namespace.
+
+ \include svg-colors.qdocinc
+
+ \sa QColor, Qt::GlobalColor
+*/
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h
index 723b9fce73..f0d7dd23ad 100644
--- a/src/gui/painting/qcolor.h
+++ b/src/gui/painting/qcolor.h
@@ -309,6 +309,12 @@ private:
friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QColor &);
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QColor &);
#endif
+
+#ifdef Q_COMPILER_UNIFORM_INIT
+public: // can't give friendship to a namespace, so it needs to be public
+ Q_DECL_CONSTEXPR explicit QColor(Spec spec, ushort a1, ushort a2, ushort a3, ushort a4, ushort a5=0) noexcept
+ : cspec(spec), ct(a1, a2, a3, a4, a5) {}
+#endif // Q_COMPILER_UNIFORM_INIT
};
Q_DECLARE_TYPEINFO(QColor, QT_VERSION >= QT_VERSION_CHECK(6,0,0) ? Q_MOVABLE_TYPE : Q_RELOCATABLE_TYPE);
@@ -326,6 +332,187 @@ inline QColor::QColor(const QString& aname)
inline bool QColor::isValid() const noexcept
{ return cspec != Invalid; }
+// define these namespaces even if the contents are ifdef'd out
+namespace QColorConstants
+{
+namespace Svg {}
+
+#if defined(Q_COMPILER_CONSTEXPR) & defined(Q_COMPILER_UNIFORM_INIT)
+ // Qt::GlobalColor names
+ constexpr Q_DECL_UNUSED QColor Color0 {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor Color1 {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xff * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor Black {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor White {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xff * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor DarkGray {QColor::Rgb, 0xff * 0x101, 0x80 * 0x101, 0x80 * 0x101, 0x80 * 0x101};
+ constexpr Q_DECL_UNUSED QColor Gray {QColor::Rgb, 0xff * 0x101, 0xa0 * 0x101, 0xa0 * 0x101, 0xa4 * 0x101};
+ constexpr Q_DECL_UNUSED QColor LightGray {QColor::Rgb, 0xff * 0x101, 0xc0 * 0x101, 0xc0 * 0x101, 0xc0 * 0x101};
+ constexpr Q_DECL_UNUSED QColor Red {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor Green {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0xff * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor Blue {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor Cyan {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0xff * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor Magenta {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x00 * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor Yellow {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xff * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor DarkRed {QColor::Rgb, 0xff * 0x101, 0x80 * 0x101, 0x00 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor DarkGreen {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x80 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor DarkBlue {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101, 0x80 * 0x101};
+ constexpr Q_DECL_UNUSED QColor DarkCyan {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x80 * 0x101, 0x80 * 0x101};
+ constexpr Q_DECL_UNUSED QColor DarkMagenta {QColor::Rgb, 0xff * 0x101, 0x80 * 0x101, 0x00 * 0x101, 0x80 * 0x101};
+ constexpr Q_DECL_UNUSED QColor DarkYellow {QColor::Rgb, 0xff * 0x101, 0x80 * 0x101, 0x80 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor Transparent {QColor::Rgb, 0x00 * 0x101, 0x00 * 0x101, 0x00 * 0x101, 0x00 * 0x101};
+
+ // SVG names supported by QColor (see qcolor.cpp).
+namespace Svg {
+ constexpr Q_DECL_UNUSED QColor aliceblue {QColor::Rgb, 0xff * 0x101, 0xf0 * 0x101, 0xf8 * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor antiquewhite {QColor::Rgb, 0xff * 0x101, 0xfa * 0x101, 0xeb * 0x101, 0xd7 * 0x101};
+ constexpr Q_DECL_UNUSED QColor aqua {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0xff * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor aquamarine {QColor::Rgb, 0xff * 0x101, 0x7f * 0x101, 0xff * 0x101, 0xd4 * 0x101};
+ constexpr Q_DECL_UNUSED QColor azure {QColor::Rgb, 0xff * 0x101, 0xf0 * 0x101, 0xff * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor beige {QColor::Rgb, 0xff * 0x101, 0xf5 * 0x101, 0xf5 * 0x101, 0xdc * 0x101};
+ constexpr Q_DECL_UNUSED QColor bisque {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xe4 * 0x101, 0xc4 * 0x101};
+ constexpr Q_DECL_UNUSED QColor black {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor blanchedalmond {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xeb * 0x101, 0xcd * 0x101};
+ constexpr Q_DECL_UNUSED QColor blue {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor blueviolet {QColor::Rgb, 0xff * 0x101, 0x8a * 0x101, 0x2b * 0x101, 0xe2 * 0x101};
+ constexpr Q_DECL_UNUSED QColor brown {QColor::Rgb, 0xff * 0x101, 0xa5 * 0x101, 0x2a * 0x101, 0x2a * 0x101};
+ constexpr Q_DECL_UNUSED QColor burlywood {QColor::Rgb, 0xff * 0x101, 0xde * 0x101, 0xb8 * 0x101, 0x87 * 0x101};
+ constexpr Q_DECL_UNUSED QColor cadetblue {QColor::Rgb, 0xff * 0x101, 0x5f * 0x101, 0x9e * 0x101, 0xa0 * 0x101};
+ constexpr Q_DECL_UNUSED QColor chartreuse {QColor::Rgb, 0xff * 0x101, 0x7f * 0x101, 0xff * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor chocolate {QColor::Rgb, 0xff * 0x101, 0xd2 * 0x101, 0x69 * 0x101, 0x1e * 0x101};
+ constexpr Q_DECL_UNUSED QColor coral {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x7f * 0x101, 0x50 * 0x101};
+ constexpr Q_DECL_UNUSED QColor cornflowerblue {QColor::Rgb, 0xff * 0x101, 0x64 * 0x101, 0x95 * 0x101, 0xed * 0x101};
+ constexpr Q_DECL_UNUSED QColor cornsilk {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xf8 * 0x101, 0xdc * 0x101};
+ constexpr Q_DECL_UNUSED QColor crimson {QColor::Rgb, 0xff * 0x101, 0xdc * 0x101, 0x14 * 0x101, 0x3c * 0x101};
+ constexpr Q_DECL_UNUSED QColor cyan {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0xff * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkblue {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101, 0x8b * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkcyan {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x8b * 0x101, 0x8b * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkgoldenrod {QColor::Rgb, 0xff * 0x101, 0xb8 * 0x101, 0x86 * 0x101, 0x0b * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkgray {QColor::Rgb, 0xff * 0x101, 0xa9 * 0x101, 0xa9 * 0x101, 0xa9 * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkgreen {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x64 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkgrey {QColor::Rgb, 0xff * 0x101, 0xa9 * 0x101, 0xa9 * 0x101, 0xa9 * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkkhaki {QColor::Rgb, 0xff * 0x101, 0xbd * 0x101, 0xb7 * 0x101, 0x6b * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkmagenta {QColor::Rgb, 0xff * 0x101, 0x8b * 0x101, 0x00 * 0x101, 0x8b * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkolivegreen {QColor::Rgb, 0xff * 0x101, 0x55 * 0x101, 0x6b * 0x101, 0x2f * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkorange {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x8c * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkorchid {QColor::Rgb, 0xff * 0x101, 0x99 * 0x101, 0x32 * 0x101, 0xcc * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkred {QColor::Rgb, 0xff * 0x101, 0x8b * 0x101, 0x00 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor darksalmon {QColor::Rgb, 0xff * 0x101, 0xe9 * 0x101, 0x96 * 0x101, 0x7a * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkseagreen {QColor::Rgb, 0xff * 0x101, 0x8f * 0x101, 0xbc * 0x101, 0x8f * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkslateblue {QColor::Rgb, 0xff * 0x101, 0x48 * 0x101, 0x3d * 0x101, 0x8b * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkslategray {QColor::Rgb, 0xff * 0x101, 0x2f * 0x101, 0x4f * 0x101, 0x4f * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkslategrey {QColor::Rgb, 0xff * 0x101, 0x2f * 0x101, 0x4f * 0x101, 0x4f * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkturquoise {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0xce * 0x101, 0xd1 * 0x101};
+ constexpr Q_DECL_UNUSED QColor darkviolet {QColor::Rgb, 0xff * 0x101, 0x94 * 0x101, 0x00 * 0x101, 0xd3 * 0x101};
+ constexpr Q_DECL_UNUSED QColor deeppink {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x14 * 0x101, 0x93 * 0x101};
+ constexpr Q_DECL_UNUSED QColor deepskyblue {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0xbf * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor dimgray {QColor::Rgb, 0xff * 0x101, 0x69 * 0x101, 0x69 * 0x101, 0x69 * 0x101};
+ constexpr Q_DECL_UNUSED QColor dimgrey {QColor::Rgb, 0xff * 0x101, 0x69 * 0x101, 0x69 * 0x101, 0x69 * 0x101};
+ constexpr Q_DECL_UNUSED QColor dodgerblue {QColor::Rgb, 0xff * 0x101, 0x1e * 0x101, 0x90 * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor firebrick {QColor::Rgb, 0xff * 0x101, 0xb2 * 0x101, 0x22 * 0x101, 0x22 * 0x101};
+ constexpr Q_DECL_UNUSED QColor floralwhite {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xfa * 0x101, 0xf0 * 0x101};
+ constexpr Q_DECL_UNUSED QColor forestgreen {QColor::Rgb, 0xff * 0x101, 0x22 * 0x101, 0x8b * 0x101, 0x22 * 0x101};
+ constexpr Q_DECL_UNUSED QColor fuchsia {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x00 * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor gainsboro {QColor::Rgb, 0xff * 0x101, 0xdc * 0x101, 0xdc * 0x101, 0xdc * 0x101};
+ constexpr Q_DECL_UNUSED QColor ghostwhite {QColor::Rgb, 0xff * 0x101, 0xf8 * 0x101, 0xf8 * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor gold {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xd7 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor goldenrod {QColor::Rgb, 0xff * 0x101, 0xda * 0x101, 0xa5 * 0x101, 0x20 * 0x101};
+ constexpr Q_DECL_UNUSED QColor gray {QColor::Rgb, 0xff * 0x101, 0x80 * 0x101, 0x80 * 0x101, 0x80 * 0x101};
+ constexpr Q_DECL_UNUSED QColor green {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x80 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor greenyellow {QColor::Rgb, 0xff * 0x101, 0xad * 0x101, 0xff * 0x101, 0x2f * 0x101};
+ constexpr Q_DECL_UNUSED QColor grey {QColor::Rgb, 0xff * 0x101, 0x80 * 0x101, 0x80 * 0x101, 0x80 * 0x101};
+ constexpr Q_DECL_UNUSED QColor honeydew {QColor::Rgb, 0xff * 0x101, 0xf0 * 0x101, 0xff * 0x101, 0xf0 * 0x101};
+ constexpr Q_DECL_UNUSED QColor hotpink {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x69 * 0x101, 0xb4 * 0x101};
+ constexpr Q_DECL_UNUSED QColor indianred {QColor::Rgb, 0xff * 0x101, 0xcd * 0x101, 0x5c * 0x101, 0x5c * 0x101};
+ constexpr Q_DECL_UNUSED QColor indigo {QColor::Rgb, 0xff * 0x101, 0x4b * 0x101, 0x00 * 0x101, 0x82 * 0x101};
+ constexpr Q_DECL_UNUSED QColor ivory {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xff * 0x101, 0xf0 * 0x101};
+ constexpr Q_DECL_UNUSED QColor khaki {QColor::Rgb, 0xff * 0x101, 0xf0 * 0x101, 0xe6 * 0x101, 0x8c * 0x101};
+ constexpr Q_DECL_UNUSED QColor lavender {QColor::Rgb, 0xff * 0x101, 0xe6 * 0x101, 0xe6 * 0x101, 0xfa * 0x101};
+ constexpr Q_DECL_UNUSED QColor lavenderblush {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xf0 * 0x101, 0xf5 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lawngreen {QColor::Rgb, 0xff * 0x101, 0x7c * 0x101, 0xfc * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lemonchiffon {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xfa * 0x101, 0xcd * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightblue {QColor::Rgb, 0xff * 0x101, 0xad * 0x101, 0xd8 * 0x101, 0xe6 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightcoral {QColor::Rgb, 0xff * 0x101, 0xf0 * 0x101, 0x80 * 0x101, 0x80 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightcyan {QColor::Rgb, 0xff * 0x101, 0xe0 * 0x101, 0xff * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightgoldenrodyellow {QColor::Rgb, 0xff * 0x101, 0xfa * 0x101, 0xfa * 0x101, 0xd2 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightgray {QColor::Rgb, 0xff * 0x101, 0xd3 * 0x101, 0xd3 * 0x101, 0xd3 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightgreen {QColor::Rgb, 0xff * 0x101, 0x90 * 0x101, 0xee * 0x101, 0x90 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightgrey {QColor::Rgb, 0xff * 0x101, 0xd3 * 0x101, 0xd3 * 0x101, 0xd3 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightpink {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xb6 * 0x101, 0xc1 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightsalmon {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xa0 * 0x101, 0x7a * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightseagreen {QColor::Rgb, 0xff * 0x101, 0x20 * 0x101, 0xb2 * 0x101, 0xaa * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightskyblue {QColor::Rgb, 0xff * 0x101, 0x87 * 0x101, 0xce * 0x101, 0xfa * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightslategray {QColor::Rgb, 0xff * 0x101, 0x77 * 0x101, 0x88 * 0x101, 0x99 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightslategrey {QColor::Rgb, 0xff * 0x101, 0x77 * 0x101, 0x88 * 0x101, 0x99 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightsteelblue {QColor::Rgb, 0xff * 0x101, 0xb0 * 0x101, 0xc4 * 0x101, 0xde * 0x101};
+ constexpr Q_DECL_UNUSED QColor lightyellow {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xff * 0x101, 0xe0 * 0x101};
+ constexpr Q_DECL_UNUSED QColor lime {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0xff * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor limegreen {QColor::Rgb, 0xff * 0x101, 0x32 * 0x101, 0xcd * 0x101, 0x32 * 0x101};
+ constexpr Q_DECL_UNUSED QColor linen {QColor::Rgb, 0xff * 0x101, 0xfa * 0x101, 0xf0 * 0x101, 0xe6 * 0x101};
+ constexpr Q_DECL_UNUSED QColor magenta {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x00 * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor maroon {QColor::Rgb, 0xff * 0x101, 0x80 * 0x101, 0x00 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor mediumaquamarine {QColor::Rgb, 0xff * 0x101, 0x66 * 0x101, 0xcd * 0x101, 0xaa * 0x101};
+ constexpr Q_DECL_UNUSED QColor mediumblue {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101, 0xcd * 0x101};
+ constexpr Q_DECL_UNUSED QColor mediumorchid {QColor::Rgb, 0xff * 0x101, 0xba * 0x101, 0x55 * 0x101, 0xd3 * 0x101};
+ constexpr Q_DECL_UNUSED QColor mediumpurple {QColor::Rgb, 0xff * 0x101, 0x93 * 0x101, 0x70 * 0x101, 0xdb * 0x101};
+ constexpr Q_DECL_UNUSED QColor mediumseagreen {QColor::Rgb, 0xff * 0x101, 0x3c * 0x101, 0xb3 * 0x101, 0x71 * 0x101};
+ constexpr Q_DECL_UNUSED QColor mediumslateblue {QColor::Rgb, 0xff * 0x101, 0x7b * 0x101, 0x68 * 0x101, 0xee * 0x101};
+ constexpr Q_DECL_UNUSED QColor mediumspringgreen {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0xfa * 0x101, 0x9a * 0x101};
+ constexpr Q_DECL_UNUSED QColor mediumturquoise {QColor::Rgb, 0xff * 0x101, 0x48 * 0x101, 0xd1 * 0x101, 0xcc * 0x101};
+ constexpr Q_DECL_UNUSED QColor mediumvioletred {QColor::Rgb, 0xff * 0x101, 0xc7 * 0x101, 0x15 * 0x101, 0x85 * 0x101};
+ constexpr Q_DECL_UNUSED QColor midnightblue {QColor::Rgb, 0xff * 0x101, 0x19 * 0x101, 0x19 * 0x101, 0x70 * 0x101};
+ constexpr Q_DECL_UNUSED QColor mintcream {QColor::Rgb, 0xff * 0x101, 0xf5 * 0x101, 0xff * 0x101, 0xfa * 0x101};
+ constexpr Q_DECL_UNUSED QColor mistyrose {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xe4 * 0x101, 0xe1 * 0x101};
+ constexpr Q_DECL_UNUSED QColor moccasin {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xe4 * 0x101, 0xb5 * 0x101};
+ constexpr Q_DECL_UNUSED QColor navajowhite {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xde * 0x101, 0xad * 0x101};
+ constexpr Q_DECL_UNUSED QColor navy {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101, 0x80 * 0x101};
+ constexpr Q_DECL_UNUSED QColor oldlace {QColor::Rgb, 0xff * 0x101, 0xfd * 0x101, 0xf5 * 0x101, 0xe6 * 0x101};
+ constexpr Q_DECL_UNUSED QColor olive {QColor::Rgb, 0xff * 0x101, 0x80 * 0x101, 0x80 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor olivedrab {QColor::Rgb, 0xff * 0x101, 0x6b * 0x101, 0x8e * 0x101, 0x23 * 0x101};
+ constexpr Q_DECL_UNUSED QColor orange {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xa5 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor orangered {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x45 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor orchid {QColor::Rgb, 0xff * 0x101, 0xda * 0x101, 0x70 * 0x101, 0xd6 * 0x101};
+ constexpr Q_DECL_UNUSED QColor palegoldenrod {QColor::Rgb, 0xff * 0x101, 0xee * 0x101, 0xe8 * 0x101, 0xaa * 0x101};
+ constexpr Q_DECL_UNUSED QColor palegreen {QColor::Rgb, 0xff * 0x101, 0x98 * 0x101, 0xfb * 0x101, 0x98 * 0x101};
+ constexpr Q_DECL_UNUSED QColor paleturquoise {QColor::Rgb, 0xff * 0x101, 0xaf * 0x101, 0xee * 0x101, 0xee * 0x101};
+ constexpr Q_DECL_UNUSED QColor palevioletred {QColor::Rgb, 0xff * 0x101, 0xdb * 0x101, 0x70 * 0x101, 0x93 * 0x101};
+ constexpr Q_DECL_UNUSED QColor papayawhip {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xef * 0x101, 0xd5 * 0x101};
+ constexpr Q_DECL_UNUSED QColor peachpuff {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xda * 0x101, 0xb9 * 0x101};
+ constexpr Q_DECL_UNUSED QColor peru {QColor::Rgb, 0xff * 0x101, 0xcd * 0x101, 0x85 * 0x101, 0x3f * 0x101};
+ constexpr Q_DECL_UNUSED QColor pink {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xc0 * 0x101, 0xcb * 0x101};
+ constexpr Q_DECL_UNUSED QColor plum {QColor::Rgb, 0xff * 0x101, 0xdd * 0x101, 0xa0 * 0x101, 0xdd * 0x101};
+ constexpr Q_DECL_UNUSED QColor powderblue {QColor::Rgb, 0xff * 0x101, 0xb0 * 0x101, 0xe0 * 0x101, 0xe6 * 0x101};
+ constexpr Q_DECL_UNUSED QColor purple {QColor::Rgb, 0xff * 0x101, 0x80 * 0x101, 0x00 * 0x101, 0x80 * 0x101};
+ constexpr Q_DECL_UNUSED QColor red {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x00 * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor rosybrown {QColor::Rgb, 0xff * 0x101, 0xbc * 0x101, 0x8f * 0x101, 0x8f * 0x101};
+ constexpr Q_DECL_UNUSED QColor royalblue {QColor::Rgb, 0xff * 0x101, 0x41 * 0x101, 0x69 * 0x101, 0xe1 * 0x101};
+ constexpr Q_DECL_UNUSED QColor saddlebrown {QColor::Rgb, 0xff * 0x101, 0x8b * 0x101, 0x45 * 0x101, 0x13 * 0x101};
+ constexpr Q_DECL_UNUSED QColor salmon {QColor::Rgb, 0xff * 0x101, 0xfa * 0x101, 0x80 * 0x101, 0x72 * 0x101};
+ constexpr Q_DECL_UNUSED QColor sandybrown {QColor::Rgb, 0xff * 0x101, 0xf4 * 0x101, 0xa4 * 0x101, 0x60 * 0x101};
+ constexpr Q_DECL_UNUSED QColor seagreen {QColor::Rgb, 0xff * 0x101, 0x2e * 0x101, 0x8b * 0x101, 0x57 * 0x101};
+ constexpr Q_DECL_UNUSED QColor seashell {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xf5 * 0x101, 0xee * 0x101};
+ constexpr Q_DECL_UNUSED QColor sienna {QColor::Rgb, 0xff * 0x101, 0xa0 * 0x101, 0x52 * 0x101, 0x2d * 0x101};
+ constexpr Q_DECL_UNUSED QColor silver {QColor::Rgb, 0xff * 0x101, 0xc0 * 0x101, 0xc0 * 0x101, 0xc0 * 0x101};
+ constexpr Q_DECL_UNUSED QColor skyblue {QColor::Rgb, 0xff * 0x101, 0x87 * 0x101, 0xce * 0x101, 0xeb * 0x101};
+ constexpr Q_DECL_UNUSED QColor slateblue {QColor::Rgb, 0xff * 0x101, 0x6a * 0x101, 0x5a * 0x101, 0xcd * 0x101};
+ constexpr Q_DECL_UNUSED QColor slategray {QColor::Rgb, 0xff * 0x101, 0x70 * 0x101, 0x80 * 0x101, 0x90 * 0x101};
+ constexpr Q_DECL_UNUSED QColor slategrey {QColor::Rgb, 0xff * 0x101, 0x70 * 0x101, 0x80 * 0x101, 0x90 * 0x101};
+ constexpr Q_DECL_UNUSED QColor snow {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xfa * 0x101, 0xfa * 0x101};
+ constexpr Q_DECL_UNUSED QColor springgreen {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0xff * 0x101, 0x7f * 0x101};
+ constexpr Q_DECL_UNUSED QColor steelblue {QColor::Rgb, 0xff * 0x101, 0x46 * 0x101, 0x82 * 0x101, 0xb4 * 0x101};
+ constexpr Q_DECL_UNUSED QColor tan {QColor::Rgb, 0xff * 0x101, 0xd2 * 0x101, 0xb4 * 0x101, 0x8c * 0x101};
+ constexpr Q_DECL_UNUSED QColor teal {QColor::Rgb, 0xff * 0x101, 0x00 * 0x101, 0x80 * 0x101, 0x80 * 0x101};
+ constexpr Q_DECL_UNUSED QColor thistle {QColor::Rgb, 0xff * 0x101, 0xd8 * 0x101, 0xbf * 0x101, 0xd8 * 0x101};
+ constexpr Q_DECL_UNUSED QColor tomato {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0x63 * 0x101, 0x47 * 0x101};
+ constexpr Q_DECL_UNUSED QColor turquoise {QColor::Rgb, 0xff * 0x101, 0x40 * 0x101, 0xe0 * 0x101, 0xd0 * 0x101};
+ constexpr Q_DECL_UNUSED QColor violet {QColor::Rgb, 0xff * 0x101, 0xee * 0x101, 0x82 * 0x101, 0xee * 0x101};
+ constexpr Q_DECL_UNUSED QColor wheat {QColor::Rgb, 0xff * 0x101, 0xf5 * 0x101, 0xde * 0x101, 0xb3 * 0x101};
+ constexpr Q_DECL_UNUSED QColor white {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xff * 0x101, 0xff * 0x101};
+ constexpr Q_DECL_UNUSED QColor whitesmoke {QColor::Rgb, 0xff * 0x101, 0xf5 * 0x101, 0xf5 * 0x101, 0xf5 * 0x101};
+ constexpr Q_DECL_UNUSED QColor yellow {QColor::Rgb, 0xff * 0x101, 0xff * 0x101, 0xff * 0x101, 0x00 * 0x101};
+ constexpr Q_DECL_UNUSED QColor yellowgreen {QColor::Rgb, 0xff * 0x101, 0x9a * 0x101, 0xcd * 0x101, 0x32 * 0x101};
+} // namespace Svg
+#endif // Q_COMPILER_CONSTEXPR && Q_COMPILER_UNIFORM_INIT
+} // namespace QColorLiterals
+
QT_END_NAMESPACE
#endif // QCOLOR_H
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 55d69221f5..c17bf2ddfd 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -88,6 +88,7 @@ template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB444>() { return 4; }
template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB555>() { return 5; }
template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB666>() { return 6; }
template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_BGR888>() { return 8; }
template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB8565_Premultiplied>() { return 5; }
@@ -101,6 +102,7 @@ template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB444>() { return 8;
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB555>() { return 10; }
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB666>() { return 12; }
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB888>() { return 16; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_BGR888>() { return 0; }
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB4444_Premultiplied>() { return 8; }
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB8555_Premultiplied>() { return 18; }
template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB8565_Premultiplied>() { return 19; }
@@ -119,6 +121,7 @@ template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB444>() { return 4;
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB555>() { return 5; }
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB666>() { return 6; }
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_BGR888>() { return 8; }
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB8565_Premultiplied>() { return 6; }
@@ -132,6 +135,7 @@ template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB444>() { return 4;
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB555>() { return 5; }
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB666>() { return 6; }
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_BGR888>() { return 8; }
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB8555_Premultiplied>() { return 13; }
template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB8565_Premultiplied>() { return 13; }
@@ -150,6 +154,7 @@ template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB444>() { return 4;
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB555>() { return 5; }
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB666>() { return 6; }
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_BGR888>() { return 8; }
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB8565_Premultiplied>() { return 5; }
@@ -163,6 +168,7 @@ template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB444>() { return 0;
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB555>() { return 0; }
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB666>() { return 0; }
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB888>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_BGR888>() { return 16; }
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB4444_Premultiplied>() { return 0; }
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB8555_Premultiplied>() { return 8; }
template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB8565_Premultiplied>() { return 8; }
@@ -181,6 +187,7 @@ template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB444>() { return 0;
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB555>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB666>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB888>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_BGR888>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB8555_Premultiplied>() { return 8; }
template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB8565_Premultiplied>() { return 8; }
@@ -194,6 +201,7 @@ template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB444>() { return 0;
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB555>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB666>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB888>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_BGR888>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB4444_Premultiplied>() { return 12; }
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB8555_Premultiplied>() { return 0; }
template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB8565_Premultiplied>() { return 0; }
@@ -214,6 +222,7 @@ template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB444>() { r
template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB555>() { return QPixelLayout::BPP16; }
template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB666>() { return QPixelLayout::BPP24; }
template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB888>() { return QPixelLayout::BPP24; }
+template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_BGR888>() { return QPixelLayout::BPP24; }
template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB4444_Premultiplied>() { return QPixelLayout::BPP16; }
template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8555_Premultiplied>() { return QPixelLayout::BPP24; }
template<> constexpr QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8565_Premultiplied>() { return QPixelLayout::BPP24; }
@@ -1528,7 +1537,8 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
{ false, false, QPixelLayout::BPP16, nullptr,
convertGrayscale16ToRGB32, convertGrayscale16ToRGBA64,
fetchGrayscale16ToRGB32, fetchGrayscale16ToRGBA64,
- storeGrayscale16FromARGB32PM, storeGrayscale16FromRGB32 } // Format_Grayscale16
+ storeGrayscale16FromARGB32PM, storeGrayscale16FromRGB32 }, // Format_Grayscale16
+ pixelLayoutRGB<QImage::Format_BGR888>(),
};
Q_STATIC_ASSERT(sizeof(qPixelLayouts) / sizeof(*qPixelLayouts) == QImage::NImageFormats);
@@ -1643,7 +1653,8 @@ ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats] = {
storeRGBX64FromRGBA64PM,
storeRGBA64FromRGBA64PM,
storeRGBA64PMFromRGBA64PM,
- storeGray16FromRGBA64PM
+ storeGray16FromRGBA64PM,
+ storeGenericFromRGBA64PM<QImage::Format_BGR888>,
};
/*
@@ -1732,6 +1743,7 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
destFetch, // Format_RGBA64
destFetch, // Format_RGBA64_Premultiplied
destFetch, // Format_Grayscale16
+ destFetch, // Format_BGR888
};
#if QT_CONFIG(raster_64bit)
@@ -1782,6 +1794,7 @@ static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
destFetch64, // Format_RGBA64
destFetchRGB64, // Format_RGBA64_Premultiplied
destFetch64, // Format_Grayscale16
+ destFetch64, // Format_BGR888
};
#endif
@@ -1922,6 +1935,7 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] =
destStore, // Format_RGBA64
destStore, // Format_RGBA64_Premultiplied
destStore, // Format_Grayscale16
+ destStore, // Format_BGR888
};
#if QT_CONFIG(raster_64bit)
@@ -1971,6 +1985,7 @@ static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
destStore64RGBA64, // Format_RGBA64
0, // Format_RGBA64_Premultiplied
destStore64, // Format_Grayscale16
+ destStore64, // Format_BGR888
};
#endif
@@ -3922,6 +3937,7 @@ static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = {
fetchUntransformed, // RGBA64
fetchUntransformed, // RGBA64_Premultiplied
fetchUntransformed, // Grayscale16
+ fetchUntransformed, // BGR888
};
static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = {
@@ -6589,6 +6605,14 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
qt_alphargbblit_generic,
qt_rectfill_quint16
},
+ // Format_BGR888
+ {
+ blend_color_generic,
+ 0,
+ qt_alphamapblit_generic,
+ qt_alphargbblit_generic,
+ qt_rectfill_quint24
+ },
};
#if !defined(__SSE2__)
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index b1d1f30800..1fb37ece56 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1855,10 +1855,9 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt,
}
// split curve and try again...
- QBezier first_half, second_half;
- bezier.split(&first_half, &second_half);
- qt_painterpath_isect_curve(first_half, pt, winding, depth + 1);
- qt_painterpath_isect_curve(second_half, pt, winding, depth + 1);
+ const auto halves = bezier.split();
+ qt_painterpath_isect_curve(halves.first, pt, winding, depth + 1);
+ qt_painterpath_isect_curve(halves.second, pt, winding, depth + 1);
}
}
@@ -2013,10 +2012,9 @@ static bool qt_isect_curve_horizontal(const QBezier &bezier, qreal y, qreal x1,
if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound))
return true;
- QBezier first_half, second_half;
- bezier.split(&first_half, &second_half);
- if (qt_isect_curve_horizontal(first_half, y, x1, x2, depth + 1)
- || qt_isect_curve_horizontal(second_half, y, x1, x2, depth + 1))
+ const auto halves = bezier.split();
+ if (qt_isect_curve_horizontal(halves.first, y, x1, x2, depth + 1)
+ || qt_isect_curve_horizontal(halves.second, y, x1, x2, depth + 1))
return true;
}
return false;
@@ -2032,10 +2030,9 @@ static bool qt_isect_curve_vertical(const QBezier &bezier, qreal x, qreal y1, qr
if (depth == 32 || (bounds.width() < lower_bound && bounds.height() < lower_bound))
return true;
- QBezier first_half, second_half;
- bezier.split(&first_half, &second_half);
- if (qt_isect_curve_vertical(first_half, x, y1, y2, depth + 1)
- || qt_isect_curve_vertical(second_half, x, y1, y2, depth + 1))
+ const auto halves = bezier.split();
+ if (qt_isect_curve_vertical(halves.first, x, y1, y2, depth + 1)
+ || qt_isect_curve_vertical(halves.second, x, y1, y2, depth + 1))
return true;
}
return false;
diff --git a/src/gui/platform/wasm/qwasmlocalfileaccess.cpp b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp
index 83f9415c69..85c894a74a 100644
--- a/src/gui/platform/wasm/qwasmlocalfileaccess.cpp
+++ b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp
@@ -164,6 +164,43 @@ void openFile(const std::string &accept,
openFiles(accept, FileSelectMode::SingleFile, fileDialogClosedWithInt, acceptFile, fileDataReady);
}
+void saveFile(const char *content, size_t size, const std::string &fileNameHint)
+{
+ // Save a file by creating programatically clicking a download
+ // link to an object url to a Blob containing the file content.
+ // File content is copied once, so that the passed in content
+ // buffer can be released as soon as this function returns - we
+ // don't know for how long the browser will retain the TypedArray
+ // view used to create the Blob.
+
+ emscripten::val document = emscripten::val::global("document");
+ emscripten::val window = emscripten::val::global("window");
+
+ emscripten::val fileContentView = emscripten::val(emscripten::typed_memory_view(size, content));
+ emscripten::val fileContentCopy = emscripten::val::global("ArrayBuffer").new_(size);
+ emscripten::val fileContentCopyView = emscripten::val::global("Uint8Array").new_(fileContentCopy);
+ fileContentCopyView.call<void>("set", fileContentView);
+
+ emscripten::val contentArray = emscripten::val::array();
+ contentArray.call<void>("push", fileContentCopyView);
+ emscripten::val type = emscripten::val::object();
+ type.set("type","application/octet-stream");
+ emscripten::val contentBlob = emscripten::val::global("Blob").new_(contentArray, type);
+
+ emscripten::val contentUrl = window["URL"].call<emscripten::val>("createObjectURL", contentBlob);
+ emscripten::val contentLink = document.call<emscripten::val>("createElement", std::string("a"));
+ contentLink.set("href", contentUrl);
+ contentLink.set("download", fileNameHint);
+ contentLink.set("style", "display:none");
+
+ emscripten::val body = document["body"];
+ body.call<void>("appendChild", contentLink);
+ contentLink.call<void>("click");
+ body.call<void>("removeChild", contentLink);
+
+ window["URL"].call<emscripten::val>("revokeObjectURL", contentUrl);
+}
+
} // namespace QWasmLocalFileAccess
QT_END_NAMESPACE
diff --git a/src/gui/platform/wasm/qwasmlocalfileaccess_p.h b/src/gui/platform/wasm/qwasmlocalfileaccess_p.h
index 794db8d9b2..ccd88570c8 100644
--- a/src/gui/platform/wasm/qwasmlocalfileaccess_p.h
+++ b/src/gui/platform/wasm/qwasmlocalfileaccess_p.h
@@ -71,6 +71,8 @@ void openFile(const std::string &accept,
const std::function<char *(uint64_t size, const std::string name)> &acceptFile,
const std::function<void()> &fileDataReady);
+void saveFile(const char *content, size_t size, const std::string &fileNameHint);
+
} // namespace QWasmLocalFileAccess
QT_END_NAMESPACE
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 45f1ca596e..ce7c7610c1 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -92,6 +92,7 @@ static const QCssKnownValue properties[NumProperties - 1] = {
{ "border-bottom-right-radius", BorderBottomRightRadius },
{ "border-bottom-style", BorderBottomStyle },
{ "border-bottom-width", BorderBottomWidth },
+ { "border-collapse", BorderCollapse },
{ "border-color", BorderColor },
{ "border-image", BorderImage },
{ "border-left", BorderLeft },
@@ -611,11 +612,7 @@ bool ValueExtractor::extractBorder(int *borders, QBrush *colors, BorderStyle *st
case BorderRightStyle: styles[RightEdge] = decl.styleValue(); break;
case BorderStyles: decl.styleValues(styles); break;
-#ifndef QT_OS_ANDROID_GCC_48_WORKAROUND
case BorderTopLeftRadius: radii[0] = sizeValue(decl); break;
-#else
- case BorderTopLeftRadius: new(radii)QSize(sizeValue(decl)); break;
-#endif
case BorderTopRightRadius: radii[1] = sizeValue(decl); break;
case BorderBottomLeftRadius: radii[2] = sizeValue(decl); break;
case BorderBottomRightRadius: radii[3] = sizeValue(decl); break;
@@ -1732,6 +1729,14 @@ void Declaration::borderImageValue(QString *image, int *cuts,
*h = *v;
}
+bool Declaration::borderCollapseValue() const
+{
+ if (d->values.count() != 1)
+ return false;
+ else
+ return d->values.at(0).toString() == QLatin1String("collapse");
+}
+
QIcon Declaration::iconValue() const
{
if (d->parsed.isValid())
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index ddc46803ae..ab85e76cf3 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -122,6 +122,7 @@ enum Property {
BorderRight,
BorderTop,
BorderBottom,
+ BorderCollapse,
Padding,
PaddingLeft,
PaddingRight,
@@ -478,6 +479,7 @@ struct Q_GUI_EXPORT Declaration
QIcon iconValue() const;
void borderImageValue(QString *image, int *cuts, TileMode *h, TileMode *v) const;
+ bool borderCollapseValue() const;
};
QT_CSS_DECLARE_TYPEINFO(Declaration, Q_MOVABLE_TYPE)
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 97e73f0723..3c1a052f37 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -180,14 +180,14 @@ Q_GUI_EXPORT int qt_defaultDpi()
}
QFontPrivate::QFontPrivate()
- : engineData(0), dpi(qt_defaultDpi()), screen(0),
+ : engineData(0), dpi(qt_defaultDpi()),
underline(false), overline(false), strikeOut(false), kerning(true),
capital(0), letterSpacingIsAbsolute(false), scFont(0)
{
}
QFontPrivate::QFontPrivate(const QFontPrivate &other)
- : request(other.request), engineData(0), dpi(other.dpi), screen(other.screen),
+ : request(other.request), engineData(0), dpi(other.dpi),
underline(other.underline), overline(other.overline),
strikeOut(other.strikeOut), kerning(other.kerning),
capital(other.capital), letterSpacingIsAbsolute(other.letterSpacingIsAbsolute),
@@ -581,11 +581,9 @@ QFont::QFont(const QFont &font, const QPaintDevice *pd)
{
Q_ASSERT(pd);
const int dpi = pd->logicalDpiY();
- const int screen = 0;
- if (font.d->dpi != dpi || font.d->screen != screen ) {
+ if (font.d->dpi != dpi) {
d = new QFontPrivate(*font.d);
d->dpi = dpi;
- d->screen = screen;
} else {
d = font.d;
}
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index 466e19e9cc..adbb7a0121 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -185,7 +185,6 @@ public:
QFontDef request;
mutable QFontEngineData *engineData;
int dpi;
- int screen;
uint underline : 1;
uint overline : 1;
@@ -230,19 +229,17 @@ public:
void clear();
struct Key {
- Key() : script(0), multi(0), screen(0) { }
- Key(const QFontDef &d, uchar c, bool m = 0, uchar s = 0)
- : def(d), script(c), multi(m), screen(s) { }
+ Key() : script(0), multi(0) { }
+ Key(const QFontDef &d, uchar c, bool m = 0)
+ : def(d), script(c), multi(m) { }
QFontDef def;
uchar script;
uchar multi: 1;
- uchar screen: 7;
inline bool operator<(const Key &other) const
{
if (script != other.script) return script < other.script;
- if (screen != other.screen) return screen < other.screen;
if (multi != other.multi) return multi < other.multi;
if (multi && def.fallBackFamilies.size() != other.def.fallBackFamilies.size())
return def.fallBackFamilies.size() < other.def.fallBackFamilies.size();
@@ -251,7 +248,6 @@ public:
inline bool operator==(const Key &other) const
{
return script == other.script
- && screen == other.screen
&& multi == other.multi
&& (!multi || def.fallBackFamilies == other.def.fallBackFamilies)
&& def == other.def;
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index c85dd4e1e3..d3e4f11e8c 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -185,11 +185,9 @@ QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice)
#endif
{
const int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
- const int screen = 0;
- if (font.d->dpi != dpi || font.d->screen != screen ) {
+ if (font.d->dpi != dpi) {
d = new QFontPrivate(*font.d);
d->dpi = dpi;
- d->screen = screen;
} else {
d = font.d;
}
@@ -1178,11 +1176,9 @@ QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice)
#endif
{
int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
- const int screen = 0;
- if (font.d->dpi != dpi || font.d->screen != screen ) {
+ if (font.d->dpi != dpi) {
d = new QFontPrivate(*font.d);
d->dpi = dpi;
- d->screen = screen;
} else {
d = font.d;
}
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index dc34a96918..c80617f929 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -2593,51 +2593,43 @@ void QTextHtmlExporter::emitFloatStyle(QTextFrameFormat::Position pos, StyleMode
html += QLatin1Char('\"');
}
-void QTextHtmlExporter::emitBorderStyle(QTextFrameFormat::BorderStyle style)
+static QLatin1String richtextBorderStyleToHtmlBorderStyle(QTextFrameFormat::BorderStyle style)
{
- Q_ASSERT(style <= QTextFrameFormat::BorderStyle_Outset);
-
- html += QLatin1String(" border-style:");
-
switch (style) {
case QTextFrameFormat::BorderStyle_None:
- html += QLatin1String("none");
- break;
+ return QLatin1String("none");
case QTextFrameFormat::BorderStyle_Dotted:
- html += QLatin1String("dotted");
- break;
+ return QLatin1String("dotted");
case QTextFrameFormat::BorderStyle_Dashed:
- html += QLatin1String("dashed");
- break;
+ return QLatin1String("dashed");
case QTextFrameFormat::BorderStyle_Solid:
- html += QLatin1String("solid");
- break;
+ return QLatin1String("solid");
case QTextFrameFormat::BorderStyle_Double:
- html += QLatin1String("double");
- break;
+ return QLatin1String("double");
case QTextFrameFormat::BorderStyle_DotDash:
- html += QLatin1String("dot-dash");
- break;
+ return QLatin1String("dot-dash");
case QTextFrameFormat::BorderStyle_DotDotDash:
- html += QLatin1String("dot-dot-dash");
- break;
+ return QLatin1String("dot-dot-dash");
case QTextFrameFormat::BorderStyle_Groove:
- html += QLatin1String("groove");
- break;
+ return QLatin1String("groove");
case QTextFrameFormat::BorderStyle_Ridge:
- html += QLatin1String("ridge");
- break;
+ return QLatin1String("ridge");
case QTextFrameFormat::BorderStyle_Inset:
- html += QLatin1String("inset");
- break;
+ return QLatin1String("inset");
case QTextFrameFormat::BorderStyle_Outset:
- html += QLatin1String("outset");
- break;
+ return QLatin1String("outset");
default:
- Q_ASSERT(false);
- break;
+ Q_UNREACHABLE();
};
+ return QLatin1String("");
+}
+
+void QTextHtmlExporter::emitBorderStyle(QTextFrameFormat::BorderStyle style)
+{
+ Q_ASSERT(style <= QTextFrameFormat::BorderStyle_Outset);
+ html += QLatin1String(" border-style:");
+ html += richtextBorderStyleToHtmlBorderStyle(style);
html += QLatin1Char(';');
}
@@ -3204,6 +3196,33 @@ void QTextHtmlExporter::emitTable(const QTextTable *table)
if (cellFormat.hasProperty(QTextFormat::TableCellBottomPadding))
styleString += QLatin1String(" padding-bottom:") + QString::number(cellFormat.bottomPadding()) + QLatin1Char(';');
+ if (cellFormat.hasProperty(QTextFormat::TableCellTopBorder))
+ styleString += QLatin1String(" border-top:") + QString::number(cellFormat.topBorder()) + QLatin1String("px;");
+ if (cellFormat.hasProperty(QTextFormat::TableCellRightBorder))
+ styleString += QLatin1String(" border-right:") + QString::number(cellFormat.rightBorder()) + QLatin1String("px;");
+ if (cellFormat.hasProperty(QTextFormat::TableCellBottomBorder))
+ styleString += QLatin1String(" border-bottom:") + QString::number(cellFormat.bottomBorder()) + QLatin1String("px;");
+ if (cellFormat.hasProperty(QTextFormat::TableCellLeftBorder))
+ styleString += QLatin1String(" border-left:") + QString::number(cellFormat.leftBorder()) + QLatin1String("px;");
+
+ if (cellFormat.hasProperty(QTextFormat::TableCellTopBorderBrush))
+ styleString += QLatin1String(" border-top-color:") + cellFormat.topBorderBrush().color().name() + QLatin1Char(';');
+ if (cellFormat.hasProperty(QTextFormat::TableCellRightBorderBrush))
+ styleString += QLatin1String(" border-right-color:") + cellFormat.rightBorderBrush().color().name() + QLatin1Char(';');
+ if (cellFormat.hasProperty(QTextFormat::TableCellBottomBorderBrush))
+ styleString += QLatin1String(" border-bottom-color:") + cellFormat.bottomBorderBrush().color().name() + QLatin1Char(';');
+ if (cellFormat.hasProperty(QTextFormat::TableCellLeftBorderBrush))
+ styleString += QLatin1String(" border-left-color:") + cellFormat.leftBorderBrush().color().name() + QLatin1Char(';');
+
+ if (cellFormat.hasProperty(QTextFormat::TableCellTopBorderStyle))
+ styleString += QLatin1String(" border-top-style:") + richtextBorderStyleToHtmlBorderStyle(cellFormat.topBorderStyle()) + QLatin1Char(';');
+ if (cellFormat.hasProperty(QTextFormat::TableCellRightBorderStyle))
+ styleString += QLatin1String(" border-right-style:") + richtextBorderStyleToHtmlBorderStyle(cellFormat.rightBorderStyle()) + QLatin1Char(';');
+ if (cellFormat.hasProperty(QTextFormat::TableCellBottomBorderStyle))
+ styleString += QLatin1String(" border-bottom-style:") + richtextBorderStyleToHtmlBorderStyle(cellFormat.bottomBorderStyle()) + QLatin1Char(';');
+ if (cellFormat.hasProperty(QTextFormat::TableCellLeftBorderStyle))
+ styleString += QLatin1String(" border-left-style:") + richtextBorderStyleToHtmlBorderStyle(cellFormat.leftBorderStyle()) + QLatin1Char(';');
+
if (!styleString.isEmpty())
html += QLatin1String(" style=\"") + styleString + QLatin1Char('\"');
@@ -3310,6 +3329,9 @@ void QTextHtmlExporter::emitFrameStyle(const QTextFrameFormat &format, FrameType
QString::number(format.leftMargin()),
QString::number(format.rightMargin()));
+ if (format.property(QTextFormat::TableBorderCollapse).toBool())
+ html += QLatin1String(" border-collapse:collapse;");
+
if (html.length() == originalHtmlLength) // nothing emitted?
html.chop(styleAttribute.size());
else
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index 34698b2fb0..723e5c907c 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -986,6 +986,7 @@ QTextHtmlImporter::Table QTextHtmlImporter::scanTable(int tableNodeIdx)
tableFmt.setColumns(table.columns);
tableFmt.setColumnWidthConstraints(columnWidths);
tableFmt.setHeaderRowCount(tableHeaderRowCount);
+ tableFmt.setBorderCollapse(node.borderCollapse);
fmt = tableFmt;
}
@@ -1061,6 +1062,31 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processBlockNode()
fmt.setLeftPadding(leftPadding(currentNodeIdx));
if (rightPadding(currentNodeIdx) >= 0)
fmt.setRightPadding(rightPadding(currentNodeIdx));
+ if (tableCellBorder(currentNodeIdx, QCss::TopEdge) > 0)
+ fmt.setTopBorder(tableCellBorder(currentNodeIdx, QCss::TopEdge));
+ if (tableCellBorder(currentNodeIdx, QCss::RightEdge) > 0)
+ fmt.setRightBorder(tableCellBorder(currentNodeIdx, QCss::RightEdge));
+ if (tableCellBorder(currentNodeIdx, QCss::BottomEdge) > 0)
+ fmt.setBottomBorder(tableCellBorder(currentNodeIdx, QCss::BottomEdge));
+ if (tableCellBorder(currentNodeIdx, QCss::LeftEdge) > 0)
+ fmt.setLeftBorder(tableCellBorder(currentNodeIdx, QCss::LeftEdge));
+ if (tableCellBorderStyle(currentNodeIdx, QCss::TopEdge) != QTextFrameFormat::BorderStyle_None)
+ fmt.setTopBorderStyle(tableCellBorderStyle(currentNodeIdx, QCss::TopEdge));
+ if (tableCellBorderStyle(currentNodeIdx, QCss::RightEdge) != QTextFrameFormat::BorderStyle_None)
+ fmt.setRightBorderStyle(tableCellBorderStyle(currentNodeIdx, QCss::RightEdge));
+ if (tableCellBorderStyle(currentNodeIdx, QCss::BottomEdge) != QTextFrameFormat::BorderStyle_None)
+ fmt.setBottomBorderStyle(tableCellBorderStyle(currentNodeIdx, QCss::BottomEdge));
+ if (tableCellBorderStyle(currentNodeIdx, QCss::LeftEdge) != QTextFrameFormat::BorderStyle_None)
+ fmt.setLeftBorderStyle(tableCellBorderStyle(currentNodeIdx, QCss::LeftEdge));
+ if (tableCellBorderBrush(currentNodeIdx, QCss::TopEdge) != Qt::NoBrush)
+ fmt.setTopBorderBrush(tableCellBorderBrush(currentNodeIdx, QCss::TopEdge));
+ if (tableCellBorderBrush(currentNodeIdx, QCss::RightEdge) != Qt::NoBrush)
+ fmt.setRightBorderBrush(tableCellBorderBrush(currentNodeIdx, QCss::RightEdge));
+ if (tableCellBorderBrush(currentNodeIdx, QCss::BottomEdge) != Qt::NoBrush)
+ fmt.setBottomBorderBrush(tableCellBorderBrush(currentNodeIdx, QCss::BottomEdge));
+ if (tableCellBorderBrush(currentNodeIdx, QCss::LeftEdge) != Qt::NoBrush)
+ fmt.setLeftBorderBrush(tableCellBorderBrush(currentNodeIdx, QCss::LeftEdge));
+
cell.setFormat(fmt);
cursor.setPosition(cell.firstPosition());
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 43b32e7e2c..5d37982a8b 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -491,12 +491,19 @@ QTextHtmlParserNode::QTextHtmlParserNode()
listStyle(QTextListFormat::ListStyleUndefined), imageWidth(-1), imageHeight(-1), tableBorder(0),
tableCellRowSpan(1), tableCellColSpan(1), tableCellSpacing(2), tableCellPadding(0),
borderBrush(Qt::darkGray), borderStyle(QTextFrameFormat::BorderStyle_Outset),
+ borderCollapse(false),
userState(-1), cssListIndent(0), wsm(WhiteSpaceModeUndefined)
{
margin[QTextHtmlParser::MarginLeft] = 0;
margin[QTextHtmlParser::MarginRight] = 0;
margin[QTextHtmlParser::MarginTop] = 0;
margin[QTextHtmlParser::MarginBottom] = 0;
+
+ for (int i = 0; i < 4; ++i) {
+ tableCellBorderStyle[i] = QTextFrameFormat::BorderStyle_None;
+ tableCellBorder[i] = 0;
+ tableCellBorderBrush[i] = Qt::NoBrush;
+ }
}
void QTextHtmlParser::dumpHtml()
@@ -1169,6 +1176,25 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
QCss::ValueExtractor extractor(declarations);
extractor.extractBox(margin, padding);
+ if (id == Html_td || id == Html_th) {
+ QCss::BorderStyle cssStyles[4];
+ int cssBorder[4];
+ QSize cssRadii[4]; // unused
+ for (int i = 0; i < 4; ++i) {
+ cssStyles[i] = QCss::BorderStyle_None;
+ cssBorder[i] = 0;
+ }
+ // this will parse (and cache) "border-width" as a list so the
+ // QCss::BorderWidth parsing below which expects a single value
+ // will not work as expected - which in this case does not matter
+ // because tableBorder is not relevant for cells.
+ extractor.extractBorder(cssBorder, tableCellBorderBrush, cssStyles, cssRadii);
+ for (int i = 0; i < 4; ++i) {
+ tableCellBorderStyle[i] = static_cast<QTextFrameFormat::BorderStyle>(cssStyles[i] - 1);
+ tableCellBorder[i] = static_cast<qreal>(cssBorder[i]);
+ }
+ }
+
for (int i = 0; i < declarations.count(); ++i) {
const QCss::Declaration &decl = declarations.at(i);
if (decl.d->values.isEmpty()) continue;
@@ -1186,6 +1212,9 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
case QCss::BorderWidth:
tableBorder = extractor.lengthValue(decl);
break;
+ case QCss::BorderCollapse:
+ borderCollapse = decl.borderCollapseValue();
+ break;
case QCss::Color: charFormat.setForeground(decl.colorValue()); break;
case QCss::Float:
cssFloat = QTextFrameFormat::InFlow;
@@ -1654,6 +1683,11 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
if (!c.isValid())
qWarning("QTextHtmlParser::applyAttributes: Unknown color name '%s'",value.toLatin1().constData());
node->charFormat.setBackground(c);
+ } else if (key == QLatin1String("bordercolor")) {
+ QColor c; c.setNamedColor(value);
+ if (!c.isValid())
+ qWarning("QTextHtmlParser::applyAttributes: Unknown color name '%s'",value.toLatin1().constData());
+ node->borderBrush = c;
} else if (key == QLatin1String("background")) {
node->applyBackgroundImage(value, resourceProvider);
} else if (key == QLatin1String("cellspacing")) {
diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h
index ff5f5b4c35..31f558709f 100644
--- a/src/gui/text/qtexthtmlparser_p.h
+++ b/src/gui/text/qtexthtmlparser_p.h
@@ -195,8 +195,12 @@ struct QTextHtmlParserNode {
int tableCellColSpan;
qreal tableCellSpacing;
qreal tableCellPadding;
+ qreal tableCellBorder[4];
+ QBrush tableCellBorderBrush[4];
+ QTextFrameFormat::BorderStyle tableCellBorderStyle[4];
QBrush borderBrush;
QTextFrameFormat::BorderStyle borderStyle;
+ bool borderCollapse;
int userState;
int cssListIndent;
@@ -290,6 +294,10 @@ public:
inline int leftPadding(int i) const { return at(i).padding[MarginLeft]; }
inline int rightPadding(int i) const { return at(i).padding[MarginRight]; }
+ inline qreal tableCellBorder(int i, int edge) const { return at(i).tableCellBorder[edge]; }
+ inline QTextFrameFormat::BorderStyle tableCellBorderStyle(int i, int edge) const { return at(i).tableCellBorderStyle[edge]; }
+ inline QBrush tableCellBorderBrush(int i, int edge) const { return at(i).tableCellBorderBrush[edge]; }
+
void dumpHtml();
void parse(const QString &text, const QTextDocument *resourceProvider);
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index 8a92308f12..cfb20dcd71 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -97,7 +97,8 @@ qtConfig(http) {
access/qhttpnetworkrequest.cpp \
access/qhttpprotocolhandler.cpp \
access/qhttpthreaddelegate.cpp \
- access/qnetworkreplyhttpimpl.cpp
+ access/qnetworkreplyhttpimpl.cpp \
+ access/qhttp2configuration.cpp
HEADERS += \
access/qabstractprotocolhandler_p.h \
@@ -111,7 +112,8 @@ qtConfig(http) {
access/qhttpnetworkrequest_p.h \
access/qhttpprotocolhandler_p.h \
access/qhttpthreaddelegate_p.h \
- access/qnetworkreplyhttpimpl_p.h
+ access/qnetworkreplyhttpimpl_p.h \
+ access/qhttp2configuration.h
qtConfig(ssl) {
SOURCES += \
diff --git a/src/network/access/http2/hpack.cpp b/src/network/access/http2/hpack.cpp
index 2d324d5092..b40cc29e1a 100644
--- a/src/network/access/http2/hpack.cpp
+++ b/src/network/access/http2/hpack.cpp
@@ -208,6 +208,11 @@ void Encoder::setMaxDynamicTableSize(quint32 size)
lookupTable.setMaxDynamicTableSize(size);
}
+void Encoder::setCompressStrings(bool compress)
+{
+ compressStrings = compress;
+}
+
bool Encoder::encodeRequestPseudoHeaders(BitOStream &outputStream,
const HttpHeader &header)
{
diff --git a/src/network/access/http2/hpack_p.h b/src/network/access/http2/hpack_p.h
index 6a1d30d87b..8c2701e7af 100644
--- a/src/network/access/http2/hpack_p.h
+++ b/src/network/access/http2/hpack_p.h
@@ -83,6 +83,7 @@ public:
quint32 newSize);
void setMaxDynamicTableSize(quint32 size);
+ void setCompressStrings(bool compress);
private:
bool encodeRequestPseudoHeaders(BitOStream &outputStream,
diff --git a/src/network/access/http2/http2frames.cpp b/src/network/access/http2/http2frames.cpp
index e695b4dd9e..ce33505683 100644
--- a/src/network/access/http2/http2frames.cpp
+++ b/src/network/access/http2/http2frames.cpp
@@ -305,7 +305,7 @@ FrameStatus FrameReader::read(QAbstractSocket &socket)
return status;
}
- if (Http2PredefinedParameters::maxFrameSize < frame.payloadSize())
+ if (Http2PredefinedParameters::maxPayloadSize < frame.payloadSize())
return FrameStatus::sizeError;
frame.buffer.resize(frame.payloadSize() + frameHeaderSize);
@@ -388,7 +388,7 @@ void FrameWriter::setPayloadSize(quint32 size)
auto &buffer = frame.buffer;
Q_ASSERT(buffer.size() >= frameHeaderSize);
- Q_ASSERT(size < maxPayloadSize);
+ Q_ASSERT(size <= maxPayloadSize);
buffer[0] = size >> 16;
buffer[1] = size >> 8;
diff --git a/src/network/access/http2/http2protocol.cpp b/src/network/access/http2/http2protocol.cpp
index 0be72042c6..31da6fd616 100644
--- a/src/network/access/http2/http2protocol.cpp
+++ b/src/network/access/http2/http2protocol.cpp
@@ -43,6 +43,8 @@
#include "private/qhttpnetworkrequest_p.h"
#include "private/qhttpnetworkreply_p.h"
+#include <access/qhttp2configuration.h>
+
#include <QtCore/qbytearray.h>
#include <QtCore/qstring.h>
@@ -62,88 +64,29 @@ const char Http2clientPreface[clientPrefaceLength] =
0x2e, 0x30, 0x0d, 0x0a, 0x0d, 0x0a,
0x53, 0x4d, 0x0d, 0x0a, 0x0d, 0x0a};
-// TODO: (in 5.11) - remove it!
-const char *http2ParametersPropertyName = "QT_HTTP2_PARAMETERS_PROPERTY";
-
-ProtocolParameters::ProtocolParameters()
-{
- settingsFrameData[Settings::INITIAL_WINDOW_SIZE_ID] = qtDefaultStreamReceiveWindowSize;
- settingsFrameData[Settings::ENABLE_PUSH_ID] = 0;
-}
-
-bool ProtocolParameters::validate() const
+Frame configurationToSettingsFrame(const QHttp2Configuration &config)
{
- // 0. Huffman/indexing: any values are valid and allowed.
-
- // 1. Session receive window size (client side): HTTP/2 starts from the
- // default value of 64Kb, if a client code tries to set lesser value,
- // the delta would become negative, but this is not allowed.
- if (maxSessionReceiveWindowSize < qint32(defaultSessionWindowSize)) {
- qCWarning(QT_HTTP2, "Session receive window must be at least 65535 bytes");
- return false;
- }
-
- // 2. HEADER_TABLE_SIZE: we do not validate HEADER_TABLE_SIZE, considering
- // all values as valid. RFC 7540 and 7541 do not provide any lower/upper
- // limits. If it's 0 - we do not index anything, if it's too huge - a user
- // who provided such a value can potentially have a huge memory footprint,
- // up to them to decide.
-
- // 3. SETTINGS_ENABLE_PUSH: RFC 7540, 6.5.2, a value other than 0 or 1 will
- // be treated by our peer as a PROTOCOL_ERROR.
- if (settingsFrameData.contains(Settings::ENABLE_PUSH_ID)
- && settingsFrameData[Settings::ENABLE_PUSH_ID] > 1) {
- qCWarning(QT_HTTP2, "SETTINGS_ENABLE_PUSH can be only 0 or 1");
- return false;
- }
-
- // 4. SETTINGS_MAX_CONCURRENT_STREAMS : RFC 7540 recommends 100 as the lower
- // limit, says nothing about the upper limit. The RFC allows 0, but this makes
- // no sense to us at all: there is no way a user can change this later and
- // we'll not be able to get any responses on such a connection.
- if (settingsFrameData.contains(Settings::MAX_CONCURRENT_STREAMS_ID)
- && !settingsFrameData[Settings::MAX_CONCURRENT_STREAMS_ID]) {
- qCWarning(QT_HTTP2, "MAX_CONCURRENT_STREAMS must be a positive number");
- return false;
- }
-
- // 5. SETTINGS_INITIAL_WINDOW_SIZE.
- if (settingsFrameData.contains(Settings::INITIAL_WINDOW_SIZE_ID)) {
- const quint32 value = settingsFrameData[Settings::INITIAL_WINDOW_SIZE_ID];
- // RFC 7540, 6.5.2 (the upper limit). The lower limit is our own - we send
- // SETTINGS frame only once and will not be able to change this 0, thus
- // we'll suspend all streams.
- if (!value || value > quint32(maxSessionReceiveWindowSize)) {
- qCWarning(QT_HTTP2, "INITIAL_WINDOW_SIZE must be in the range "
- "(0, 2^31-1]");
- return false;
- }
- }
-
- // 6. SETTINGS_MAX_FRAME_SIZE: RFC 7540, 6.5.2, a value outside of the range
- // [2^14-1, 2^24-1] will be treated by our peer as a PROTOCOL_ERROR.
- if (settingsFrameData.contains(Settings::MAX_FRAME_SIZE_ID)) {
- const quint32 value = settingsFrameData[Settings::INITIAL_WINDOW_SIZE_ID];
- if (value < maxFrameSize || value > maxPayloadSize) {
- qCWarning(QT_HTTP2, "MAX_FRAME_SIZE must be in the range [2^14, 2^24-1]");
- return false;
- }
+ // 6.5 SETTINGS
+ FrameWriter builder(FrameType::SETTINGS, FrameFlag::EMPTY, connectionStreamID);
+ // Server push:
+ builder.append(Settings::ENABLE_PUSH_ID);
+ builder.append(int(config.serverPushEnabled()));
+ // Stream receive window size:
+ builder.append(Settings::INITIAL_WINDOW_SIZE_ID);
+ builder.append(config.streamReceiveWindowSize());
+
+ if (config.maxFrameSize() != minPayloadLimit) {
+ builder.append(Settings::MAX_FRAME_SIZE_ID);
+ builder.append(config.maxFrameSize());
}
-
- // For SETTINGS_MAX_HEADER_LIST_SIZE RFC 7540 does not provide any specific
- // numbers. It's clear, if a value is too small, no header can ever be sent
- // by our peer at all. The default value is unlimited and we normally do not
- // change this.
- //
- // Note: the size is calculated as the length of uncompressed (no HPACK)
- // name + value + 32 bytes.
-
- return true;
+ // TODO: In future, if the need is proven, we can
+ // also send decoding table size and header list size.
+ // For now, defaults suffice.
+ return builder.outboundFrame();
}
-QByteArray ProtocolParameters::settingsFrameToBase64() const
+QByteArray settingsFrameToBase64(const Frame &frame)
{
- Frame frame(settingsFrame());
// SETTINGS frame's payload consists of pairs:
// 2-byte-identifier | 4-byte-value == multiple of 6.
Q_ASSERT(frame.payloadSize() && !(frame.payloadSize() % 6));
@@ -157,20 +100,7 @@ QByteArray ProtocolParameters::settingsFrameToBase64() const
return wrapper.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
}
-Frame ProtocolParameters::settingsFrame() const
-{
- // 6.5 SETTINGS
- FrameWriter builder(FrameType::SETTINGS, FrameFlag::EMPTY, connectionStreamID);
- for (auto it = settingsFrameData.cbegin(), end = settingsFrameData.cend();
- it != end; ++it) {
- builder.append(it.key());
- builder.append(it.value());
- }
-
- return builder.outboundFrame();
-}
-
-void ProtocolParameters::addProtocolUpgradeHeaders(QHttpNetworkRequest *request) const
+void appendProtocolUpgradeHeaders(const QHttp2Configuration &config, QHttpNetworkRequest *request)
{
Q_ASSERT(request);
// RFC 2616, 14.10
@@ -184,8 +114,10 @@ void ProtocolParameters::addProtocolUpgradeHeaders(QHttpNetworkRequest *request)
request->setHeaderField("Connection", value);
// This we just (re)write.
request->setHeaderField("Upgrade", "h2c");
+
+ const Frame frame(configurationToSettingsFrame(config));
// This we just (re)write.
- request->setHeaderField("HTTP2-Settings", settingsFrameToBase64());
+ request->setHeaderField("HTTP2-Settings", settingsFrameToBase64(frame));
}
void qt_error(quint32 errorCode, QNetworkReply::NetworkError &error,
diff --git a/src/network/access/http2/http2protocol_p.h b/src/network/access/http2/http2protocol_p.h
index 7142d6f1fa..b0af5aa919 100644
--- a/src/network/access/http2/http2protocol_p.h
+++ b/src/network/access/http2/http2protocol_p.h
@@ -55,12 +55,14 @@
#include <QtCore/qloggingcategory.h>
#include <QtCore/qmetatype.h>
#include <QtCore/qglobal.h>
+#include <QtCore/qmap.h>
// Different HTTP/2 constants/values as defined by RFC 7540.
QT_BEGIN_NAMESPACE
class QHttpNetworkRequest;
+class QHttp2Configuration;
class QHttpNetworkReply;
class QByteArray;
class QString;
@@ -118,13 +120,19 @@ enum Http2PredefinedParameters
connectionStreamID = 0, // HTTP/2, 5.1.1
frameHeaderSize = 9, // HTTP/2, 4.1
- // It's our max frame size we send in SETTINGS frame,
- // it's also the default one and we also use it to later
- // validate incoming frames:
- maxFrameSize = 16384, // HTTP/2 6.5.2
+ // The initial allowed payload size. We would use it as an
+ // upper limit for a frame payload we send, until our peer
+ // updates us with a larger SETTINGS_MAX_FRAME_SIZE.
- defaultSessionWindowSize = 65535, // HTTP/2 6.5.2
+ // The initial maximum payload size that an HTTP/2 frame
+ // can contain is 16384. It's also the minimal size that
+ // can be advertised via 'SETTINGS' frames. A real frame
+ // can have a payload smaller than 16384.
+ minPayloadLimit = 16384, // HTTP/2 6.5.2
+ // The maximum allowed payload size.
maxPayloadSize = (1 << 24) - 1, // HTTP/2 6.5.2
+
+ defaultSessionWindowSize = 65535, // HTTP/2 6.5.2
// Using 1000 (rather arbitrarily), just to
// impose *some* upper limit:
maxPeerConcurrentStreams = 1000,
@@ -145,48 +153,9 @@ const quint32 lastValidStreamID((quint32(1) << 31) - 1); // HTTP/2, 5.1.1
const qint32 maxSessionReceiveWindowSize((quint32(1) << 31) - 1);
const qint32 qtDefaultStreamReceiveWindowSize = maxSessionReceiveWindowSize / maxConcurrentStreams;
-// The class ProtocolParameters allows client code to customize HTTP/2 protocol
-// handler, if needed. Normally, we use our own default parameters (see below).
-// In 5.10 we can also use setProperty/property on a QNAM object to pass the
-// non-default values to the protocol handler. In 5.11 this will probably become
-// a public API.
-
-using RawSettings = QMap<Settings, quint32>;
-
-struct Q_AUTOTEST_EXPORT ProtocolParameters
-{
- ProtocolParameters();
-
- bool validate() const;
- QByteArray settingsFrameToBase64() const;
- struct Frame settingsFrame() const;
- void addProtocolUpgradeHeaders(QHttpNetworkRequest *request) const;
-
- // HPACK:
- // TODO: for now we ignore them (fix it for 5.11, would require changes in HPACK)
- bool useHuffman = true;
- bool indexStrings = true;
-
- // This parameter is not negotiated via SETTINGS frames, so we have it
- // as a member and will convey it to our peer as a WINDOW_UPDATE frame.
- // Note, some servers do not accept our WINDOW_UPDATE from the default
- // 64 KB to the possible maximum. Let's use a half of it:
- qint32 maxSessionReceiveWindowSize = Http2::maxSessionReceiveWindowSize / 2;
-
- // This is our default SETTINGS frame:
- //
- // SETTINGS_INITIAL_WINDOW_SIZE: (2^31 - 1) / 100
- // SETTINGS_ENABLE_PUSH: 0.
- //
- // Note, whenever we skip some value in our SETTINGS frame, our peer
- // will assume the defaults recommended by RFC 7540, which in general
- // are good enough, although we (and most browsers) prefer to work
- // with larger window sizes.
- RawSettings settingsFrameData;
-};
-
-// TODO: remove in 5.11
-extern const Q_AUTOTEST_EXPORT char *http2ParametersPropertyName;
+struct Frame configurationToSettingsFrame(const QHttp2Configuration &configuration);
+QByteArray settingsFrameToBase64(const Frame &settingsFrame);
+void appendProtocolUpgradeHeaders(const QHttp2Configuration &configuration, QHttpNetworkRequest *request);
extern const Q_AUTOTEST_EXPORT char Http2clientPreface[clientPrefaceLength];
@@ -235,6 +204,5 @@ Q_DECLARE_LOGGING_CATEGORY(QT_HTTP2)
QT_END_NAMESPACE
Q_DECLARE_METATYPE(Http2::Settings)
-Q_DECLARE_METATYPE(Http2::ProtocolParameters)
#endif
diff --git a/src/network/access/qhttp2configuration.cpp b/src/network/access/qhttp2configuration.cpp
new file mode 100644
index 0000000000..a32bccfd09
--- /dev/null
+++ b/src/network/access/qhttp2configuration.cpp
@@ -0,0 +1,312 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhttp2configuration.h"
+
+#include "private/http2protocol_p.h"
+#include "private/hpack_p.h"
+
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QHttp2Configuration
+ \brief The QHttp2Configuration class controls HTTP/2 parameters and settings
+ \since 5.14
+
+ \reentrant
+ \inmodule QtNetwork
+ \ingroup network
+ \ingroup shared
+
+ QHttp2Configuration controls HTTP/2 parameters and settings that
+ QNetworkAccessManager will use to send requests and process responses
+ when the HTTP/2 protocol is enabled.
+
+ The HTTP/2 parameters that QHttp2Configuration currently supports include:
+
+ \list
+ \li The session window size for connection-level flow control.
+ Will be sent to a remote peer when needed as 'WINDOW_UPDATE'
+ frames on the stream with an identifier 0.
+ \li The stream receiving window size for stream-level flow control.
+ Sent as 'SETTINGS_INITIAL_WINDOW_SIZE' parameter in the initial
+ SETTINGS frame and, when needed, 'WINDOW_UPDATE' frames will be
+ sent on streams that QNetworkAccessManager opens.
+ \li The maximum frame size. This parameter limits the maximum payload
+ a frame coming from the remote peer can have. Sent by QNetworkAccessManager
+ as 'SETTINGS_MAX_FRAME_SIZE' parameter in the initial 'SETTINGS'
+ frame.
+ \li The server push. Allows to enable or disable server push. Sent
+ as 'SETTINGS_ENABLE_PUSH' parameter in the initial 'SETTINGS'
+ frame.
+ \endlist
+
+ The QHttp2Configuration class also controls if the header compression
+ algorithm (HPACK) is additionally using Huffman coding for string
+ compression.
+
+ \note The configuration must be set before the first request
+ was sent to a given host (and thus an HTTP/2 session established).
+
+ \note Details about flow control, server push and 'SETTINGS'
+ can be found in \l {https://httpwg.org/specs/rfc7540.html}{RFC 7540}.
+ Different modes and parameters of the HPACK compression algorithm
+ are described in \l {https://httpwg.org/specs/rfc7541.html}{RFC 7541}.
+
+ \sa QNetworkRequest::setHttp2Configuration(), QNetworkRequest::http2Configuration(), QNetworkAccessManager
+*/
+
+class QHttp2ConfigurationPrivate : public QSharedData
+{
+public:
+ unsigned sessionWindowSize = Http2::defaultSessionWindowSize;
+ // The size below is quite a limiting default value, QNetworkRequest
+ // by default sets a larger number, an application can change this using
+ // QNetworkRequest::setHttp2Configuration.
+ unsigned streamWindowSize = Http2::defaultSessionWindowSize;
+
+ unsigned maxFrameSize = Http2::minPayloadLimit; // Initial (default) value of 16Kb.
+
+ bool pushEnabled = false;
+ // TODO: for now those two below are noop.
+ bool huffmanCompressionEnabled = true;
+};
+
+/*!
+ Default constructs a QHttp2Configuration object.
+
+ Such a configuration has the following values:
+ \list
+ \li Server push is disabled
+ \li Huffman string compression is enabled
+ \li Window size for connection-level flow control is 65535 octets
+ \li Window size for stream-level flow control is 65535 octets
+ \li Frame size is 16384 octets
+ \endlist
+*/
+QHttp2Configuration::QHttp2Configuration()
+ : d(new QHttp2ConfigurationPrivate)
+{
+}
+
+/*!
+ Copy-constructs this QHttp2Configuration.
+*/
+QHttp2Configuration::QHttp2Configuration(const QHttp2Configuration &) = default;
+
+/*!
+ Move-constructs this QHttp2Configuration from \a other
+*/
+QHttp2Configuration::QHttp2Configuration(QHttp2Configuration &&other) noexcept
+{
+ swap(other);
+}
+
+/*!
+ Copy-assigns to this QHttp2Configuration.
+*/
+QHttp2Configuration &QHttp2Configuration::operator=(const QHttp2Configuration &) = default;
+
+/*!
+ Move-assigns to this QHttp2Configuration.
+*/
+QHttp2Configuration &QHttp2Configuration::operator=(QHttp2Configuration &&) noexcept = default;
+
+/*!
+ Destructor.
+*/
+QHttp2Configuration::~QHttp2Configuration()
+{
+}
+
+/*!
+ If \a enable is \c true, a remote server can potentially
+ use server push to send reponses in advance.
+
+ \sa serverPushEnabled
+*/
+void QHttp2Configuration::setServerPushEnabled(bool enable)
+{
+ d->pushEnabled = enable;
+}
+
+/*!
+ Returns true if server push was enabled.
+
+ \note By default, QNetworkAccessManager disables server
+ push via the 'SETTINGS' frame.
+
+ \sa setServerPushEnabled
+*/
+bool QHttp2Configuration::serverPushEnabled() const
+{
+ return d->pushEnabled;
+}
+
+/*!
+ If \a enable is \c true, HPACK compression will additionally
+ compress string using the Huffman coding. Enabled by default.
+
+ \note This parameter only affects 'HEADERS' frames that
+ QNetworkAccessManager is sending.
+
+ \sa huffmanCompressionEnabled
+*/
+void QHttp2Configuration::setHuffmanCompressionEnabled(bool enable)
+{
+ d->huffmanCompressionEnabled = enable;
+}
+
+/*!
+ Returns \c true if the Huffman coding in HPACK is enabled.
+
+ \sa setHuffmanCompressionEnabled
+*/
+bool QHttp2Configuration::huffmanCompressionEnabled() const
+{
+ return d->huffmanCompressionEnabled;
+}
+
+/*!
+ Sets the window size for connection-level flow control.
+ \a size cannot be 0 and must not exceed 2147483647 octets.
+
+ \sa sessionReceiveWindowSize
+*/
+bool QHttp2Configuration::setSessionReceiveWindowSize(unsigned size)
+{
+ if (!size || size > Http2::maxSessionReceiveWindowSize) { // RFC-7540, 6.9
+ qCWarning(QT_HTTP2) << "Invalid session window size";
+ return false;
+ }
+
+ d->sessionWindowSize = size;
+ return true;
+}
+
+/*!
+ Returns the window size for connection-level flow control.
+ The default value QNetworkAccessManager will be using is
+ 2147483647 octets.
+*/
+unsigned QHttp2Configuration::sessionReceiveWindowSize() const
+{
+ return d->sessionWindowSize;
+}
+
+/*!
+ Sets the window size for stream-level flow control.
+ \a size cannot be 0 and must not exceed 2147483647 octets.
+
+ \sa streamReceiveWindowSize
+ */
+bool QHttp2Configuration::setStreamReceiveWindowSize(unsigned size)
+{
+ if (!size || size > Http2::maxSessionReceiveWindowSize) { // RFC-7540, 6.9
+ qCWarning(QT_HTTP2) << "Invalid stream window size";
+ return false;
+ }
+
+ d->streamWindowSize = size;
+ return true;
+}
+
+/*!
+ Returns the window size for stream-level flow control.
+ The default value QNetworkAccessManager will be using is
+ 21474836 octets.
+*/
+unsigned QHttp2Configuration::streamReceiveWindowSize() const
+{
+ return d->streamWindowSize;
+}
+
+/*!
+ Sets the maximum frame size that QNetworkAccessManager
+ will advertise to the server when sending its initial SETTINGS frame.
+ \note While this \a size is required to be within a range between
+ 16384 and 16777215 inclusive, the actual payload size in frames
+ that carry payload maybe be less than 16384.
+*/
+bool QHttp2Configuration::setMaxFrameSize(unsigned size)
+{
+ if (size < Http2::minPayloadLimit || size > Http2::maxPayloadSize) {
+ qCWarning(QT_HTTP2) << "Maximum frame size to advertise is invalid";
+ return false;
+ }
+
+ d->maxFrameSize = size;
+ return true;
+}
+
+/*!
+ The maximum payload size that HTTP/2 frames can
+ have. The default (initial) value is 16384 octets.
+*/
+unsigned QHttp2Configuration::maxFrameSize() const
+{
+ return d->maxFrameSize;
+}
+
+/*!
+ Swaps this configuration with the \a other configuration.
+*/
+void QHttp2Configuration::swap(QHttp2Configuration &other) noexcept
+{
+ d.swap(other.d);
+}
+
+/*!
+ Returns \c true if \a lhs and \a rhs have the same set of HTTP/2
+ parameters.
+*/
+bool operator==(const QHttp2Configuration &lhs, const QHttp2Configuration &rhs)
+{
+ if (lhs.d == rhs.d)
+ return true;
+
+ return lhs.d->pushEnabled == rhs.d->pushEnabled
+ && lhs.d->huffmanCompressionEnabled == rhs.d->huffmanCompressionEnabled
+ && lhs.d->sessionWindowSize == rhs.d->sessionWindowSize
+ && lhs.d->streamWindowSize == rhs.d->streamWindowSize;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/access/qhttp2configuration.h b/src/network/access/qhttp2configuration.h
new file mode 100644
index 0000000000..e5c235e2be
--- /dev/null
+++ b/src/network/access/qhttp2configuration.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHTTP2CONFIGURATION_H
+#define QHTTP2CONFIGURATION_H
+
+#include <QtNetwork/qtnetworkglobal.h>
+
+#include <QtCore/qshareddata.h>
+
+#ifndef Q_CLANG_QDOC
+QT_REQUIRE_CONFIG(http);
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QHttp2ConfigurationPrivate;
+class Q_NETWORK_EXPORT QHttp2Configuration
+{
+ friend Q_NETWORK_EXPORT bool operator==(const QHttp2Configuration &lhs, const QHttp2Configuration &rhs);
+
+public:
+ QHttp2Configuration();
+ QHttp2Configuration(const QHttp2Configuration &other);
+ QHttp2Configuration(QHttp2Configuration &&other) noexcept;
+ QHttp2Configuration &operator = (const QHttp2Configuration &other);
+ QHttp2Configuration &operator = (QHttp2Configuration &&other) noexcept;
+
+ ~QHttp2Configuration();
+
+ void setServerPushEnabled(bool enable);
+ bool serverPushEnabled() const;
+
+ void setHuffmanCompressionEnabled(bool enable);
+ bool huffmanCompressionEnabled() const;
+
+ bool setSessionReceiveWindowSize(unsigned size);
+ unsigned sessionReceiveWindowSize() const;
+
+ bool setStreamReceiveWindowSize(unsigned size);
+ unsigned streamReceiveWindowSize() const;
+
+ bool setMaxFrameSize(unsigned size);
+ unsigned maxFrameSize() const;
+
+ void swap(QHttp2Configuration &other) noexcept;
+
+private:
+
+ QSharedDataPointer<QHttp2ConfigurationPrivate> d;
+};
+
+Q_DECLARE_SHARED(QHttp2Configuration)
+
+Q_NETWORK_EXPORT bool operator==(const QHttp2Configuration &lhs, const QHttp2Configuration &rhs);
+
+inline bool operator!=(const QHttp2Configuration &lhs, const QHttp2Configuration &rhs)
+{
+ return !(lhs == rhs);
+}
+
+QT_END_NAMESPACE
+
+#endif // QHTTP2CONFIGURATION_H
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index 0ece5b7179..c1053882af 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -40,6 +40,7 @@
#include "qhttpnetworkconnection_p.h"
#include "qhttp2protocolhandler_p.h"
+#include "http2/http2frames_p.h"
#include "http2/bitstreams_p.h"
#include <private/qnoncontiguousbytedevice_p.h>
@@ -51,6 +52,8 @@
#include <QtCore/qlist.h>
#include <QtCore/qurl.h>
+#include <qhttp2configuration.h>
+
#ifndef QT_NO_NETWORKPROXY
#include <QtNetwork/qnetworkproxy.h>
#endif
@@ -172,30 +175,11 @@ QHttp2ProtocolHandler::QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *chan
Q_ASSERT(channel && m_connection);
continuedFrames.reserve(20);
- const ProtocolParameters params(m_connection->http2Parameters());
- Q_ASSERT(params.validate());
-
- maxSessionReceiveWindowSize = params.maxSessionReceiveWindowSize;
-
- const RawSettings &data = params.settingsFrameData;
- for (auto param = data.cbegin(), end = data.cend(); param != end; ++param) {
- switch (param.key()) {
- case Settings::INITIAL_WINDOW_SIZE_ID:
- streamInitialReceiveWindowSize = param.value();
- break;
- case Settings::ENABLE_PUSH_ID:
- pushPromiseEnabled = param.value();
- break;
- case Settings::HEADER_TABLE_SIZE_ID:
- case Settings::MAX_CONCURRENT_STREAMS_ID:
- case Settings::MAX_FRAME_SIZE_ID:
- case Settings::MAX_HEADER_LIST_SIZE_ID:
- // These other settings are just recommendations to our peer. We
- // only check they are not crazy in ProtocolParameters::validate().
- default:
- break;
- }
- }
+ const auto h2Config = m_connection->http2Parameters();
+ maxSessionReceiveWindowSize = h2Config.sessionReceiveWindowSize();
+ pushPromiseEnabled = h2Config.serverPushEnabled();
+ streamInitialReceiveWindowSize = h2Config.streamReceiveWindowSize();
+ encoder.setCompressStrings(h2Config.huffmanCompressionEnabled());
if (!channel->ssl && m_connection->connectionType() != QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
// We upgraded from HTTP/1.1 to HTTP/2. channel->request was already sent
@@ -422,20 +406,17 @@ bool QHttp2ProtocolHandler::sendClientPreface()
return false;
// 6.5 SETTINGS
- const ProtocolParameters params(m_connection->http2Parameters());
- Q_ASSERT(params.validate());
- frameWriter.setOutboundFrame(params.settingsFrame());
+ frameWriter.setOutboundFrame(Http2::configurationToSettingsFrame(m_connection->http2Parameters()));
Q_ASSERT(frameWriter.outboundFrame().payloadSize());
if (!frameWriter.write(*m_socket))
return false;
sessionReceiveWindowSize = maxSessionReceiveWindowSize;
- // ProtocolParameters::validate does not allow maxSessionReceiveWindowSize
- // to be smaller than defaultSessionWindowSize, so everything is OK here with
- // 'delta':
+ // We only send WINDOW_UPDATE for the connection if the size differs from the
+ // default 64 KB:
const auto delta = maxSessionReceiveWindowSize - Http2::defaultSessionWindowSize;
- if (!sendWINDOW_UPDATE(Http2::connectionStreamID, delta))
+ if (delta && !sendWINDOW_UPDATE(Http2::connectionStreamID, delta))
return false;
prefaceSent = true;
@@ -1069,7 +1050,7 @@ bool QHttp2ProtocolHandler::acceptSetting(Http2::Settings identifier, quint32 ne
}
if (identifier == Settings::MAX_FRAME_SIZE_ID) {
- if (newValue < Http2::maxFrameSize || newValue > Http2::maxPayloadSize) {
+ if (newValue < Http2::minPayloadLimit || newValue > Http2::maxPayloadSize) {
connectionError(PROTOCOL_ERROR, "SETTGINGS max frame size is out of range");
return false;
}
diff --git a/src/network/access/qhttp2protocolhandler_p.h b/src/network/access/qhttp2protocolhandler_p.h
index b582123961..1943827e23 100644
--- a/src/network/access/qhttp2protocolhandler_p.h
+++ b/src/network/access/qhttp2protocolhandler_p.h
@@ -55,6 +55,8 @@
#include <private/qabstractprotocolhandler_p.h>
#include <private/qhttpnetworkrequest_p.h>
+#include <access/qhttp2configuration.h>
+
#include <private/http2protocol_p.h>
#include <private/http2streams_p.h>
#include <private/http2frames_p.h>
@@ -163,8 +165,9 @@ private:
static const std::deque<quint32>::size_type maxRecycledStreams;
std::deque<quint32> recycledStreams;
- // Peer's max frame size.
- quint32 maxFrameSize = Http2::maxFrameSize;
+ // Peer's max frame size (this min is the default value
+ // we start with, that can be updated by SETTINGS frame):
+ quint32 maxFrameSize = Http2::minPayloadLimit;
Http2::FrameReader frameReader;
Http2::Frame inboundFrame;
@@ -176,28 +179,28 @@ private:
// Control flow:
- // This is how many concurrent streams our peer expects from us:
- // 100 is the default value, can be updated by the server's SETTINGS
- // frame(s):
+ // This is how many concurrent streams our peer allows us, 100 is the
+ // initial value, can be updated by the server's SETTINGS frame(s):
quint32 maxConcurrentStreams = Http2::maxConcurrentStreams;
// While we allow sending SETTTINGS_MAX_CONCURRENT_STREAMS to limit our peer,
// it's just a hint and we do not actually enforce it (and we can continue
// sending requests and creating streams while maxConcurrentStreams allows).
- // This is the max value, we set it in a ctor from Http2::ProtocolParameters,
- // it does not change after that.
+ // This is our (client-side) maximum possible receive window size, we set
+ // it in a ctor from QHttp2Configuration, it does not change after that.
+ // The default is 64Kb:
qint32 maxSessionReceiveWindowSize = Http2::defaultSessionWindowSize;
- // Our session receive window size, default is 64Kb. We'll update it from QNAM's
- // Http2::ProtocolParameters. Signed integer since it can become negative
+ // Our session current receive window size, updated in a ctor from
+ // QHttp2Configuration. Signed integer since it can become negative
// (it's still a valid window size).
qint32 sessionReceiveWindowSize = Http2::defaultSessionWindowSize;
// Our per-stream receive window size, default is 64 Kb, will be updated
- // from QNAM's Http2::ProtocolParameters. Again, signed - can become negative.
+ // from QHttp2Configuration. Again, signed - can become negative.
qint32 streamInitialReceiveWindowSize = Http2::defaultSessionWindowSize;
// These are our peer's receive window sizes, they will be updated by the
- // peer's SETTINGS and WINDOW_UPDATE frames.
+ // peer's SETTINGS and WINDOW_UPDATE frames, defaults presumed to be 64Kb.
qint32 sessionSendWindowSize = Http2::defaultSessionWindowSize;
qint32 streamInitialSendWindowSize = Http2::defaultSessionWindowSize;
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 1f1de478ea..13be1aa6b5 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -1456,21 +1456,16 @@ void QHttpNetworkConnection::setConnectionType(ConnectionType type)
d->connectionType = type;
}
-Http2::ProtocolParameters QHttpNetworkConnection::http2Parameters() const
+QHttp2Configuration QHttpNetworkConnection::http2Parameters() const
{
Q_D(const QHttpNetworkConnection);
return d->http2Parameters;
}
-void QHttpNetworkConnection::setHttp2Parameters(const Http2::ProtocolParameters &params)
+void QHttpNetworkConnection::setHttp2Parameters(const QHttp2Configuration &params)
{
Q_D(QHttpNetworkConnection);
- if (params.validate()) {
- d->http2Parameters = params;
- } else {
- qCWarning(QT_HTTP2)
- << "invalid HTTP/2 parameters, falling back to defaults instead";
- }
+ d->http2Parameters = params;
}
// SSL support below
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 85d89f20c2..6808a0c0ac 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -57,6 +57,8 @@
#include <QtNetwork/qabstractsocket.h>
#include <QtNetwork/qnetworksession.h>
+#include <qhttp2configuration.h>
+
#include <private/qobject_p.h>
#include <qauthenticator.h>
#include <qnetworkproxy.h>
@@ -142,8 +144,8 @@ public:
ConnectionType connectionType();
void setConnectionType(ConnectionType type);
- Http2::ProtocolParameters http2Parameters() const;
- void setHttp2Parameters(const Http2::ProtocolParameters &params);
+ QHttp2Configuration http2Parameters() const;
+ void setHttp2Parameters(const QHttp2Configuration &params);
#ifndef QT_NO_SSL
void setSslConfiguration(const QSslConfiguration &config);
@@ -294,7 +296,7 @@ public:
QSharedPointer<QNetworkSession> networkSession;
#endif
- Http2::ProtocolParameters http2Parameters;
+ QHttp2Configuration http2Parameters;
QString peerVerifyName;
// If network status monitoring is enabled, we activate connectionMonitor
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 3c9d53c5b5..716ea6c8b2 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -40,6 +40,7 @@
#include "qhttpnetworkconnectionchannel_p.h"
#include "qhttpnetworkconnection_p.h"
+#include "qhttp2configuration.h"
#include "private/qnoncontiguousbytedevice_p.h"
#include <qpair.h>
@@ -48,6 +49,7 @@
#include <private/qhttp2protocolhandler_p.h>
#include <private/qhttpprotocolhandler_p.h>
#include <private/qspdyprotocolhandler_p.h>
+#include <private/http2protocol_p.h>
#ifndef QT_NO_SSL
# include <private/qsslsocket_p.h>
@@ -947,9 +949,7 @@ void QHttpNetworkConnectionChannel::_q_connected()
if (tryProtocolUpgrade) {
// Let's augment our request with some magic headers and try to
// switch to HTTP/2.
- const Http2::ProtocolParameters params(connection->http2Parameters());
- Q_ASSERT(params.validate());
- params.addProtocolUpgradeHeaders(&request);
+ Http2::appendProtocolUpgradeHeaders(connection->http2Parameters(), &request);
}
sendRequest();
}
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index acc551a7c9..1900397eab 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -352,9 +352,9 @@ void QHttpThreadDelegate::startRequest()
networkSession);
#endif // QT_NO_BEARERMANAGEMENT
if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2
- && http2Parameters.validate()) {
+ || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct) {
httpConnection->setHttp2Parameters(http2Parameters);
- } // else we ignore invalid parameters and use our own defaults.
+ }
#ifndef QT_NO_SSL
// Set the QSslConfiguration from this QNetworkRequest.
if (ssl)
diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h
index 6184b39b30..355d1afc30 100644
--- a/src/network/access/qhttpthreaddelegate_p.h
+++ b/src/network/access/qhttpthreaddelegate_p.h
@@ -62,6 +62,7 @@
#include <QNetworkReply>
#include "qhttpnetworkrequest_p.h"
#include "qhttpnetworkconnection_p.h"
+#include "qhttp2configuration.h"
#include <QSharedPointer>
#include <QScopedPointer>
#include "private/qnoncontiguousbytedevice_p.h"
@@ -116,7 +117,7 @@ public:
qint64 removedContentLength;
QNetworkReply::NetworkError incomingErrorCode;
QString incomingErrorDetail;
- Http2::ProtocolParameters http2Parameters;
+ QHttp2Configuration http2Parameters;
#ifndef QT_NO_BEARERMANAGEMENT
QSharedPointer<QNetworkSession> networkSession;
#endif
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 29192ae7b0..fdc3cd3b3a 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -70,6 +70,7 @@
#include "QtNetwork/private/qauthenticator_p.h"
#include "QtNetwork/qsslconfiguration.h"
#include "QtNetwork/qnetworkconfigmanager.h"
+#include "QtNetwork/private/http2protocol_p.h"
#if QT_CONFIG(http)
#include "qhttpmultipart.h"
@@ -489,6 +490,7 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent)
qRegisterMetaType<QSharedPointer<char> >();
Q_D(QNetworkAccessManager);
+
if (QNetworkStatusMonitor::isEnabled()) {
connect(&d->statusMonitor, SIGNAL(onlineStateChanged(bool)),
SLOT(_q_onlineStateChanged(bool)));
@@ -1178,7 +1180,6 @@ QSharedPointer<QNetworkSession> QNetworkAccessManagerPrivate::getNetworkSession(
#endif // QT_NO_BEARERMANAGEMENT
-
#ifndef QT_NO_SSL
/*!
\since 5.2
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index b9651b35d2..b3dec282b0 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -797,10 +797,8 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
// Create the HTTP thread delegate
QHttpThreadDelegate *delegate = new QHttpThreadDelegate;
- // Propagate Http/2 settings if any
- const QVariant blob(manager->property(Http2::http2ParametersPropertyName));
- if (blob.isValid() && blob.canConvert<Http2::ProtocolParameters>())
- delegate->http2Parameters = blob.value<Http2::ProtocolParameters>();
+ // Propagate Http/2 settings:
+ delegate->http2Parameters = request.http2Configuration();
#ifndef QT_NO_BEARERMANAGEMENT
if (!QNetworkStatusMonitor::isEnabled())
delegate->networkSession = managerPrivate->getNetworkSession();
@@ -1054,59 +1052,39 @@ void QNetworkReplyHttpImplPrivate::replyDownloadData(QByteArray d)
if (!q->isOpen())
return;
- int pendingSignals = (int)pendingDownloadDataEmissions->fetchAndAddAcquire(-1) - 1;
+ if (cacheEnabled && isCachingAllowed() && !cacheSaveDevice)
+ initCacheSaveDevice();
+
+ // This is going to look a little strange. When downloading data while a
+ // HTTP redirect is happening (and enabled), we write the redirect
+ // response to the cache. However, we do not append it to our internal
+ // buffer as that will contain the response data only for the final
+ // response
+ if (cacheSaveDevice)
+ cacheSaveDevice->write(d);
+
+ if (!isHttpRedirectResponse()) {
+ buffer.append(d);
+ bytesDownloaded += d.size();
+ }
+ bytesBuffered += d.size();
+ int pendingSignals = pendingDownloadDataEmissions->fetchAndSubAcquire(1) - 1;
if (pendingSignals > 0) {
// Some more signal emissions to this slot are pending.
// Instead of writing the downstream data, we wait
// and do it in the next call we get
// (signal comppression)
- pendingDownloadData.append(d);
return;
}
- pendingDownloadData.append(d);
- d.clear();
- // We need to usa a copy for calling writeDownstreamData as we could
- // possibly recurse into this this function when we call
- // appendDownstreamDataSignalEmissions because the user might call
- // processEvents() or spin an event loop when this occur.
- QByteDataBuffer pendingDownloadDataCopy = pendingDownloadData;
- pendingDownloadData.clear();
-
- if (cacheEnabled && isCachingAllowed() && !cacheSaveDevice) {
- initCacheSaveDevice();
- }
-
- qint64 bytesWritten = 0;
- for (int i = 0; i < pendingDownloadDataCopy.bufferCount(); i++) {
- QByteArray const &item = pendingDownloadDataCopy[i];
-
- // This is going to look a little strange. When downloading data while a
- // HTTP redirect is happening (and enabled), we write the redirect
- // response to the cache. However, we do not append it to our internal
- // buffer as that will contain the response data only for the final
- // response
- if (cacheSaveDevice)
- cacheSaveDevice->write(item.constData(), item.size());
-
- if (!isHttpRedirectResponse())
- buffer.append(item);
-
- bytesWritten += item.size();
- }
- bytesBuffered += bytesWritten;
- pendingDownloadDataCopy.clear();
+ if (isHttpRedirectResponse())
+ return;
QVariant totalSize = cookedHeaders.value(QNetworkRequest::ContentLengthHeader);
if (preMigrationDownloaded != Q_INT64_C(-1))
totalSize = totalSize.toLongLong() + preMigrationDownloaded;
- if (isHttpRedirectResponse())
- return;
-
- bytesDownloaded += bytesWritten;
-
emit q->readyRead();
// emit readyRead before downloadProgress incase this will cause events to be
// processed and we get into a recursive call (as in QProgressDialog).
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index f5f01d0811..ef69ce0653 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -63,7 +63,6 @@
#include <QtNetwork/QNetworkCacheMetaData>
#include <private/qhttpnetworkrequest_p.h>
-#include <private/qbytedata_p.h>
#include <private/qnetworkreply_p.h>
#include <QtNetwork/QNetworkProxy>
#include <QtNetwork/QNetworkSession>
@@ -248,7 +247,6 @@ public:
quint64 resumeOffset;
qint64 preMigrationDownloaded;
- QByteDataBuffer pendingDownloadData; // For signal compression
qint64 bytesDownloaded;
qint64 bytesBuffered;
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 37f64c3f52..118fb6b1fb 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -42,6 +42,10 @@
#include "qplatformdefs.h"
#include "qnetworkcookie.h"
#include "qsslconfiguration.h"
+#if QT_CONFIG(http) || defined(Q_CLANG_QDOC)
+#include "qhttp2configuration.h"
+#include "private/http2protocol_p.h"
+#endif
#include "QtCore/qshareddata.h"
#include "QtCore/qlocale.h"
#include "QtCore/qdatetime.h"
@@ -445,6 +449,9 @@ public:
sslConfiguration = new QSslConfiguration(*other.sslConfiguration);
#endif
peerVerifyName = other.peerVerifyName;
+#if QT_CONFIG(http)
+ h2Configuration = other.h2Configuration;
+#endif
}
inline bool operator==(const QNetworkRequestPrivate &other) const
@@ -454,7 +461,11 @@ public:
rawHeaders == other.rawHeaders &&
attributes == other.attributes &&
maxRedirectsAllowed == other.maxRedirectsAllowed &&
- peerVerifyName == other.peerVerifyName;
+ peerVerifyName == other.peerVerifyName
+#if QT_CONFIG(http)
+ && h2Configuration == other.h2Configuration
+#endif
+ ;
// don't compare cookedHeaders
}
@@ -465,6 +476,9 @@ public:
#endif
int maxRedirectsAllowed;
QString peerVerifyName;
+#if QT_CONFIG(http)
+ QHttp2Configuration h2Configuration;
+#endif
};
/*!
@@ -476,6 +490,15 @@ public:
QNetworkRequest::QNetworkRequest()
: d(new QNetworkRequestPrivate)
{
+#if QT_CONFIG(http)
+ // Initial values proposed by RFC 7540 are quite draconian,
+ // so unless an application will set its own parameters, we
+ // make stream window size larger and increase (via WINDOW_UPDATE)
+ // the session window size. These are our 'defaults':
+ d->h2Configuration.setStreamReceiveWindowSize(Http2::qtDefaultStreamReceiveWindowSize);
+ d->h2Configuration.setSessionReceiveWindowSize(Http2::maxSessionReceiveWindowSize);
+ d->h2Configuration.setServerPushEnabled(false);
+#endif // QT_CONFIG(http)
}
/*!
@@ -835,6 +858,52 @@ void QNetworkRequest::setPeerVerifyName(const QString &peerName)
d->peerVerifyName = peerName;
}
+#if QT_CONFIG(http) || defined(Q_CLANG_QDOC)
+/*!
+ \since 5.14
+
+ Returns the current parameters that QNetworkAccessManager is
+ using for this request and its underlying HTTP/2 connection.
+ This is either a configuration previously set by an application
+ or a default configuration.
+
+ The default values that QNetworkAccessManager is using are:
+
+ \list
+ \li Window size for connection-level flowcontrol is 2147483647 octets
+ \li Window size for stream-level flowcontrol is 21474836 octets
+ \li Max frame size is 16384
+ \endlist
+
+ By default, server push is disabled, Huffman compression and
+ string indexing are enabled.
+
+ \sa setHttp2Configuration
+*/
+QHttp2Configuration QNetworkRequest::http2Configuration() const
+{
+ return d->h2Configuration;
+}
+
+/*!
+ \since 5.14
+
+ Sets request's HTTP/2 parameters from \a configuration.
+
+ \note The configuration must be set prior to making a request.
+ \note HTTP/2 multiplexes several streams in a single HTTP/2
+ connection. This implies that QNetworkAccessManager will use
+ the configuration found in the first request from a series
+ of requests sent to the same host.
+
+ \sa http2Configuration, QNetworkAccessManager, QHttp2Configuration
+*/
+void QNetworkRequest::setHttp2Configuration(const QHttp2Configuration &configuration)
+{
+ d->h2Configuration = configuration;
+}
+#endif // QT_CONFIG(http) || defined(Q_CLANG_QDOC)
+
static QByteArray headerName(QNetworkRequest::KnownHeaders header)
{
switch (header) {
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index 8ad4ab41c0..e09ff8aaae 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -49,6 +49,7 @@
QT_BEGIN_NAMESPACE
class QSslConfiguration;
+class QHttp2Configuration;
class QNetworkRequestPrivate;
class Q_NETWORK_EXPORT QNetworkRequest
@@ -175,6 +176,10 @@ public:
QString peerVerifyName() const;
void setPeerVerifyName(const QString &peerName);
+#if QT_CONFIG(http) || defined(Q_CLANG_QDOC)
+ QHttp2Configuration http2Configuration() const;
+ void setHttp2Configuration(const QHttp2Configuration &configuration);
+#endif // QT_CONFIG(http) || defined(Q_CLANG_QDOC)
private:
QSharedDataPointer<QNetworkRequestPrivate> d;
friend class QNetworkRequestPrivate;
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
index 07ef60c5ff..d9d76c1146 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+++ b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
@@ -854,6 +854,8 @@ void QKmsDevice::discoverPlanes()
plane.crtcYPropertyId = prop->prop_id;
} else if (!strcasecmp(prop->name, "zpos")) {
plane.zposPropertyId = prop->prop_id;
+ } else if (!strcasecmp(prop->name, "blend_op")) {
+ plane.blendOpPropertyId = prop->prop_id;
}
});
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice_p.h b/src/platformsupport/kmsconvenience/qkmsdevice_p.h
index 403972fbb8..77070c293d 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice_p.h
+++ b/src/platformsupport/kmsconvenience/qkmsdevice_p.h
@@ -178,6 +178,7 @@ struct QKmsPlane
uint32_t crtcwidthPropertyId = 0;
uint32_t crtcheightPropertyId = 0;
uint32_t zposPropertyId = 0;
+ uint32_t blendOpPropertyId = 0;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QKmsPlane::Rotations)
diff --git a/src/plugins/bearer/android/jar/jar.pro b/src/plugins/bearer/android/jar/jar.pro
index f988019dac..8277a8abc1 100644
--- a/src/plugins/bearer/android/jar/jar.pro
+++ b/src/plugins/bearer/android/jar/jar.pro
@@ -1,3 +1,5 @@
+CONFIG += single_arch
+
TARGET = QtAndroidBearer
load(qt_build_paths)
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 0fb21df1d3..1f1675e490 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -492,6 +492,8 @@ inline my_jpeg_destination_mgr::my_jpeg_destination_mgr(QIODevice *device)
free_in_buffer = max_buf;
}
+static constexpr int maxMarkerSize = 65533;
+
static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QString &description)
{
const QMap<QString, QString> text = qt_getImageText(image, description);
@@ -500,12 +502,33 @@ static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QSt
if (!comment.isEmpty())
comment += ": ";
comment += it.value().toUtf8();
- if (comment.length() > 65530)
- comment.truncate(65530);
+ if (comment.length() > maxMarkerSize)
+ comment.truncate(maxMarkerSize);
jpeg_write_marker(cinfo, JPEG_COM, (const JOCTET *)comment.constData(), comment.size());
}
}
+static inline void write_icc_profile(const QImage &image, j_compress_ptr cinfo)
+{
+ const QByteArray iccProfile = image.colorSpace().iccProfile();
+ if (iccProfile.isEmpty())
+ return;
+
+ const QByteArray iccSignature("ICC_PROFILE", 12);
+ constexpr int maxIccMarkerSize = maxMarkerSize - (12 + 2);
+ int index = 0;
+ const int markers = (iccProfile.size() + (maxIccMarkerSize - 1)) / maxIccMarkerSize;
+ Q_ASSERT(markers < 256);
+ for (int marker = 1; marker <= markers; ++marker) {
+ const int len = std::min(iccProfile.size() - index, maxIccMarkerSize);
+ const QByteArray block = iccSignature
+ + QByteArray(1, char(marker)) + QByteArray(1, char(markers))
+ + iccProfile.mid(index, len);
+ jpeg_write_marker(cinfo, JPEG_APP0 + 2, reinterpret_cast<const JOCTET *>(block.constData()), block.size());
+ index += len;
+ }
+}
+
static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description, bool optimize, bool progressive)
{
bool success = false;
@@ -586,6 +609,8 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
jpeg_start_compress(&cinfo, TRUE);
set_text(image, &cinfo, description);
+ if (cinfo.in_color_space == JCS_RGB)
+ write_icc_profile(image, &cinfo);
row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
int w = cinfo.image_width;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
index 09a10bcc9c..2034632fb3 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
@@ -331,6 +331,9 @@ void QEglFSKmsGbmScreen::flip()
static int zpos = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_ZPOS");
if (zpos)
drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->zposPropertyId, zpos);
+ static uint blendOp = uint(qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_BLEND_OP"));
+ if (blendOp)
+ drmModeAtomicAddProperty(request, op.eglfs_plane->id, op.eglfs_plane->blendOpPropertyId, blendOp);
}
#endif
} else {
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index dc7ea08dc5..cb8962d4b8 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -188,7 +188,7 @@ static QImage::Format determineFormat(const fb_var_screeninfo &info, int depth)
if (memcmp(rgba, rgb888, 3 * sizeof(fb_bitfield)) == 0) {
format = QImage::Format_RGB888;
} else if (memcmp(rgba, bgr888, 3 * sizeof(fb_bitfield)) == 0) {
- format = QImage::Format_RGB888;
+ format = QImage::Format_BGR888;
// pixeltype = BGRPixel;
}
break;
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp
index ea6336c4d1..90411f2a2c 100644
--- a/src/plugins/printsupport/cups/qppdprintdevice.cpp
+++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp
@@ -41,7 +41,9 @@
#include "qcupsprintersupport_p.h"
+#if QT_CONFIG(mimetype)
#include <QtCore/QMimeDatabase>
+#endif
#include <qdebug.h>
#include "private/qcups_p.h" // Only needed for PDPK_*
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 10bbd59bfb..4c7b8a6917 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -91,7 +91,7 @@ FILE *openProcess(const QString &command)
#if defined(Q_OS_WIN32)
QString processedCommand = QLatin1Char('\"') + command + QLatin1Char('\"');
#else
- QString processedCommand = command;
+ const QString& processedCommand = command;
#endif
return popen(processedCommand.toLocal8Bit().constData(), QT_POPEN_READ);
@@ -99,7 +99,7 @@ FILE *openProcess(const QString &command)
struct QtDependency
{
- QtDependency(QString rpath, QString apath) : relativePath(rpath), absolutePath(apath) {}
+ QtDependency(const QString &rpath, const QString &apath) : relativePath(rpath), absolutePath(apath) {}
bool operator==(const QtDependency &other) const
{
@@ -127,7 +127,6 @@ struct Options
, sectionsOnly(false)
, protectedAuthenticationPath(false)
, jarSigner(false)
- , gdbServer(Auto)
, installApk(false)
, uninstallApk(false)
{}
@@ -150,7 +149,6 @@ struct Options
bool generateAssetsFileList;
bool build;
bool auxMode;
- bool stripLibraries = true;
ActionTimer timer;
// External tools
@@ -175,22 +173,22 @@ struct Options
// lib c++ path
QString stdCppPath;
- QString stdCppName = QStringLiteral("gnustl_shared");
+ QString stdCppName = QStringLiteral("c++_shared");
// Build information
QString androidPlatform;
- QString architecture;
- QString toolchainVersion;
+ QHash<QString, QString> architectures;
+ QString currentArchitecture;
QString toolchainPrefix;
- QString toolPrefix;
- bool useLLVM = false;
QString ndkHost;
// Package information
DeploymentMechanism deploymentMechanism;
QString packageName;
QStringList extraLibs;
+ QHash<QString, QStringList> archExtraLibs;
QStringList extraPlugins;
+ QHash<QString, QStringList> archExtraPlugins;
// Signing information
bool releasePackage;
@@ -211,25 +209,36 @@ struct Options
bool jarSigner;
QString apkPath;
- // Gdbserver
- TriState gdbServer;
-
// Installation information
bool installApk;
bool uninstallApk;
QString installLocation;
- // Collected information
+ // Per architecture collected information
+ void clear(const QString &arch)
+ {
+ currentArchitecture = arch;
+ }
typedef QPair<QString, QString> BundledFile;
- QList<BundledFile> bundledFiles;
- QList<QtDependency> qtDependencies;
- QStringList localLibs;
+ QHash<QString, QList<BundledFile>> bundledFiles;
+ QHash<QString, QList<QtDependency>> qtDependencies;
+ QHash<QString, QStringList> localLibs;
+ bool usesOpenGL = false;
+
+ // Per package collected information
QStringList localJars;
QStringList initClasses;
QStringList permissions;
QStringList features;
};
+static const QHash<QByteArray, QByteArray> elfArchitecures = {
+ {"aarch64", "arm64-v8a"},
+ {"arm", "armeabi-v7a"},
+ {"i386", "x86"},
+ {"x86_64", "x86_64"}
+};
+
// Copy-pasted from qmake/library/ioutil.cpp
inline static bool hasSpecialChars(const QString &arg, const uchar (&iqm)[16])
{
@@ -301,6 +310,59 @@ static QString shellQuote(const QString &arg)
return shellQuoteUnix(arg);
}
+QString architecureFromName(const QString &name)
+{
+ QRegExp architecture(QStringLiteral(".*_(.*)\\.so"));
+ if (!architecture.exactMatch(name))
+ return {};
+ return architecture.capturedTexts().last();
+}
+
+QString fileArchitecture(const Options &options, const QString &path)
+{
+ auto arch = architecureFromName(path);
+ if (!arch.isEmpty())
+ return arch;
+
+ QString readElf = QStringLiteral("%1/toolchains/%2/prebuilt/%3/bin/llvm-readobj").arg(options.ndkPath,
+ options.toolchainPrefix,
+ options.ndkHost);
+#if defined(Q_OS_WIN32)
+ readElf += QStringLiteral(".exe");
+#endif
+
+ if (!QFile::exists(readElf)) {
+ fprintf(stderr, "Command does not exist: %s\n", qPrintable(readElf));
+ return {};
+ }
+
+ readElf = QStringLiteral("%1 -needed-libs %2").arg(shellQuote(readElf), shellQuote(path));
+
+ FILE *readElfCommand = openProcess(readElf);
+ if (!readElfCommand) {
+ fprintf(stderr, "Cannot execute command %s\n", qPrintable(readElf));
+ return {};
+ }
+
+ char buffer[512];
+ while (fgets(buffer, sizeof(buffer), readElfCommand) != nullptr) {
+ QByteArray line = QByteArray::fromRawData(buffer, qstrlen(buffer));
+ QString library;
+ line = line.trimmed();
+ if (line.startsWith("Arch: ")) {
+ auto it = elfArchitecures.find(line.mid(6));
+ pclose(readElfCommand);
+ return it != elfArchitecures.constEnd() ? QString::fromLatin1(it.value()) : QString{};
+ }
+ }
+ pclose(readElfCommand);
+ return {};
+}
+
+bool checkArchitecture(const Options &options, const QString &fileName)
+{
+ return fileArchitecture(options, fileName) == options.currentArchitecture;
+}
void deleteMissingFiles(const Options &options, const QDir &srcDir, const QDir &dstDir)
{
@@ -388,10 +450,6 @@ Options parseOptions()
options.installLocation = arguments.at(++i);
} else if (argument.compare(QLatin1String("--release"), Qt::CaseInsensitive) == 0) {
options.releasePackage = true;
- } else if (argument.compare(QLatin1String("--gdbserver"), Qt::CaseInsensitive) == 0) {
- options.gdbServer = Options::True;
- } else if (argument.compare(QLatin1String("--no-gdbserver"), Qt::CaseInsensitive) == 0) {
- options.gdbServer = Options::False;
} else if (argument.compare(QLatin1String("--jdk"), Qt::CaseInsensitive) == 0) {
if (i + 1 == arguments.size())
options.helpRequested = true;
@@ -462,8 +520,6 @@ Options parseOptions()
options.generateAssetsFileList = false;
} else if (argument.compare(QLatin1String("--aux-mode"), Qt::CaseInsensitive) == 0) {
options.auxMode = true;
- } else if (argument.compare(QLatin1String("--no-strip"), Qt::CaseInsensitive) == 0) {
- options.stripLibraries = false;
}
}
@@ -533,10 +589,6 @@ void printHelp()
" --protected: Keystore has protected authentication path.\n"
" --jarsigner: Force jarsigner usage, otherwise apksigner will be\n"
" used if available.\n"
- " --gdbserver: Adds the gdbserver to the package. By default the gdbserver\n"
- " is bundled for debug pacakges.\n"
- " --no-gdbserver: Prevents the gdbserver from being added to the package\n"
- " By default the gdbserver is bundled for debug pacakges.\n"
" --jdk <path/to/jdk>: Used to find the jarsigner tool when used\n"
" in combination with the --release argument. By default,\n"
" an attempt is made to detect the tool using the JAVA_HOME and\n"
@@ -549,7 +601,6 @@ void printHelp()
" --aux-mode: Operate in auxiliary mode. This will only copy the\n"
" dependencies into the build directory and update the XML templates.\n"
" The project will not be built or installed.\n"
- " --no-strip: Do not strip debug symbols from libraries.\n"
" --apk <path/where/to/copy/the/apk>: Path where to copy the built apk.\n"
" --help: Displays this information.\n\n",
qPrintable(QCoreApplication::arguments().at(0))
@@ -580,9 +631,10 @@ bool alwaysOverwritableFile(const QString &fileName)
|| fileName.endsWith(QLatin1String("/src/org/qtproject/qt5/android/bindings/QtActivity.java")));
}
+
bool copyFileIfNewer(const QString &sourceFileName,
const QString &destinationFileName,
- bool verbose,
+ const Options &options,
bool forceOverwrite = false)
{
if (QFile::exists(destinationFileName)) {
@@ -592,7 +644,7 @@ bool copyFileIfNewer(const QString &sourceFileName,
if (!forceOverwrite
&& sourceFileInfo.lastModified() <= destinationFileInfo.lastModified()
&& !alwaysOverwritableFile(destinationFileName)) {
- if (verbose)
+ if (options.verbose)
fprintf(stdout, " -- Skipping file %s. Same or newer file already in place.\n", qPrintable(sourceFileName));
return true;
} else {
@@ -611,11 +663,10 @@ bool copyFileIfNewer(const QString &sourceFileName,
if (!QFile::exists(destinationFileName) && !QFile::copy(sourceFileName, destinationFileName)) {
fprintf(stderr, "Failed to copy %s to %s.\n", qPrintable(sourceFileName), qPrintable(destinationFileName));
return false;
- } else if (verbose) {
+ } else if (options.verbose) {
fprintf(stdout, " -- Copied %s\n", qPrintable(destinationFileName));
fflush(stdout);
}
-
return true;
}
@@ -666,7 +717,7 @@ QString cleanPackageName(QString packageName)
}
}
if (keywords.contains(word)) {
- packageName.insert(next, QLatin1String("_"));
+ packageName.insert(next, QStringLiteral("_"));
index = next + 1;
} else {
index = next;
@@ -678,7 +729,7 @@ QString cleanPackageName(QString packageName)
QString detectLatestAndroidPlatform(const QString &sdkPath)
{
- QDir dir(sdkPath + QLatin1String("/platforms"));
+ QDir dir(sdkPath + QStringLiteral("/platforms"));
if (!dir.exists()) {
fprintf(stderr, "Directory %s does not exist\n", qPrintable(dir.absolutePath()));
return QString();
@@ -795,53 +846,22 @@ bool readInputFile(Options *options)
}
{
- const QJsonValue applicationBinary = jsonObject.value(QStringLiteral("application-binary"));
- if (applicationBinary.isUndefined()) {
- fprintf(stderr, "No application binary defined in json file.\n");
- return false;
- }
- options->applicationBinary = applicationBinary.toString();
-
- if (!QFile::exists(options->applicationBinary)) {
- fprintf(stderr, "Cannot find application binary %s.\n", qPrintable(options->applicationBinary));
+ const QJsonObject targetArchitectures = jsonObject.value(QStringLiteral("architectures")).toObject();
+ if (targetArchitectures.isEmpty()) {
+ fprintf(stderr, "No target architecture defined in json file.\n");
return false;
}
- }
-
- {
- const QJsonValue deploymentDependencies = jsonObject.value(QStringLiteral("deployment-dependencies"));
- if (!deploymentDependencies.isUndefined()) {
- QString deploymentDependenciesString = deploymentDependencies.toString();
- const auto dependencies = deploymentDependenciesString.splitRef(QLatin1Char(','));
- for (const QStringRef &dependency : dependencies) {
- QString path = options->qtInstallDirectory + QLatin1Char('/') + dependency;
- if (QFileInfo(path).isDir()) {
- QDirIterator iterator(path, QDirIterator::Subdirectories);
- while (iterator.hasNext()) {
- iterator.next();
- if (iterator.fileInfo().isFile()) {
- QString subPath = iterator.filePath();
- options->qtDependencies.append(QtDependency(subPath.mid(options->qtInstallDirectory.length() + 1),
- subPath));
- }
- }
- } else {
- options->qtDependencies.append(QtDependency(dependency.toString(), path));
- }
+ for (auto it = targetArchitectures.constBegin(); it != targetArchitectures.constEnd(); ++it) {
+ if (it.value().isUndefined()) {
+ fprintf(stderr, "Invalid architecure.\n");
+ return false;
}
+ if (it.value().isNull())
+ continue;
+ options->architectures.insert(it.key(), it.value().toString());
}
}
-
- {
- const QJsonValue targetArchitecture = jsonObject.value(QStringLiteral("target-architecture"));
- if (targetArchitecture.isUndefined()) {
- fprintf(stderr, "No target architecture defined in json file.\n");
- return false;
- }
- options->architecture = targetArchitecture.toString();
- }
-
{
const QJsonValue ndk = jsonObject.value(QStringLiteral("ndk"));
if (ndk.isUndefined()) {
@@ -852,11 +872,6 @@ bool readInputFile(Options *options)
}
{
- const QJsonValue value = jsonObject.value(QStringLiteral("useLLVM"));
- options->useLLVM = value.toBool(false);
- }
-
- {
const QJsonValue toolchainPrefix = jsonObject.value(QStringLiteral("toolchain-prefix"));
if (toolchainPrefix.isUndefined()) {
fprintf(stderr, "No toolchain prefix defined in json file.\n");
@@ -866,25 +881,6 @@ bool readInputFile(Options *options)
}
{
- const QJsonValue toolPrefix = jsonObject.value(QStringLiteral("tool-prefix"));
- if (toolPrefix.isUndefined()) {
- fprintf(stderr, "Warning: No tool prefix defined in json file.\n");
- options->toolPrefix = options->toolchainPrefix;
- } else {
- options->toolPrefix = toolPrefix.toString();
- }
- }
-
- if (!options->useLLVM) {
- const QJsonValue toolchainVersion = jsonObject.value(QStringLiteral("toolchain-version"));
- if (toolchainVersion.isUndefined()) {
- fprintf(stderr, "No toolchain version defined in json file.\n");
- return false;
- }
- options->toolchainVersion = toolchainVersion.toString();
- }
-
- {
const QJsonValue ndkHost = jsonObject.value(QStringLiteral("ndk-host"));
if (ndkHost.isUndefined()) {
fprintf(stderr, "No NDK host defined in json file.\n");
@@ -893,10 +889,6 @@ bool readInputFile(Options *options)
options->ndkHost = ndkHost.toString();
}
- options->packageName = packageNameFromAndroidManifest(options->androidSourceDirectory + QLatin1String("/AndroidManifest.xml"));
- if (options->packageName.isEmpty())
- options->packageName = cleanPackageName(QString::fromLatin1("org.qtproject.example.%1").arg(QFileInfo(options->applicationBinary).baseName().mid(sizeof("lib") - 1)));
-
{
const QJsonValue extraLibs = jsonObject.value(QStringLiteral("android-extra-libs"));
if (!extraLibs.isUndefined())
@@ -916,12 +908,6 @@ bool readInputFile(Options *options)
return false;
}
options->stdCppPath = stdcppPath.toString();
- auto name = QFileInfo(options->stdCppPath).baseName();
- if (!name.startsWith(QLatin1String("lib"))) {
- fprintf(stderr, "Invalid STD C++ library name.\n");
- return false;
- }
- options->stdCppName = name.mid(3);
}
{
@@ -935,10 +921,68 @@ bool readInputFile(Options *options)
if (!qmlImportPaths.isUndefined())
options->qmlImportPaths = qmlImportPaths.toString().split(QLatin1Char(','));
}
+
+ {
+ const QJsonValue applicationBinary = jsonObject.value(QStringLiteral("application-binary"));
+ if (applicationBinary.isUndefined()) {
+ fprintf(stderr, "No application binary defined in json file.\n");
+ return false;
+ }
+ options->applicationBinary = applicationBinary.toString();
+ if (options->build) {
+ for (auto it = options->architectures.constBegin(); it != options->architectures.constEnd(); ++it) {
+ if (!QFile::exists(QStringLiteral("%1/libs/%2/lib%3_%2.so").arg(options->outputDirectory, it.key(), options->applicationBinary))) {
+ fprintf(stderr, "Cannot find application binary %s.\n", qPrintable(options->applicationBinary));
+ return false;
+ }
+ }
+ }
+ }
+
+ {
+ const QJsonValue deploymentDependencies = jsonObject.value(QStringLiteral("deployment-dependencies"));
+ if (!deploymentDependencies.isUndefined()) {
+ QString deploymentDependenciesString = deploymentDependencies.toString();
+ const auto dependencies = deploymentDependenciesString.splitRef(QLatin1Char(','));
+ for (const QStringRef &dependency : dependencies) {
+ QString path = options->qtInstallDirectory + QLatin1Char('/') + dependency;
+ if (QFileInfo(path).isDir()) {
+ QDirIterator iterator(path, QDirIterator::Subdirectories);
+ while (iterator.hasNext()) {
+ iterator.next();
+ if (iterator.fileInfo().isFile()) {
+ QString subPath = iterator.filePath();
+ auto arch = fileArchitecture(*options, subPath);
+ if (!arch.isEmpty()) {
+ options->qtDependencies[arch].append(QtDependency(subPath.mid(options->qtInstallDirectory.length() + 1),
+ subPath));
+ } else if (options->verbose) {
+ fprintf(stderr, "Skipping \"%s\", unknown architecture\n", qPrintable(subPath));
+ fflush(stderr);
+ }
+ }
+ }
+ } else {
+ auto arch = fileArchitecture(*options, path);
+ if (!arch.isEmpty()) {
+ options->qtDependencies[arch].append(QtDependency(dependency.toString(), path));
+ } else if (options->verbose) {
+ fprintf(stderr, "Skipping \"%s\", unknown architecture\n", qPrintable(path));
+ fflush(stderr);
+ }
+ }
+ }
+ }
+ }
+
+ options->packageName = packageNameFromAndroidManifest(options->androidSourceDirectory + QStringLiteral("/AndroidManifest.xml"));
+ if (options->packageName.isEmpty())
+ options->packageName = cleanPackageName(QStringLiteral("org.qtproject.example.%1").arg(options->applicationBinary));
+
return true;
}
-bool copyFiles(const QDir &sourceDirectory, const QDir &destinationDirectory, bool verbose, bool forceOverwrite = false)
+bool copyFiles(const QDir &sourceDirectory, const QDir &destinationDirectory, const Options &options, bool forceOverwrite = false)
{
const QFileInfoList entries = sourceDirectory.entryInfoList(QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
for (const QFileInfo &entry : entries) {
@@ -949,11 +993,11 @@ bool copyFiles(const QDir &sourceDirectory, const QDir &destinationDirectory, bo
return false;
}
- if (!copyFiles(dir, QDir(destinationDirectory.path() + QLatin1String("/") + dir.dirName()), verbose, forceOverwrite))
+ if (!copyFiles(dir, QDir(destinationDirectory.path() + QStringLiteral("/") + dir.dirName()), options, forceOverwrite))
return false;
} else {
QString destination = destinationDirectory.absoluteFilePath(entry.fileName());
- if (!copyFileIfNewer(entry.absoluteFilePath(), destination, verbose, forceOverwrite))
+ if (!copyFileIfNewer(entry.absoluteFilePath(), destination, options, forceOverwrite))
return false;
}
}
@@ -993,7 +1037,7 @@ bool copyAndroidTemplate(const Options &options, const QString &androidTemplate,
return false;
}
- return copyFiles(sourceDirectory, QDir(outDir), options.verbose);
+ return copyFiles(sourceDirectory, QDir(outDir), options);
}
bool copyGradleTemplate(const Options &options)
@@ -1010,7 +1054,7 @@ bool copyGradleTemplate(const Options &options)
return false;
}
- return copyFiles(sourceDirectory, QDir(outDir), options.verbose);
+ return copyFiles(sourceDirectory, QDir(outDir), options);
}
bool copyAndroidTemplate(const Options &options)
@@ -1041,38 +1085,42 @@ bool copyAndroidSources(const Options &options)
return false;
}
- return copyFiles(sourceDirectory, QDir(options.outputDirectory), options.verbose, true);
+ return copyFiles(sourceDirectory, QDir(options.outputDirectory), options, true);
}
-bool copyAndroidExtraLibs(const Options &options)
+bool copyAndroidExtraLibs(Options *options)
{
- if (options.extraLibs.isEmpty())
+ if (options->extraLibs.isEmpty())
return true;
- if (options.verbose)
- fprintf(stdout, "Copying %d external libraries to package.\n", options.extraLibs.size());
+ if (options->verbose)
+ fprintf(stdout, "Copying %d external libraries to package.\n", options->extraLibs.size());
- for (const QString &extraLib : options.extraLibs) {
+ for (const QString &extraLib : options->extraLibs) {
QFileInfo extraLibInfo(extraLib);
if (!extraLibInfo.exists()) {
fprintf(stderr, "External library %s does not exist!\n", qPrintable(extraLib));
return false;
}
-
- if (!extraLibInfo.fileName().startsWith(QLatin1String("lib")) || extraLibInfo.suffix() != QLatin1String("so")) {
+ if (!checkArchitecture(*options, extraLibInfo.filePath())) {
+ if (options->verbose)
+ fprintf(stdout, "Skipping \"%s\", architecture mismatch.\n", qPrintable(extraLib));
+ continue;
+ }
+ if (!extraLibInfo.fileName().startsWith(QStringLiteral("lib")) || extraLibInfo.suffix() != QStringLiteral("so")) {
fprintf(stderr, "The file name of external library %s must begin with \"lib\" and end with the suffix \".so\".\n",
qPrintable(extraLib));
return false;
}
-
- QString destinationFile(options.outputDirectory
- + QLatin1String("/libs/")
- + options.architecture
+ QString destinationFile(options->outputDirectory
+ + QStringLiteral("/libs/")
+ + options->currentArchitecture
+ QLatin1Char('/')
+ extraLibInfo.fileName());
- if (!copyFileIfNewer(extraLib, destinationFile, options.verbose))
+ if (!copyFileIfNewer(extraLib, destinationFile, *options))
return false;
+ options->archExtraLibs[options->currentArchitecture] += extraLib;
}
return true;
@@ -1093,15 +1141,15 @@ QStringList allFilesInside(const QDir& current, const QDir& rootDir)
return result;
}
-bool copyAndroidExtraResources(const Options &options)
+bool copyAndroidExtraResources(Options *options)
{
- if (options.extraPlugins.isEmpty())
+ if (options->extraPlugins.isEmpty())
return true;
- if (options.verbose)
- fprintf(stdout, "Copying %d external resources to package.\n", options.extraPlugins.size());
+ if (options->verbose)
+ fprintf(stdout, "Copying %d external resources to package.\n", options->extraPlugins.size());
- for (const QString &extraResource : options.extraPlugins) {
+ for (const QString &extraResource : options->extraPlugins) {
QFileInfo extraResourceInfo(extraResource);
if (!extraResourceInfo.exists() || !extraResourceInfo.isDir()) {
fprintf(stderr, "External resource %s does not exist or not a correct directory!\n", qPrintable(extraResource));
@@ -1109,20 +1157,22 @@ bool copyAndroidExtraResources(const Options &options)
}
QDir resourceDir(extraResource);
- QString assetsDir = options.outputDirectory + QStringLiteral("/assets/") + resourceDir.dirName() + QLatin1Char('/');
- QString libsDir = options.outputDirectory + QStringLiteral("/libs/") + options.architecture + QLatin1Char('/');
+ QString assetsDir = options->outputDirectory + QStringLiteral("/assets/") + resourceDir.dirName() + QLatin1Char('/');
+ QString libsDir = options->outputDirectory + QStringLiteral("/libs/") + options->currentArchitecture + QLatin1Char('/');
const QStringList files = allFilesInside(resourceDir, resourceDir);
for (const QString &resourceFile : files) {
QString originFile(resourceDir.filePath(resourceFile));
QString destinationFile;
- if (!resourceFile.endsWith(QLatin1String(".so"))) {
+ if (!resourceFile.endsWith(QStringLiteral(".so"))) {
destinationFile = assetsDir + resourceFile;
} else {
+ if (!checkArchitecture(*options, originFile))
+ continue;
destinationFile = libsDir + QStringLiteral("/lib") + QString(resourceDir.dirName() + QLatin1Char('/') + resourceFile).replace(QLatin1Char('/'), QLatin1Char('_'));
+ options->archExtraPlugins[options->currentArchitecture] += resourceFile;
}
-
- if (!copyFileIfNewer(originFile, destinationFile, options.verbose))
+ if (!copyFileIfNewer(originFile, destinationFile, *options))
return false;
}
}
@@ -1174,75 +1224,118 @@ bool updateFile(const QString &fileName, const QHash<QString, QString> &replacem
}
-bool updateLibsXml(const Options &options)
+bool updateLibsXml(Options *options)
{
- if (options.verbose)
+ if (options->verbose)
fprintf(stdout, " -- res/values/libs.xml\n");
- QString fileName = options.outputDirectory + QLatin1String("/res/values/libs.xml");
+ QString fileName = options->outputDirectory + QStringLiteral("/res/values/libs.xml");
if (!QFile::exists(fileName)) {
fprintf(stderr, "Cannot find %s in prepared packaged. This file is required.\n", qPrintable(fileName));
return false;
}
- QString libsPath = QLatin1String("libs/") + options.architecture + QLatin1Char('/');
-
- QString qtLibs = QLatin1String("<item>") + options.stdCppName + QLatin1String("</item>\n");
+ QString qtLibs;
QString bundledInLibs;
QString bundledInAssets;
- for (const Options::BundledFile &bundledFile : options.bundledFiles) {
- if (bundledFile.second.startsWith(QLatin1String("lib/"))) {
- QString s = bundledFile.second.mid(sizeof("lib/lib") - 1);
- s.chop(sizeof(".so") - 1);
- qtLibs += QString::fromLatin1("<item>%1</item>\n").arg(s);
- } else if (bundledFile.first.startsWith(libsPath)) {
- QString s = bundledFile.first.mid(libsPath.length());
- bundledInLibs += QString::fromLatin1("<item>%1:%2</item>\n")
- .arg(s).arg(bundledFile.second);
- } else if (bundledFile.first.startsWith(QLatin1String("assets/"))) {
- QString s = bundledFile.first.mid(sizeof("assets/") - 1);
- bundledInAssets += QString::fromLatin1("<item>%1:%2</item>\n")
- .arg(s).arg(bundledFile.second);
+ QString allLocalLibs;
+ QString extraLibs;
+
+ for (auto it = options->architectures.constBegin(); it != options->architectures.constEnd(); ++it) {
+ QString libsPath = QStringLiteral("libs/") + it.key() + QLatin1Char('/');
+
+ qtLibs += QStringLiteral(" <item>%1;%2</item>\n").arg(it.key(), options->stdCppName);
+ for (const Options::BundledFile &bundledFile : options->bundledFiles[it.key()]) {
+ if (bundledFile.second.startsWith(QStringLiteral("lib/"))) {
+ QString s = bundledFile.second.mid(sizeof("lib/lib") - 1);
+ s.chop(sizeof(".so") - 1);
+ qtLibs += QStringLiteral(" <item>%1;%2</item>\n").arg(it.key(), s);
+ } else if (bundledFile.first.startsWith(libsPath)) {
+ QString s = bundledFile.first.mid(libsPath.length());
+ bundledInLibs += QString::fromLatin1(" <item>%1;%2:%3</item>\n")
+ .arg(it.key(), s, bundledFile.second);
+ } else if (bundledFile.first.startsWith(QStringLiteral("assets/"))) {
+ QString s = bundledFile.first.mid(sizeof("assets/") - 1);
+ bundledInAssets += QString::fromLatin1(" <item>%1:%2</item>\n")
+ .arg(s).arg(bundledFile.second);
+ }
}
- }
- if (!options.extraPlugins.isEmpty()) {
- for (const QString &extraRes : options.extraPlugins) {
- QDir resourceDir(extraRes);
- const QStringList files = allFilesInside(resourceDir, resourceDir);
- for (const QString &file : files) {
- QString destinationPath = resourceDir.dirName() + QLatin1Char('/') + file;
- if (!file.endsWith(QLatin1String(".so"))) {
- bundledInAssets += QStringLiteral("<item>%1:%1</item>\n")
- .arg(destinationPath);
- } else {
- bundledInLibs += QStringLiteral("<item>lib%1:%2</item>\n")
- .arg(QString(destinationPath).replace(QLatin1Char('/'), QLatin1Char('_')))
- .arg(destinationPath);
+ if (!options->archExtraPlugins[it.key()].isEmpty()) {
+ for (const QString &extraRes : options->archExtraPlugins[it.key()]) {
+ QDir resourceDir(extraRes);
+ const QStringList files = allFilesInside(resourceDir, resourceDir);
+ for (const QString &file : files) {
+ QString destinationPath = resourceDir.dirName() + QLatin1Char('/') + file;
+ if (!file.endsWith(QStringLiteral(".so"))) {
+ bundledInAssets += QStringLiteral(" <item>%1:%1</item>\n")
+ .arg(destinationPath);
+ } else {
+ bundledInLibs += QStringLiteral(" <item>%1;lib%2:%3</item>\n")
+ .arg(it.key(),
+ QString(destinationPath).replace(QLatin1Char('/'), QLatin1Char('_')),
+ destinationPath);
+ }
}
}
}
- }
- QHash<QString, QString> replacements;
- replacements[QLatin1String("<!-- %%INSERT_QT_LIBS%% -->")] = qtLibs;
+ if (!options->archExtraLibs[it.key()].isEmpty()) {
+ for (const QString &extraLib : options->archExtraLibs[it.key()]) {
+ QFileInfo extraLibInfo(extraLib);
+ QString name = extraLibInfo.fileName().mid(sizeof("lib") - 1);
+ name.chop(sizeof(".so") - 1);
+ extraLibs += QStringLiteral(" <item>%1;%2").arg(it.key(), name);
+ }
+ }
- if (options.deploymentMechanism == Options::Bundled) {
- replacements[QLatin1String("<!-- %%INSERT_BUNDLED_IN_LIB%% -->")] = bundledInLibs;
- replacements[QLatin1String("<!-- %%INSERT_BUNDLED_IN_ASSETS%% -->")] = bundledInAssets;
- }
+ QStringList localLibs;
+ localLibs = options->localLibs[it.key()];
+ // If .pro file overrides dependency detection, we need to see which platform plugin they picked
+ if (localLibs.isEmpty()) {
+ QString plugin;
+ for (const QtDependency &qtDependency : options->qtDependencies[it.key()]) {
+ if (qtDependency.relativePath.endsWith(QStringLiteral("libqtforandroid.so"))
+ || qtDependency.relativePath.endsWith(QStringLiteral("libqtforandroidGL.so"))) {
+ if (!plugin.isEmpty() && plugin != qtDependency.relativePath) {
+ fprintf(stderr, "Both platform plugins libqtforandroid.so and libqtforandroidGL.so included in package. Please include only one.\n");
+ return false;
+ }
- QString extraLibs;
- if (!options.extraLibs.isEmpty()) {
- for (const QString extraLib : options.extraLibs) {
- QFileInfo extraLibInfo(extraLib);
- QString name = extraLibInfo.fileName().mid(sizeof("lib") - 1);
- name.chop(sizeof(".so") - 1);
+ plugin = qtDependency.relativePath;
+ }
+ if (qtDependency.relativePath.contains(QStringLiteral("libQt5OpenGL"))
+ || qtDependency.relativePath.contains(QStringLiteral("libQt5Quick"))) {
+ options->usesOpenGL |= true;
+ break;
+ }
+ }
- extraLibs += QLatin1String("<item>") + name + QLatin1String("</item>\n");
+ if (plugin.isEmpty()) {
+ fflush(stdout);
+ fprintf(stderr, "No platform plugin, neither libqtforandroid.so or libqtforandroidGL.so, included in package. Please include one.\n");
+ fflush(stderr);
+ return false;
+ }
+
+ localLibs.append(plugin);
+ if (options->verbose)
+ fprintf(stdout, " -- Using platform plugin %s\n", qPrintable(plugin));
}
+ allLocalLibs += QStringLiteral(" <item>%1;%2</item>\n").arg(it.key(), localLibs.join(QLatin1Char(':'))
+ .replace(QStringLiteral("lib/"), QString{})
+ .replace(QLatin1Char('/'), QLatin1Char('_')));
+ }
+
+ QHash<QString, QString> replacements;
+ replacements[QStringLiteral("<!-- %%INSERT_QT_LIBS%% -->")] += qtLibs.trimmed();
+ replacements[QStringLiteral("<!-- %%INSERT_LOCAL_LIBS%% -->")] = allLocalLibs.trimmed();
+ replacements[QStringLiteral("<!-- %%INSERT_EXTRA_LIBS%% -->")] = extraLibs.trimmed();
+
+ if (options->deploymentMechanism == Options::Bundled) {
+ replacements[QStringLiteral("<!-- %%INSERT_BUNDLED_IN_LIB%% -->")] += bundledInLibs.trimmed();
+ replacements[QStringLiteral("<!-- %%INSERT_BUNDLED_IN_ASSETS%% -->")] += bundledInAssets.trimmed();
}
- replacements[QLatin1String("<!-- %%INSERT_EXTRA_LIBS%% -->")] = extraLibs;
if (!updateFile(fileName, replacements))
return false;
@@ -1256,9 +1349,9 @@ bool updateStringsXml(const Options &options)
fprintf(stdout, " -- res/values/strings.xml\n");
QHash<QString, QString> replacements;
- replacements[QStringLiteral("<!-- %%INSERT_APP_NAME%% -->")] = QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1);
+ replacements[QStringLiteral("<!-- %%INSERT_APP_NAME%% -->")] = options.applicationBinary;
- QString fileName = options.outputDirectory + QLatin1String("/res/values/strings.xml");
+ QString fileName = options.outputDirectory + QStringLiteral("/res/values/strings.xml");
if (!QFile::exists(fileName)) {
if (options.verbose)
fprintf(stdout, " -- Create strings.xml since it's missing.\n");
@@ -1268,7 +1361,7 @@ bool updateStringsXml(const Options &options)
return false;
}
file.write(QByteArray("<?xml version='1.0' encoding='utf-8'?><resources><string name=\"app_name\" translatable=\"false\">")
- .append(QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1).toLatin1())
+ .append(options.applicationBinary.toLatin1())
.append("</string></resources>\n"));
return true;
}
@@ -1284,71 +1377,34 @@ bool updateAndroidManifest(Options &options)
if (options.verbose)
fprintf(stdout, " -- AndroidManifest.xml \n");
- QStringList localLibs = options.localLibs;
-
- // If .pro file overrides dependency detection, we need to see which platform plugin they picked
- if (localLibs.isEmpty()) {
- QString plugin;
- for (const QtDependency &qtDependency : qAsConst(options.qtDependencies)) {
- if (qtDependency.relativePath.endsWith(QLatin1String("libqtforandroid.so"))
- || qtDependency.relativePath.endsWith(QLatin1String("libqtforandroidGL.so"))) {
- if (!plugin.isEmpty() && plugin != qtDependency.relativePath) {
- fprintf(stderr, "Both platform plugins libqtforandroid.so and libqtforandroidGL.so included in package. Please include only one.\n");
- return false;
- }
-
- plugin = qtDependency.relativePath;
- }
- }
-
- if (plugin.isEmpty()) {
- fprintf(stderr, "No platform plugin, neither libqtforandroid.so or libqtforandroidGL.so, included in package. Please include one.\n");
- return false;
- }
-
- localLibs.append(plugin);
- if (options.verbose)
- fprintf(stdout, " -- Using platform plugin %s\n", qPrintable(plugin));
- }
-
- bool usesGL = false;
- for (const QtDependency &qtDependency : qAsConst(options.qtDependencies)) {
- if (qtDependency.relativePath.endsWith(QLatin1String("libQt5OpenGL.so"))
- || qtDependency.relativePath.endsWith(QLatin1String("libQt5Quick.so"))) {
- usesGL = true;
- break;
- }
- }
-
options.localJars.removeDuplicates();
options.initClasses.removeDuplicates();
QHash<QString, QString> replacements;
- replacements[QLatin1String("-- %%INSERT_APP_NAME%% --")] = QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1);
- replacements[QLatin1String("-- %%INSERT_APP_LIB_NAME%% --")] = QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1);
- replacements[QLatin1String("-- %%INSERT_LOCAL_LIBS%% --")] = localLibs.join(QLatin1Char(':'));
- replacements[QLatin1String("-- %%INSERT_LOCAL_JARS%% --")] = options.localJars.join(QLatin1Char(':'));
- replacements[QLatin1String("-- %%INSERT_INIT_CLASSES%% --")] = options.initClasses.join(QLatin1Char(':'));
- replacements[QLatin1String("-- %%INSERT_VERSION_NAME%% --")] = options.versionName;
- replacements[QLatin1String("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode;
- replacements[QLatin1String("package=\"org.qtproject.example\"")] = QString::fromLatin1("package=\"%1\"").arg(options.packageName);
- replacements[QLatin1String("-- %%BUNDLE_LOCAL_QT_LIBS%% --")]
- = (options.deploymentMechanism == Options::Bundled) ? QString::fromLatin1("1") : QString::fromLatin1("0");
- replacements[QLatin1String("-- %%USE_LOCAL_QT_LIBS%% --")]
- = (options.deploymentMechanism != Options::Ministro) ? QString::fromLatin1("1") : QString::fromLatin1("0");
+ replacements[QStringLiteral("-- %%INSERT_APP_NAME%% --")] = options.applicationBinary;
+ replacements[QStringLiteral("-- %%INSERT_APP_LIB_NAME%% --")] = options.applicationBinary;
+ replacements[QStringLiteral("-- %%INSERT_LOCAL_JARS%% --")] = options.localJars.join(QLatin1Char(':'));
+ replacements[QStringLiteral("-- %%INSERT_INIT_CLASSES%% --")] = options.initClasses.join(QLatin1Char(':'));
+ replacements[QStringLiteral("-- %%INSERT_VERSION_NAME%% --")] = options.versionName;
+ replacements[QStringLiteral("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode;
+ replacements[QStringLiteral("package=\"org.qtproject.example\"")] = QStringLiteral("package=\"%1\"").arg(options.packageName);
+ replacements[QStringLiteral("-- %%BUNDLE_LOCAL_QT_LIBS%% --")]
+ = (options.deploymentMechanism == Options::Bundled) ? QStringLiteral("1") : QStringLiteral("0");
+ replacements[QStringLiteral("-- %%USE_LOCAL_QT_LIBS%% --")]
+ = (options.deploymentMechanism != Options::Ministro) ? QStringLiteral("1") : QStringLiteral("0");
QString permissions;
for (const QString &permission : qAsConst(options.permissions))
- permissions += QString::fromLatin1(" <uses-permission android:name=\"%1\" />\n").arg(permission);
- replacements[QLatin1String("<!-- %%INSERT_PERMISSIONS -->")] = permissions;
+ permissions += QStringLiteral(" <uses-permission android:name=\"%1\" />\n").arg(permission);
+ replacements[QStringLiteral("<!-- %%INSERT_PERMISSIONS -->")] = permissions.trimmed();
QString features;
for (const QString &feature : qAsConst(options.features))
features += QStringLiteral(" <uses-feature android:name=\"%1\" android:required=\"false\" />\n").arg(feature);
- if (usesGL)
+ if (options.usesOpenGL)
features += QStringLiteral(" <uses-feature android:glEsVersion=\"0x00020000\" android:required=\"true\" />");
- replacements[QLatin1String("<!-- %%INSERT_FEATURES -->")] = features;
+ replacements[QStringLiteral("<!-- %%INSERT_FEATURES -->")] = features.trimmed();
QString androidManifestPath = options.outputDirectory + QLatin1String("/AndroidManifest.xml");
if (!updateFile(androidManifestPath, replacements))
@@ -1409,7 +1465,7 @@ bool updateAndroidFiles(Options &options)
if (options.verbose)
fprintf(stdout, "Updating Android package files with project settings.\n");
- if (!updateLibsXml(options))
+ if (!updateLibsXml(&options))
return false;
if (!updateAndroidManifest(options))
@@ -1466,7 +1522,7 @@ bool readAndroidDependencyXml(Options *options,
QSet<QString> *usedDependencies,
QSet<QString> *remainingDependencies)
{
- QString androidDependencyName = absoluteFilePath(options, QString::fromLatin1("/lib/%1-android-dependencies.xml").arg(moduleName));
+ QString androidDependencyName = absoluteFilePath(options, QStringLiteral("/lib/%1-android-dependencies.xml").arg(moduleName));
QFile androidDependencyFile(androidDependencyName);
if (androidDependencyFile.exists()) {
@@ -1505,7 +1561,7 @@ bool readAndroidDependencyXml(Options *options,
if (options->verbose)
fprintf(stdout, "Appending dependency from xml: %s\n", qPrintable(fileName.relativePath));
- options->qtDependencies.append(fileName);
+ options->qtDependencies[options->currentArchitecture].append(fileName);
}
} else if (reader.name() == QLatin1String("jar")) {
int bundling = reader.attributes().value(QLatin1String("bundling")).toInt();
@@ -1513,7 +1569,7 @@ bool readAndroidDependencyXml(Options *options,
if (bundling == (options->deploymentMechanism == Options::Bundled)) {
QtDependency dependency(fileName, absoluteFilePath(options, fileName));
if (!usedDependencies->contains(dependency.absolutePath)) {
- options->qtDependencies.append(dependency);
+ options->qtDependencies[options->currentArchitecture].append(dependency);
usedDependencies->insert(dependency.absolutePath);
}
}
@@ -1529,15 +1585,15 @@ bool readAndroidDependencyXml(Options *options,
if (reader.attributes().hasAttribute(QLatin1String("replaces"))) {
QString replaces = reader.attributes().value(QLatin1String("replaces")).toString();
for (int i=0; i<options->localLibs.size(); ++i) {
- if (options->localLibs.at(i) == replaces) {
- options->localLibs[i] = fileName;
+ if (options->localLibs[options->currentArchitecture].at(i) == replaces) {
+ options->localLibs[options->currentArchitecture][i] = fileName;
break;
}
}
} else if (!fileName.isEmpty()) {
- options->localLibs.append(fileName);
+ options->localLibs[options->currentArchitecture].append(fileName);
}
- if (fileName.endsWith(QLatin1String(".so"))) {
+ if (fileName.endsWith(QStringLiteral(".so")) && checkArchitecture(*options, fileName)) {
remainingDependencies->insert(fileName);
}
} else if (reader.name() == QLatin1String("permission")) {
@@ -1557,26 +1613,19 @@ bool readAndroidDependencyXml(Options *options,
} else if (options->verbose) {
fprintf(stdout, "No android dependencies for %s\n", qPrintable(moduleName));
}
+ options->permissions.removeDuplicates();
+ options->features.removeDuplicates();
return true;
}
QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
{
- QString readElf = options.ndkPath
- + QLatin1String("/toolchains/")
- + options.toolchainPrefix;
-
- if (!options.useLLVM)
- readElf += QLatin1Char('-') + options.toolchainVersion;
-
- readElf += QLatin1String("/prebuilt/")
- + options.ndkHost
- + QLatin1String("/bin/")
- + options.toolPrefix +
- (options.useLLVM ? QLatin1String("-readobj") : QLatin1String("-readelf"));
+ QString readElf = QStringLiteral("%1/toolchains/%2/prebuilt/%3/bin/llvm-readobj").arg(options.ndkPath,
+ options.toolchainPrefix,
+ options.ndkHost);
#if defined(Q_OS_WIN32)
- readElf += QLatin1String(".exe");
+ readElf += QStringLiteral(".exe");
#endif
if (!QFile::exists(readElf)) {
@@ -1584,14 +1633,11 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
return QStringList();
}
- if (options.useLLVM)
- readElf = QString::fromLatin1("%1 -needed-libs %2").arg(shellQuote(readElf), shellQuote(fileName));
- else
- readElf = QString::fromLatin1("%1 -d -W %2").arg(shellQuote(readElf), shellQuote(fileName));
+ readElf = QStringLiteral("%1 -needed-libs %2").arg(shellQuote(readElf), shellQuote(fileName));
FILE *readElfCommand = openProcess(readElf);
if (!readElfCommand) {
- fprintf(stderr, "Cannot execute command %s", qPrintable(readElf));
+ fprintf(stderr, "Cannot execute command %s\n", qPrintable(readElf));
return QStringList();
}
@@ -1599,23 +1645,26 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
bool readLibs = false;
char buffer[512];
- while (fgets(buffer, sizeof(buffer), readElfCommand) != 0) {
+ while (fgets(buffer, sizeof(buffer), readElfCommand) != nullptr) {
QByteArray line = QByteArray::fromRawData(buffer, qstrlen(buffer));
QString library;
- if (options.useLLVM) {
- line = line.trimmed();
- if (!readLibs) {
- readLibs = line.startsWith("NeededLibraries");
- continue;
+ line = line.trimmed();
+ if (!readLibs) {
+ if (line.startsWith("Arch: ")) {
+ auto it = elfArchitecures.find(line.mid(6));
+ if (it == elfArchitecures.constEnd() || *it != options.currentArchitecture.toLatin1()) {
+ if (options.verbose)
+ fprintf(stdout, "Skipping \"%s\", architecture mismatch\n", qPrintable(fileName));
+ return {};
+ }
}
- if (!line.startsWith("lib"))
- continue;
- library = QString::fromLatin1(line);
- } else if (line.contains("(NEEDED)") && line.contains("Shared library:")) {
- const int pos = line.lastIndexOf('[') + 1;
- library = QString::fromLatin1(line.mid(pos, line.length() - pos - 2));
+ readLibs = line.startsWith("NeededLibraries");
+ continue;
}
- QString libraryName = QLatin1String("lib/") + library;
+ if (!line.startsWith("lib"))
+ continue;
+ library = QString::fromLatin1(line);
+ QString libraryName = QStringLiteral("lib/") + library;
if (QFile::exists(absoluteFilePath(&options, libraryName)))
ret += libraryName;
}
@@ -1653,7 +1702,7 @@ bool readDependenciesFromElf(Options *options,
return false;
}
- options->qtDependencies.append(QtDependency(dependency, absoluteDependencyPath));
+ options->qtDependencies[options->currentArchitecture].append(QtDependency(dependency, absoluteDependencyPath));
if (options->verbose)
fprintf(stdout, "Appending dependency: %s\n", qPrintable(dependency));
dependenciesToCheck.append(dependency);
@@ -1797,10 +1846,10 @@ bool scanImports(Options *options, QSet<QString> *usedDependencies)
fprintf(stdout, " -- Appending dependency found by qmlimportscanner: %s\n", qPrintable(fileName.absolutePath));
// Put all imports in default import path in assets
- fileName.relativePath.prepend(QLatin1String("qml/"));
- options->qtDependencies.append(fileName);
+ fileName.relativePath.prepend(QStringLiteral("qml/"));
+ options->qtDependencies[options->currentArchitecture].append(fileName);
- if (fileName.absolutePath.endsWith(QLatin1String(".so"))) {
+ if (fileName.absolutePath.endsWith(QStringLiteral(".so")) && checkArchitecture(*options, fileName.absolutePath)) {
QSet<QString> remainingDependencies;
if (!readDependenciesFromElf(options, fileName.absolutePath, usedDependencies, &remainingDependencies))
return false;
@@ -1819,7 +1868,7 @@ bool readDependencies(Options *options)
fprintf(stdout, "Detecting dependencies of application.\n");
// Override set in .pro file
- if (!options->qtDependencies.isEmpty()) {
+ if (!options->qtDependencies[options->currentArchitecture].isEmpty()) {
if (options->verbose)
fprintf(stdout, "\tDependencies explicitly overridden in .pro file. No detection needed.\n");
return true;
@@ -1829,11 +1878,7 @@ bool readDependencies(Options *options)
QSet<QString> remainingDependencies;
// Add dependencies of application binary first
- if (!readDependenciesFromElf(options, options->applicationBinary, &usedDependencies, &remainingDependencies))
- return false;
-
- // Jam in the dependencies of the platform plugin, since the application will crash without it
- if (!readDependenciesFromElf(options, options->qtInstallDirectory + QLatin1String("/plugins/platforms/android/libqtforandroid.so"), &usedDependencies, &remainingDependencies))
+ if (!readDependenciesFromElf(options, QStringLiteral("%1/libs/%2/lib%3_%2.so").arg(options->outputDirectory, options->currentArchitecture, options->applicationBinary), &usedDependencies, &remainingDependencies))
return false;
while (!remainingDependencies.isEmpty()) {
@@ -1853,14 +1898,14 @@ bool readDependencies(Options *options)
}
}
- QStringList::iterator it = options->localLibs.begin();
- while (it != options->localLibs.end()) {
+ QStringList::iterator it = options->localLibs[options->currentArchitecture].begin();
+ while (it != options->localLibs[options->currentArchitecture].end()) {
QStringList unmetDependencies;
if (!goodToCopy(options, absoluteFilePath(options, *it), &unmetDependencies)) {
fprintf(stdout, "Skipping %s due to unmet dependencies: %s\n",
qPrintable(*it),
qPrintable(unmetDependencies.join(QLatin1Char(','))));
- it = options->localLibs.erase(it);
+ it = options->localLibs[options->currentArchitecture].erase(it);
} else {
++it;
}
@@ -1872,94 +1917,33 @@ bool readDependencies(Options *options)
return true;
}
-bool stripFile(const Options &options, const QString &fileName)
-{
- QString strip = options.ndkPath
- + QLatin1String("/toolchains/")
- + options.toolchainPrefix;
-
- if (!options.useLLVM)
- strip += QLatin1Char('-') + options.toolchainVersion;
-
- strip += QLatin1String("/prebuilt/")
- + options.ndkHost
- + QLatin1String("/bin/")
- + options.toolPrefix
- + QLatin1String("-strip");
-#if defined(Q_OS_WIN32)
- strip += QLatin1String(".exe");
-#endif
-
- if (!QFile::exists(strip)) {
- fprintf(stderr, "Command does not exist: %s\n", qPrintable(strip));
- return false;
- }
-
- if (options.useLLVM)
- strip = QString::fromLatin1("%1 -strip-all %2").arg(shellQuote(strip), shellQuote(fileName));
- else
- strip = QString::fromLatin1("%1 %2").arg(shellQuote(strip), shellQuote(fileName));
-
- FILE *stripCommand = openProcess(strip);
- if (stripCommand == 0) {
- fprintf(stderr, "Cannot execute command %s", qPrintable(strip));
- return false;
- }
-
- pclose(stripCommand);
-
- return true;
-}
-
-bool stripLibraries(const Options &options)
+bool containsApplicationBinary(Options *options)
{
- if (!options.stripLibraries)
+ if (!options->build)
return true;
- if (options.verbose)
- fprintf(stdout, "Stripping libraries to minimize size.\n");
-
-
- QString libraryPath = options.outputDirectory
- + QLatin1String("/libs/")
- + options.architecture;
- const QStringList libraries = QDir(libraryPath).entryList(QDir::Files);
- for (const QString &library : libraries) {
- if (library.endsWith(QLatin1String(".so"))) {
- if (!stripFile(options, libraryPath + QLatin1Char('/') + library))
- return false;
- }
- }
-
- return true;
-}
-
-bool containsApplicationBinary(const Options &options)
-{
- if (options.verbose)
+ if (options->verbose)
fprintf(stdout, "Checking if application binary is in package.\n");
- QFileInfo applicationBinary(options.applicationBinary);
- QString destinationFileName = options.outputDirectory
- + QLatin1String("/libs/")
- + options.architecture
- + QLatin1Char('/')
- + applicationBinary.fileName();
+ QFileInfo applicationBinary(options->applicationBinary);
+ QString applicationFileName = QStringLiteral("lib%1_%2.so").arg(options->applicationBinary,
+ options->currentArchitecture);
- if (!QFile::exists(destinationFileName)) {
+ QString applicationPath = QStringLiteral("%1/libs/%2/%3").arg(options->outputDirectory,
+ options->currentArchitecture,
+ applicationFileName);
+ if (!QFile::exists(applicationPath)) {
#if defined(Q_OS_WIN32)
QLatin1String makeTool("mingw32-make"); // Only Mingw host builds supported on Windows currently
#else
QLatin1String makeTool("make");
#endif
-
fprintf(stderr, "Application binary is not in output directory: %s. Please run '%s install INSTALL_ROOT=%s' first.\n",
- qPrintable(destinationFileName),
+ qPrintable(applicationFileName),
qPrintable(makeTool),
- qPrintable(options.outputDirectory));
+ qPrintable(options->outputDirectory));
return false;
}
-
return true;
}
@@ -1997,10 +1981,13 @@ bool goodToCopy(const Options *options, const QString &file, QStringList *unmetD
if (!file.endsWith(QLatin1String(".so")))
return true;
+ if (!checkArchitecture(*options, file))
+ return false;
+
bool ret = true;
const auto libs = getQtLibsFromElf(*options, file);
for (const QString &lib : libs) {
- if (!options->qtDependencies.contains(QtDependency(lib, absoluteFilePath(options, lib)))) {
+ if (!options->qtDependencies[options->currentArchitecture].contains(QtDependency(lib, absoluteFilePath(options, lib)))) {
ret = false;
unmetDependencies->append(lib);
}
@@ -2027,25 +2014,22 @@ bool copyQtFiles(Options *options)
QString libsDirectory = QLatin1String("libs/");
+
// Copy other Qt dependencies
- QString libDestinationDirectory = libsDirectory + options->architecture + QLatin1Char('/');
- QString assetsDestinationDirectory = QLatin1String("assets/--Added-by-androiddeployqt--/");
- for (const QtDependency &qtDependency : qAsConst(options->qtDependencies)) {
+ QString assetsDestinationDirectory = QStringLiteral("assets/--Added-by-androiddeployqt--/");
+ for (const QtDependency &qtDependency : qAsConst(options->qtDependencies[options->currentArchitecture])) {
QString sourceFileName = qtDependency.absolutePath;
QString destinationFileName;
- if (qtDependency.relativePath.endsWith(QLatin1String(".so"))) {
+ if (qtDependency.relativePath.endsWith(QStringLiteral(".so"))) {
QString garbledFileName;
- if (qtDependency.relativePath.startsWith(QLatin1String("lib/"))) {
+ if (qtDependency.relativePath.startsWith(QStringLiteral("lib/"))) {
garbledFileName = qtDependency.relativePath.mid(sizeof("lib/") - 1);
} else {
- garbledFileName = QLatin1String("lib")
- + QString(qtDependency.relativePath).replace(QLatin1Char('/'), QLatin1Char('_'));
-
+ garbledFileName = QString(qtDependency.relativePath).replace(QLatin1Char('/'), QLatin1Char('_'));
}
- destinationFileName = libDestinationDirectory + garbledFileName;
-
- } else if (qtDependency.relativePath.startsWith(QLatin1String("jar/"))) {
+ destinationFileName = libsDirectory + options->currentArchitecture + QLatin1Char('/') + garbledFileName;
+ } else if (qtDependency.relativePath.startsWith(QStringLiteral("jar/"))) {
destinationFileName = libsDirectory + qtDependency.relativePath.mid(sizeof("jar/") - 1);
} else {
destinationFileName = assetsDestinationDirectory + qtDependency.relativePath;
@@ -2058,20 +2042,34 @@ bool copyQtFiles(Options *options)
QStringList unmetDependencies;
if (!goodToCopy(options, sourceFileName, &unmetDependencies)) {
- fprintf(stdout, " -- Skipping %s. It has unmet dependencies: %s.\n",
- qPrintable(sourceFileName),
- qPrintable(unmetDependencies.join(QLatin1Char(','))));
+ if (unmetDependencies.isEmpty()) {
+ if (options->verbose) {
+ fprintf(stdout, " -- Skipping %s, architecture mismatch.\n",
+ qPrintable(sourceFileName));
+ }
+ } else {
+ if (unmetDependencies.isEmpty()) {
+ if (options->verbose) {
+ fprintf(stdout, " -- Skipping %s, architecture mismatch.\n",
+ qPrintable(sourceFileName));
+ }
+ } else {
+ fprintf(stdout, " -- Skipping %s. It has unmet dependencies: %s.\n",
+ qPrintable(sourceFileName),
+ qPrintable(unmetDependencies.join(QLatin1Char(','))));
+ }
+ }
continue;
}
if (options->deploymentMechanism == Options::Bundled
&& !copyFileIfNewer(sourceFileName,
options->outputDirectory + QLatin1Char('/') + destinationFileName,
- options->verbose)) {
+ *options)) {
return false;
}
- options->bundledFiles += qMakePair(destinationFileName, qtDependency.relativePath);
+ options->bundledFiles[options->currentArchitecture] += qMakePair(destinationFileName, qtDependency.relativePath);
}
return true;
@@ -2409,21 +2407,18 @@ bool copyStdCpp(Options *options)
if (options->verbose)
fprintf(stdout, "Copying STL library\n");
- if (!QFile::exists(options->stdCppPath)) {
- fprintf(stderr, "STL library does not exist at %s\n", qPrintable(options->stdCppPath));
- return false;
- }
-
- const QString destinationDirectory = options->outputDirectory
- + QLatin1String("/libs/") + options->architecture;
-
- if (!copyFileIfNewer(options->stdCppPath, destinationDirectory + QLatin1String("/lib")
- + options->stdCppName + QLatin1String(".so"),
- options->verbose)) {
+ QString stdCppPath = QStringLiteral("%1/%2/lib%3.so").arg(options->stdCppPath, options->architectures[options->currentArchitecture], options->stdCppName);
+ if (!QFile::exists(stdCppPath)) {
+ fprintf(stderr, "STL library does not exist at %s\n", qPrintable(stdCppPath));
+ fflush(stdout);
+ fflush(stderr);
return false;
}
- return true;
+ const QString destinationFile = QStringLiteral("%1/libs/%2/lib%3.so").arg(options->outputDirectory,
+ options->currentArchitecture,
+ options->stdCppName);
+ return copyFileIfNewer(stdCppPath, destinationFile, *options);
}
bool jarSignerSignPackage(const Options &options)
@@ -2654,55 +2649,6 @@ bool signPackage(const Options &options)
return apkSignerRunner() && QFile::remove(apkPath(options, UnsignedAPK));
}
-bool copyGdbServer(const Options &options)
-{
- if (options.verbose)
- fprintf(stdout, "Copying gdbserver into package.\n");
-
- QString architectureSubDirectory;
- if (options.architecture == QLatin1String("arm64-v8a"))
- architectureSubDirectory = QLatin1String("android-arm64");
- else if (options.architecture.startsWith(QLatin1String("arm")))
- architectureSubDirectory = QLatin1String("android-arm");
- else
- architectureSubDirectory = QLatin1String("android-") + options.architecture;
-
- QString gdbServerBinary = options.ndkPath
- + QLatin1String("/prebuilt/")
- + architectureSubDirectory
- + QLatin1String("/gdbserver/gdbserver");
- if (!QFile::exists(gdbServerBinary)) {
- fprintf(stderr, "Cannot find gdbserver at %s.\n", qPrintable(gdbServerBinary));
- return false;
- }
-
- QString gdbServerTarget = options.outputDirectory + QLatin1String("/libs/") + options.architecture;
-
- if (!copyFileIfNewer(gdbServerBinary,
- gdbServerTarget + QLatin1String("/gdbserver"),
- options.verbose)
- || !copyFileIfNewer(gdbServerBinary,
- gdbServerTarget + QLatin1String("/libgdbserver.so"),
- options.verbose)) {
- return false;
- }
-
- QString addedByAndroidDeployQtPath = options.outputDirectory + QLatin1String("/assets/--Added-by-androiddeployqt--/");
- if (!QDir().mkpath(addedByAndroidDeployQtPath)) {
- fprintf(stderr, "Failed to create directory '%s'", qPrintable(addedByAndroidDeployQtPath));
- return false;
- }
- QFile f(addedByAndroidDeployQtPath + QLatin1String("debugger.command"));
- if (!f.open(QIODevice::WriteOnly)) {
- fprintf(stderr, "Failed to create directory '%s'", qPrintable(addedByAndroidDeployQtPath));
- return false;
- }
- f.write("lib/libgdbserver.so --multi +");
- f.close();
-
- return true;
-}
-
bool generateAssetsFileList(const Options &options)
{
if (options.verbose)
@@ -2764,8 +2710,6 @@ enum ErrorCode
CannotCopyGnuStl = 5,
CannotCopyQtFiles = 6,
CannotFindApplicationBinary = 7,
- CannotCopyGdbServer = 8,
- CannotStripLibraries = 9,
CannotCopyAndroidExtraLibs = 10,
CannotCopyAndroidSources = 11,
CannotUpdateAndroidFiles = 12,
@@ -2813,25 +2757,7 @@ int main(int argc, char *argv[])
: "No"
);
- if (options.auxMode) {
- if (!readDependencies(&options))
- return CannotReadDependencies;
- if (!copyQtFiles(&options))
- return CannotCopyQtFiles;
- if (!copyAndroidExtraResources(options))
- return CannotCopyAndroidExtraResources;
- if (!copyAndroidExtraLibs(options))
- return CannotCopyAndroidExtraLibs;
- if (!stripLibraries(options))
- return CannotStripLibraries;
- if (!updateAndroidFiles(options))
- return CannotUpdateAndroidFiles;
- if (options.generateAssetsFileList && !generateAssetsFileList(options))
- return CannotGenerateAssetsFileList;
- return 0;
- }
-
- if (options.build) {
+ if (options.build && !options.auxMode) {
cleanAndroidFiles(options);
if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %d ms: Cleaned Android file\n", options.timer.elapsed());
@@ -2843,60 +2769,68 @@ int main(int argc, char *argv[])
fprintf(stdout, "[TIMING] %d ms: Copied Android template\n", options.timer.elapsed());
}
- if (!readDependencies(&options))
- return CannotReadDependencies;
-
- if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Read dependencies\n", options.timer.elapsed());
+ for (auto it = options.architectures.constBegin(); it != options.architectures.constEnd(); ++it) {
+ options.clear(it.key());
- if (options.deploymentMechanism != Options::Ministro && !copyStdCpp(&options))
- return CannotCopyGnuStl;
+ if (!readDependencies(&options))
+ return CannotReadDependencies;
- if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Copied GNU STL\n", options.timer.elapsed());
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Read dependencies\n", options.timer.elapsed());
- if (!copyQtFiles(&options))
- return CannotCopyQtFiles;
+ if (!copyQtFiles(&options))
+ return CannotCopyQtFiles;
- if (options.build) {
if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %d ms: Copied Qt files\n", options.timer.elapsed());
- if (!containsApplicationBinary(options))
- return CannotFindApplicationBinary;
+ if (!copyAndroidExtraLibs(&options))
+ return CannotCopyAndroidExtraLibs;
if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Checked for application binary\n", options.timer.elapsed());
+ fprintf(stdout, "[TIMING] %d ms: Copied extra libs\n", options.timer.elapsed());
- bool needToCopyGdbServer = options.gdbServer == Options::True
- || (options.gdbServer == Options::Auto && !options.releasePackage);
- if (needToCopyGdbServer && !copyGdbServer(options))
- return CannotCopyGdbServer;
+ if (!copyAndroidExtraResources(&options))
+ return CannotCopyAndroidExtraResources;
if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Copied GDB server\n", options.timer.elapsed());
+ fprintf(stdout, "[TIMING] %d ms: Copied extra resources\n", options.timer.elapsed());
- if (!copyAndroidExtraLibs(options))
- return CannotCopyAndroidExtraLibs;
+ if (!options.auxMode) {
+ if (options.deploymentMechanism != Options::Ministro && !copyStdCpp(&options))
+ return CannotCopyGnuStl;
+
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Copied GNU STL\n", options.timer.elapsed());
+ }
+
+ if (!containsApplicationBinary(&options))
+ return CannotFindApplicationBinary;
if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Copied extra libs\n", options.timer.elapsed());
+ fprintf(stdout, "[TIMING] %d ms: Checked for application binary\n", options.timer.elapsed());
- if (!copyAndroidExtraResources(options))
- return CannotCopyAndroidExtraResources;
+ if (options.deploymentMechanism != Options::Ministro) {
+ if (Q_UNLIKELY(options.timing))
+ fprintf(stdout, "[TIMING] %d ms: Bundled Qt libs\n", options.timer.elapsed());
+ }
+ }
+ if (options.auxMode) {
+ if (!updateAndroidFiles(options))
+ return CannotUpdateAndroidFiles;
+ if (options.generateAssetsFileList && !generateAssetsFileList(options))
+ return CannotGenerateAssetsFileList;
+ return 0;
+ }
+
+ if (options.build) {
if (!copyAndroidSources(options))
return CannotCopyAndroidSources;
if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %d ms: Copied android sources\n", options.timer.elapsed());
- if (!stripLibraries(options))
- return CannotStripLibraries;
-
- if (Q_UNLIKELY(options.timing))
- fprintf(stdout, "[TIMING] %d ms: Stripped libraries\n", options.timer.elapsed());
-
if (!updateAndroidFiles(options))
return CannotUpdateAndroidFiles;
diff --git a/src/tools/androidtestrunner/main.cpp b/src/tools/androidtestrunner/main.cpp
index e6d6f72354..f61d407d4a 100644
--- a/src/tools/androidtestrunner/main.cpp
+++ b/src/tools/androidtestrunner/main.cpp
@@ -362,7 +362,7 @@ static bool parseTestArgs()
g_options.testArgs += QStringLiteral(" -o output.%1,%1").arg(format);
g_options.testArgs += unhandledArgs;
- g_options.testArgs = QStringLiteral("shell am start -e applicationArguments \"'%1'\" -n %2/%3").arg(shellQuote(g_options.testArgs.trimmed()),
+ g_options.testArgs = QStringLiteral("shell am start -e applicationArguments \\\"%1\\\" -n %2/%3").arg(shellQuote(g_options.testArgs.trimmed()),
g_options.package,
g_options.activity);
return true;
@@ -409,7 +409,7 @@ static bool pullFiles()
return false;
}
auto checkerIt = g_options.checkFiles.find(it.key());
- ret &= checkerIt != g_options.checkFiles.end() && checkerIt.value()(output);
+ ret = ret && checkerIt != g_options.checkFiles.end() && checkerIt.value()(output);
if (it.value() == QStringLiteral("-")){
fprintf(stdout, "%s", output.constData());
fflush(stdout);
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index a89192e76f..a1b9003c1c 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -2448,6 +2448,51 @@ void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::funct
}
/*!
+ This is a convenience static function that saves \a fileContent to a file, using
+ a file name and location chosen by the user. \a fileNameHint can be provided to
+ suggest a file name to the user.
+
+ This function is used to save files to the local file system on Qt for WebAssembly, where
+ the web sandbox places restrictions on how such access may happen. Its implementation will
+ make the browser display a native file dialog, where the user makes the file selection.
+
+ It can also be used on other platforms, where it will fall back to using QFileDialog.
+
+ The function is asynchronous and returns immediately.
+
+ \snippet code/src_gui_dialogs_qfiledialog.cpp 16
+ \since 5.14
+*/
+void QFileDialog::saveFileContent(const QByteArray &fileContent, const QString &fileNameHint)
+{
+#ifdef Q_OS_WASM
+ QWasmLocalFileAccess::saveFile(fileContent.constData(), fileContent.size(), fileNameHint.toStdString());
+#else
+ QFileDialog *dialog = new QFileDialog();
+ dialog->setAcceptMode(QFileDialog::AcceptSave);
+ dialog->setFileMode(QFileDialog::AnyFile);
+ dialog->selectFile(fileNameHint);
+
+ auto fileSelected = [=](const QString &fileName) {
+ if (!fileName.isNull()) {
+ QFile selectedFile(fileName);
+ if (selectedFile.open(QIODevice::WriteOnly))
+ selectedFile.write(fileContent);
+ }
+ };
+
+ auto dialogClosed = [=](int code) {
+ Q_UNUSED(code);
+ delete dialog;
+ };
+
+ connect(dialog, &QFileDialog::fileSelected, fileSelected);
+ connect(dialog, &QFileDialog::finished, dialogClosed);
+ dialog->show();
+#endif
+}
+
+/*!
This is a convenience static function that will return a file name selected
by the user. The file does not have to exist.
diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h
index 354a1f928b..790f52f2e7 100644
--- a/src/widgets/dialogs/qfiledialog.h
+++ b/src/widgets/dialogs/qfiledialog.h
@@ -284,6 +284,7 @@ public:
static void getOpenFileContent(const QString &nameFilter,
const std::function<void(const QString &, const QByteArray &)> &fileContentsReady);
+ static void saveFileContent(const QByteArray &fileContent, const QString &fileNameHint = QString());
protected:
QFileDialog(const QFileDialogArgs &args);
diff --git a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
index 39aca459db..7ccd827a04 100644
--- a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
+++ b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp
@@ -155,3 +155,8 @@ auto fileOpenCompleted = [](const QString &fileName, const QByteArray &fileConte
}
QFileDialog::getOpenFileContent("Images (*.png *.xpm *.jpg)", fileContentReady);
//! [15]
+
+//! [16]
+QByteArray imageData; // obtained from e.g. QImage::save()
+QFileDialog::saveFile("myimage.png", imageData);
+//! [16]
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
index 2b6712075f..7413a26261 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -404,7 +404,7 @@ void QGraphicsProxyWidgetPrivate::_q_removeWidgetSlot()
{
Q_Q(QGraphicsProxyWidget);
if (!widget.isNull()) {
- if (QWExtra *extra = widget->d_func()->extra)
+ if (const auto &extra = widget->d_func()->extra)
extra->proxyWidget = 0;
}
widget = 0;
@@ -477,8 +477,8 @@ void QGraphicsProxyWidgetPrivate::updateProxyInputMethodAcceptanceFromWidget()
*/
void QGraphicsProxyWidgetPrivate::embedSubWindow(QWidget *subWin)
{
- QWExtra *extra;
- if (!((extra = subWin->d_func()->extra) && extra->proxyWidget)) {
+ const auto &extra = subWin->d_func()->extra;
+ if (!extra || !extra->proxyWidget) {
QGraphicsProxyWidget *subProxy = new QGraphicsProxyWidget(q_func(), subWin->windowFlags());
subProxy->d_func()->setWidget_helper(subWin, false);
}
@@ -631,7 +631,7 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto
if (!newWidget)
return;
if (!newWidget->isWindow()) {
- QWExtra *extra = newWidget->parentWidget()->d_func()->extra;
+ const auto &extra = newWidget->parentWidget()->d_func()->extra;
if (!extra || !extra->proxyWidget) {
qWarning("QGraphicsProxyWidget::setWidget: cannot embed widget %p "
"which is not a toplevel widget, and is not a child of an embedded widget", newWidget);
@@ -641,10 +641,10 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto
// Register this proxy within the widget's private.
// ### This is a bit backdoorish
- QWExtra *extra = newWidget->d_func()->extra;
+ QWExtra *extra = newWidget->d_func()->extra.get();
if (!extra) {
newWidget->d_func()->createExtra();
- extra = newWidget->d_func()->extra;
+ extra = newWidget->d_func()->extra.get();
}
QGraphicsProxyWidget **proxyWidget = &extra->proxyWidget;
if (*proxyWidget) {
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 94b14ecb4f..629c696544 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -3388,7 +3388,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
#if QT_CONFIG(graphicsview)
// QGraphicsProxyWidget handles its own propagation,
// and we must not change QDragManagers currentTarget.
- QWExtra *extra = w->window()->d_func()->extra;
+ const auto &extra = w->window()->d_func()->extra;
if (extra && extra->proxyWidget) {
res = d->notify_helper(w, dragEvent);
break;
@@ -3416,7 +3416,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
#if QT_CONFIG(graphicsview)
// QGraphicsProxyWidget handles its own propagation,
// and we must not change QDragManagers currentTarget.
- QWExtra *extra = w->window()->d_func()->extra;
+ const auto &extra = w->window()->d_func()->extra;
bool isProxyWidget = extra && extra->proxyWidget;
if (!isProxyWidget)
#endif
diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp
index a4ebcdfc84..39b08dbc1e 100644
--- a/src/widgets/kernel/qshortcut.cpp
+++ b/src/widgets/kernel/qshortcut.cpp
@@ -178,7 +178,7 @@ static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidge
// Below is Qt::WindowShortcut context
QWidget *tlw = w->window();
#if QT_CONFIG(graphicsview)
- if (auto topData = static_cast<QWidgetPrivate *>(QObjectPrivate::get(tlw))->extra) {
+ if (auto topData = static_cast<QWidgetPrivate *>(QObjectPrivate::get(tlw))->extra.get()) {
if (topData->proxyWidget) {
bool res = correctGraphicsWidgetContext(context, topData->proxyWidget, active_window);
return res;
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index c0c7f5cf3d..c024f7f1f3 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -130,7 +130,6 @@ extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
QWidgetPrivate::QWidgetPrivate(int version)
: QObjectPrivate(version)
- , extra(0)
, focus_next(0)
, focus_prev(0)
, focus_child(0)
@@ -1460,7 +1459,7 @@ QWidget::~QWidget()
while (w->d_func()->extra && w->d_func()->extra->focus_proxy)
w = w->d_func()->extra->focus_proxy;
QWidget *window = w->window();
- QWExtra *e = window ? window->d_func()->extra : 0;
+ QWExtra *e = window ? window->d_func()->extra.get() : nullptr ;
if (!e || !e->proxyWidget || (w->parentWidget() && w->parentWidget()->d_func()->focus_child == this))
#endif
clearFocus();
@@ -1618,7 +1617,7 @@ void QWidgetPrivate::createTLExtra()
void QWidgetPrivate::createExtra()
{
if (!extra) { // if not exists
- extra = new QWExtra;
+ extra = qt_make_unique<QWExtra>();
extra->glContext = 0;
#if QT_CONFIG(graphicsview)
extra->proxyWidget = 0;
@@ -1666,9 +1665,8 @@ void QWidgetPrivate::deleteExtra()
deleteTLSysExtra();
// extra->topextra->backingStore destroyed in QWidgetPrivate::deleteTLSysExtra()
}
- delete extra;
// extra->xic destroyed in QWidget::destroy()
- extra = 0;
+ extra.reset();
}
}
@@ -1739,7 +1737,7 @@ QRegion QWidgetPrivate::overlappedRegion(const QRect &rect, bool breakAfterFirst
const QRect siblingRect = sibling->d_func()->effectiveRectFor(sibling->data->crect);
if (qRectIntersects(siblingRect, r)) {
- const QWExtra *siblingExtra = sibling->d_func()->extra;
+ const auto &siblingExtra = sibling->d_func()->extra;
if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
&& !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) {
continue;
@@ -3733,7 +3731,7 @@ QSize QWidget::sizeIncrement() const
QSize QWidget::baseSize() const
{
Q_D(const QWidget);
- return (d->extra != 0 && d->extra->topextra != 0)
+ return (d->extra && d->extra->topextra)
? QSize(d->extra->topextra->basew, d->extra->topextra->baseh)
: QSize(0, 0);
}
@@ -5694,7 +5692,7 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
QGraphicsProxyWidget *QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin)
{
if (origin) {
- QWExtra *extra = origin->d_func()->extra;
+ const auto &extra = origin->d_func()->extra;
if (extra && extra->proxyWidget)
return extra->proxyWidget;
return nearestGraphicsProxyWidget(origin->parentWidget());
@@ -6240,7 +6238,7 @@ bool QWidget::hasFocus() const
w = w->d_func()->extra->focus_proxy;
#if QT_CONFIG(graphicsview)
if (QWidget *window = w->window()) {
- QWExtra *e = window->d_func()->extra;
+ const auto &e = window->d_func()->extra;
if (e && e->proxyWidget && e->proxyWidget->hasFocus() && window->focusWidget() == w)
return true;
}
@@ -6297,7 +6295,7 @@ void QWidget::setFocus(Qt::FocusReason reason)
#if QT_CONFIG(graphicsview)
QWidget *previousProxyFocus = 0;
- if (QWExtra *topData = window()->d_func()->extra) {
+ if (const auto &topData = window()->d_func()->extra) {
if (topData->proxyWidget && topData->proxyWidget->hasFocus()) {
previousProxyFocus = topData->proxyWidget->widget()->focusWidget();
if (previousProxyFocus && previousProxyFocus->focusProxy())
@@ -6310,7 +6308,7 @@ void QWidget::setFocus(Qt::FocusReason reason)
#if QT_CONFIG(graphicsview)
// Update proxy state
- if (QWExtra *topData = window()->d_func()->extra) {
+ if (const auto &topData = window()->d_func()->extra) {
if (topData->proxyWidget && !topData->proxyWidget->hasFocus()) {
f->d_func()->updateFocusChild();
topData->proxyWidget->d_func()->focusFromWidgetToProxy = 1;
@@ -6351,7 +6349,7 @@ void QWidget::setFocus(Qt::FocusReason reason)
}
#endif
#if QT_CONFIG(graphicsview)
- if (QWExtra *topData = window()->d_func()->extra) {
+ if (const auto &topData = window()->d_func()->extra) {
if (topData->proxyWidget) {
if (previousProxyFocus && previousProxyFocus != f) {
// Send event to self
@@ -6364,7 +6362,7 @@ void QWidget::setFocus(Qt::FocusReason reason)
if (!isHidden()) {
#if QT_CONFIG(graphicsview)
// Update proxy state
- if (QWExtra *topData = window()->d_func()->extra)
+ if (const auto &topData = window()->d_func()->extra)
if (topData->proxyWidget && topData->proxyWidget->hasFocus())
topData->proxyWidget->d_func()->updateProxyInputMethodAcceptanceFromWidget();
#endif
@@ -6501,7 +6499,7 @@ void QWidget::clearFocus()
}
#if QT_CONFIG(graphicsview)
- QWExtra *topData = d_func()->extra;
+ const auto &topData = d_func()->extra;
if (topData && topData->proxyWidget)
topData->proxyWidget->clearFocus();
#endif
@@ -6660,7 +6658,7 @@ bool QWidget::isActiveWindow() const
return true;
#if QT_CONFIG(graphicsview)
- if (QWExtra *tlwExtra = tlw->d_func()->extra) {
+ if (const auto &tlwExtra = tlw->d_func()->extra) {
if (isVisible() && tlwExtra->proxyWidget)
return tlwExtra->proxyWidget->isActiveWindow();
}
@@ -10050,7 +10048,7 @@ void QWidget::setSizePolicy(QSizePolicy policy)
d->size_policy = policy;
#if QT_CONFIG(graphicsview)
- if (QWExtra *extra = d->extra) {
+ if (const auto &extra = d->extra) {
if (extra->proxyWidget)
extra->proxyWidget->setSizePolicy(policy);
}
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index cfb9a1ad8c..7d8a3ae737 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -626,7 +626,7 @@ public:
// Variables.
// Regular pointers (keep them together to avoid gaps on 64 bit architectures).
- QWExtra *extra;
+ std::unique_ptr<QWExtra> extra;
QWidget *focus_next;
QWidget *focus_prev;
QWidget *focus_child;
@@ -803,7 +803,7 @@ public:
inline QWExtra *QWidgetPrivate::extraData() const
{
- return extra;
+ return extra.get();
}
inline QTLWExtra *QWidgetPrivate::topData() const
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp
index 9be99c4723..5900326087 100644
--- a/src/widgets/widgets/qdockarealayout.cpp
+++ b/src/widgets/widgets/qdockarealayout.cpp
@@ -138,11 +138,8 @@ bool QDockAreaLayoutItem::skip() const
QSize QDockAreaLayoutItem::minimumSize() const
{
- if (widgetItem != 0) {
- int left, top, right, bottom;
- widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
- return widgetItem->minimumSize() + QSize(left+right, top+bottom);
- }
+ if (widgetItem)
+ return widgetItem->minimumSize().grownBy(widgetItem->widget()->contentsMargins());
if (subinfo != 0)
return subinfo->minimumSize();
return QSize(0, 0);
@@ -150,11 +147,8 @@ QSize QDockAreaLayoutItem::minimumSize() const
QSize QDockAreaLayoutItem::maximumSize() const
{
- if (widgetItem != 0) {
- int left, top, right, bottom;
- widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
- return widgetItem->maximumSize()+ QSize(left+right, top+bottom);
- }
+ if (widgetItem)
+ return widgetItem->maximumSize().grownBy(widgetItem->widget()->contentsMargins());
if (subinfo != 0)
return subinfo->maximumSize();
return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
@@ -180,11 +174,8 @@ QSize QDockAreaLayoutItem::sizeHint() const
{
if (placeHolderItem != 0)
return QSize(0, 0);
- if (widgetItem != 0) {
- int left, top, right, bottom;
- widgetItem->widget()->getContentsMargins(&left, &top, &right, &bottom);
- return widgetItem->sizeHint() + QSize(left+right, top+bottom);
- }
+ if (widgetItem)
+ return widgetItem->sizeHint().grownBy(widgetItem->widget()->contentsMargins());
if (subinfo != 0)
return subinfo->sizeHint();
return QSize(-1, -1);
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index 1ba34e0fed..05ec3aface 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -381,11 +381,10 @@ QSize QDockWidgetLayout::sizeFromContent(const QSize &content, bool floating) co
if (content.height() < 0)
result.setHeight(-1);
- int left, top, right, bottom;
- w->getContentsMargins(&left, &top, &right, &bottom);
+ const QMargins margins = w->contentsMargins();
//we need to subtract the contents margin (it will be added by the caller)
- QSize min = w->minimumSize() - QSize(left + right, top + bottom);
- QSize max = w->maximumSize() - QSize(left + right, top + bottom);
+ QSize min = w->minimumSize().shrunkBy(margins);
+ QSize max = w->maximumSize().shrunkBy(margins);
/* A floating dockwidget will automatically get its minimumSize set to the layout's
minimum size + deco. We're *not* interested in this, we only take minimumSize()
diff --git a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
index 53372ce9ae..33cd53d788 100644
--- a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
+++ b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST
@@ -1,9 +1,5 @@
[pauseAndPropertyAnimations]
-osx-10.12
-osx-10.14
-osx-10.13
+osx
[multipleSequentialGroups]
-osx-10.12
-osx-10.14
-osx-10.13
+osx
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST b/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST
index 9b210b0d5f..457499591d 100644
--- a/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST
+++ b/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST
@@ -1,9 +1,7 @@
# QTBUG-33574 QTBUG-30943
[signalsEmittedAfterFileMoved]
-windows-10 msvc-2017
-windows-10 msvc-2019
-windows-10 msvc-2015
windows-7sp1
+windows-10
[watchFileAndItsDirectory:native backend-testfile]
osx
windows
diff --git a/tests/auto/corelib/io/qprocess/BLACKLIST b/tests/auto/corelib/io/qprocess/BLACKLIST
index aa9fdab64d..682bcbc60c 100644
--- a/tests/auto/corelib/io/qprocess/BLACKLIST
+++ b/tests/auto/corelib/io/qprocess/BLACKLIST
@@ -2,6 +2,5 @@
redhatenterpriselinuxworkstation-6.6
# QTBUG-48455
[fileWriterProcess]
-windows-10 msvc-2015
windows-10 msvc-2017
diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp
index 3a4493474b..f305edb2c5 100644
--- a/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/tst_qabstractitemmodel.cpp
@@ -1830,7 +1830,7 @@ void ListenerObject::slotAboutToBeReset()
void ListenerObject::slotReset()
{
- foreach (const QModelIndex &idx, m_persistentIndexes) {
+ for (const auto &idx : qAsConst(m_persistentIndexes)) {
QVERIFY(!idx.isValid());
}
}
diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp
index f78f5bc138..c74101928a 100644
--- a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp
@@ -32,6 +32,9 @@
#include <algorithm>
+Q_DECLARE_METATYPE(QItemSelectionModel::SelectionFlag)
+Q_DECLARE_METATYPE(Qt::SortOrder)
+
class tst_QItemSelectionModel : public QObject
{
Q_OBJECT
@@ -1463,7 +1466,7 @@ void tst_QItemSelectionModel::persistentselections()
QFETCH(IntList, insertColumns);
QFETCH(IntList, deleteRows);
QFETCH(IntList, deleteColumns);
- QFETCH(PairList, expectedList);
+ QFETCH(const PairList, expectedList);
// make sure the model is sane (5x5)
QCOMPARE(model->rowCount(QModelIndex()), 5);
@@ -1504,7 +1507,7 @@ void tst_QItemSelectionModel::persistentselections()
// check that the selected items are the correct number and indexes
QModelIndexList selectedList = selection->selectedIndexes();
QCOMPARE(selectedList.count(), expectedList.count());
- foreach(IntPair pair, expectedList) {
+ for (const auto &pair : expectedList) {
QModelIndex index = model->index(pair.first, pair.second, QModelIndex());
QVERIFY(selectedList.contains(index));
}
@@ -1679,7 +1682,7 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
{
QTest::addColumn<IntListList>("items");
QTest::addColumn<IntPairPairList>("initialSelectedRanges");
- QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<Qt::SortOrder>("sortOrder");
QTest::addColumn<int>("sortColumn");
QTest::addColumn<IntPairPairList>("expectedSelectedRanges");
@@ -1689,7 +1692,7 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
<< (IntList() << 3 << 2 << 1 << 0))
<< (IntPairPairList()
<< IntPairPair(IntPair(0, 0), IntPair(3, 1)))
- << int(Qt::DescendingOrder)
+ << Qt::DescendingOrder
<< 0
<< (IntPairPairList()
<< IntPairPair(IntPair(0, 0), IntPair(3, 1)));
@@ -1699,7 +1702,7 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
<< (IntList() << 3 << 2 << 1 << 0))
<< (IntPairPairList()
<< IntPairPair(IntPair(0, 0), IntPair(1, 1)))
- << int(Qt::DescendingOrder)
+ << Qt::DescendingOrder
<< 0
<< (IntPairPairList()
<< IntPairPair(IntPair(2, 0), IntPair(3, 1)));
@@ -1709,7 +1712,7 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
<< (IntList() << 3 << 2 << 1 << 0))
<< (IntPairPairList()
<< IntPairPair(IntPair(1, 0), IntPair(2, 1)))
- << int(Qt::DescendingOrder)
+ << Qt::DescendingOrder
<< 0
<< (IntPairPairList()
<< IntPairPair(IntPair(1, 0), IntPair(2, 1)));
@@ -1720,7 +1723,7 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
<< (IntPairPairList()
<< IntPairPair(IntPair(1, 0), IntPair(1, 1))
<< IntPairPair(IntPair(3, 0), IntPair(3, 1)))
- << int(Qt::AscendingOrder)
+ << Qt::AscendingOrder
<< 0
<< (IntPairPairList()
<< IntPairPair(IntPair(0, 0), IntPair(0, 1))
@@ -1730,8 +1733,8 @@ void tst_QItemSelectionModel::modelLayoutChanged_data()
void tst_QItemSelectionModel::modelLayoutChanged()
{
QFETCH(IntListList, items);
- QFETCH(IntPairPairList, initialSelectedRanges);
- QFETCH(int, sortOrder);
+ QFETCH(const IntPairPairList, initialSelectedRanges);
+ QFETCH(Qt::SortOrder, sortOrder);
QFETCH(int, sortColumn);
QFETCH(IntPairPairList, expectedSelectedRanges);
@@ -1746,9 +1749,9 @@ void tst_QItemSelectionModel::modelLayoutChanged()
// select initial ranges
QItemSelectionModel selectionModel(&model);
- foreach (IntPairPair range, initialSelectedRanges) {
- IntPair tl = range.first;
- IntPair br = range.second;
+ for (const auto &range : initialSelectedRanges) {
+ const auto &tl = range.first;
+ const auto &br = range.second;
QItemSelection selection(
model.index(tl.first, tl.second),
model.index(br.first, br.second));
@@ -1756,7 +1759,7 @@ void tst_QItemSelectionModel::modelLayoutChanged()
}
// sort the model
- model.sort(sortColumn, Qt::SortOrder(sortOrder));
+ model.sort(sortColumn, sortOrder);
// verify that selection is as expected
QItemSelection selection = selectionModel.selection();
@@ -2126,43 +2129,43 @@ void tst_QItemSelectionModel::merge_data()
{
QTest::addColumn<QItemSelection>("init");
QTest::addColumn<QItemSelection>("other");
- QTest::addColumn<int>("command");
+ QTest::addColumn<QItemSelectionModel::SelectionFlag>("command");
QTest::addColumn<QItemSelection>("result");
QTest::newRow("Simple select")
<< QItemSelection()
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
- << int(QItemSelectionModel::Select)
+ << QItemSelectionModel::Select
<< QItemSelection(model->index(2, 1) , model->index(3, 4));
QTest::newRow("Simple deselect")
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
- << int(QItemSelectionModel::Deselect)
+ << QItemSelectionModel::Deselect
<< QItemSelection();
QTest::newRow("Simple Toggle deselect")
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
- << int(QItemSelectionModel::Toggle)
+ << QItemSelectionModel::Toggle
<< QItemSelection();
QTest::newRow("Simple Toggle select")
<< QItemSelection()
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
- << int(QItemSelectionModel::Toggle)
+ << QItemSelectionModel::Toggle
<< QItemSelection(model->index(2, 1) , model->index(3, 4));
QTest::newRow("Add select")
<< QItemSelection(model->index(2, 1) , model->index(3, 3))
<< QItemSelection(model->index(2, 2) , model->index(3, 4))
- << int(QItemSelectionModel::Select)
+ << QItemSelectionModel::Select
<< QItemSelection(model->index(2, 1) , model->index(3, 4));
QTest::newRow("Deselect")
<< QItemSelection(model->index(2, 1) , model->index(3, 4))
<< QItemSelection(model->index(2, 2) , model->index(3, 4))
- << int(QItemSelectionModel::Deselect)
+ << QItemSelectionModel::Deselect
<< QItemSelection(model->index(2, 1) , model->index(3, 1));
QItemSelection r1(model->index(2, 1) , model->index(3, 1));
@@ -2170,7 +2173,7 @@ void tst_QItemSelectionModel::merge_data()
QTest::newRow("Toggle")
<< QItemSelection(model->index(2, 1) , model->index(3, 3))
<< QItemSelection(model->index(2, 2) , model->index(3, 4))
- << int(QItemSelectionModel::Toggle)
+ << QItemSelectionModel::Toggle
<< r1;
}
@@ -2178,15 +2181,18 @@ void tst_QItemSelectionModel::merge()
{
QFETCH(QItemSelection, init);
QFETCH(QItemSelection, other);
- QFETCH(int, command);
+ QFETCH(QItemSelectionModel::SelectionFlag, command);
QFETCH(QItemSelection, result);
- init.merge(other, QItemSelectionModel::SelectionFlags(command));
+ init.merge(other, command);
- foreach(const QModelIndex &idx, init.indexes())
- QVERIFY(result.contains(idx));
- foreach(const QModelIndex &idx, result.indexes())
- QVERIFY(init.contains(idx));
+ auto verify = [](const QModelIndexList &a, const QItemSelection &b)
+ {
+ for (const QModelIndex &idx : a)
+ QVERIFY(b.contains(idx));
+ };
+ verify(init.indexes(), result);
+ verify(result.indexes(), init);
}
void tst_QItemSelectionModel::isRowSelected()
@@ -2267,13 +2273,12 @@ void tst_QItemSelectionModel::layoutChangedWithAllSelected1()
proxy.setFilterRegularExpression(QRegularExpression("f"));
QCOMPARE(proxy.rowCount(), 2);
- QList<QPersistentModelIndex> indexList;
- indexList << proxy.index(0,0) << proxy.index(1,0);
- selection.select( QItemSelection(indexList.first(), indexList.last()), QItemSelectionModel::Select);
+ const QList<QPersistentModelIndex> indexList({proxy.index(0,0), proxy.index(1,0)});
+ selection.select(QItemSelection(indexList.first(), indexList.last()), QItemSelectionModel::Select);
//let's check the selection hasn't changed
QCOMPARE(selection.selectedIndexes().count(), indexList.count());
- foreach(QPersistentModelIndex index, indexList)
+ for (const auto &index : indexList)
QVERIFY(selection.isSelected(index));
proxy.setFilterRegularExpression(QRegularExpression());
@@ -2281,7 +2286,7 @@ void tst_QItemSelectionModel::layoutChangedWithAllSelected1()
//let's check the selection hasn't changed
QCOMPARE(selection.selectedIndexes().count(), indexList.count());
- foreach(QPersistentModelIndex index, indexList)
+ for (const auto &index : indexList)
QVERIFY(selection.isSelected(index));
}
@@ -2321,9 +2326,8 @@ void tst_QItemSelectionModel::layoutChangedWithAllSelected2()
selection.select( QItemSelection(proxy.index(0,0), proxy.index(proxy.rowCount() - 1, proxy.columnCount() - 1)), QItemSelectionModel::Select);
- QList<QPersistentModelIndex> indexList;
- foreach(const QModelIndex &id, selection.selectedIndexes())
- indexList << id;
+ const auto selIndexes = selection.selectedIndexes();
+ const QList<QPersistentModelIndex> indexList(selIndexes.begin(), selIndexes.end());
proxy.filtering = false;
proxy.invalidate();
@@ -2331,7 +2335,7 @@ void tst_QItemSelectionModel::layoutChangedWithAllSelected2()
//let's check the selection hasn't changed
QCOMPARE(selection.selectedIndexes().count(), indexList.count());
- foreach(QPersistentModelIndex index, indexList)
+ for (const auto &index : indexList)
QVERIFY(selection.isSelected(index));
}
@@ -2375,7 +2379,8 @@ public:
public slots:
void selectionChanged(const QItemSelection & /* selected */, const QItemSelection &deselected)
{
- foreach(const QModelIndex &index, deselected.indexes()) {
+ const auto deselIndexes = deselected.indexes();
+ for (const auto &index : deselIndexes) {
QVERIFY(!m_itemSelectionModel->selection().contains(index));
}
QCOMPARE(m_itemSelectionModel->selection().size(), 2);
@@ -2633,9 +2638,9 @@ private slots:
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
- foreach(const QItemSelectionRange &range, selected)
+ for (const auto &range : selected)
QVERIFY(range.isValid());
- foreach(const QItemSelectionRange &range, deselected)
+ for (const auto &range : deselected)
QVERIFY(range.isValid());
}
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
index 0f7588a71a..624187349b 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
@@ -829,7 +829,7 @@ void tst_QSortFilterProxyModel::removeRows_data()
void tst_QSortFilterProxyModel::removeRows()
{
- QFETCH(QStringList, initial);
+ QFETCH(const QStringList, initial);
QFETCH(int, sortOrder);
QFETCH(QString, filter);
QFETCH(int, position);
@@ -843,7 +843,7 @@ void tst_QSortFilterProxyModel::removeRows()
proxy.setSourceModel(&model);
// prepare model
- foreach (QString s, initial)
+ for (const auto &s : initial)
model.appendRow(new QStandardItem(s));
if (sortOrder != -1)
@@ -3035,15 +3035,15 @@ void tst_QSortFilterProxyModel::removeRowsRecursive()
QList<QPersistentModelIndex> sourceIndexes;
QList<QPersistentModelIndex> proxyIndexes;
- foreach (QStandardItem *item, items) {
+ for (const auto item : qAsConst(items)) {
QModelIndex idx = item->index();
sourceIndexes << idx;
proxyIndexes << proxy.mapFromSource(idx);
}
- foreach (const QPersistentModelIndex &pidx, sourceIndexes)
+ for (const auto &pidx : qAsConst(sourceIndexes))
QVERIFY(pidx.isValid());
- foreach (const QPersistentModelIndex &pidx, proxyIndexes)
+ for (const auto &pidx : qAsConst(proxyIndexes))
QVERIFY(pidx.isValid());
QList<QStandardItem*> itemRow = pItem1->takeRow(0);
@@ -3051,9 +3051,9 @@ void tst_QSortFilterProxyModel::removeRowsRecursive()
QCOMPARE(itemRow.count(), 1);
QCOMPARE(itemRow.first(), pItem11);
- foreach (const QPersistentModelIndex &pidx, sourceIndexes)
+ for (const auto &pidx : qAsConst(sourceIndexes))
QVERIFY(!pidx.isValid());
- foreach (const QPersistentModelIndex &pidx, proxyIndexes)
+ for (const auto &pidx : qAsConst(proxyIndexes))
QVERIFY(!pidx.isValid());
delete pItem11;
@@ -3280,10 +3280,8 @@ void tst_QSortFilterProxyModel::testMultipleProxiesWithSelection()
static bool isValid(const QItemSelection &selection)
{
- foreach (const QItemSelectionRange &range, selection)
- if (!range.isValid())
- return false;
- return true;
+ return std::all_of(selection.begin(), selection.end(),
+ [](const QItemSelectionRange &range) { return range.isValid(); });
}
void tst_QSortFilterProxyModel::mapSelectionFromSource()
@@ -3737,14 +3735,16 @@ void tst_QSortFilterProxyModel::testParentLayoutChanged()
QVERIFY(beforeParents.first() == proxy.mapFromSource(model.indexFromItem(model.invisibleRootItem()->child(1))));
- QList<QPersistentModelIndex> proxy2BeforeList = proxy2ParentsAboutToBeChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
- QList<QPersistentModelIndex> proxy2AfterList = proxy2ParentsChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
+ const QList<QPersistentModelIndex> proxy2BeforeList =
+ proxy2ParentsAboutToBeChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
+ const QList<QPersistentModelIndex> proxy2AfterList =
+ proxy2ParentsChangedSpy.first().first().value<QList<QPersistentModelIndex> >();
QCOMPARE(proxy2BeforeList.size(), beforeParents.size());
QCOMPARE(proxy2AfterList.size(), afterParents.size());
- foreach (const QPersistentModelIndex &idx, proxy2BeforeList)
+ for (const QPersistentModelIndex &idx : proxy2BeforeList)
QVERIFY(beforeParents.contains(proxy2.mapToSource(idx)));
- foreach (const QPersistentModelIndex &idx, proxy2AfterList)
+ for (const QPersistentModelIndex &idx : proxy2AfterList)
QVERIFY(afterParents.contains(proxy2.mapToSource(idx)));
}
diff --git a/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST b/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST
index 4c9fe53c14..569880e1db 100644
--- a/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST
+++ b/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST
@@ -1,4 +1,3 @@
[elapsed]
-windows-10 msvc-2015
osx-10.13
-windows-10 msvc-2017
+windows-10
diff --git a/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST b/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST
index f3b7fc97b1..f2e5e78592 100644
--- a/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST
+++ b/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST
@@ -1,4 +1,3 @@
[unexpectedDisconnection]
-osx-10.12
-windows-10 msvc-2015
windows-7sp1
+windows-10 msvc-2015
diff --git a/tests/auto/corelib/kernel/qtimer/BLACKLIST b/tests/auto/corelib/kernel/qtimer/BLACKLIST
deleted file mode 100644
index dc8b8987e5..0000000000
--- a/tests/auto/corelib/kernel/qtimer/BLACKLIST
+++ /dev/null
@@ -1,9 +0,0 @@
-[remainingTime]
-osx-10.12
-osx-10.14
-osx-10.13
-windows-10 msvc-2017
-[basic_chrono]
-osx-10.14
-osx-10.13
-
diff --git a/tests/auto/corelib/serialization/qtextstream/BLACKLIST b/tests/auto/corelib/serialization/qtextstream/BLACKLIST
index b8c1b742f4..674569e204 100644
--- a/tests/auto/corelib/serialization/qtextstream/BLACKLIST
+++ b/tests/auto/corelib/serialization/qtextstream/BLACKLIST
@@ -1,4 +1,3 @@
[stillOpenWhenAtEnd]
-windows-10 msvc-2017
-winrt
windows-7sp1
+winrt
diff --git a/tests/auto/corelib/thread/qsemaphore/BLACKLIST b/tests/auto/corelib/thread/qsemaphore/BLACKLIST
index f61f4c1a3b..d7af5c420b 100644
--- a/tests/auto/corelib/thread/qsemaphore/BLACKLIST
+++ b/tests/auto/corelib/thread/qsemaphore/BLACKLIST
@@ -1,6 +1,5 @@
[tryAcquireWithTimeout]
-osx-10.12
-osx-10.13
+osx
[tryAcquireWithTimeout:0.2s]
windows
osx-10.12
diff --git a/tests/auto/corelib/thread/qthread/BLACKLIST b/tests/auto/corelib/thread/qthread/BLACKLIST
index 87538a1048..c683154da1 100644
--- a/tests/auto/corelib/thread/qthread/BLACKLIST
+++ b/tests/auto/corelib/thread/qthread/BLACKLIST
@@ -1,7 +1,5 @@
[wait3_slowDestructor]
-windows-10 msvc-2015
-windows-7sp1
-windows-10 msvc-2017
+windows-10
[sleep]
windows-7sp1
diff --git a/tests/auto/corelib/thread/qthreadpool/BLACKLIST b/tests/auto/corelib/thread/qthreadpool/BLACKLIST
index e4f2fcd822..b8c1f3bf3f 100644
--- a/tests/auto/corelib/thread/qthreadpool/BLACKLIST
+++ b/tests/auto/corelib/thread/qthreadpool/BLACKLIST
@@ -1,7 +1,4 @@
[expiryTimeoutRace]
-rhel-7.6
opensuse-leap
-osx-10.13
-ubuntu-18.04
-osx-10.12
-opensuse-42.3
+ubuntu
+rhel
diff --git a/tests/auto/corelib/tools/qsize/tst_qsize.cpp b/tests/auto/corelib/tools/qsize/tst_qsize.cpp
index 385ff18ce5..6824bad9c8 100644
--- a/tests/auto/corelib/tools/qsize/tst_qsize.cpp
+++ b/tests/auto/corelib/tools/qsize/tst_qsize.cpp
@@ -29,6 +29,7 @@
#include <QtTest/QtTest>
#include <qsize.h>
+Q_DECLARE_METATYPE(QMargins)
class tst_QSize : public QObject
{
@@ -43,6 +44,9 @@ private slots:
void boundedTo_data();
void boundedTo();
+ void grownOrShrunkBy_data();
+ void grownOrShrunkBy();
+
void transpose_data();
void transpose();
};
@@ -186,6 +190,46 @@ void tst_QSize::boundedTo()
QCOMPARE( input1.boundedTo(input2), expected);
}
+void tst_QSize::grownOrShrunkBy_data()
+{
+ QTest::addColumn<QSize>("input");
+ QTest::addColumn<QMargins>("margins");
+ QTest::addColumn<QSize>("grown");
+ QTest::addColumn<QSize>("shrunk");
+
+ auto row = [](QSize i, QMargins m, QSize g, QSize s) {
+ QTest::addRow("{%d,%d}/{%d,%d,%d,%d}", i.width(), i.height(),
+ m.left(), m.top(), m.right(), m.bottom())
+ << i << m << g << s;
+ };
+
+ const QSize zero = {0, 0};
+ const QSize some = {100, 200};
+ const QMargins zeroMargins = {};
+ const QMargins negative = {-1, -2, -3, -4};
+ const QMargins positive = { 1, 2, 3, 4};
+
+ row(zero, zeroMargins, zero, zero);
+ row(zero, negative, {-4, -6}, { 4, 6});
+ row(zero, positive, { 4, 6}, {-4, -6});
+ row(some, zeroMargins, some, some);
+ row(some, negative, { 96, 194}, {104, 206});
+ row(some, positive, {104, 206}, { 96, 194});
+}
+
+void tst_QSize::grownOrShrunkBy()
+{
+ QFETCH(const QSize, input);
+ QFETCH(const QMargins, margins);
+ QFETCH(const QSize, grown);
+ QFETCH(const QSize, shrunk);
+
+ QCOMPARE(input.grownBy(margins), grown);
+ QCOMPARE(input.shrunkBy(margins), shrunk);
+ QCOMPARE(grown.shrunkBy(margins), input);
+ QCOMPARE(shrunk.grownBy(margins), input);
+}
+
void tst_QSize::transpose_data()
{
QTest::addColumn<QSize>("input1");
diff --git a/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp b/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp
index 42801d63a9..bbffa74a62 100644
--- a/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp
+++ b/tests/auto/corelib/tools/qsizef/tst_qsizef.cpp
@@ -29,6 +29,7 @@
#include <QtTest/QtTest>
#include <qsize.h>
+Q_DECLARE_METATYPE(QMarginsF)
class tst_QSizeF : public QObject
{
@@ -45,6 +46,9 @@ private slots:
void boundedTo_data();
void boundedTo();
+ void grownOrShrunkBy_data();
+ void grownOrShrunkBy();
+
void transpose_data();
void transpose();
};
@@ -152,6 +156,46 @@ void tst_QSizeF::boundedTo() {
QCOMPARE( input1.boundedTo(input2), expected);
}
+void tst_QSizeF::grownOrShrunkBy_data()
+{
+ QTest::addColumn<QSizeF>("input");
+ QTest::addColumn<QMarginsF>("margins");
+ QTest::addColumn<QSizeF>("grown");
+ QTest::addColumn<QSizeF>("shrunk");
+
+ auto row = [](QSizeF i, QMarginsF m, QSizeF g, QSizeF s) {
+ QTest::addRow("{%g,%g}/{%g,%g,%g,%g}", i.width(), i.height(),
+ m.left(), m.top(), m.right(), m.bottom())
+ << i << m << g << s;
+ };
+
+ const QSizeF zero = {0, 0};
+ const QSizeF some = {100, 200};
+ const QMarginsF zeroMargins = {};
+ const QMarginsF negative = {-1, -2, -3, -4};
+ const QMarginsF positive = { 1, 2, 3, 4};
+
+ row(zero, zeroMargins, zero, zero);
+ row(zero, negative, {-4, -6}, { 4, 6});
+ row(zero, positive, { 4, 6}, {-4, -6});
+ row(some, zeroMargins, some, some);
+ row(some, negative, { 96, 194}, {104, 206});
+ row(some, positive, {104, 206}, { 96, 194});
+}
+
+void tst_QSizeF::grownOrShrunkBy()
+{
+ QFETCH(const QSizeF, input);
+ QFETCH(const QMarginsF, margins);
+ QFETCH(const QSizeF, grown);
+ QFETCH(const QSizeF, shrunk);
+
+ QCOMPARE(input.grownBy(margins), grown);
+ QCOMPARE(input.shrunkBy(margins), shrunk);
+ QCOMPARE(grown.shrunkBy(margins), input);
+ QCOMPARE(shrunk.grownBy(margins), input);
+}
+
void tst_QSizeF::transpose_data() {
QTest::addColumn<QSizeF>("input1");
QTest::addColumn<QSizeF>("expected");
diff --git a/tests/auto/corelib/tools/qtimeline/BLACKLIST b/tests/auto/corelib/tools/qtimeline/BLACKLIST
index b60cab31fa..9794b0059f 100644
--- a/tests/auto/corelib/tools/qtimeline/BLACKLIST
+++ b/tests/auto/corelib/tools/qtimeline/BLACKLIST
@@ -1,8 +1,6 @@
[interpolation]
-osx-10.12
windows-10 msvc-2015
-osx-10.13
-windows-7sp1
+osx
[frameRate]
osx-10.12
osx-10.13
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 441ec17412..b84aa52465 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -303,6 +303,8 @@ static QLatin1String formatToString(QImage::Format format)
return QLatin1String("RGBA64pm");
case QImage::Format_Grayscale16:
return QLatin1String("Grayscale16");
+ case QImage::Format_BGR888:
+ return QLatin1String("BGR888");
default:
break;
};
@@ -844,6 +846,13 @@ void tst_QImage::convertToFormat_data()
QTest::newRow("blue rgb32 -> rgb888") << int(QImage::Format_RGB32) << 0xff0000ff
<< int(QImage::Format_RGB888) << 0xff0000ff;
+ QTest::newRow("red rgb32 -> bgr888") << int(QImage::Format_RGB32) << 0xffff0000
+ << int(QImage::Format_BGR888) << 0xffff0000;
+ QTest::newRow("green rgb32 -> bgr888") << int(QImage::Format_RGB32) << 0xff00ff00
+ << int(QImage::Format_BGR888) << 0xff00ff00;
+ QTest::newRow("blue rgb32 -> bgr888") << int(QImage::Format_RGB32) << 0xff0000ff
+ << int(QImage::Format_BGR888) << 0xff0000ff;
+
QTest::newRow("red rgb16 -> rgb888") << int(QImage::Format_RGB16) << 0xffff0000
<< int(QImage::Format_RGB888) << 0xffff0000;
QTest::newRow("green rgb16 -> rgb888") << int(QImage::Format_RGB16) << 0xff00ff00
@@ -858,6 +867,13 @@ void tst_QImage::convertToFormat_data()
QTest::newRow("blue rgb888 -> argb32") << int(QImage::Format_RGB888) << 0xff0000ff
<< int(QImage::Format_ARGB32) << 0xff0000ff;
+ QTest::newRow("red bgr888 -> argb32") << int(QImage::Format_RGB888) << 0xffff0000
+ << int(QImage::Format_ARGB32) << 0xffff0000;
+ QTest::newRow("green bgr888 -> argb32") << int(QImage::Format_RGB888) << 0xff00ff00
+ << int(QImage::Format_ARGB32) << 0xff00ff00;
+ QTest::newRow("blue bgr888 -> argb32") << int(QImage::Format_RGB888) << 0xff0000ff
+ << int(QImage::Format_ARGB32) << 0xff0000ff;
+
QTest::newRow("red rgb888 -> rgbx8888") << int(QImage::Format_RGB888) << 0xffff0000
<< int(QImage::Format_RGBX8888) << 0xffff0000;
QTest::newRow("green rgb888 -> rgbx8888") << int(QImage::Format_RGB888) << 0xff00ff00
@@ -1338,6 +1354,12 @@ void tst_QImage::setPixel_data()
<< 0xff00ff00 << 0x00ff00u;
QTest::newRow("RGB888 blue") << int(QImage::Format_RGB888)
<< 0xff0000ff << 0x0000ffu;
+ QTest::newRow("BGR888 red") << int(QImage::Format_BGR888)
+ << 0xffff0000 << 0x0000ffu;
+ QTest::newRow("BGR888 green") << int(QImage::Format_BGR888)
+ << 0xff00ff00 << 0x00ff00u;
+ QTest::newRow("BGR888 blue") << int(QImage::Format_BGR888)
+ << 0xff0000ff << 0xff0000u;
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
QTest::newRow("RGBA8888 red") << int(QImage::Format_RGBA8888)
<< 0xffff0000u << 0xff0000ffu;
@@ -1425,6 +1447,7 @@ void tst_QImage::setPixel()
case int(QImage::Format_ARGB8565_Premultiplied):
case int(QImage::Format_ARGB8555_Premultiplied):
case int(QImage::Format_RGB888):
+ case int(QImage::Format_BGR888):
{
for (int y = 0; y < h; ++y) {
const quint24 *row = (const quint24*)(img.scanLine(y));
@@ -2445,6 +2468,7 @@ void tst_QImage::mirrored_data()
QTest::newRow("Format_RGB555, vertical") << QImage::Format_RGB555 << true << false << 16 << 16;
QTest::newRow("Format_ARGB8555_Premultiplied, vertical") << QImage::Format_ARGB8555_Premultiplied << true << false << 16 << 16;
QTest::newRow("Format_RGB888, vertical") << QImage::Format_RGB888 << true << false << 16 << 16;
+ QTest::newRow("Format_BGR888, vertical") << QImage::Format_BGR888 << true << false << 16 << 16;
QTest::newRow("Format_RGB444, vertical") << QImage::Format_RGB444 << true << false << 16 << 16;
QTest::newRow("Format_RGBX8888, vertical") << QImage::Format_RGBX8888 << true << false << 16 << 16;
QTest::newRow("Format_RGBA8888_Premultiplied, vertical") << QImage::Format_RGBA8888_Premultiplied << true << false << 16 << 16;
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 866a41c3d1..f6ffd7b7c5 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -1863,6 +1863,7 @@ void tst_QImageReader::saveFormat_data()
QTest::newRow("Format_RGB555") << QImage::Format_RGB555;
QTest::newRow("Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied;
QTest::newRow("Format_RGB888") << QImage::Format_RGB888;
+ QTest::newRow("Format_BGR888") << QImage::Format_BGR888;
QTest::newRow("Format_RGB444") << QImage::Format_RGB444;
QTest::newRow("Format_ARGB4444_Premultiplied") << QImage::Format_ARGB4444_Premultiplied;
QTest::newRow("Format_RGBA64") << QImage::Format_RGBA64;
@@ -1914,6 +1915,13 @@ void tst_QImageReader::saveColorSpace()
QCOMPARE(stored, orig);
QCOMPARE(stored.colorSpace(), orig.colorSpace());
+
+ buf.open(QIODevice::WriteOnly);
+ QVERIFY(orig.save(&buf, "jpeg"));
+ buf.close();
+ stored = QImage::fromData(buf.buffer(), "jpeg");
+
+ QCOMPARE(stored.colorSpace(), orig.colorSpace());
}
void tst_QImageReader::readText_data()
diff --git a/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp b/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp
index 4fca9a07fc..19c5c8a4a0 100644
--- a/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp
+++ b/tests/auto/gui/kernel/noqteventloop/tst_noqteventloop.cpp
@@ -258,8 +258,8 @@ void tst_NoQtEventLoop::consumeMouseEvents()
::SetWindowPos(mainWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- Window *childWindow = new Window;
- childWindow->setParent(QWindow::fromWinId((WId)mainWnd));
+ QWindow *mainWindow = QWindow::fromWinId(reinterpret_cast<WId>(mainWnd));
+ Window *childWindow = new Window(mainWindow);
childWindow->setGeometry(margin, topVerticalMargin,
width - 2 * margin, height - margin - topVerticalMargin);
childWindow->show();
@@ -276,6 +276,7 @@ void tst_NoQtEventLoop::consumeMouseEvents()
if (g_exit)
break;
}
+ delete mainWindow;
QCOMPARE(testThread->passed(), true);
diff --git a/tests/auto/gui/kernel/qguitimer/BLACKLIST b/tests/auto/gui/kernel/qguitimer/BLACKLIST
deleted file mode 100644
index 6ab715b922..0000000000
--- a/tests/auto/gui/kernel/qguitimer/BLACKLIST
+++ /dev/null
@@ -1,8 +0,0 @@
-[basic_chrono]
-osx-10.13
-[remainingTime]
-osx-10.12
-windows-10 msvc-2015
-osx-10.14
-osx-10.13
-
diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST
index 1bb3917948..27463adf99 100644
--- a/tests/auto/gui/kernel/qwindow/BLACKLIST
+++ b/tests/auto/gui/kernel/qwindow/BLACKLIST
@@ -1,7 +1,5 @@
[positioning]
opensuse-leap
-ubuntu-16.04
-opensuse-42.3
[positioning:default]
linux
osx-10.12 ci
@@ -9,24 +7,17 @@ winrt
[positioning:fake]
osx-10.12 ci
[modalWithChildWindow]
-ubuntu-16.04
-opensuse-leap
# QTBUG-66851
# QTBUG-69160
-opensuse-42.3
+opensuse-leap
[setVisible]
# QTBUG-69154
android
[modalWindowEnterEventOnHide_QTBUG35109]
-ubuntu-16.04
-osx-10.11
-osx-10.13
-osx-10.14
-osx-10.12
+osx
[spuriousMouseMove]
# QTBUG-69162
-windows-10 msvc-2015
-windows-10 msvc-2017
+windows-10
[testInputEvents]
rhel-7.4
[exposeEventOnShrink_QTBUG54040]
diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
index c1c231089a..07c820dc86 100644
--- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
+++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp
@@ -64,6 +64,10 @@ private slots:
void globalColors_data();
void globalColors();
+#if defined(Q_COMPILER_CONSTEXPR) & defined(Q_COMPILER_UNIFORM_INIT)
+ void colorConstants_data();
+ void colorConstants();
+#endif
void setRed();
void setGreen();
@@ -364,6 +368,191 @@ void tst_QColor::globalColors()
QCOMPARE(color.rgba(), argb);
}
+#if defined(Q_COMPILER_CONSTEXPR) & defined(Q_COMPILER_UNIFORM_INIT)
+void tst_QColor::colorConstants_data()
+{
+ QTest::addColumn<QColor>("color");
+ QTest::addColumn<QRgb>("argb");
+
+ QTest::newRow("invalid") << QColor() << 0xff000000;
+ QTest::newRow("global color color0") << QColorConstants::Color0 << 0xff000000u;
+ QTest::newRow("global color color1") << QColorConstants::Color1 << 0xffffffffu;
+ QTest::newRow("global color black") << QColorConstants::Black << 0xff000000u;
+ QTest::newRow("global color white") << QColorConstants::White << 0xffffffffu;
+ QTest::newRow("global color darkGray") << QColorConstants::DarkGray << 0xff808080u;
+ QTest::newRow("global color gray") << QColorConstants::Gray << 0xffa0a0a4u;
+ QTest::newRow("global color lightGray") << QColorConstants::LightGray << 0xffc0c0c0u;
+ QTest::newRow("global color red") << QColorConstants::Red << 0xffff0000u;
+ QTest::newRow("global color green") << QColorConstants::Green << 0xff00ff00u;
+ QTest::newRow("global color blue") << QColorConstants::Blue << 0xff0000ffu;
+ QTest::newRow("global color cyan") << QColorConstants::Cyan << 0xff00ffffu;
+ QTest::newRow("global color magenta") << QColorConstants::Magenta << 0xffff00ffu;
+ QTest::newRow("global color yellow") << QColorConstants::Yellow << 0xffffff00u;
+ QTest::newRow("global color darkRed") << QColorConstants::DarkRed << 0xff800000u;
+ QTest::newRow("global color darkGreen") << QColorConstants::DarkGreen << 0xff008000u;
+ QTest::newRow("global color darkBlue") << QColorConstants::DarkBlue << 0xff000080u;
+ QTest::newRow("global color darkCyan") << QColorConstants::DarkCyan << 0xff008080u;
+ QTest::newRow("global color darkMagenta") << QColorConstants::DarkMagenta << 0xff800080u;
+ QTest::newRow("global color darkYellow") << QColorConstants::DarkYellow << 0xff808000u;
+ QTest::newRow("global color transparent") << QColorConstants::Transparent << 0x00000000u;
+
+ QTest::newRow("SVG aliceblue") << QColorConstants::Svg::aliceblue << 0xfff0f8ffu;
+ QTest::newRow("SVG antiquewhite") << QColorConstants::Svg::antiquewhite << 0xfffaebd7u;
+ QTest::newRow("SVG aqua") << QColorConstants::Svg::aqua << 0xff00ffffu;
+ QTest::newRow("SVG aquamarine") << QColorConstants::Svg::aquamarine << 0xff7fffd4u;
+ QTest::newRow("SVG azure") << QColorConstants::Svg::azure << 0xfff0ffffu;
+ QTest::newRow("SVG beige") << QColorConstants::Svg::beige << 0xfff5f5dcu;
+ QTest::newRow("SVG bisque") << QColorConstants::Svg::bisque << 0xffffe4c4u;
+ QTest::newRow("SVG black") << QColorConstants::Svg::black << 0xff000000u;
+ QTest::newRow("SVG blanchedalmond") << QColorConstants::Svg::blanchedalmond << 0xffffebcdu;
+ QTest::newRow("SVG blue") << QColorConstants::Svg::blue << 0xff0000ffu;
+ QTest::newRow("SVG blueviolet") << QColorConstants::Svg::blueviolet << 0xff8a2be2u;
+ QTest::newRow("SVG brown") << QColorConstants::Svg::brown << 0xffa52a2au;
+ QTest::newRow("SVG burlywood") << QColorConstants::Svg::burlywood << 0xffdeb887u;
+ QTest::newRow("SVG cadetblue") << QColorConstants::Svg::cadetblue << 0xff5f9ea0u;
+ QTest::newRow("SVG chartreuse") << QColorConstants::Svg::chartreuse << 0xff7fff00u;
+ QTest::newRow("SVG chocolate") << QColorConstants::Svg::chocolate << 0xffd2691eu;
+ QTest::newRow("SVG coral") << QColorConstants::Svg::coral << 0xffff7f50u;
+ QTest::newRow("SVG cornflowerblue") << QColorConstants::Svg::cornflowerblue << 0xff6495edu;
+ QTest::newRow("SVG cornsilk") << QColorConstants::Svg::cornsilk << 0xfffff8dcu;
+ QTest::newRow("SVG crimson") << QColorConstants::Svg::crimson << 0xffdc143cu;
+ QTest::newRow("SVG cyan") << QColorConstants::Svg::cyan << 0xff00ffffu;
+ QTest::newRow("SVG darkblue") << QColorConstants::Svg::darkblue << 0xff00008bu;
+ QTest::newRow("SVG darkcyan") << QColorConstants::Svg::darkcyan << 0xff008b8bu;
+ QTest::newRow("SVG darkgoldenrod") << QColorConstants::Svg::darkgoldenrod << 0xffb8860bu;
+ QTest::newRow("SVG darkgray") << QColorConstants::Svg::darkgray << 0xffa9a9a9u;
+ QTest::newRow("SVG darkgreen") << QColorConstants::Svg::darkgreen << 0xff006400u;
+ QTest::newRow("SVG darkgrey") << QColorConstants::Svg::darkgrey << 0xffa9a9a9u;
+ QTest::newRow("SVG darkkhaki") << QColorConstants::Svg::darkkhaki << 0xffbdb76bu;
+ QTest::newRow("SVG darkmagenta") << QColorConstants::Svg::darkmagenta << 0xff8b008bu;
+ QTest::newRow("SVG darkolivegreen") << QColorConstants::Svg::darkolivegreen << 0xff556b2fu;
+ QTest::newRow("SVG darkorange") << QColorConstants::Svg::darkorange << 0xffff8c00u;
+ QTest::newRow("SVG darkorchid") << QColorConstants::Svg::darkorchid << 0xff9932ccu;
+ QTest::newRow("SVG darkred") << QColorConstants::Svg::darkred << 0xff8b0000u;
+ QTest::newRow("SVG darksalmon") << QColorConstants::Svg::darksalmon << 0xffe9967au;
+ QTest::newRow("SVG darkseagreen") << QColorConstants::Svg::darkseagreen << 0xff8fbc8fu;
+ QTest::newRow("SVG darkslateblue") << QColorConstants::Svg::darkslateblue << 0xff483d8bu;
+ QTest::newRow("SVG darkslategray") << QColorConstants::Svg::darkslategray << 0xff2f4f4fu;
+ QTest::newRow("SVG darkslategrey") << QColorConstants::Svg::darkslategrey << 0xff2f4f4fu;
+ QTest::newRow("SVG darkturquoise") << QColorConstants::Svg::darkturquoise << 0xff00ced1u;
+ QTest::newRow("SVG darkviolet") << QColorConstants::Svg::darkviolet << 0xff9400d3u;
+ QTest::newRow("SVG deeppink") << QColorConstants::Svg::deeppink << 0xffff1493u;
+ QTest::newRow("SVG deepskyblue") << QColorConstants::Svg::deepskyblue << 0xff00bfffu;
+ QTest::newRow("SVG dimgray") << QColorConstants::Svg::dimgray << 0xff696969u;
+ QTest::newRow("SVG dimgrey") << QColorConstants::Svg::dimgrey << 0xff696969u;
+ QTest::newRow("SVG dodgerblue") << QColorConstants::Svg::dodgerblue << 0xff1e90ffu;
+ QTest::newRow("SVG firebrick") << QColorConstants::Svg::firebrick << 0xffb22222u;
+ QTest::newRow("SVG floralwhite") << QColorConstants::Svg::floralwhite << 0xfffffaf0u;
+ QTest::newRow("SVG forestgreen") << QColorConstants::Svg::forestgreen << 0xff228b22u;
+ QTest::newRow("SVG fuchsia") << QColorConstants::Svg::fuchsia << 0xffff00ffu;
+ QTest::newRow("SVG gainsboro") << QColorConstants::Svg::gainsboro << 0xffdcdcdcu;
+ QTest::newRow("SVG ghostwhite") << QColorConstants::Svg::ghostwhite << 0xfff8f8ffu;
+ QTest::newRow("SVG gold") << QColorConstants::Svg::gold << 0xffffd700u;
+ QTest::newRow("SVG goldenrod") << QColorConstants::Svg::goldenrod << 0xffdaa520u;
+ QTest::newRow("SVG gray") << QColorConstants::Svg::gray << 0xff808080u;
+ QTest::newRow("SVG green") << QColorConstants::Svg::green << 0xff008000u;
+ QTest::newRow("SVG greenyellow") << QColorConstants::Svg::greenyellow << 0xffadff2fu;
+ QTest::newRow("SVG grey") << QColorConstants::Svg::grey << 0xff808080u;
+ QTest::newRow("SVG honeydew") << QColorConstants::Svg::honeydew << 0xfff0fff0u;
+ QTest::newRow("SVG hotpink") << QColorConstants::Svg::hotpink << 0xffff69b4u;
+ QTest::newRow("SVG indianred") << QColorConstants::Svg::indianred << 0xffcd5c5cu;
+ QTest::newRow("SVG indigo") << QColorConstants::Svg::indigo << 0xff4b0082u;
+ QTest::newRow("SVG ivory") << QColorConstants::Svg::ivory << 0xfffffff0u;
+ QTest::newRow("SVG khaki") << QColorConstants::Svg::khaki << 0xfff0e68cu;
+ QTest::newRow("SVG lavender") << QColorConstants::Svg::lavender << 0xffe6e6fau;
+ QTest::newRow("SVG lavenderblush") << QColorConstants::Svg::lavenderblush << 0xfffff0f5u;
+ QTest::newRow("SVG lawngreen") << QColorConstants::Svg::lawngreen << 0xff7cfc00u;
+ QTest::newRow("SVG lemonchiffon") << QColorConstants::Svg::lemonchiffon << 0xfffffacdu;
+ QTest::newRow("SVG lightblue") << QColorConstants::Svg::lightblue << 0xffadd8e6u;
+ QTest::newRow("SVG lightcoral") << QColorConstants::Svg::lightcoral << 0xfff08080u;
+ QTest::newRow("SVG lightcyan") << QColorConstants::Svg::lightcyan << 0xffe0ffffu;
+ QTest::newRow("SVG lightgoldenrodyellow") << QColorConstants::Svg::lightgoldenrodyellow << 0xfffafad2u;
+ QTest::newRow("SVG lightgray") << QColorConstants::Svg::lightgray << 0xffd3d3d3u;
+ QTest::newRow("SVG lightgreen") << QColorConstants::Svg::lightgreen << 0xff90ee90u;
+ QTest::newRow("SVG lightgrey") << QColorConstants::Svg::lightgrey << 0xffd3d3d3u;
+ QTest::newRow("SVG lightpink") << QColorConstants::Svg::lightpink << 0xffffb6c1u;
+ QTest::newRow("SVG lightsalmon") << QColorConstants::Svg::lightsalmon << 0xffffa07au;
+ QTest::newRow("SVG lightseagreen") << QColorConstants::Svg::lightseagreen << 0xff20b2aau;
+ QTest::newRow("SVG lightskyblue") << QColorConstants::Svg::lightskyblue << 0xff87cefau;
+ QTest::newRow("SVG lightslategray") << QColorConstants::Svg::lightslategray << 0xff778899u;
+ QTest::newRow("SVG lightslategrey") << QColorConstants::Svg::lightslategrey << 0xff778899u;
+ QTest::newRow("SVG lightsteelblue") << QColorConstants::Svg::lightsteelblue << 0xffb0c4deu;
+ QTest::newRow("SVG lightyellow") << QColorConstants::Svg::lightyellow << 0xffffffe0u;
+ QTest::newRow("SVG lime") << QColorConstants::Svg::lime << 0xff00ff00u;
+ QTest::newRow("SVG limegreen") << QColorConstants::Svg::limegreen << 0xff32cd32u;
+ QTest::newRow("SVG linen") << QColorConstants::Svg::linen << 0xfffaf0e6u;
+ QTest::newRow("SVG magenta") << QColorConstants::Svg::magenta << 0xffff00ffu;
+ QTest::newRow("SVG maroon") << QColorConstants::Svg::maroon << 0xff800000u;
+ QTest::newRow("SVG mediumaquamarine") << QColorConstants::Svg::mediumaquamarine << 0xff66cdaau;
+ QTest::newRow("SVG mediumblue") << QColorConstants::Svg::mediumblue << 0xff0000cdu;
+ QTest::newRow("SVG mediumorchid") << QColorConstants::Svg::mediumorchid << 0xffba55d3u;
+ QTest::newRow("SVG mediumpurple") << QColorConstants::Svg::mediumpurple << 0xff9370dbu;
+ QTest::newRow("SVG mediumseagreen") << QColorConstants::Svg::mediumseagreen << 0xff3cb371u;
+ QTest::newRow("SVG mediumslateblue") << QColorConstants::Svg::mediumslateblue << 0xff7b68eeu;
+ QTest::newRow("SVG mediumspringgreen") << QColorConstants::Svg::mediumspringgreen << 0xff00fa9au;
+ QTest::newRow("SVG mediumturquoise") << QColorConstants::Svg::mediumturquoise << 0xff48d1ccu;
+ QTest::newRow("SVG mediumvioletred") << QColorConstants::Svg::mediumvioletred << 0xffc71585u;
+ QTest::newRow("SVG midnightblue") << QColorConstants::Svg::midnightblue << 0xff191970u;
+ QTest::newRow("SVG mintcream") << QColorConstants::Svg::mintcream << 0xfff5fffau;
+ QTest::newRow("SVG mistyrose") << QColorConstants::Svg::mistyrose << 0xffffe4e1u;
+ QTest::newRow("SVG moccasin") << QColorConstants::Svg::moccasin << 0xffffe4b5u;
+ QTest::newRow("SVG navajowhite") << QColorConstants::Svg::navajowhite << 0xffffdeadu;
+ QTest::newRow("SVG navy") << QColorConstants::Svg::navy << 0xff000080u;
+ QTest::newRow("SVG oldlace") << QColorConstants::Svg::oldlace << 0xfffdf5e6u;
+ QTest::newRow("SVG olive") << QColorConstants::Svg::olive << 0xff808000u;
+ QTest::newRow("SVG olivedrab") << QColorConstants::Svg::olivedrab << 0xff6b8e23u;
+ QTest::newRow("SVG orange") << QColorConstants::Svg::orange << 0xffffa500u;
+ QTest::newRow("SVG orangered") << QColorConstants::Svg::orangered << 0xffff4500u;
+ QTest::newRow("SVG orchid") << QColorConstants::Svg::orchid << 0xffda70d6u;
+ QTest::newRow("SVG palegoldenrod") << QColorConstants::Svg::palegoldenrod << 0xffeee8aau;
+ QTest::newRow("SVG palegreen") << QColorConstants::Svg::palegreen << 0xff98fb98u;
+ QTest::newRow("SVG paleturquoise") << QColorConstants::Svg::paleturquoise << 0xffafeeeeu;
+ QTest::newRow("SVG palevioletred") << QColorConstants::Svg::palevioletred << 0xffdb7093u;
+ QTest::newRow("SVG papayawhip") << QColorConstants::Svg::papayawhip << 0xffffefd5u;
+ QTest::newRow("SVG peachpuff") << QColorConstants::Svg::peachpuff << 0xffffdab9u;
+ QTest::newRow("SVG peru") << QColorConstants::Svg::peru << 0xffcd853fu;
+ QTest::newRow("SVG pink") << QColorConstants::Svg::pink << 0xffffc0cbu;
+ QTest::newRow("SVG plum") << QColorConstants::Svg::plum << 0xffdda0ddu;
+ QTest::newRow("SVG powderblue") << QColorConstants::Svg::powderblue << 0xffb0e0e6u;
+ QTest::newRow("SVG purple") << QColorConstants::Svg::purple << 0xff800080u;
+ QTest::newRow("SVG red") << QColorConstants::Svg::red << 0xffff0000u;
+ QTest::newRow("SVG rosybrown") << QColorConstants::Svg::rosybrown << 0xffbc8f8fu;
+ QTest::newRow("SVG royalblue") << QColorConstants::Svg::royalblue << 0xff4169e1u;
+ QTest::newRow("SVG saddlebrown") << QColorConstants::Svg::saddlebrown << 0xff8b4513u;
+ QTest::newRow("SVG salmon") << QColorConstants::Svg::salmon << 0xfffa8072u;
+ QTest::newRow("SVG sandybrown") << QColorConstants::Svg::sandybrown << 0xfff4a460u;
+ QTest::newRow("SVG seagreen") << QColorConstants::Svg::seagreen << 0xff2e8b57u;
+ QTest::newRow("SVG seashell") << QColorConstants::Svg::seashell << 0xfffff5eeu;
+ QTest::newRow("SVG sienna") << QColorConstants::Svg::sienna << 0xffa0522du;
+ QTest::newRow("SVG silver") << QColorConstants::Svg::silver << 0xffc0c0c0u;
+ QTest::newRow("SVG skyblue") << QColorConstants::Svg::skyblue << 0xff87ceebu;
+ QTest::newRow("SVG slateblue") << QColorConstants::Svg::slateblue << 0xff6a5acdu;
+ QTest::newRow("SVG slategray") << QColorConstants::Svg::slategray << 0xff708090u;
+ QTest::newRow("SVG slategrey") << QColorConstants::Svg::slategrey << 0xff708090u;
+ QTest::newRow("SVG snow") << QColorConstants::Svg::snow << 0xfffffafau;
+ QTest::newRow("SVG springgreen") << QColorConstants::Svg::springgreen << 0xff00ff7fu;
+ QTest::newRow("SVG steelblue") << QColorConstants::Svg::steelblue << 0xff4682b4u;
+ QTest::newRow("SVG tan") << QColorConstants::Svg::tan << 0xffd2b48cu;
+ QTest::newRow("SVG teal") << QColorConstants::Svg::teal << 0xff008080u;
+ QTest::newRow("SVG thistle") << QColorConstants::Svg::thistle << 0xffd8bfd8u;
+ QTest::newRow("SVG tomato") << QColorConstants::Svg::tomato << 0xffff6347u;
+ QTest::newRow("SVG turquoise") << QColorConstants::Svg::turquoise << 0xff40e0d0u;
+ QTest::newRow("SVG violet") << QColorConstants::Svg::violet << 0xffee82eeu;
+ QTest::newRow("SVG wheat") << QColorConstants::Svg::wheat << 0xfff5deb3u;
+ QTest::newRow("SVG white") << QColorConstants::Svg::white << 0xffffffffu;
+ QTest::newRow("SVG whitesmoke") << QColorConstants::Svg::whitesmoke << 0xfff5f5f5u;
+ QTest::newRow("SVG yellow") << QColorConstants::Svg::yellow << 0xffffff00u;
+ QTest::newRow("SVG yellowgreen") << QColorConstants::Svg::yellowgreen << 0xff9acd32u;
+}
+
+void tst_QColor::colorConstants()
+{
+ QFETCH(QColor, color);
+ QFETCH(QRgb, argb);
+ QCOMPARE(color.rgba(), argb);
+}
+#endif // defined(Q_COMPILER_CONSTEXPR) & defined(Q_COMPILER_UNIFORM_INIT)
+
/*
CSS color names = SVG 1.0 color names + transparent (rgba(0,0,0,0))
*/
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
index 4cf23455e1..d2a4dfc3e9 100644
--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -1632,6 +1632,7 @@ void tst_QPainter::qimageFormats_data()
QTest::newRow("Qimage::Format_RGB555") << QImage::Format_RGB555;
QTest::newRow("Qimage::Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied;
QTest::newRow("Qimage::Format_RGB888") << QImage::Format_RGB888;
+ QTest::newRow("Qimage::Format_BGR888") << QImage::Format_BGR888;
QTest::newRow("Qimage::Format_A2RGB30_Premultiplied") << QImage::Format_A2RGB30_Premultiplied;
QTest::newRow("Qimage::Format_RGB30") << QImage::Format_RGB30;
}
diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
index 58810f73c1..52e56feb5a 100644
--- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
+++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
@@ -50,6 +50,7 @@
#include <QDomDocument>
#include "common.h"
+// #define DEBUG_WRITE_OUTPUT
QT_FORWARD_DECLARE_CLASS(QTextDocument)
@@ -196,6 +197,7 @@ private:
void backgroundImage_checkExpectedHtml(const QTextDocument &doc);
void buildRegExpData();
static QString cssFontSizeString(const QFont &font);
+ void writeActualAndExpected(const char* testTag, const QString &actual, const QString &expected);
QTextDocument *doc;
QTextCursor cursor;
@@ -224,6 +226,27 @@ QString tst_QTextDocument::cssFontSizeString(const QFont &font)
: QString::number(font.pixelSize()) + QStringLiteral("px");
}
+void tst_QTextDocument::writeActualAndExpected(const char *testTag, const QString &actual, const QString &expected)
+{
+#ifdef DEBUG_WRITE_OUTPUT
+ {
+ QFile out(QDir::temp().absoluteFilePath(QLatin1String(testTag) + QLatin1String("-actual.html")));
+ out.open(QFile::WriteOnly);
+ out.write(actual.toUtf8());
+ out.close();
+ } {
+ QFile out(QDir::temp().absoluteFilePath(QLatin1String(testTag) + QLatin1String("-expected.html")));
+ out.open(QFile::WriteOnly);
+ out.write(expected.toUtf8());
+ out.close();
+ }
+#else
+ Q_UNUSED(testTag)
+ Q_UNUSED(actual)
+ Q_UNUSED(expected)
+#endif
+}
+
// Testing get/set functions
void tst_QTextDocument::getSetCheck()
{
@@ -1765,6 +1788,8 @@ void tst_QTextDocument::toHtml()
QString output = doc->toHtml();
+ writeActualAndExpected(QTest::currentDataTag(), output, expectedOutput);
+
QCOMPARE(output, expectedOutput);
QDomDocument document;
@@ -1962,6 +1987,8 @@ void tst_QTextDocument::toHtmlRootFrameProperties()
expectedOutput.replace("DEFAULTBLOCKSTYLE", "style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"");
expectedOutput.append(htmlTail);
+ writeActualAndExpected(QTest::currentTestFunction(), doc.toHtml(), expectedOutput);
+
QCOMPARE(doc.toHtml(), expectedOutput);
}
@@ -2734,6 +2761,8 @@ void tst_QTextDocument::backgroundImage_checkExpectedHtml(const QTextDocument &d
.arg(defaultFont.weight() * 8)
.arg((defaultFont.italic() ? "italic" : "normal"));
+ writeActualAndExpected(QTest::currentTestFunction(), doc.toHtml(), expectedHtml);
+
QCOMPARE(doc.toHtml(), expectedHtml);
}
diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
index c5243d1535..b6917f1208 100644
--- a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
+++ b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
@@ -181,6 +181,11 @@ private slots:
void html_tableCellBackground();
void css_bodyBackground();
void css_tableCellBackground();
+ void css_tableCellBorder();
+ void css_tableCellBorderShorthand();
+ void css_tableCellAllBordersShorthand();
+ void css_tableCellOverrideOneBorder();
+ void css_tableBorderCollapse();
void css_fontWeight();
void css_float();
void css_textIndent();
@@ -1753,6 +1758,135 @@ void tst_QTextDocumentFragment::css_tableCellBackground()
QCOMPARE(cell.format().background().style(), Qt::TexturePattern);
}
+void tst_QTextDocumentFragment::css_tableCellBorder()
+{
+ const char html[] = "<body><table><tr><td style=\"border-width:8px;border-color:green;border-style:groove;border-left-style:dashed;border-left-color:red;border-left-width:4px\">Foo</td></tr></table></body>";
+ doc->setHtml(html);
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::NextBlock);
+ QTextTable *table = cursor.currentTable();
+ QVERIFY(table);
+
+ QTextTableCell cell = table->cellAt(0, 0);
+ QTextTableCellFormat cellFormat = cell.format().toTableCellFormat();
+ QCOMPARE(cellFormat.leftBorder(), qreal(4));
+ QCOMPARE(cellFormat.leftBorderBrush(), QBrush(QColor("red")));
+ QCOMPARE(cellFormat.leftBorderStyle(), QTextFrameFormat::BorderStyle_Dashed);
+
+ QCOMPARE(cellFormat.rightBorder(), qreal(8));
+ QCOMPARE(cellFormat.rightBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.rightBorderStyle(), QTextFrameFormat::BorderStyle_Groove);
+
+ QCOMPARE(cellFormat.bottomBorder(), qreal(8));
+ QCOMPARE(cellFormat.bottomBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.bottomBorderStyle(), QTextFrameFormat::BorderStyle_Groove);
+
+ QCOMPARE(cellFormat.topBorder(), qreal(8));
+ QCOMPARE(cellFormat.topBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.topBorderStyle(), QTextFrameFormat::BorderStyle_Groove);
+}
+
+void tst_QTextDocumentFragment::css_tableCellBorderShorthand()
+{
+ const char html[] = "<body><table><tr><td style=\"border-left:1px solid green;border-right:2px dashed red;border-bottom:3px dotted yellow;border-top:4px dot-dash blue\">Foo</td></tr></table></body>";
+ doc->setHtml(html);
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::NextBlock);
+ QTextTable *table = cursor.currentTable();
+ QVERIFY(table);
+
+ QTextTableCell cell = table->cellAt(0, 0);
+ QTextTableCellFormat cellFormat = cell.format().toTableCellFormat();
+ QCOMPARE(cellFormat.leftBorder(), qreal(1));
+ QCOMPARE(cellFormat.leftBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.leftBorderStyle(), QTextFrameFormat::BorderStyle_Solid);
+
+ QCOMPARE(cellFormat.rightBorder(), qreal(2));
+ QCOMPARE(cellFormat.rightBorderBrush(), QBrush(QColor("red")));
+ QCOMPARE(cellFormat.rightBorderStyle(), QTextFrameFormat::BorderStyle_Dashed);
+
+ QCOMPARE(cellFormat.bottomBorder(), qreal(3));
+ QCOMPARE(cellFormat.bottomBorderBrush(), QBrush(QColor("yellow")));
+ QCOMPARE(cellFormat.bottomBorderStyle(), QTextFrameFormat::BorderStyle_Dotted);
+
+ QCOMPARE(cellFormat.topBorder(), qreal(4));
+ QCOMPARE(cellFormat.topBorderBrush(), QBrush(QColor("blue")));
+ QCOMPARE(cellFormat.topBorderStyle(), QTextFrameFormat::BorderStyle_DotDash);
+}
+
+void tst_QTextDocumentFragment::css_tableCellAllBordersShorthand()
+{
+ const char html[] = "<body><table><tr><td style=\"border:2px dashed green\">Foo</td></tr></table></body>";
+ doc->setHtml(html);
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::NextBlock);
+ QTextTable *table = cursor.currentTable();
+ QVERIFY(table);
+
+ QTextTableCell cell = table->cellAt(0, 0);
+ QTextTableCellFormat cellFormat = cell.format().toTableCellFormat();
+ QCOMPARE(cellFormat.leftBorder(), qreal(2));
+ QCOMPARE(cellFormat.leftBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.leftBorderStyle(), QTextFrameFormat::BorderStyle_Dashed);
+
+ QCOMPARE(cellFormat.rightBorder(), qreal(2));
+ QCOMPARE(cellFormat.rightBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.rightBorderStyle(), QTextFrameFormat::BorderStyle_Dashed);
+
+ QCOMPARE(cellFormat.bottomBorder(), qreal(2));
+ QCOMPARE(cellFormat.bottomBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.bottomBorderStyle(), QTextFrameFormat::BorderStyle_Dashed);
+
+ QCOMPARE(cellFormat.topBorder(), qreal(2));
+ QCOMPARE(cellFormat.topBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.topBorderStyle(), QTextFrameFormat::BorderStyle_Dashed);
+}
+
+void tst_QTextDocumentFragment::css_tableCellOverrideOneBorder()
+{
+ const char html[] = "<body><table><tr><td style=\"border:2px dashed green;border-left:4px solid red\">Foo</td></tr></table></body>";
+ doc->setHtml(html);
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::NextBlock);
+ QTextTable *table = cursor.currentTable();
+ QVERIFY(table);
+
+ QTextTableCell cell = table->cellAt(0, 0);
+ QTextTableCellFormat cellFormat = cell.format().toTableCellFormat();
+ QCOMPARE(cellFormat.leftBorder(), qreal(4));
+ QCOMPARE(cellFormat.leftBorderBrush(), QBrush(QColor("red")));
+ QCOMPARE(cellFormat.leftBorderStyle(), QTextFrameFormat::BorderStyle_Solid);
+
+ QCOMPARE(cellFormat.rightBorder(), qreal(2));
+ QCOMPARE(cellFormat.rightBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.rightBorderStyle(), QTextFrameFormat::BorderStyle_Dashed);
+
+ QCOMPARE(cellFormat.bottomBorder(), qreal(2));
+ QCOMPARE(cellFormat.bottomBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.bottomBorderStyle(), QTextFrameFormat::BorderStyle_Dashed);
+
+ QCOMPARE(cellFormat.topBorder(), qreal(2));
+ QCOMPARE(cellFormat.topBorderBrush(), QBrush(QColor("green")));
+ QCOMPARE(cellFormat.topBorderStyle(), QTextFrameFormat::BorderStyle_Dashed);
+}
+
+void tst_QTextDocumentFragment::css_tableBorderCollapse()
+{
+ const char html[] = "<body><table style=\"border-collapse:collapse\"><tr><td>Foo</td></tr></table></body>";
+ doc->setHtml(html);
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::NextBlock);
+ QTextTable *table = cursor.currentTable();
+ QVERIFY(table);
+
+ QCOMPARE(table->format().borderCollapse(), true);
+}
+
void tst_QTextDocumentFragment::css_cellPaddings()
{
const char html[] = "<body><table><tr><td style=\"padding-left:1\">Foo</td>"
diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
index f21b969aa7..7b2ff4cc10 100644
--- a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
+++ b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
@@ -50,6 +50,8 @@ typedef QList<int> IntList;
QT_FORWARD_DECLARE_CLASS(QTextDocument)
+Q_DECLARE_METATYPE(QTextFrameFormat::BorderStyle);
+
class tst_QTextTable : public QObject
{
Q_OBJECT
@@ -95,6 +97,8 @@ private slots:
#if !defined(QT_NO_PRINTER) && defined(QT_BUILD_INTERNAL)
void QTBUG31330_renderBackground();
#endif
+ void checkBorderAttributes_data();
+ void checkBorderAttributes();
private:
QTextTable *create2x2Table();
@@ -1170,5 +1174,109 @@ void tst_QTextTable::QTBUG31330_renderBackground()
}
#endif
+void tst_QTextTable::checkBorderAttributes_data()
+{
+ QTest::addColumn<QString>("html");
+ QTest::addColumn<qreal>("topBorderWidth");
+ QTest::addColumn<qreal>("bottomBorderWidth");
+ QTest::addColumn<qreal>("leftBorderWidth");
+ QTest::addColumn<qreal>("rightBorderWidth");
+ QTest::addColumn<QTextFrameFormat::BorderStyle>("topBorderStyle");
+ QTest::addColumn<QTextFrameFormat::BorderStyle>("bottomBorderStyle");
+ QTest::addColumn<QTextFrameFormat::BorderStyle>("leftBorderStyle");
+ QTest::addColumn<QTextFrameFormat::BorderStyle>("rightBorderStyle");
+ QTest::addColumn<QBrush>("topBorderBrush");
+ QTest::addColumn<QBrush>("bottomBorderBrush");
+ QTest::addColumn<QBrush>("leftBorderBrush");
+ QTest::addColumn<QBrush>("rightBorderBrush");
+
+ const QString tableHtmlStart = QStringLiteral("<html><head><style>");
+ const QString tableHtmlEnd = QStringLiteral("</style></head><body>"
+ "<table border=\"1\"><tr><td>One</td><td>Two</td></tr>"
+ "<tr><td>Three</td><td>Four</td></tr></table></body></html>");
+ QTest::newRow("1px-solid-colors")
+ << QString("%1"
+ "td {"
+ "border-top: 1px solid red;"
+ "border-bottom: 1px solid blue;"
+ "border-left: 1px solid green;"
+ "border-right: 1px solid yellow;"
+ "}"
+ "%2").arg(tableHtmlStart).arg(tableHtmlEnd)
+ << 1.0 << 1.0 << 1.0 << 1.0
+ << QTextFrameFormat::BorderStyle_Solid << QTextFrameFormat::BorderStyle_Solid
+ << QTextFrameFormat::BorderStyle_Solid << QTextFrameFormat::BorderStyle_Solid
+ << QBrush(Qt::red) << QBrush(Qt::blue) << QBrush(Qt::darkGreen) << QBrush(Qt::yellow);
+ QTest::newRow("MixedWidth-solid-colors")
+ << QString("%1"
+ "td {"
+ "border-top: 1px solid red;"
+ "border-bottom: 2px solid blue;"
+ "border-left: 3px solid green;"
+ "border-right: 4px solid yellow;"
+ "}"
+ "%2").arg(tableHtmlStart).arg(tableHtmlEnd)
+ << 1.0 << 2.0 << 3.0 << 4.0
+ << QTextFrameFormat::BorderStyle_Solid << QTextFrameFormat::BorderStyle_Solid
+ << QTextFrameFormat::BorderStyle_Solid << QTextFrameFormat::BorderStyle_Solid
+ << QBrush(Qt::red) << QBrush(Qt::blue) << QBrush(Qt::darkGreen) << QBrush(Qt::yellow);
+ QTest::newRow("MixedWidth-MixedStyle-colors")
+ << QString("%1"
+ "td {"
+ "border-top: 1px solid red;"
+ "border-bottom: 2px dotted blue;"
+ "border-left: 3px dashed green;"
+ "border-right: 4px inset yellow;"
+ "}"
+ "%2").arg(tableHtmlStart).arg(tableHtmlEnd)
+ << 1.0 << 2.0 << 3.0 << 4.0
+ << QTextFrameFormat::BorderStyle_Solid << QTextFrameFormat::BorderStyle_Dotted
+ << QTextFrameFormat::BorderStyle_Dashed << QTextFrameFormat::BorderStyle_Inset
+ << QBrush(Qt::red) << QBrush(Qt::blue) << QBrush(Qt::darkGreen) << QBrush(Qt::yellow);
+}
+
+void tst_QTextTable::checkBorderAttributes()
+{
+ QFETCH(QString, html);
+ QFETCH(qreal, topBorderWidth);
+ QFETCH(qreal, bottomBorderWidth);
+ QFETCH(qreal, leftBorderWidth);
+ QFETCH(qreal, rightBorderWidth);
+ QFETCH(QTextFrameFormat::BorderStyle, topBorderStyle);
+ QFETCH(QTextFrameFormat::BorderStyle, bottomBorderStyle);
+ QFETCH(QTextFrameFormat::BorderStyle, leftBorderStyle);
+ QFETCH(QTextFrameFormat::BorderStyle, rightBorderStyle);
+ QFETCH(QBrush, topBorderBrush);
+ QFETCH(QBrush, bottomBorderBrush);
+ QFETCH(QBrush, leftBorderBrush);
+ QFETCH(QBrush, rightBorderBrush);
+
+ QTextDocument doc;
+ doc.setHtml(html);
+ QTextCursor cursor(doc.firstBlock());
+ cursor.movePosition(QTextCursor::Right);
+
+ QTextTable *currentTable = cursor.currentTable();
+ QVERIFY(currentTable);
+ for (int row = 0; row < 2; row++) {
+ for (int column = 0; column < 2; column++) {
+ QTextTableCell cell = currentTable->cellAt(row, column);
+ QTextCharFormat cellFormat = cell.format();
+ QCOMPARE(cellFormat.doubleProperty(QTextFormat::TableCellTopBorder), topBorderWidth);
+ QCOMPARE(cellFormat.doubleProperty(QTextFormat::TableCellBottomBorder), bottomBorderWidth);
+ QCOMPARE(cellFormat.doubleProperty(QTextFormat::TableCellLeftBorder), leftBorderWidth);
+ QCOMPARE(cellFormat.doubleProperty(QTextFormat::TableCellRightBorder), rightBorderWidth);
+ QCOMPARE(cellFormat.property(QTextFormat::TableCellTopBorderStyle), topBorderStyle);
+ QCOMPARE(cellFormat.property(QTextFormat::TableCellBottomBorderStyle), bottomBorderStyle);
+ QCOMPARE(cellFormat.property(QTextFormat::TableCellLeftBorderStyle), leftBorderStyle);
+ QCOMPARE(cellFormat.property(QTextFormat::TableCellRightBorderStyle), rightBorderStyle);
+ QCOMPARE(cellFormat.brushProperty(QTextFormat::TableCellTopBorderBrush), topBorderBrush);
+ QCOMPARE(cellFormat.brushProperty(QTextFormat::TableCellBottomBorderBrush), bottomBorderBrush);
+ QCOMPARE(cellFormat.brushProperty(QTextFormat::TableCellLeftBorderBrush), leftBorderBrush);
+ QCOMPARE(cellFormat.brushProperty(QTextFormat::TableCellRightBorderBrush), rightBorderBrush);
+ }
+ }
+}
+
QTEST_MAIN(tst_QTextTable)
#include "tst_qtexttable.moc"
diff --git a/tests/auto/network/access/http2/http2srv.cpp b/tests/auto/network/access/http2/http2srv.cpp
index 5a99d4e50c..a8eebf5a24 100644
--- a/tests/auto/network/access/http2/http2srv.cpp
+++ b/tests/auto/network/access/http2/http2srv.cpp
@@ -76,7 +76,7 @@ void fill_push_header(const HttpHeader &originalRequest, HttpHeader &promisedReq
}
-Http2Server::Http2Server(H2Type type, const Http2::RawSettings &ss, const Http2::RawSettings &cs)
+Http2Server::Http2Server(H2Type type, const RawSettings &ss, const RawSettings &cs)
: connectionType(type),
serverSettings(ss),
expectedClientSettings(cs)
@@ -218,7 +218,7 @@ void Http2Server::sendDATA(quint32 streamID, quint32 windowSize)
quint32 bytesToSend = std::min<quint32>(windowSize, responseBody.size() - offset);
quint32 bytesSent = 0;
- const quint32 frameSizeLimit(clientSetting(Settings::MAX_FRAME_SIZE_ID, Http2::maxFrameSize));
+ const quint32 frameSizeLimit(clientSetting(Settings::MAX_FRAME_SIZE_ID, Http2::minPayloadLimit));
const uchar *src = reinterpret_cast<const uchar *>(responseBody.constData() + offset);
const bool last = offset + bytesToSend == quint32(responseBody.size());
@@ -236,6 +236,10 @@ void Http2Server::sendDATA(quint32 streamID, quint32 windowSize)
src += chunkSize;
bytesToSend -= chunkSize;
bytesSent += chunkSize;
+ if (frameSizeLimit != Http2::minPayloadLimit) {
+ // Our test is probably interested in how many DATA frames were sent.
+ emit sendingData();
+ }
}
if (interrupted.loadAcquire())
@@ -767,7 +771,7 @@ void Http2Server::sendResponse(quint32 streamID, bool emptyBody)
Q_ASSERT(activeRequests.find(streamID) != activeRequests.end());
const quint32 maxFrameSize(clientSetting(Settings::MAX_FRAME_SIZE_ID,
- Http2::maxFrameSize));
+ Http2::maxPayloadSize));
if (pushPromiseEnabled) {
// A real server supporting PUSH_PROMISE will probably first send
diff --git a/tests/auto/network/access/http2/http2srv.h b/tests/auto/network/access/http2/http2srv.h
index 4ef4b25101..3105684d59 100644
--- a/tests/auto/network/access/http2/http2srv.h
+++ b/tests/auto/network/access/http2/http2srv.h
@@ -42,6 +42,7 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qatomic.h>
#include <QtCore/qglobal.h>
+#include <QtCore/qmap.h>
#include <vector>
#include <map>
@@ -69,13 +70,15 @@ enum class H2Type {
h2cDirect, // Clear text direct
};
+using RawSettings = QMap<Http2::Settings, quint32>;
+
class Http2Server : public QTcpServer
{
Q_OBJECT
public:
- Http2Server(H2Type type, const Http2::RawSettings &serverSettings,
- const Http2::RawSettings &clientSettings);
+ Http2Server(H2Type type, const RawSettings &serverSettings,
+ const RawSettings &clientSettings);
~Http2Server();
@@ -125,6 +128,7 @@ Q_SIGNALS:
void receivedRequest(quint32 streamID);
void receivedData(quint32 streamID);
void windowUpdate(quint32 streamID);
+ void sendingData();
private slots:
void connectionEstablished();
@@ -147,8 +151,8 @@ private:
bool settingsSent = false;
bool waitingClientAck = false;
- Http2::RawSettings serverSettings;
- Http2::RawSettings expectedClientSettings;
+ RawSettings serverSettings;
+ RawSettings expectedClientSettings;
bool connectionError = false;
diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp
index 945ea1b448..e24a06bc34 100644
--- a/tests/auto/network/access/http2/tst_http2.cpp
+++ b/tests/auto/network/access/http2/tst_http2.cpp
@@ -32,8 +32,10 @@
#include <QtNetwork/private/http2protocol_p.h>
#include <QtNetwork/qnetworkaccessmanager.h>
+#include <QtNetwork/qhttp2configuration.h>
#include <QtNetwork/qnetworkrequest.h>
#include <QtNetwork/qnetworkreply.h>
+
#include <QtCore/qglobal.h>
#include <QtCore/qobject.h>
#include <QtCore/qthread.h>
@@ -66,6 +68,26 @@ Q_DECLARE_METATYPE(QNetworkRequest::Attribute)
QT_BEGIN_NAMESPACE
+QHttp2Configuration qt_defaultH2Configuration()
+{
+ QHttp2Configuration config;
+ config.setStreamReceiveWindowSize(Http2::qtDefaultStreamReceiveWindowSize);
+ config.setSessionReceiveWindowSize(Http2::maxSessionReceiveWindowSize);
+ config.setServerPushEnabled(false);
+ return config;
+}
+
+RawSettings qt_H2ConfigurationToSettings(const QHttp2Configuration &config = qt_defaultH2Configuration())
+{
+ RawSettings settings;
+ settings[Http2::Settings::ENABLE_PUSH_ID] = config.serverPushEnabled();
+ settings[Http2::Settings::INITIAL_WINDOW_SIZE_ID] = config.streamReceiveWindowSize();
+ if (config.maxFrameSize() != Http2::minPayloadLimit)
+ settings[Http2::Settings::MAX_FRAME_SIZE_ID] = config.maxFrameSize();
+ return settings;
+}
+
+
class tst_Http2 : public QObject
{
Q_OBJECT
@@ -87,6 +109,7 @@ private slots:
void earlyResponse();
void connectToHost_data();
void connectToHost();
+ void maxFrameSize();
protected slots:
// Slots to listen to our in-process server:
@@ -110,12 +133,13 @@ private:
// small payload.
void runEventLoop(int ms = 5000);
void stopEventLoop();
- Http2Server *newServer(const Http2::RawSettings &serverSettings, H2Type connectionType,
- const Http2::ProtocolParameters &clientSettings = {});
+ Http2Server *newServer(const RawSettings &serverSettings, H2Type connectionType,
+ const RawSettings &clientSettings = qt_H2ConfigurationToSettings());
// Send a get or post request, depending on a payload (empty or not).
void sendRequest(int streamNumber,
QNetworkRequest::Priority priority = QNetworkRequest::NormalPriority,
- const QByteArray &payload = QByteArray());
+ const QByteArray &payload = QByteArray(),
+ const QHttp2Configuration &clientConfiguration = qt_defaultH2Configuration());
QUrl requestUrl(H2Type connnectionType) const;
quint16 serverPort = 0;
@@ -131,14 +155,14 @@ private:
bool prefaceOK = false;
bool serverGotSettingsACK = false;
- static const Http2::RawSettings defaultServerSettings;
+ static const RawSettings defaultServerSettings;
};
#define STOP_ON_FAILURE \
if (QTest::currentTestFailed()) \
return;
-const Http2::RawSettings tst_Http2::defaultServerSettings{{Http2::Settings::MAX_CONCURRENT_STREAMS_ID, 100}};
+const RawSettings tst_Http2::defaultServerSettings{{Http2::Settings::MAX_CONCURRENT_STREAMS_ID, 100}};
namespace {
@@ -308,18 +332,15 @@ void tst_Http2::flowControlClientSide()
nRequests = 10;
windowUpdates = 0;
- Http2::ProtocolParameters params;
+ QHttp2Configuration params;
// A small window size for a session, and even a smaller one per stream -
// this will result in WINDOW_UPDATE frames both on connection stream and
// per stream.
- params.maxSessionReceiveWindowSize = Http2::defaultSessionWindowSize * 5;
- params.settingsFrameData[Settings::INITIAL_WINDOW_SIZE_ID] = Http2::defaultSessionWindowSize;
- // Inform our manager about non-default settings:
- manager->setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params));
-
- const Http2::RawSettings serverSettings = {{Settings::MAX_CONCURRENT_STREAMS_ID, quint32(3)}};
- ServerPtr srv(newServer(serverSettings, defaultConnectionType(), params));
+ params.setSessionReceiveWindowSize(Http2::defaultSessionWindowSize * 5);
+ params.setStreamReceiveWindowSize(Http2::defaultSessionWindowSize);
+ const RawSettings serverSettings = {{Settings::MAX_CONCURRENT_STREAMS_ID, quint32(3)}};
+ ServerPtr srv(newServer(serverSettings, defaultConnectionType(), qt_H2ConfigurationToSettings(params)));
const QByteArray respond(int(Http2::defaultSessionWindowSize * 10), 'x');
srv->setResponseBody(respond);
@@ -330,7 +351,7 @@ void tst_Http2::flowControlClientSide()
QVERIFY(serverPort != 0);
for (int i = 0; i < nRequests; ++i)
- sendRequest(i);
+ sendRequest(i, QNetworkRequest::NormalPriority, {}, params);
runEventLoop(120000);
STOP_ON_FAILURE
@@ -359,7 +380,7 @@ void tst_Http2::flowControlServerSide()
serverPort = 0;
nRequests = 10;
- const Http2::RawSettings serverSettings = {{Settings::MAX_CONCURRENT_STREAMS_ID, 7}};
+ const RawSettings serverSettings = {{Settings::MAX_CONCURRENT_STREAMS_ID, 7}};
ServerPtr srv(newServer(serverSettings, defaultConnectionType()));
@@ -392,12 +413,11 @@ void tst_Http2::pushPromise()
serverPort = 0;
nRequests = 1;
- Http2::ProtocolParameters params;
+ QHttp2Configuration params;
// Defaults are good, except ENABLE_PUSH:
- params.settingsFrameData[Settings::ENABLE_PUSH_ID] = 1;
- manager->setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params));
+ params.setServerPushEnabled(true);
- ServerPtr srv(newServer(defaultServerSettings, defaultConnectionType(), params));
+ ServerPtr srv(newServer(defaultServerSettings, defaultConnectionType(), qt_H2ConfigurationToSettings(params)));
srv->enablePushPromise(true, QByteArray("/script.js"));
QMetaObject::invokeMethod(srv.data(), "startServer", Qt::QueuedConnection);
@@ -410,6 +430,7 @@ void tst_Http2::pushPromise()
QNetworkRequest request(url);
request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true));
+ request.setHttp2Configuration(params);
auto reply = manager->get(request);
connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
@@ -678,6 +699,73 @@ void tst_Http2::connectToHost()
QVERIFY(reply->isFinished());
}
+void tst_Http2::maxFrameSize()
+{
+#if !QT_CONFIG(ssl)
+ QSKIP("TLS support is needed for this test");
+#endif // QT_CONFIG(ssl)
+
+ // Here we test we send 'MAX_FRAME_SIZE' setting in our
+ // 'SETTINGS'. If done properly, our server will not chunk
+ // the payload into several DATA frames.
+
+#if QT_CONFIG(securetransport)
+ // Normally on macOS we use plain text only for SecureTransport
+ // does not support ALPN on the server side. With 'direct encrytped'
+ // we have to use TLS sockets (== private key) and thus suppress a
+ // keychain UI asking for permission to use a private key.
+ // Our CI has this, but somebody testing locally - will have a problem.
+ qputenv("QT_SSL_USE_TEMPORARY_KEYCHAIN", QByteArray("1"));
+ auto envRollback = qScopeGuard([](){
+ qunsetenv("QT_SSL_USE_TEMPORARY_KEYCHAIN");
+ });
+#endif // QT_CONFIG(securetransport)
+
+ auto connectionType = H2Type::h2Alpn;
+ auto attribute = QNetworkRequest::HTTP2AllowedAttribute;
+ if (clearTextHTTP2) {
+ connectionType = H2Type::h2Direct;
+ attribute = QNetworkRequest::Http2DirectAttribute;
+ }
+
+ auto h2Config = qt_defaultH2Configuration();
+ h2Config.setMaxFrameSize(Http2::minPayloadLimit * 3);
+
+ serverPort = 0;
+ nRequests = 1;
+
+ ServerPtr srv(newServer(defaultServerSettings, connectionType,
+ qt_H2ConfigurationToSettings(h2Config)));
+ srv->setResponseBody(QByteArray(Http2::minPayloadLimit * 2, 'q'));
+ QMetaObject::invokeMethod(srv.data(), "startServer", Qt::QueuedConnection);
+ runEventLoop();
+ QVERIFY(serverPort != 0);
+
+ const QSignalSpy frameCounter(srv.data(), &Http2Server::sendingData);
+ auto url = requestUrl(connectionType);
+ url.setPath(QString("/stream1.html"));
+
+ QNetworkRequest request(url);
+ request.setAttribute(attribute, QVariant(true));
+ request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
+ request.setHttp2Configuration(h2Config);
+
+ QNetworkReply *reply = manager->get(request);
+ reply->ignoreSslErrors();
+ connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
+
+ runEventLoop();
+ STOP_ON_FAILURE
+
+ // Normally, with a 16kb limit, our server would split such
+ // a response into 3 'DATA' frames (16kb + 16kb + 0|END_STREAM).
+ QCOMPARE(frameCounter.count(), 1);
+
+ QVERIFY(nRequests == 0);
+ QVERIFY(prefaceOK);
+ QVERIFY(serverGotSettingsACK);
+}
+
void tst_Http2::serverStarted(quint16 port)
{
serverPort = port;
@@ -689,7 +777,6 @@ void tst_Http2::clearHTTP2State()
windowUpdates = 0;
prefaceOK = false;
serverGotSettingsACK = false;
- manager->setProperty(Http2::http2ParametersPropertyName, QVariant());
}
void tst_Http2::runEventLoop(int ms)
@@ -702,12 +789,11 @@ void tst_Http2::stopEventLoop()
eventLoop.exitLoop();
}
-Http2Server *tst_Http2::newServer(const Http2::RawSettings &serverSettings, H2Type connectionType,
- const Http2::ProtocolParameters &clientSettings)
+Http2Server *tst_Http2::newServer(const RawSettings &serverSettings, H2Type connectionType,
+ const RawSettings &clientSettings)
{
using namespace Http2;
- auto srv = new Http2Server(connectionType, serverSettings,
- clientSettings.settingsFrameData);
+ auto srv = new Http2Server(connectionType, serverSettings, clientSettings);
using Srv = Http2Server;
using Cl = tst_Http2;
@@ -729,7 +815,8 @@ Http2Server *tst_Http2::newServer(const Http2::RawSettings &serverSettings, H2Ty
void tst_Http2::sendRequest(int streamNumber,
QNetworkRequest::Priority priority,
- const QByteArray &payload)
+ const QByteArray &payload,
+ const QHttp2Configuration &h2Config)
{
auto url = requestUrl(defaultConnectionType());
url.setPath(QString("/stream%1.html").arg(streamNumber));
@@ -739,6 +826,7 @@ void tst_Http2::sendRequest(int streamNumber,
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, QVariant(true));
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
request.setPriority(priority);
+ request.setHttp2Configuration(h2Config);
QNetworkReply *reply = nullptr;
if (payload.size())
diff --git a/tests/auto/network/access/qabstractnetworkcache/BLACKLIST b/tests/auto/network/access/qabstractnetworkcache/BLACKLIST
deleted file mode 100644
index 12f45f0e12..0000000000
--- a/tests/auto/network/access/qabstractnetworkcache/BLACKLIST
+++ /dev/null
@@ -1,2 +0,0 @@
-[cacheControl]
-windows-10 msvc-2015
diff --git a/tests/auto/network/access/qftp/BLACKLIST b/tests/auto/network/access/qftp/BLACKLIST
index 463030a089..0a99f3eb00 100644
--- a/tests/auto/network/access/qftp/BLACKLIST
+++ b/tests/auto/network/access/qftp/BLACKLIST
@@ -7,15 +7,10 @@ redhatenterpriselinuxworkstation-6.6
redhatenterpriselinuxworkstation-6.6
[list]
-ubuntu-16.04
opensuse-leap
-osx-10.11
windows-7sp1
-ubuntu-18.04
-osx-10.14
-b2qt
-osx-10.12
windows-10 msvc-2015
-opensuse-42.3
+ubuntu
+osx
[list:epsvNotSupported]
*
diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST
index f9bbdd96c3..2a0651f96f 100644
--- a/tests/auto/network/access/qnetworkreply/BLACKLIST
+++ b/tests/auto/network/access/qnetworkreply/BLACKLIST
@@ -1,106 +1,53 @@
# See qtbase/src/testlib/qtestblacklist.cpp for format
[authenticationCacheAfterCancel]
-windows-10 msvc-2017
-windows-10 msvc-2015
-osx-10.13
windows-7sp1
-[httpAbort]
-ubuntu-16.04
-rhel-7.6
+windows-10 msvc-2015
[backgroundRequestInterruption]
-ubuntu-16.04
opensuse-leap
-ubuntu-18.04
-b2qt
-osx-10.12
windows-10 msvc-2015
-opensuse-42.3
+b2qt
+ubuntu
+osx
[backgroundRequestInterruption:ftp, bg, nobg]
*
-[getErrors]
-osx-10.13
-# QTBUG-71953
[getErrors:ftp-host]
linux
# QTBUG-71953
[getFromHttp]
-rhel-6.6
-ubuntu-16.04
-rhel-7.6
-opensuse-leap
-osx-10.11
-osx-10.13
-windows-7sp1
-ubuntu-18.04
-osx-10.14
-rhel-7.4
-b2qt
-windows-10 msvc-2017
-osx-10.12
-windows-10 msvc-2015
-opensuse-42.3
+* !android !winrt
[getFromHttp:success-external]
*
[getFromHttpIntoBuffer]
-osx-10.12
-osx-10.13
+osx
[getFromHttpIntoBuffer2]
-windows-10 msvc-2015
-windows-10 msvc-2017
+windows-10
[headFromHttp]
-osx-10.13
windows-10 msvc-2017
-[ioGetFromHttpWithSocksProxy]
-osx-10.12
[ioPostToHttpFromSocket]
# QTBUG-66247
-osx-10.13
windows-7sp1
windows-10 msvc-2017
-osx-10.12
-windows-10 msvc-2015
+osx
[ioHttpRedirect]
-windows-10 msvc-2015
# QTBUG-66602
-windows-10 msvc-2017
+windows-10
[ioHttpRedirectMultipartPost]
-ubuntu-16.04
-rhel-7.6
# QTBUG-66247
-opensuse-leap
-osx-10.13
-ubuntu-18.04
-rhel-7.4
b2qt
-osx-10.12
windows-10 msvc-2015
-opensuse-42.3
+ubuntu
+rhel
[ioHttpRedirectPolicy]
-ubuntu-16.04
opensuse-leap
-windows-7sp1
-ubuntu-18.04
b2qt
-windows-10 msvc-2017
-windows-10 msvc-2015
-opensuse-42.3
-[ioHttpRedirectPostPut]
-osx-10.12
-windows-10 msvc-2015
+ubuntu
+windows-10
[putToFtp]
-windows-10 msvc-2017
+windows-10
[putWithServerClosingConnectionImmediately]
-osx-10.11
-osx-10.13
-windows-7sp1
-windows-10 msvc-2017
-osx-10.12
-windows-10 msvc-2015
-[qtbug28035browserDoesNotLoadQtProjectOrgCorrectly]
-windows-10 msvc-2015
windows-7sp1
-[authenticationWithDifferentRealm]
-osx-10.13
+windows-10
+osx
[backgroundRequest]
osx-10.12
[connectToIPv6Address]
@@ -109,141 +56,73 @@ osx-10.12
osx-10.12
[downloadProgress]
osx-10.12
-[emitErrorForAllReplies]
-osx-10.12
[encrypted]
osx-10.13
-[ftpAuthentication]
-osx-10.13
[httpCanReadLine]
osx-10.12
-osx-10.13
[httpRecursiveCreation]
-osx-10.12
-osx-10.13
+osx
[httpWithNoCredentialUsage]
osx-10.12
[ignoreSslErrorsList]
-osx-10.12
-osx-10.13
+osx
[ignoreSslErrorsListWithSlot]
-osx-10.12
-osx-10.13
+osx
[ioGetFromBuiltinHttp]
-osx-10.12
-osx-10.11
-osx-10.14
-osx-10.13
+osx
[ioGetFromHttp]
osx-10.12
-[ioGetFromHttpWithAuth]
-osx-10.12
-osx-10.13
-[ioGetFromHttpWithAuthSynchronous]
-osx-10.12
-[ioGetFromHttpWithProxyAuth]
-osx-10.12
-[ioGetFromHttpWithReuseParallel]
-osx-10.12
-osx-10.13
-[ioGetFromHttpWithReuseSequential]
-osx-10.12
-osx-10.13
-[ioGetFromHttpsWithIgnoreSslErrors]
-osx-10.12
-[ioGetFromHttpsWithSslErrors]
-osx-10.12
-[ioGetFromHttpsWithSslHandshakeError]
-osx-10.12
-[ioGetWithManyProxies]
-osx-10.12
[ioPostToHttpFromFile]
osx-10.13
-[ioPostToHttpFromMiddleOfFileFiveBytes]
-osx-10.13
-[ioPostToHttpFromMiddleOfFileToEnd]
-osx-10.13
-[ioPostToHttpFromMiddleOfQBufferFiveBytes]
-osx-10.13
[ioPostToHttpFromSocketSynchronous]
-osx-10.12
-osx-10.13
-[ioPostToHttpNoBufferFlag]
-osx-10.13
+osx
[ioPostToHttpUploadProgress]
-osx-10.12
-osx-10.11
-osx-10.13
+osx
[ioPutToHttpFromFile]
osx-10.13
[lastModifiedHeaderForHttp]
osx-10.12
-osx-10.13
[multipartSkipIndices]
osx-10.12
-osx-10.13
[nestedEventLoops]
-osx-10.12
-osx-10.13
-[pipelining]
-osx-10.13
+osx
[postToHttp]
osx-10.12
-osx-10.13
[postToHttpMultipart]
osx-10.12
-osx-10.13
[postToHttpSynchronous]
osx-10.12
-osx-10.13
[postToHttps]
-osx-10.12
-osx-10.13
+osx
[postToHttpsMultipart]
-osx-10.12
-osx-10.13
+osx
[postToHttpsSynchronous]
-osx-10.12
-osx-10.13
+osx
[putGetDeleteGetFromHttp]
osx-10.12
-[putToHttp]
-osx-10.12
-osx-10.13
[putToHttpSynchronous]
osx-10.12
-osx-10.13
[putToHttps]
-osx-10.12
-osx-10.13
+osx
[putToHttpsSynchronous]
-osx-10.12
-osx-10.13
+osx
[putWithRateLimiting]
-osx-10.12
osx-10.13
[qtbug13431replyThrottling]
osx-10.12
[receiveCookiesFromHttp]
-osx-10.12
-osx-10.13
+osx
[receiveCookiesFromHttpSynchronous]
-osx-10.12
-osx-10.13
+osx
[sendCookies]
-osx-10.12
-osx-10.13
+osx
[sendCookiesSynchronous]
-osx-10.12
-osx-10.13
+osx
[sendCustomRequestToHttp]
osx-10.12
[sslConfiguration]
-osx-10.12
-osx-10.13
+osx
[synchronousRequest]
-osx-10.12
-osx-10.13
+osx
[backgroundRequestConnectInBackground]
-osx-10.12
-osx-10.13
+osx
diff --git a/tests/auto/network/access/spdy/BLACKLIST b/tests/auto/network/access/spdy/BLACKLIST
index ce2f7f383f..5cf79327be 100644
--- a/tests/auto/network/access/spdy/BLACKLIST
+++ b/tests/auto/network/access/spdy/BLACKLIST
@@ -1,8 +1,5 @@
[download]
opensuse-leap
-ubuntu-18.04
-ubuntu-16.04
-b2qt
[upload]
opensuse-leap
ubuntu-18.04
diff --git a/tests/auto/network/kernel/qdnslookup/BLACKLIST b/tests/auto/network/kernel/qdnslookup/BLACKLIST
index 4461d8b5f7..f07a8ce9a3 100644
--- a/tests/auto/network/kernel/qdnslookup/BLACKLIST
+++ b/tests/auto/network/kernel/qdnslookup/BLACKLIST
@@ -1,12 +1,2 @@
[lookup]
-rhel-7.6
-opensuse-leap
-osx-10.13
-windows-7sp1
-ubuntu-18.04
-rhel-7.4
-b2qt
-windows-10 msvc-2017
-osx-10.12
-windows-10 msvc-2015
-opensuse-42.3
+*
diff --git a/tests/auto/network/socket/qsocks5socketengine/BLACKLIST b/tests/auto/network/socket/qsocks5socketengine/BLACKLIST
index f769aafbdd..61fff6ee00 100644
--- a/tests/auto/network/socket/qsocks5socketengine/BLACKLIST
+++ b/tests/auto/network/socket/qsocks5socketengine/BLACKLIST
@@ -4,8 +4,7 @@
ubuntu-18.04
# QTBUG-74162
[passwordAuth2]
-osx-10.12
-ubuntu-18.04
+ubuntu
[downloadBigFile]
windows-10 msvc-2015
windows-7sp1
diff --git a/tests/auto/network/socket/qtcpserver/BLACKLIST b/tests/auto/network/socket/qtcpserver/BLACKLIST
index ad0edf0af1..e268468bdb 100644
--- a/tests/auto/network/socket/qtcpserver/BLACKLIST
+++ b/tests/auto/network/socket/qtcpserver/BLACKLIST
@@ -1,24 +1,16 @@
-[listenWhileListening]
-windows-10 msvc-2015
[listenWhileListening:WithSocks5Proxy]
linux
windows
[ipv6Server]
-windows-10 msvc-2015
windows-7sp1
windows-10 msvc-2017
[ipv6Server:WithoutProxy]
windows
osx
-[addressReusable]
-windows-10 msvc-2015
[eagainBlockingAccept]
-windows-10 msvc-2015
-windows-7sp1
-windows-10 msvc-2017
-[proxyFactory]
windows-7sp1
+windows-10
[serverAddress]
-windows-10 msvc-2017
-windows-10 msvc-2015
windows-7sp1
+windows-10
+
diff --git a/tests/auto/network/socket/qtcpsocket/BLACKLIST b/tests/auto/network/socket/qtcpsocket/BLACKLIST
index 8c2f8d2638..07532710b3 100644
--- a/tests/auto/network/socket/qtcpsocket/BLACKLIST
+++ b/tests/auto/network/socket/qtcpsocket/BLACKLIST
@@ -5,9 +5,6 @@ windows-7sp1
windows
[bind:[::]:randomport]
windows
-[timeoutConnect]
-windows-10 msvc-2015
-# QTBUG-66247
[timeoutConnect:ip]
windows
# QTBUG-66247
diff --git a/tests/auto/network/socket/qudpsocket/BLACKLIST b/tests/auto/network/socket/qudpsocket/BLACKLIST
index 9b5aa8a3fc..bc6068d695 100644
--- a/tests/auto/network/socket/qudpsocket/BLACKLIST
+++ b/tests/auto/network/socket/qudpsocket/BLACKLIST
@@ -2,15 +2,9 @@
windows-10 msvc-2017
windows-10 msvc-2015
windows-7sp1
-[multicastLeaveAfterClose]
-osx-10.12
-osx-10.11
[readyReadForEmptyDatagram]
opensuse-leap
-ubuntu-16.04
[echo]
opensuse-42.3
-[ipv6Loop]
-osx-10.12
[readyReadForEmptyDatagram]
linux
diff --git a/tests/auto/network/ssl/qsslkey/BLACKLIST b/tests/auto/network/ssl/qsslkey/BLACKLIST
index e9723001f5..19fb15cd1f 100644
--- a/tests/auto/network/ssl/qsslkey/BLACKLIST
+++ b/tests/auto/network/ssl/qsslkey/BLACKLIST
@@ -1,16 +1,9 @@
[constructor]
-rhel-6.6
-rhel-7.4
-rhel-7.6
+rhel
[length]
-rhel-6.6
-rhel-7.4
-rhel-7.6
+rhel
[toEncryptedPemOrDer]
-rhel-6.6
-rhel-7.4
-rhel-7.6
+rhel
[toPemOrDer]
-rhel-6.6
-rhel-7.4
-rhel-7.6
+rhel
+
diff --git a/tests/auto/network/ssl/qsslsocket/BLACKLIST b/tests/auto/network/ssl/qsslsocket/BLACKLIST
index 36143691c9..7b4a29f463 100644
--- a/tests/auto/network/ssl/qsslsocket/BLACKLIST
+++ b/tests/auto/network/ssl/qsslsocket/BLACKLIST
@@ -1,11 +1,7 @@
-[abortOnSslErrors]
-windows-10 msvc-2015
[deprecatedProtocols]
windows
[spontaneousWrite]
windows-7sp1
-[sslErrors]
-windows-7sp1
[connectToHostEncrypted]
osx-10.13
[setSslConfiguration]
diff --git a/tests/auto/other/networkselftest/BLACKLIST b/tests/auto/other/networkselftest/BLACKLIST
index 948081eb78..55ebad985d 100644
--- a/tests/auto/other/networkselftest/BLACKLIST
+++ b/tests/auto/other/networkselftest/BLACKLIST
@@ -1,6 +1,5 @@
# QTBUG-27571
[ftpProxyServer]
-windows-10 msvc-2017
-windows-10 msvc-2015
windows-7sp1
+windows-10
diff --git a/tests/auto/other/qfocusevent/BLACKLIST b/tests/auto/other/qfocusevent/BLACKLIST
deleted file mode 100644
index 5af8be91a0..0000000000
--- a/tests/auto/other/qfocusevent/BLACKLIST
+++ /dev/null
@@ -1,3 +0,0 @@
-[checkReason_ActiveWindow]
-winrt
-
diff --git a/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST b/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST
index 65a939cdcb..6173488c00 100644
--- a/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST
+++ b/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST
@@ -1,5 +1,4 @@
[downloadCheck]
-windows-10 msvc-2015
-windows-10 msvc-2017
+windows-10
[downloadCheck:with-zeroCopy]
windows
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST b/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST
index f2f0f8d26e..aae2cacc3b 100644
--- a/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST
@@ -7,13 +7,10 @@ b2qt
[specialFiles]
b2qt
[dirsBeforeFiles]
-ubuntu-16.04
-rhel-7.6
-windows-10 msvc-2017
-ubuntu-18.04
-b2qt
winrt
-windows-10 msvc-2015
-
+b2qt
+ubuntu
+windows-10
+rhel
[drives]
winrt
diff --git a/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST b/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST
index e633e7c0a3..8d8a7c2105 100644
--- a/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST
+++ b/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST
@@ -1,6 +1,4 @@
[defaultButton]
-ubuntu-16.04
-rhel-7.6
opensuse-leap
-ubuntu-18.04
-rhel-7.4
+rhel-7.6
+ubuntu
diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
index da75e64d1e..243cb6483e 100644
--- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
+++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
@@ -417,7 +417,7 @@ void tst_QWizard::setPixmap()
QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull());
QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull());
QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull());
- if (QSysInfo::macVersion() <= Q_MV_OSX(10, 13))
+ if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::MacOSHighSierra)
QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
else
QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull());
@@ -425,7 +425,7 @@ void tst_QWizard::setPixmap()
QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull());
QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull());
QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull());
- if (QSysInfo::macVersion() <= Q_MV_OSX(10, 13))
+ if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::MacOSHighSierra)
QVERIFY(!wizard.pixmap(QWizard::BackgroundPixmap).isNull());
else
QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
index 7b914512ab..72ea2ae31a 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -272,6 +272,9 @@ class tst_QGraphicsItem : public QObject
{
Q_OBJECT
+public:
+ static void initMain();
+
private slots:
void construction();
void constructionWithParent();
@@ -474,6 +477,14 @@ private:
QTouchDevice *m_touchDevice = nullptr;
};
+void tst_QGraphicsItem::initMain()
+{
+#ifdef Q_OS_WIN
+ // Ensure minimum size constraints of framed windows on High DPI screens
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+#endif
+}
+
void tst_QGraphicsItem::construction()
{
for (int i = 0; i < 7; ++i) {
diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST
index a3c9e2e421..c3797c9d57 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST
+++ b/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST
@@ -1,7 +1,5 @@
[isActive]
opensuse-42.3 ci
-[removeFullyTransparentItem]
-osx-10.12
[tabFocus_sceneWithNestedFocusWidgets]
opensuse-42.3
diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
index 46f1d5df5c..950f3ef670 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -26,11 +26,24 @@
**
****************************************************************************/
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QDial>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QGraphicsView>
+#include <QtWidgets/QGraphicsScene>
+#include <QtWidgets/QGraphicsPixmapItem>
+#include <QtWidgets/QStyle>
+#include <QtWidgets/QStyleFactory>
+#include <QtWidgets/QVBoxLayout>
+
+#include <QtGui/QScreen>
#include <QtTest/QtTest>
-#include <QtGui>
-#include <QtWidgets>
+#include <QtCore/QDebug>
+#include <QtCore/QLoggingCategory>
+
#include <private/qgraphicsscene_p.h>
#include <private/qgraphicssceneindex_p.h>
#include <math.h>
@@ -39,7 +52,7 @@
#include <private/qinputmethod_p.h>
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-#include <windows.h>
+#include <QtCore/qt_windows.h>
#define Q_CHECK_PAINTEVENTS \
if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \
QSKIP("The Graphics View doesn't get the paint events");
@@ -51,6 +64,7 @@ Q_DECLARE_METATYPE(Qt::FocusReason)
Q_DECLARE_METATYPE(QPainterPath)
Q_DECLARE_METATYPE(Qt::AspectRatioMode)
Q_DECLARE_METATYPE(Qt::ItemSelectionMode)
+Q_DECLARE_METATYPE(QGraphicsItem::GraphicsItemFlags)
static const int randomX[] = {276, 40, 250, 864, -56, 426, 855, 825, 184, 955, -798, -804, 773,
282, 489, 686, 780, -220, 50, 749, -856, -205, 81, 492, -819, 518,
@@ -95,14 +109,16 @@ static const int randomY[] = {603, 70, -318, 843, 450, -637, 199, -527, 407, 964
-588, 864, 234, 225, -303, 493, 246, 153, 338, -378, 377, -819, 140, 136,
467, -849, -326, -533, 166, 252, -994, -699, 904, -566, 621, -752};
+Q_LOGGING_CATEGORY(lcTests, "qt.widgets.tests")
+
class HoverItem : public QGraphicsRectItem
{
public:
HoverItem()
- : QGraphicsRectItem(QRectF(-10, -10, 20, 20)), isHovered(false)
+ : QGraphicsRectItem(QRectF(-10, -10, 20, 20))
{ setAcceptHoverEvents(true); }
- bool isHovered;
+ bool isHovered = false;
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
@@ -128,13 +144,13 @@ class EventSpy : public QGraphicsWidget
Q_OBJECT
public:
EventSpy(QObject *watched, QEvent::Type type)
- : _count(0), spied(type)
+ : spied(type)
{
watched->installEventFilter(this);
}
EventSpy(QGraphicsScene *scene, QGraphicsItem *watched, QEvent::Type type)
- : _count(0), spied(type)
+ : spied(type)
{
scene->addItem(this);
watched->installSceneEventFilter(this);
@@ -143,7 +159,7 @@ public:
int count() const { return _count; }
protected:
- bool eventFilter(QObject *watched, QEvent *event)
+ bool eventFilter(QObject *watched, QEvent *event) override
{
Q_UNUSED(watched);
if (event->type() == spied)
@@ -151,7 +167,7 @@ protected:
return false;
}
- bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
+ bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override
{
Q_UNUSED(watched);
if (event->type() == spied)
@@ -159,13 +175,17 @@ protected:
return false;
}
- int _count;
- QEvent::Type spied;
+ int _count = 0;
+ const QEvent::Type spied;
};
class tst_QGraphicsScene : public QObject
{
Q_OBJECT
+public:
+ tst_QGraphicsScene();
+ static void initMain() { QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); }
+
public slots:
void cleanup();
@@ -268,13 +288,26 @@ private slots:
void taskQTBUG_15977_renderWithDeviceCoordinateCache();
void taskQTBUG_16401_focusItem();
void taskQTBUG_42915_focusNextPrevChild();
+
+private:
+ QRect m_availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
+ QSize m_testSize;
};
+tst_QGraphicsScene::tst_QGraphicsScene()
+{
+ const int testSize = qMax(200, m_availableGeometry.width() / 10);
+ m_testSize.setWidth(testSize);
+ m_testSize.setHeight(testSize);
+}
+
void tst_QGraphicsScene::cleanup()
{
// ensure not even skipped tests with custom input context leave it dangling
- QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
- inputMethodPrivate->testContext = 0;
+ QInputMethodPrivate *inputMethodPrivate =
+ QInputMethodPrivate::get(QGuiApplication::inputMethod());
+ inputMethodPrivate->testContext = nullptr;
+ QTRY_VERIFY(QApplication::topLevelWidgets().isEmpty());
}
void tst_QGraphicsScene::construction()
@@ -287,7 +320,7 @@ void tst_QGraphicsScene::construction()
QVERIFY(scene.items(QPolygonF()).isEmpty());
QVERIFY(scene.items(QPainterPath()).isEmpty());
QTest::ignoreMessage(QtWarningMsg, "QGraphicsScene::collidingItems: cannot find collisions for null item");
- QVERIFY(scene.collidingItems(0).isEmpty());
+ QVERIFY(scene.collidingItems(nullptr).isEmpty());
QVERIFY(scene.items(QPointF()).isEmpty());
QVERIFY(scene.selectedItems().isEmpty());
QVERIFY(!scene.focusItem());
@@ -301,7 +334,7 @@ static inline const QGraphicsItem *itemAt(const QGraphicsScene &scene, qreal x,
void tst_QGraphicsScene::sceneRect()
{
QGraphicsScene scene;
- QSignalSpy sceneRectChanged(&scene, SIGNAL(sceneRectChanged(QRectF)));
+ QSignalSpy sceneRectChanged(&scene, &QGraphicsScene::sceneRectChanged);
QCOMPARE(scene.sceneRect(), QRectF());
QCOMPARE(sceneRectChanged.count(), 0);
@@ -435,9 +468,9 @@ void tst_QGraphicsScene::items()
scene.removeItem(items.at(5));
delete items.at(5);
- QVERIFY(!scene.items().contains(0));
+ QVERIFY(!scene.items().contains(nullptr));
delete items.at(7);
- QVERIFY(!scene.items().contains(0));
+ QVERIFY(!scene.items().contains(nullptr));
}
{
QGraphicsScene scene;
@@ -516,7 +549,7 @@ void tst_QGraphicsScene::itemsBoundingRect()
QGraphicsScene scene;
- foreach (QRectF rect, rects) {
+ for (const auto &rect : qAsConst(rects)) {
QPainterPath path;
path.addRect(rect);
QGraphicsPathItem *item = scene.addPath(path);
@@ -581,7 +614,7 @@ void tst_QGraphicsScene::items_QPointF()
int n = 0;
QList<QGraphicsItem *> addedItems;
- foreach(QRectF rect, items) {
+ for (const auto &rect : qAsConst(items)) {
QPainterPath path;
path.addRect(0, 0, rect.width(), rect.height());
@@ -593,7 +626,8 @@ void tst_QGraphicsScene::items_QPointF()
}
QList<int> itemIndexes;
- foreach (QGraphicsItem *item, scene.items(point))
+ const auto &actualItemsAtPoint = scene.items(point);
+ for (QGraphicsItem *item : actualItemsAtPoint)
itemIndexes << addedItems.indexOf(item);
QCOMPARE(itemIndexes, itemsAtPoint);
@@ -912,12 +946,11 @@ void tst_QGraphicsScene::items_QPainterPath_2()
class CustomView : public QGraphicsView
{
public:
- CustomView() : repaints(0)
- { }
+ using QGraphicsView::QGraphicsView;
- int repaints;
+ int repaints = 0;
protected:
- void paintEvent(QPaintEvent *event)
+ void paintEvent(QPaintEvent *event) override
{
++repaints;
QGraphicsView::paintEvent(event);
@@ -927,7 +960,7 @@ protected:
void tst_QGraphicsScene::selectionChanged()
{
QGraphicsScene scene(0, 0, 1000, 1000);
- QSignalSpy spy(&scene, SIGNAL(selectionChanged()));
+ QSignalSpy spy(&scene, &QGraphicsScene::selectionChanged);
QCOMPARE(spy.count(), 0);
QPainterPath path;
@@ -997,7 +1030,7 @@ void tst_QGraphicsScene::selectionChanged()
void tst_QGraphicsScene::selectionChanged2()
{
QGraphicsScene scene;
- QSignalSpy spy(&scene, SIGNAL(selectionChanged()));
+ QSignalSpy spy(&scene, &QGraphicsScene::selectionChanged);
QGraphicsItem *item1 = scene.addRect(0, 0, 100, 100);
QGraphicsItem *item2 = scene.addRect(100, 100, 100, 100);
@@ -1009,13 +1042,13 @@ void tst_QGraphicsScene::selectionChanged2()
QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
event.setScenePos(QPointF(50, 50));
event.setButton(Qt::LeftButton);
- qApp->sendEvent(&scene, &event);
+ QCoreApplication::sendEvent(&scene, &event);
}
{
QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
event.setScenePos(QPointF(50, 50));
event.setButton(Qt::LeftButton);
- qApp->sendEvent(&scene, &event);
+ QCoreApplication::sendEvent(&scene, &event);
}
QVERIFY(item1->isSelected());
QVERIFY(!item2->isSelected());
@@ -1024,13 +1057,13 @@ void tst_QGraphicsScene::selectionChanged2()
QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
event.setScenePos(QPointF(150, 150));
event.setButton(Qt::LeftButton);
- qApp->sendEvent(&scene, &event);
+ QCoreApplication::sendEvent(&scene, &event);
}
{
QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
event.setScenePos(QPointF(150, 150));
event.setButton(Qt::LeftButton);
- qApp->sendEvent(&scene, &event);
+ QCoreApplication::sendEvent(&scene, &event);
}
QVERIFY(!item1->isSelected());
QVERIFY(item2->isSelected());
@@ -1040,7 +1073,7 @@ void tst_QGraphicsScene::selectionChanged2()
event.setScenePos(QPointF(50, 50));
event.setButton(Qt::LeftButton);
event.setModifiers(Qt::ControlModifier);
- qApp->sendEvent(&scene, &event);
+ QCoreApplication::sendEvent(&scene, &event);
}
QVERIFY(!item1->isSelected());
QVERIFY(item2->isSelected());
@@ -1049,7 +1082,7 @@ void tst_QGraphicsScene::selectionChanged2()
QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
event.setScenePos(QPointF(50, 50));
event.setButton(Qt::LeftButton);
- qApp->sendEvent(&scene, &event);
+ QCoreApplication::sendEvent(&scene, &event);
}
QVERIFY(item1->isSelected());
QVERIFY(!item2->isSelected());
@@ -1065,10 +1098,12 @@ void tst_QGraphicsScene::addItem()
QGraphicsScene scene;
CustomView view;
+ view.setWindowTitle(QTest::currentTestFunction());
view.setScene(&scene);
+ view.resize(m_testSize);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- qApp->processEvents();
+ QCoreApplication::processEvents();
view.repaints = 0;
scene.addItem(path);
@@ -1115,14 +1150,14 @@ void tst_QGraphicsScene::addEllipse()
QCOMPARE(ellipse->pen(), QPen(Qt::red));
QCOMPARE(ellipse->brush(), QBrush(Qt::blue));
QCOMPARE(ellipse->rect(), QRectF(-10, -10, 20, 20));
- QCOMPARE(itemAt(scene, 0, 0), (QGraphicsItem *)ellipse);
+ QCOMPARE(itemAt(scene, 0, 0), ellipse);
QVERIFY(scene.items(QPointF(-10, -10)).isEmpty());
- QCOMPARE(itemAt(scene, -9.9, 0), (QGraphicsItem *)ellipse);
+ QCOMPARE(itemAt(scene, -9.9, 0), ellipse);
QVERIFY(scene.items(QPointF(-10, 10)).isEmpty());
- QCOMPARE(itemAt(scene, 0, -9.9), (QGraphicsItem *)ellipse);
- QCOMPARE(itemAt(scene, 0, 9.9), (QGraphicsItem *)ellipse);
+ QCOMPARE(itemAt(scene, 0, -9.9), ellipse);
+ QCOMPARE(itemAt(scene, 0, 9.9), ellipse);
QVERIFY(scene.items(QPointF(10, -10)).isEmpty());
- QCOMPARE(itemAt(scene, 9.9, 0), (QGraphicsItem *)ellipse);
+ QCOMPARE(itemAt(scene, 9.9, 0), ellipse);
QVERIFY(scene.items(QPointF(10, 10)).isEmpty());
}
@@ -1136,15 +1171,15 @@ void tst_QGraphicsScene::addLine()
QCOMPARE(line->pos(), QPointF());
QCOMPARE(line->pen(), pen);
QCOMPARE(line->line(), QLineF(-10, -10, 20, 20));
- QCOMPARE(itemAt(scene, 0, 0), (QGraphicsItem *)line);
- QCOMPARE(itemAt(scene, -10, -10), (QGraphicsItem *)line);
+ QCOMPARE(itemAt(scene, 0, 0), line);
+ QCOMPARE(itemAt(scene, -10, -10), line);
QVERIFY(scene.items(QPointF(-9.9, 0)).isEmpty());
QVERIFY(scene.items(QPointF(-10, 10)).isEmpty());
QVERIFY(scene.items(QPointF(0, -9.9)).isEmpty());
QVERIFY(scene.items(QPointF(0, 9.9)).isEmpty());
QVERIFY(scene.items(QPointF(10, -10)).isEmpty());
QVERIFY(scene.items(QPointF(9.9, 0)).isEmpty());
- QCOMPARE(itemAt(scene, 10, 10), (QGraphicsItem *)line);
+ QCOMPARE(itemAt(scene, 10, 10), line);
}
void tst_QGraphicsScene::addPath()
@@ -1162,16 +1197,16 @@ void tst_QGraphicsScene::addPath()
path->setPen(QPen(Qt::red, 0));
- QCOMPARE(itemAt(scene, 0, 0), (QGraphicsItem *)path);
- QCOMPARE(itemAt(scene, -9.9, 0), (QGraphicsItem *)path);
- QCOMPARE(itemAt(scene, 9.9, 0), (QGraphicsItem *)path);
- QCOMPARE(itemAt(scene, 0, -9.9), (QGraphicsItem *)path);
- QCOMPARE(itemAt(scene, 0, 9.9), (QGraphicsItem *)path);
- QCOMPARE(itemAt(scene, 0, 30), (QGraphicsItem *)path);
- QCOMPARE(itemAt(scene, -9.9, 30), (QGraphicsItem *)path);
- QCOMPARE(itemAt(scene, 9.9, 30), (QGraphicsItem *)path);
- QCOMPARE(itemAt(scene, 0, 20.1), (QGraphicsItem *)path);
- QCOMPARE(itemAt(scene, 0, 39.9), (QGraphicsItem *)path);
+ QCOMPARE(itemAt(scene, 0, 0), path);
+ QCOMPARE(itemAt(scene, -9.9, 0), path);
+ QCOMPARE(itemAt(scene, 9.9, 0), path);
+ QCOMPARE(itemAt(scene, 0, -9.9), path);
+ QCOMPARE(itemAt(scene, 0, 9.9), path);
+ QCOMPARE(itemAt(scene, 0, 30), path);
+ QCOMPARE(itemAt(scene, -9.9, 30), path);
+ QCOMPARE(itemAt(scene, 9.9, 30), path);
+ QCOMPARE(itemAt(scene, 0, 20.1), path);
+ QCOMPARE(itemAt(scene, 0, 39.9), path);
QVERIFY(scene.items(QPointF(-10, -10)).isEmpty());
QVERIFY(scene.items(QPointF(10, -10)).isEmpty());
QVERIFY(scene.items(QPointF(-10, 10)).isEmpty());
@@ -1193,10 +1228,10 @@ void tst_QGraphicsScene::addPixmap()
QCOMPARE(pixmap->pos(), QPointF());
QCOMPARE(pixmap->pixmap(), pix);
- QCOMPARE(itemAt(scene, 0, 0), (QGraphicsItem *)pixmap);
- QCOMPARE(itemAt(scene, pix.width() - 1, 0), (QGraphicsItem *)pixmap);
- QCOMPARE(itemAt(scene, 0, pix.height() - 1), (QGraphicsItem *)pixmap);
- QCOMPARE(itemAt(scene, pix.width() - 1, pix.height() - 1), (QGraphicsItem *)pixmap);
+ QCOMPARE(itemAt(scene, 0, 0), pixmap);
+ QCOMPARE(itemAt(scene, pix.width() - 1, 0), pixmap);
+ QCOMPARE(itemAt(scene, 0, pix.height() - 1), pixmap);
+ QCOMPARE(itemAt(scene, pix.width() - 1, pix.height() - 1), pixmap);
QVERIFY(scene.items(QPointF(-1, -1)).isEmpty());
QVERIFY(scene.items(QPointF(pix.width() - 1, -1)).isEmpty());
@@ -1218,14 +1253,14 @@ void tst_QGraphicsScene::addRect()
rect->setPen(QPen(Qt::red, 0));
- QCOMPARE(itemAt(scene, 0, 0), (QGraphicsItem *)rect);
- QCOMPARE(itemAt(scene, -10, -10), (QGraphicsItem *)rect);
- QCOMPARE(itemAt(scene, -9.9, 0), (QGraphicsItem *)rect);
+ QCOMPARE(itemAt(scene, 0, 0),rect);
+ QCOMPARE(itemAt(scene, -10, -10), rect);
+ QCOMPARE(itemAt(scene, -9.9, 0), rect);
QVERIFY(scene.items(QPointF(-10, 10)).isEmpty());
- QCOMPARE(itemAt(scene, 0, -9.9), (QGraphicsItem *)rect);
- QCOMPARE(itemAt(scene, 0, 9.9), (QGraphicsItem *)rect);
+ QCOMPARE(itemAt(scene, 0, -9.9), rect);
+ QCOMPARE(itemAt(scene, 0, 9.9), rect);
QVERIFY(scene.items(QPointF(10, -10)).isEmpty());
- QCOMPARE(itemAt(scene, 9.9, 0), (QGraphicsItem *)rect);
+ QCOMPARE(itemAt(scene, 9.9, 0), rect);
QVERIFY(scene.items(QPointF(10, 10)).isEmpty());
}
@@ -1271,6 +1306,7 @@ void tst_QGraphicsScene::removeItem()
scene.setSceneRect(-50, -50, 100, 100);
QGraphicsView view(&scene);
+ view.setWindowTitle(QTest::currentTestFunction());
view.setFixedSize(150, 150);
view.show();
QApplication::setActiveWindow(&view);
@@ -1342,7 +1378,7 @@ void tst_QGraphicsScene::focusItem()
class FocusItem : public QGraphicsTextItem
{
protected:
- void focusOutEvent(QFocusEvent *)
+ void focusOutEvent(QFocusEvent *) override
{
QVERIFY(!scene()->focusItem());
}
@@ -1359,14 +1395,14 @@ void tst_QGraphicsScene::focusItemLostFocus()
scene.addItem(item);
item->setFocus();
- QCOMPARE(scene.focusItem(), (QGraphicsItem *)item);
+ QCOMPARE(scene.focusItem(), item);
item->clearFocus();
}
class ClearTestItem : public QGraphicsRectItem
{
public:
- ClearTestItem(QGraphicsItem *parent = 0) : QGraphicsRectItem(parent) {}
+ using QGraphicsRectItem::QGraphicsRectItem;
~ClearTestItem() { qDeleteAll(items); }
QList<QGraphicsItem *> items;
};
@@ -1389,7 +1425,7 @@ void tst_QGraphicsScene::clear()
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
scene.addItem(firstItem);
scene.addItem(secondItem);
- QCOMPARE(scene.items().at(0), (QGraphicsItem*)firstItem);
+ QCOMPARE(scene.items().at(0), firstItem);
QCOMPARE(scene.items().at(1), secondItem);
ClearTestItem *thirdItem = new ClearTestItem(firstItem);
@@ -1441,7 +1477,7 @@ void tst_QGraphicsScene::setFocusItem()
QVERIFY(item->hasFocus());
QVERIFY(!item2->hasFocus());
- scene.setFocusItem(0);
+ scene.setFocusItem(nullptr);
QVERIFY(!item->hasFocus());
QVERIFY(!item2->hasFocus());
@@ -1562,26 +1598,26 @@ void tst_QGraphicsScene::hoverEvents_siblings()
Q_CHECK_PAINTEVENTS
QGraphicsScene scene;
- QGraphicsItem *lastItem = 0;
+ QGraphicsItem *lastItem = nullptr;
QList<HoverItem *> items;
for (int i = 0; i < 15; ++i) {
- QGraphicsItem *item = new HoverItem;
+ auto item = new HoverItem;
scene.addItem(item);
- items << (HoverItem *)item;
- if (lastItem) {
+ items << item;
+ if (lastItem)
item->setPos(lastItem->pos() + QPointF(sin(i / 3.0) * 17, cos(i / 3.0) * 17));
- }
item->setZValue(i);
lastItem = item;
}
QGraphicsView view(&scene);
+ view.setWindowTitle(QTest::currentTestFunction());
view.setRenderHint(QPainter::Antialiasing, true);
view.setMinimumSize(400, 300);
view.rotate(10);
view.scale(1.7, 1.7);
view.show();
- qApp->setActiveWindow(&view);
+ QApplication::setActiveWindow(&view);
view.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&view));
@@ -1604,8 +1640,8 @@ void tst_QGraphicsScene::hoverEvents_siblings()
mouseEvent.setScenePos(items.at(i)->mapToScene(0, 0));
QApplication::sendEvent(&scene, &mouseEvent);
- qApp->processEvents(); // this posts updates from the scene to the view
- qApp->processEvents(); // which trigger a repaint here
+ QCoreApplication::processEvents(); // this posts updates from the scene to the view
+ QCoreApplication::processEvents(); // which trigger a repaint here
QTRY_VERIFY(items.at(i)->isHovered);
if (j && i > 0)
@@ -1621,8 +1657,8 @@ void tst_QGraphicsScene::hoverEvents_siblings()
mouseEvent.setScenePos(QPointF(-1000, -1000));
QApplication::sendEvent(&scene, &mouseEvent);
- qApp->processEvents(); // this posts updates from the scene to the view
- qApp->processEvents(); // which trigger a repaint here
+ QCoreApplication::processEvents(); // this posts updates from the scene to the view
+ QCoreApplication::processEvents(); // which trigger a repaint here
}
}
@@ -1631,12 +1667,12 @@ void tst_QGraphicsScene::hoverEvents_parentChild()
Q_CHECK_PAINTEVENTS
QGraphicsScene scene;
- QGraphicsItem *lastItem = 0;
+ QGraphicsItem *lastItem = nullptr;
QList<HoverItem *> items;
for (int i = 0; i < 15; ++i) {
- QGraphicsItem *item = new HoverItem;
+ auto item = new HoverItem;
scene.addItem(item);
- items << (HoverItem *)item;
+ items << item;
if (lastItem) {
item->setParentItem(lastItem);
item->setPos(sin(i / 3.0) * 17, cos(i / 3.0) * 17);
@@ -1645,12 +1681,13 @@ void tst_QGraphicsScene::hoverEvents_parentChild()
}
QGraphicsView view(&scene);
+ view.setWindowTitle(QTest::currentTestFunction());
view.setRenderHint(QPainter::Antialiasing, true);
view.setMinimumSize(400, 300);
view.rotate(10);
view.scale(1.7, 1.7);
view.show();
- qApp->setActiveWindow(&view);
+ QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
@@ -1669,8 +1706,8 @@ void tst_QGraphicsScene::hoverEvents_parentChild()
mouseEvent.setScenePos(items.at(i)->mapToScene(0, 0));
QApplication::sendEvent(&scene, &mouseEvent);
- qApp->processEvents(); // this posts updates from the scene to the view
- qApp->processEvents(); // which trigger a repaint here
+ QCoreApplication::processEvents(); // this posts updates from the scene to the view
+ QCoreApplication::processEvents(); // which trigger a repaint here
QTRY_VERIFY(items.at(i)->isHovered);
if (i < 14)
@@ -1683,8 +1720,8 @@ void tst_QGraphicsScene::hoverEvents_parentChild()
mouseEvent.setScenePos(QPointF(-1000, -1000));
QApplication::sendEvent(&scene, &mouseEvent);
- qApp->processEvents(); // this posts updates from the scene to the view
- qApp->processEvents(); // which trigger a repaint here
+ QCoreApplication::processEvents(); // this posts updates from the scene to the view
+ QCoreApplication::processEvents(); // which trigger a repaint here
}
}
@@ -1712,23 +1749,23 @@ void tst_QGraphicsScene::createItemGroup()
// All items in children1 are children of parent1
QGraphicsItem *parent1 = scene.addRect(QRectF(-10, -10, 20, 20));
- foreach (QGraphicsItem *item, children1)
+ for (QGraphicsItem *item : qAsConst(children1))
item->setParentItem(parent1);
QGraphicsItemGroup *group = scene.createItemGroup(children1);
QCOMPARE(group->parentItem(), parent1);
- QCOMPARE(children1.first()->parentItem(), (QGraphicsItem *)group);
+ QCOMPARE(children1.first()->parentItem(), group);
scene.destroyItemGroup(group);
QCOMPARE(children1.first()->parentItem(), parent1);
group = scene.createItemGroup(children1);
QCOMPARE(group->parentItem(), parent1);
- QCOMPARE(children1.first()->parentItem(), (QGraphicsItem *)group);
+ QCOMPARE(children1.first()->parentItem(), group);
scene.destroyItemGroup(group);
QCOMPARE(children1.first()->parentItem(), parent1);
// All items in children2 are children of parent2
QGraphicsItem *parent2 = scene.addRect(QRectF(-10, -10, 20, 20));
- foreach (QGraphicsItem *item, children2)
+ for (QGraphicsItem *item : qAsConst(children2))
item->setParentItem(parent2);
// Now make parent2 a child of parent1, so all children2 are also children
@@ -1738,21 +1775,21 @@ void tst_QGraphicsScene::createItemGroup()
// The children2 group should still have parent2 as their common ancestor.
group = scene.createItemGroup(children2);
QCOMPARE(group->parentItem(), parent2);
- QCOMPARE(children2.first()->parentItem(), (QGraphicsItem *)group);
+ QCOMPARE(children2.first()->parentItem(), group);
scene.destroyItemGroup(group);
QCOMPARE(children2.first()->parentItem(), parent2);
// But the set of both children2 and children1 share only parent1.
group = scene.createItemGroup(children2 + children1);
QCOMPARE(group->parentItem(), parent1);
- QCOMPARE(children1.first()->parentItem(), (QGraphicsItem *)group);
- QCOMPARE(children2.first()->parentItem(), (QGraphicsItem *)group);
+ QCOMPARE(children1.first()->parentItem(), group);
+ QCOMPARE(children2.first()->parentItem(), group);
scene.destroyItemGroup(group);
QCOMPARE(children1.first()->parentItem(), parent1);
QCOMPARE(children2.first()->parentItem(), parent1);
// Fixup the parent-child chain
- foreach (QGraphicsItem *item, children2)
+ for (QGraphicsItem *item : qAsConst(children2))
item->setParentItem(parent2);
// These share no common parent
@@ -1762,7 +1799,7 @@ void tst_QGraphicsScene::createItemGroup()
// Make children3 children of parent3
QGraphicsItem *parent3 = scene.addRect(QRectF(-10, -10, 20, 20));
- foreach (QGraphicsItem *item, children3)
+ for (QGraphicsItem *item : qAsConst(children3))
item->setParentItem(parent3);
// These should have parent3 as a parent
@@ -1794,15 +1831,14 @@ void tst_QGraphicsScene::createItemGroup()
class EventTester : public QGraphicsEllipseItem
{
public:
- EventTester()
- : QGraphicsEllipseItem(QRectF(-10, -10, 20, 20)), ignoreMouse(false)
+ EventTester() : QGraphicsEllipseItem(QRectF(-10, -10, 20, 20))
{ }
- bool ignoreMouse;
- QList<QEvent::Type> eventTypes;
+ bool ignoreMouse = false;
+ QVector<QEvent::Type> eventTypes;
protected:
- bool sceneEvent(QEvent *event)
+ bool sceneEvent(QEvent *event) override
{
eventTypes << QEvent::Type(event->type());
switch (event->type()) {
@@ -1813,6 +1849,7 @@ protected:
event->ignore();
return true;
}
+ break;
default:
break;
}
@@ -1867,7 +1904,7 @@ void tst_QGraphicsScene::mouseEventPropagation()
QCOMPARE(c->eventTypes.size(), 0);
QCOMPARE(b->eventTypes.size(), 0);
QCOMPARE(a->eventTypes.size(), 0);
- QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)d);
+ QCOMPARE(scene.mouseGrabberItem(), d);
// Send a move
QApplication::sendEvent(&scene, &moveEvent);
@@ -1876,7 +1913,7 @@ void tst_QGraphicsScene::mouseEventPropagation()
QCOMPARE(c->eventTypes.size(), 0);
QCOMPARE(b->eventTypes.size(), 0);
QCOMPARE(a->eventTypes.size(), 0);
- QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)d);
+ QCOMPARE(scene.mouseGrabberItem(), d);
// Send a release
QApplication::sendEvent(&scene, &releaseEvent);
@@ -1898,7 +1935,7 @@ void tst_QGraphicsScene::mouseEventPropagation()
QCOMPARE(c->eventTypes.at(1), QEvent::GraphicsSceneMousePress);
QCOMPARE(b->eventTypes.size(), 0);
QCOMPARE(a->eventTypes.size(), 0);
- QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)c);
+ QCOMPARE(scene.mouseGrabberItem(), c);
// Send another press, with a button that isn't actually accepted
QApplication::sendEvent(&scene, &pressEvent);
@@ -1908,7 +1945,7 @@ void tst_QGraphicsScene::mouseEventPropagation()
QCOMPARE(c->eventTypes.at(2), QEvent::GraphicsSceneMousePress);
QCOMPARE(b->eventTypes.size(), 0);
QCOMPARE(a->eventTypes.size(), 0);
- QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)c);
+ QCOMPARE(scene.mouseGrabberItem(), c);
// Send a move
QApplication::sendEvent(&scene, &moveEvent);
@@ -1917,7 +1954,7 @@ void tst_QGraphicsScene::mouseEventPropagation()
QCOMPARE(c->eventTypes.at(3), QEvent::GraphicsSceneMouseMove);
QCOMPARE(b->eventTypes.size(), 0);
QCOMPARE(a->eventTypes.size(), 0);
- QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)c);
+ QCOMPARE(scene.mouseGrabberItem(), c);
// Send a release
QApplication::sendEvent(&scene, &releaseEvent);
@@ -1950,7 +1987,7 @@ void tst_QGraphicsScene::mouseEventPropagation()
QCOMPARE(c->eventTypes.at(7), QEvent::GraphicsSceneMousePress);
QCOMPARE(b->eventTypes.size(), 0);
QCOMPARE(a->eventTypes.size(), 0);
- QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)c);
+ QCOMPARE(scene.mouseGrabberItem(), c);
// Clicking outside the items removes the mouse grabber
}
@@ -1999,7 +2036,7 @@ void tst_QGraphicsScene::mouseEventPropagation_ignore()
QCOMPARE(d->eventTypes.at(0), QEvent::GrabMouse);
QCOMPARE(d->eventTypes.at(1), QEvent::GraphicsSceneMousePress);
QCOMPARE(d->eventTypes.at(2), QEvent::UngrabMouse);
- QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)a);
+ QCOMPARE(scene.mouseGrabberItem(), a);
a->ignoreMouse = true;
@@ -2115,7 +2152,7 @@ public:
QVector<QPointF> mouseMovePoints;
protected:
- void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
{
mouseMovePoints << event->scenePos();
}
@@ -2140,22 +2177,17 @@ void tst_QGraphicsScene::mouseEventPropagation_mouseMove()
class DndTester : public QGraphicsEllipseItem
{
public:
- DndTester(const QRectF &rect)
- : QGraphicsEllipseItem(rect), lastEvent(0),
- ignoresDragEnter(false), ignoresDragMove(false)
-
- {
- }
+ using QGraphicsEllipseItem::QGraphicsEllipseItem;
~DndTester()
{
delete lastEvent;
}
- QGraphicsSceneDragDropEvent *lastEvent;
+ QGraphicsSceneDragDropEvent *lastEvent = nullptr;
QList<QEvent::Type> eventList;
- bool ignoresDragEnter;
- bool ignoresDragMove;
+ bool ignoresDragEnter = false;
+ bool ignoresDragMove = false;
protected:
void dragEnterEvent(QGraphicsSceneDragDropEvent *event)
@@ -2218,21 +2250,21 @@ void tst_QGraphicsScene::dragAndDrop_simple()
QMimeData mimeData;
// Initial drag enter for the scene
- QDragEnterEvent dragEnter(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragEnterEvent dragEnter(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragEnter);
QVERIFY(dragEnter.isAccepted());
QCOMPARE(dragEnter.dropAction(), Qt::CopyAction);
{
// Move outside the item
- QDragMoveEvent dragMove(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(!dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::CopyAction);
}
{
// Move inside the item without setAcceptDrops
- QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(!dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::CopyAction);
@@ -2241,7 +2273,7 @@ void tst_QGraphicsScene::dragAndDrop_simple()
item->setAcceptDrops(true);
{
// Move inside the item with setAcceptDrops
- QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::IgnoreAction);
@@ -2255,7 +2287,7 @@ void tst_QGraphicsScene::dragAndDrop_simple()
}
{
// Another move inside the item
- QDragMoveEvent dragMove(view.mapFromScene(item->mapToScene(5, 5)), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(item->mapToScene(5, 5)), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::IgnoreAction);
@@ -2268,7 +2300,7 @@ void tst_QGraphicsScene::dragAndDrop_simple()
}
{
// Move outside the item
- QDragMoveEvent dragMove(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(!dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::CopyAction);
@@ -2281,7 +2313,7 @@ void tst_QGraphicsScene::dragAndDrop_simple()
}
{
// Move inside the item again
- QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::IgnoreAction);
@@ -2295,7 +2327,7 @@ void tst_QGraphicsScene::dragAndDrop_simple()
}
{
// Drop inside the item
- QDropEvent drop(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDropEvent drop(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &drop);
QVERIFY(drop.isAccepted());
QCOMPARE(drop.dropAction(), Qt::CopyAction);
@@ -2322,13 +2354,13 @@ void tst_QGraphicsScene::dragAndDrop_disabledOrInvisible()
QMimeData mimeData;
// Initial drag enter for the scene
- QDragEnterEvent dragEnter(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragEnterEvent dragEnter(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragEnter);
QVERIFY(dragEnter.isAccepted());
QCOMPARE(dragEnter.dropAction(), Qt::CopyAction);
{
// Move inside the item
- QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::IgnoreAction);
@@ -2338,7 +2370,7 @@ void tst_QGraphicsScene::dragAndDrop_disabledOrInvisible()
}
{
// Move outside the item
- QDragMoveEvent dragMove(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(!dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::CopyAction);
@@ -2353,7 +2385,7 @@ void tst_QGraphicsScene::dragAndDrop_disabledOrInvisible()
{
// Move inside the item
- QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(!dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::CopyAction);
@@ -2369,7 +2401,7 @@ void tst_QGraphicsScene::dragAndDrop_disabledOrInvisible()
{
// Move inside the item
- QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(item->scenePos()), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(!dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::CopyAction);
@@ -2378,7 +2410,7 @@ void tst_QGraphicsScene::dragAndDrop_disabledOrInvisible()
}
// Dummy drop event to keep the Mac from crashing.
- QDropEvent dropEvent(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDropEvent dropEvent(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dropEvent);
}
@@ -2405,14 +2437,14 @@ void tst_QGraphicsScene::dragAndDrop_propagate()
QMimeData mimeData;
// Initial drag enter for the scene
- QDragEnterEvent dragEnter(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragEnterEvent dragEnter(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragEnter);
QVERIFY(dragEnter.isAccepted());
QCOMPARE(dragEnter.dropAction(), Qt::CopyAction);
{
// Move outside the items
- QDragMoveEvent dragMove(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(!dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::CopyAction);
@@ -2421,7 +2453,7 @@ void tst_QGraphicsScene::dragAndDrop_propagate()
}
{
// Move inside item1
- QDragMoveEvent dragMove(view.mapFromScene(-5, -5), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(-5, -5), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::IgnoreAction);
@@ -2432,7 +2464,7 @@ void tst_QGraphicsScene::dragAndDrop_propagate()
{
// Move into the intersection item1-item2
- QDragMoveEvent dragMove(view.mapFromScene(5, 5), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(5, 5), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(!dragMove.isAccepted()); // move does not propagate, (ignoresDragMove = true)
QCOMPARE(item1->eventList.size(), 3);
@@ -2443,7 +2475,7 @@ void tst_QGraphicsScene::dragAndDrop_propagate()
}
{
// Move into the item2
- QDragMoveEvent dragMove(view.mapFromScene(15, 15), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(15, 15), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(!dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::CopyAction);
@@ -2453,7 +2485,7 @@ void tst_QGraphicsScene::dragAndDrop_propagate()
}
{
// Move inside item1
- QDragMoveEvent dragMove(view.mapFromScene(-5, -5), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(-5, -5), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(dragMove.isAccepted());
QCOMPARE(dragMove.dropAction(), Qt::IgnoreAction);
@@ -2467,7 +2499,7 @@ void tst_QGraphicsScene::dragAndDrop_propagate()
{
item2->ignoresDragEnter = true;
// Move into the intersection item1-item2
- QDragMoveEvent dragMove(view.mapFromScene(5, 5), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDragMoveEvent dragMove(view.mapFromScene(5, 5), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dragMove);
QVERIFY(dragMove.isAccepted()); // dragEnter propagates down to item1, which then accepts the move event.
QCOMPARE(dragMove.dropAction(), Qt::IgnoreAction);
@@ -2480,7 +2512,7 @@ void tst_QGraphicsScene::dragAndDrop_propagate()
{
item2->ignoresDragEnter = false;
// Drop on the intersection item1-item2
- QDropEvent drop(view.mapFromScene(5, 5), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDropEvent drop(view.mapFromScene(5, 5), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &drop);
QVERIFY(drop.isAccepted());
QCOMPARE(drop.dropAction(), Qt::CopyAction);
@@ -2491,7 +2523,7 @@ void tst_QGraphicsScene::dragAndDrop_propagate()
}
// Dummy drop event to keep the Mac from crashing.
- QDropEvent dropEvent(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, 0);
+ QDropEvent dropEvent(QPoint(0, 0), Qt::CopyAction, &mimeData, Qt::LeftButton, {});
QApplication::sendEvent(view.viewport(), &dropEvent);
}
#endif
@@ -2580,6 +2612,8 @@ void tst_QGraphicsScene::render()
pix.fill(Qt::blue);
QGraphicsView view;
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.resize(m_testSize);
QGraphicsScene scene(&view);
scene.addEllipse(QRectF(-10, -10, 20, 20), QPen(Qt::black, 0), QBrush(Qt::white));
scene.addEllipse(QRectF(-2, -7, 4, 4), QPen(Qt::black, 0), QBrush(Qt::yellow))->setZValue(1);
@@ -2642,6 +2676,7 @@ void tst_QGraphicsScene::render()
gridLayout->addWidget(newLabel, 2, 0);
QWidget widget;
+ widget.setWindowTitle(QTest::currentTestFunction());
widget.setLayout(gridLayout);
widget.show();
@@ -2660,33 +2695,32 @@ void tst_QGraphicsScene::renderItemsWithNegativeWidthOrHeight()
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) || defined(Q_OS_WINRT)
QSKIP("Test only works on platforms with resizable windows");
#endif
-
- QGraphicsScene scene(0, 0, 150, 150);
+ QGraphicsScene scene(0, 0, m_testSize.width(), m_testSize.height());
// Add item with negative width.
- QGraphicsRectItem *item1 = new QGraphicsRectItem(0, 0, -150, 50);
+ QGraphicsRectItem *item1 = new QGraphicsRectItem(0, 0, -m_testSize.width(), 50);
item1->setBrush(Qt::red);
- item1->setPos(150, 50);
+ item1->setPos(m_testSize.width(), 50);
scene.addItem(item1);
// Add item with negative height.
- QGraphicsRectItem *item2 = new QGraphicsRectItem(0, 0, 50, -150);
+ QGraphicsRectItem *item2 = new QGraphicsRectItem(0, 0, 50, -m_testSize.height());
item2->setBrush(Qt::blue);
- item2->setPos(50, 150);
+ item2->setPos(50, m_testSize.height());
scene.addItem(item2);
QGraphicsView view(&scene);
+ view.setWindowTitle(QTest::currentTestFunction());
view.setFrameStyle(QFrame::NoFrame);
- view.resize(150, 150);
view.show();
- QCOMPARE(view.viewport()->size(), QSize(150, 150));
+ QTRY_COMPARE(view.viewport()->size(), m_testSize);
QImage expected(view.viewport()->size(), QImage::Format_RGB32);
view.viewport()->render(&expected);
// Make sure the scene background is the same as the viewport background.
scene.setBackgroundBrush(view.viewport()->palette().brush(view.viewport()->backgroundRole()));
- QImage actual(150, 150, QImage::Format_RGB32);
+ QImage actual(m_testSize, QImage::Format_RGB32);
QPainter painter(&actual);
scene.render(&painter);
painter.end();
@@ -2710,6 +2744,8 @@ void tst_QGraphicsScene::contextMenuEvent()
QVERIFY(scene.hasFocus());
QGraphicsView view(&scene);
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.resize(m_testSize);
view.show();
view.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&view));
@@ -2726,11 +2762,11 @@ void tst_QGraphicsScene::contextMenuEvent()
class ContextMenuItem : public QGraphicsRectItem
{
public:
- ContextMenuItem() : QGraphicsRectItem(0, 0, 100, 100)
+ ContextMenuItem(const QSize &s) : QGraphicsRectItem(0, 0, s.width(), s.height())
{ setBrush(Qt::red); }
protected:
- void contextMenuEvent(QGraphicsSceneContextMenuEvent *)
+ void contextMenuEvent(QGraphicsSceneContextMenuEvent *) override
{ /* just accept */ }
};
@@ -2740,26 +2776,30 @@ void tst_QGraphicsScene::contextMenuEvent_ItemIgnoresTransformations()
QSKIP("Test fails on some Android devices (QTBUG-44430)");
#endif
- QGraphicsScene scene(0, 0, 200, 200);
- ContextMenuItem *item = new ContextMenuItem;
+ QGraphicsScene scene(0, 0, m_testSize.width(), m_testSize.height());
+ const QSize itemSize = m_testSize / 2;
+ ContextMenuItem *item = new ContextMenuItem(itemSize);
item->setFlag(QGraphicsItem::ItemIgnoresTransformations);
scene.addItem(item);
QWidget topLevel;
+ topLevel.setWindowTitle(QTest::currentTestFunction());
+ topLevel.resize(m_testSize);
QGraphicsView view(&scene, &topLevel);
- view.resize(200, 200);
topLevel.show();
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
+
+
{
- QPoint pos(50, 50);
+ QPoint pos(itemSize.width() / 2, itemSize.height() / 2);
QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.viewport()->mapToGlobal(pos));
event.ignore();
QApplication::sendEvent(view.viewport(), &event);
QVERIFY(event.isAccepted());
}
{
- QPoint pos(150, 150);
+ QPoint pos(itemSize.width() * 3 / 2, itemSize.height() * 3 / 2);
QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.viewport()->mapToGlobal(pos));
event.ignore();
QApplication::sendEvent(view.viewport(), &event);
@@ -2767,14 +2807,14 @@ void tst_QGraphicsScene::contextMenuEvent_ItemIgnoresTransformations()
}
view.scale(1.5, 1.5);
{
- QPoint pos(25, 25);
+ QPoint pos(itemSize.width() / 4, itemSize.height() / 4);
QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.viewport()->mapToGlobal(pos));
event.ignore();
QApplication::sendEvent(view.viewport(), &event);
QVERIFY(event.isAccepted());
}
{
- QPoint pos(55, 55);
+ QPoint pos(itemSize.width() / 2 + 5, itemSize.height() / 2 + 5);
QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.viewport()->mapToGlobal(pos));
event.ignore();
QApplication::sendEvent(view.viewport(), &event);
@@ -2790,14 +2830,14 @@ void tst_QGraphicsScene::update()
QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 100, 100);
rect->setPen(QPen(Qt::black, 0));
scene.addItem(rect);
- qApp->processEvents();
+ QCoreApplication::processEvents();
rect->setPos(-100, -100);
// This function forces indexing
itemAt(scene, 0, 0);
qRegisterMetaType<QList<QRectF> >("QList<QRectF>");
- QSignalSpy spy(&scene, SIGNAL(changed(QList<QRectF>)));
+ QSignalSpy spy(&scene, &QGraphicsScene::changed);
// We update the scene.
scene.update();
@@ -2806,12 +2846,13 @@ void tst_QGraphicsScene::update()
itemAt(scene, 0, 0);
// This will process the pending update
- QApplication::instance()->processEvents();
+ QCoreApplication::processEvents();
// Check that the update region is correct
QCOMPARE(spy.count(), 1);
QRectF region;
- foreach (QRectF rectF, qvariant_cast<QList<QRectF> >(spy.at(0).at(0)))
+ const auto &rects = qvariant_cast<QList<QRectF> >(spy.at(0).at(0));
+ for (const auto &rectF : rects)
region |= rectF;
QCOMPARE(region, QRectF(-100, -100, 200, 200));
}
@@ -2821,9 +2862,11 @@ void tst_QGraphicsScene::update2()
QGraphicsScene scene;
scene.setSceneRect(-200, -200, 200, 200);
CustomView view;
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.resize(m_testSize);
view.setScene(&scene);
view.show();
- qApp->setActiveWindow(&view);
+ QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QTRY_VERIFY(view.repaints >= 1);
view.repaints = 0;
@@ -2831,13 +2874,13 @@ void tst_QGraphicsScene::update2()
// Make sure QGraphicsScene::update only requires one event-loop iteration
// before the view is updated.
scene.update();
- qApp->processEvents();
+ QCoreApplication::processEvents();
QTRY_COMPARE(view.repaints, 1);
view.repaints = 0;
// The same for partial scene updates.
scene.update(QRectF(-100, -100, 100, 100));
- qApp->processEvents();
+ QCoreApplication::processEvents();
QCOMPARE(view.repaints, 1);
}
@@ -2853,7 +2896,7 @@ void tst_QGraphicsScene::views()
QCOMPARE(scene.views().size(), 2);
QVERIFY(scene.views().contains(&view1));
- view.setScene(0);
+ view.setScene(nullptr);
QCOMPARE(scene.views().size(), 1);
QCOMPARE(scene.views().at(0), &view1);
@@ -2871,12 +2914,12 @@ void tst_QGraphicsScene::views()
class CustomScene : public QGraphicsScene
{
public:
- CustomScene() : gotTimerEvent(false)
+ CustomScene()
{ startTimer(10); }
- bool gotTimerEvent;
+ bool gotTimerEvent = false;
protected:
- void timerEvent(QTimerEvent *)
+ void timerEvent(QTimerEvent *) override
{
gotTimerEvent = true;
}
@@ -2893,7 +2936,7 @@ void tst_QGraphicsScene::testEvent()
class DisabledItemTester : public QGraphicsRectItem
{
public:
- DisabledItemTester(const QRectF &rect, QGraphicsItem *parent = 0)
+ DisabledItemTester(const QRectF &rect, QGraphicsItem *parent = nullptr)
: QGraphicsRectItem(rect, parent)
{ }
@@ -2901,13 +2944,13 @@ public:
QList<QEvent::Type> receivedSceneEventFilters;
protected:
- bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
+ bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override
{
receivedSceneEventFilters << event->type();
return QGraphicsRectItem::sceneEventFilter(watched, event);
}
- bool sceneEvent(QEvent *event)
+ bool sceneEvent(QEvent *event) override
{
receivedSceneEvents << event->type();
return QGraphicsRectItem::sceneEvent(event);
@@ -2965,11 +3008,9 @@ void tst_QGraphicsScene::eventsToDisabledItems()
class ExposedPixmapItem : public QGraphicsPixmapItem
{
public:
- ExposedPixmapItem(QGraphicsItem *item = 0)
- : QGraphicsPixmapItem(item)
- { }
+ using QGraphicsPixmapItem::QGraphicsPixmapItem;
- void paint(QPainter *, const QStyleOptionGraphicsItem *option, QWidget *)
+ void paint(QPainter *, const QStyleOptionGraphicsItem *option, QWidget *) override
{
exposed = option->exposedRect;
}
@@ -3013,8 +3054,9 @@ void tst_QGraphicsScene::tabFocus_emptyScene()
QWidget widget;
widget.setLayout(layout);
+ widget.setWindowTitle(QTest::currentTestFunction());
widget.show();
- qApp->setActiveWindow(&widget);
+ QApplication::setActiveWindow(&widget);
widget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&widget));
@@ -3060,9 +3102,10 @@ void tst_QGraphicsScene::tabFocus_sceneWithFocusableItems()
layout->addWidget(dial2);
QWidget widget;
+ widget.setWindowTitle(QTest::currentTestFunction());
widget.setLayout(layout);
widget.show();
- qApp->setActiveWindow(&widget);
+ QApplication::setActiveWindow(&widget);
widget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&widget));
@@ -3112,18 +3155,18 @@ void tst_QGraphicsScene::tabFocus_sceneWithFocusableItems()
QVERIFY(!view->viewport()->hasFocus());
QVERIFY(!scene.hasFocus());
QVERIFY(!item->hasFocus());
- QCOMPARE(scene.focusItem(), static_cast<QGraphicsItem *>(item));
+ QCOMPARE(scene.focusItem(), item);
// Check that the correct item regains focus.
widget.show();
- qApp->setActiveWindow(&widget);
+ QApplication::setActiveWindow(&widget);
widget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&widget));
QVERIFY(view->hasFocus());
QTRY_VERIFY(scene.isActive());
QVERIFY(view->viewport()->hasFocus());
QVERIFY(scene.hasFocus());
- QCOMPARE(scene.focusItem(), static_cast<QGraphicsItem *>(item));
+ QCOMPARE(scene.focusItem(), item);
QVERIFY(item->hasFocus());
}
@@ -3131,14 +3174,13 @@ class FocusWidget : public QGraphicsWidget
{
Q_OBJECT
public:
- FocusWidget(QGraphicsItem *parent = 0)
- : QGraphicsWidget(parent), tabs(0), backTabs(0)
+ FocusWidget(QGraphicsItem *parent = nullptr) : QGraphicsWidget(parent)
{
setFocusPolicy(Qt::StrongFocus);
resize(100, 100);
}
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) override
{
if (option->state & QStyle::State_HasFocus) {
painter->fillRect(rect(), Qt::blue);
@@ -3152,11 +3194,11 @@ public:
}
}
- int tabs;
- int backTabs;
+ int tabs = 0;
+ int backTabs = 0;
protected:
- bool sceneEvent(QEvent *event)
+ bool sceneEvent(QEvent *event) override
{
if (event->type() == QEvent::KeyPress) {
QKeyEvent *k = static_cast<QKeyEvent *>(event);
@@ -3168,9 +3210,9 @@ protected:
return QGraphicsWidget::sceneEvent(event);
}
- void focusInEvent(QFocusEvent *)
+ void focusInEvent(QFocusEvent *) override
{ update(); }
- void focusOutEvent(QFocusEvent *)
+ void focusOutEvent(QFocusEvent *) override
{ update(); }
};
@@ -3195,9 +3237,10 @@ void tst_QGraphicsScene::tabFocus_sceneWithFocusWidgets()
layout->addWidget(dial2);
QWidget widget;
+ widget.setWindowTitle(QTest::currentTestFunction());
widget.setLayout(layout);
widget.show();
- qApp->setActiveWindow(&widget);
+ QApplication::setActiveWindow(&widget);
widget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&widget));
@@ -3236,7 +3279,7 @@ void tst_QGraphicsScene::tabFocus_sceneWithFocusWidgets()
widget.hide();
QTest::qWait(15);
widget.show();
- qApp->setActiveWindow(&widget);
+ QApplication::setActiveWindow(&widget);
widget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&widget));
QTRY_VERIFY(widget1->hasFocus());
@@ -3279,9 +3322,10 @@ void tst_QGraphicsScene::tabFocus_sceneWithNestedFocusWidgets()
layout->addWidget(dial2);
QWidget widget;
+ widget.setWindowTitle(QTest::currentTestFunction());
widget.setLayout(layout);
widget.show();
- qApp->setActiveWindow(&widget);
+ QApplication::setActiveWindow(&widget);
widget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&widget));
@@ -3366,7 +3410,7 @@ void tst_QGraphicsScene::tabFocus_sceneWithNestedFocusWidgets()
widget.hide();
QTest::qWait(12);
widget.show();
- qApp->setActiveWindow(&widget);
+ QApplication::setActiveWindow(&widget);
widget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&widget));
QTRY_VERIFY(widget1->hasFocus());
@@ -3390,11 +3434,11 @@ void tst_QGraphicsScene::style()
QCOMPARE(sceneSpy.count(), 1);
QCOMPARE(proxySpy.count(), 1);
QCOMPARE(editSpy.count(), 1);
- QCOMPARE(scene.style(), (QStyle *)windowsStyle);
- QCOMPARE(proxy->style(), (QStyle *)windowsStyle);
- QCOMPARE(edit->style(), (QStyle *)windowsStyle);
+ QCOMPARE(scene.style(), windowsStyle.data());
+ QCOMPARE(proxy->style(), windowsStyle.data());
+ QCOMPARE(edit->style(), windowsStyle.data());
- scene.setStyle(0);
+ scene.setStyle(nullptr);
QCOMPARE(sceneSpy.count(), 2);
QCOMPARE(proxySpy.count(), 2);
QCOMPARE(editSpy.count(), 2);
@@ -3411,11 +3455,12 @@ void tst_QGraphicsScene::task139710_bspTreeCrash()
for (int i = 0; i < 2; ++i) {
// trigger delayed item indexing
- qApp->processEvents();
+ QCoreApplication::processEvents();
scene.setSceneRect(0, 0, 10000, 10000);
// delete all items in the scene - pointers are now likely to be recycled
- foreach (QGraphicsItem *item, scene.items()) {
+ const auto &items = scene.items();
+ for (QGraphicsItem *item : items) {
scene.removeItem(item);
delete item;
}
@@ -3427,7 +3472,7 @@ void tst_QGraphicsScene::task139710_bspTreeCrash()
}
// trigger delayed item indexing for the first 1000 items
- qApp->processEvents();
+ QCoreApplication::processEvents();
// add 1000 more items - the BSP tree is now resized
for (int i = 0; i < 1000; ++i) {
@@ -3437,7 +3482,8 @@ void tst_QGraphicsScene::task139710_bspTreeCrash()
// get items from the BSP tree and use them. there was junk in the tree
// the second time this happened.
- foreach (QGraphicsItem *item, scene.items(QRectF(0, 0, 1000, 1000)))
+ const auto &itemsWithin = scene.items(QRectF(0, 0, 1000, 1000));
+ for (QGraphicsItem *item : itemsWithin)
item->moveBy(0, 0);
}
}
@@ -3446,7 +3492,7 @@ void tst_QGraphicsScene::task139782_containsItemBoundingRect()
{
// The item in question has a scene bounding rect of (10, 10, 50, 50)
QGraphicsScene scene(0.0, 0.0, 200.0, 200.0);
- QGraphicsRectItem *item = new QGraphicsRectItem(0.0, 0.0, 50.0, 50.0, 0);
+ QGraphicsRectItem *item = new QGraphicsRectItem(0.0, 0.0, 50.0, 50.0, nullptr);
scene.addItem(item);
item->setPos(10.0, 10.0);
@@ -3476,7 +3522,8 @@ void tst_QGraphicsScene::task160653_selectionChanged()
QGraphicsScene scene(0, 0, 100, 100);
scene.addItem(new QGraphicsRectItem(0, 0, 20, 20));
scene.addItem(new QGraphicsRectItem(30, 30, 20, 20));
- foreach (QGraphicsItem *item, scene.items()) {
+ const auto &items = scene.items();
+ for (QGraphicsItem *item : items) {
item->setFlags(
item->flags() | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
item->setSelected(true);
@@ -3484,12 +3531,14 @@ void tst_QGraphicsScene::task160653_selectionChanged()
QVERIFY(scene.items().size() > 1);
QCOMPARE(scene.items().size(), scene.selectedItems().size());
- QSignalSpy spy(&scene, SIGNAL(selectionChanged()));
+ QSignalSpy spy(&scene, &QGraphicsScene::selectionChanged);
QGraphicsView view(&scene);
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.resize(m_testSize);
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
QTest::mouseClick(
- view.viewport(), Qt::LeftButton, 0, view.mapFromScene(scene.items().first()->scenePos()));
+ view.viewport(), Qt::LeftButton, {}, view.mapFromScene(scene.items().first()->scenePos()));
QCOMPARE(spy.count(), 1);
}
@@ -3574,17 +3623,21 @@ void tst_QGraphicsScene::sorting()
scene.addItem(t_1);
- foreach (QGraphicsItem *item, scene.items())
+ const auto &items = scene.items();
+ for (QGraphicsItem *item : items)
item->setFlag(QGraphicsItem::ItemIsSelectable);
// QGraphicsView view(&scene);
// view.setDragMode(QGraphicsView::RubberBandDrag);
// view.show();
- qDebug() << "items: {";
- foreach (QGraphicsItem *item, scene.items(QRectF(32, 31, 4, 55)))
- qDebug() << "\t" << item->data(0).toString();
- qDebug() << "}";
+ if (lcTests().isDebugEnabled()) {
+ qCDebug(lcTests) << "items: {";
+ const auto &itemsWithin = scene.items(QRectF(32, 31, 4, 55));
+ for (QGraphicsItem *item : itemsWithin)
+ qCDebug(lcTests).nospace() << '\t' << item->data(0).toString();
+ qCDebug(lcTests) << '}';
+ }
QCOMPARE(scene.items(QRectF(32, 31, 4, 55)),
QList<QGraphicsItem *>()
@@ -3664,11 +3717,11 @@ void tst_QGraphicsScene::changedSignal()
QFETCH(bool, withView);
QGraphicsScene scene;
ChangedListener cl;
- connect(&scene, SIGNAL(changed(QList<QRectF>)), &cl, SLOT(changed(QList<QRectF>)));
+ connect(&scene, &QGraphicsScene::changed, &cl, &ChangedListener::changed);
- QGraphicsView *view = 0;
+ QScopedPointer<QGraphicsView> view;
if (withView)
- view = new QGraphicsView(&scene);
+ view.reset(new QGraphicsView(&scene));
QGraphicsRectItem *rect = new QGraphicsRectItem(0, 0, 10, 10);
rect->setPen(QPen(Qt::black, 0));
@@ -3682,16 +3735,13 @@ void tst_QGraphicsScene::changedSignal()
rect->setPos(20, 0);
QCOMPARE(cl.changes.size(), 1);
- qApp->processEvents();
+ QCoreApplication::processEvents();
QCOMPARE(cl.changes.size(), 2);
QCOMPARE(cl.changes.at(1).size(), 2);
QCOMPARE(cl.changes.at(1).first(), QRectF(0, 0, 10, 10));
QCOMPARE(cl.changes.at(1).last(), QRectF(20, 0, 10, 10));
QCOMPARE(scene.sceneRect(), QRectF(0, 0, 30, 10));
-
- if (withView)
- delete view;
}
void tst_QGraphicsScene::stickyFocus_data()
@@ -3718,7 +3768,7 @@ void tst_QGraphicsScene::stickyFocus()
QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
event.setScenePos(QPointF(-10, -10)); // outside item
event.setButton(Qt::LeftButton);
- qApp->sendEvent(&scene, &event);
+ QCoreApplication::sendEvent(&scene, &event);
QCOMPARE(text->hasFocus(), sticky);
}
@@ -3736,43 +3786,51 @@ void tst_QGraphicsScene::sendEvent()
void tst_QGraphicsScene::inputMethod_data()
{
- QTest::addColumn<int>("flags");
+ QTest::addColumn<QGraphicsItem::GraphicsItemFlags>("flags");
QTest::addColumn<bool>("callFocusItem");
- QTest::newRow("0") << 0 << false;
- QTest::newRow("1") << (int)QGraphicsItem::ItemAcceptsInputMethod << false;
- QTest::newRow("2") << (int)QGraphicsItem::ItemIsFocusable << false;
+ QTest::newRow("0") << QGraphicsItem::GraphicsItemFlags() << false;
+ QTest::newRow("1") << QGraphicsItem::GraphicsItemFlags(QGraphicsItem::ItemAcceptsInputMethod) << false;
+ QTest::newRow("2") << QGraphicsItem::GraphicsItemFlags(QGraphicsItem::ItemIsFocusable) << false;
QTest::newRow("3") <<
- (int)(QGraphicsItem::ItemAcceptsInputMethod|QGraphicsItem::ItemIsFocusable) << true;
+ (QGraphicsItem::ItemAcceptsInputMethod|QGraphicsItem::ItemIsFocusable) << true;
}
class InputMethodTester : public QGraphicsRectItem
{
- void inputMethodEvent(QInputMethodEvent *) { ++eventCalls; }
- QVariant inputMethodQuery(Qt::InputMethodQuery) const { ++queryCalls; return QVariant(); }
+ void inputMethodEvent(QInputMethodEvent *) override { ++eventCalls; }
+ QVariant inputMethodQuery(Qt::InputMethodQuery) const override
+ {
+ ++queryCalls;
+ return QVariant();
+ }
+
public:
- int eventCalls;
- mutable int queryCalls;
+ int eventCalls = 0;
+ mutable int queryCalls = 0;
};
void tst_QGraphicsScene::inputMethod()
{
PlatformInputContext inputContext;
- QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
+ QInputMethodPrivate *inputMethodPrivate =
+ QInputMethodPrivate::get(QGuiApplication::inputMethod());
inputMethodPrivate->testContext = &inputContext;
- QFETCH(int, flags);
+ QFETCH(QGraphicsItem::GraphicsItemFlags, flags);
QFETCH(bool, callFocusItem);
InputMethodTester *item = new InputMethodTester;
- item->setFlags((QGraphicsItem::GraphicsItemFlags)flags);
+ item->setFlags(flags);
QGraphicsScene scene;
QGraphicsView view(&scene);
+ view.resize(m_testSize);
view.show();
+ view.setWindowTitle(QTest::currentTestFunction());
QApplication::setActiveWindow(&view);
view.setFocus();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QCOMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
+ QCOMPARE(QApplication::activeWindow(), &view);
inputContext.m_resetCallCount = 0;
inputContext.m_commitCallCount = 0;
@@ -3784,25 +3842,25 @@ void tst_QGraphicsScene::inputMethod()
QCOMPARE(inputContext.m_resetCallCount, 0);
item->eventCalls = 0;
- qApp->sendEvent(&scene, &event);
+ QCoreApplication::sendEvent(&scene, &event);
QCOMPARE(item->eventCalls, callFocusItem ? 1 : 0);
item->queryCalls = 0;
- scene.inputMethodQuery((Qt::InputMethodQuery)0);
+ scene.inputMethodQuery(Qt::InputMethodQuery(0));
QCOMPARE(item->queryCalls, callFocusItem ? 1 : 0);
- scene.setFocusItem(0);
+ scene.setFocusItem(nullptr);
// the input context is reset twice, once because an item has lost focus and again because
// the Qt::WA_InputMethodEnabled flag is cleared because no item has focus.
QCOMPARE(inputContext.m_resetCallCount + inputContext.m_commitCallCount, callFocusItem ? 2 : 0);
QCOMPARE(item->queryCalls, callFocusItem ? 1 : 0); // verify that value is unaffected
item->eventCalls = 0;
- qApp->sendEvent(&scene, &event);
+ QCoreApplication::sendEvent(&scene, &event);
QCOMPARE(item->eventCalls, 0);
item->queryCalls = 0;
- scene.inputMethodQuery((Qt::InputMethodQuery)0);
+ scene.inputMethodQuery(Qt::InputMethodQuery(0));
QCOMPARE(item->queryCalls, 0);
}
@@ -3826,18 +3884,18 @@ void tst_QGraphicsScene::dispatchHoverOnPress()
me.setButtons(Qt::LeftButton);
QGraphicsSceneMouseEvent me2(QEvent::GraphicsSceneMouseRelease);
me2.setButton(Qt::LeftButton);
- qApp->sendEvent(&scene, &me);
- qApp->sendEvent(&scene, &me2);
- QCOMPARE(tester1->eventTypes, QList<QEvent::Type>()
+ QCoreApplication::sendEvent(&scene, &me);
+ QCoreApplication::sendEvent(&scene, &me2);
+ QCOMPARE(tester1->eventTypes, QVector<QEvent::Type>()
<< QEvent::GraphicsSceneHoverEnter
<< QEvent::GraphicsSceneHoverMove
<< QEvent::GrabMouse
<< QEvent::GraphicsSceneMousePress
<< QEvent::UngrabMouse);
tester1->eventTypes.clear();
- qApp->sendEvent(&scene, &me);
- qApp->sendEvent(&scene, &me2);
- QCOMPARE(tester1->eventTypes, QList<QEvent::Type>()
+ QCoreApplication::sendEvent(&scene, &me);
+ QCoreApplication::sendEvent(&scene, &me2);
+ QCOMPARE(tester1->eventTypes, QVector<QEvent::Type>()
<< QEvent::GraphicsSceneHoverMove
<< QEvent::GrabMouse
<< QEvent::GraphicsSceneMousePress
@@ -3852,21 +3910,21 @@ void tst_QGraphicsScene::dispatchHoverOnPress()
me2.setScenePos(QPointF(30, 30));
me2.setButton(Qt::LeftButton);
tester1->eventTypes.clear();
- qApp->sendEvent(&scene, &me);
- qApp->sendEvent(&scene, &me2);
- qDebug() << tester1->eventTypes;
- QCOMPARE(tester1->eventTypes, QList<QEvent::Type>()
+ QCoreApplication::sendEvent(&scene, &me);
+ QCoreApplication::sendEvent(&scene, &me2);
+ qCDebug(lcTests) << tester1->eventTypes;
+ QCOMPARE(tester1->eventTypes, QVector<QEvent::Type>()
<< QEvent::GraphicsSceneHoverLeave);
- QCOMPARE(tester2->eventTypes, QList<QEvent::Type>()
+ QCOMPARE(tester2->eventTypes, QVector<QEvent::Type>()
<< QEvent::GraphicsSceneHoverEnter
<< QEvent::GraphicsSceneHoverMove
<< QEvent::GrabMouse
<< QEvent::GraphicsSceneMousePress
<< QEvent::UngrabMouse);
tester2->eventTypes.clear();
- qApp->sendEvent(&scene, &me);
- qApp->sendEvent(&scene, &me2);
- QCOMPARE(tester2->eventTypes, QList<QEvent::Type>()
+ QCoreApplication::sendEvent(&scene, &me);
+ QCoreApplication::sendEvent(&scene, &me2);
+ QCOMPARE(tester2->eventTypes, QVector<QEvent::Type>()
<< QEvent::GraphicsSceneHoverMove
<< QEvent::GrabMouse
<< QEvent::GraphicsSceneMousePress
@@ -3915,7 +3973,7 @@ void tst_QGraphicsScene::initialFocus()
if (activeScene) {
QEvent windowActivate(QEvent::WindowActivate);
- qApp->sendEvent(&scene, &windowActivate);
+ QCoreApplication::sendEvent(&scene, &windowActivate);
scene.setFocus();
}
@@ -3923,7 +3981,7 @@ void tst_QGraphicsScene::initialFocus()
if (!activeScene) {
QEvent windowActivate(QEvent::WindowActivate);
- qApp->sendEvent(&scene, &windowActivate);
+ QCoreApplication::sendEvent(&scene, &windowActivate);
scene.setFocus();
}
@@ -3933,14 +3991,13 @@ void tst_QGraphicsScene::initialFocus()
class PolishItem : public QGraphicsTextItem
{
public:
- PolishItem(QGraphicsItem *parent = 0)
- : QGraphicsTextItem(parent), polished(false), deleteChildrenInPolish(true), addChildrenInPolish(false) { }
+ using QGraphicsTextItem::QGraphicsTextItem;
- bool polished;
- bool deleteChildrenInPolish;
- bool addChildrenInPolish;
+ bool polished = false;
+ bool deleteChildrenInPolish = true;
+ bool addChildrenInPolish = false;
protected:
- QVariant itemChange(GraphicsItemChange change, const QVariant& value)
+ QVariant itemChange(GraphicsItemChange change, const QVariant& value) override
{
if (change == ItemVisibleChange) {
polished = true;
@@ -3979,19 +4036,19 @@ void tst_QGraphicsScene::polishItems2()
// Wait for the polish event to be delivered.
QVERIFY(!item->polished);
- QApplication::sendPostedEvents(&scene, QEvent::MetaCall);
+ QCoreApplication::sendPostedEvents(&scene, QEvent::MetaCall);
QVERIFY(item->polished);
// We deleted the children we added above, but we also
// added 10 new children. These should be polished in the next
// event loop iteration.
- QList<QGraphicsItem *> children = item->childItems();
+ const QList<QGraphicsItem *> children = item->childItems();
QCOMPARE(children.count(), 10);
- foreach (QGraphicsItem *child, children)
+ for (QGraphicsItem *child : children)
QVERIFY(!static_cast<PolishItem *>(child)->polished);
- QApplication::sendPostedEvents(&scene, QEvent::MetaCall);
- foreach (QGraphicsItem *child, children)
+ QCoreApplication::sendPostedEvents(&scene, QEvent::MetaCall);
+ for (QGraphicsItem *child : children)
QVERIFY(static_cast<PolishItem *>(child)->polished);
}
@@ -4008,6 +4065,8 @@ void tst_QGraphicsScene::isActive()
{
QWidget toplevel1;
+ toplevel1.setWindowTitle(QTest::currentTestFunction());
+ toplevel1.resize(m_testSize);
QHBoxLayout *layout = new QHBoxLayout;
toplevel1.setLayout(layout);
QGraphicsView *view1 = new QGraphicsView(&scene1);
@@ -4073,8 +4132,9 @@ void tst_QGraphicsScene::isActive()
{
- const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
QWidget toplevel2;
+ toplevel2.setWindowTitle(QTest::currentTestFunction());
+ toplevel2.resize(m_testSize);
QHBoxLayout *layout = new QHBoxLayout;
toplevel2.setLayout(layout);
QGraphicsView *view1 = new QGraphicsView(&scene1);
@@ -4087,7 +4147,7 @@ void tst_QGraphicsScene::isActive()
QVERIFY(!scene1.hasFocus());
QVERIFY(!scene2.hasFocus());
- toplevel2.move(availableGeometry.topLeft() + QPoint(50, 50));
+ toplevel2.move(m_availableGeometry.topLeft() + QPoint(50, 50));
toplevel2.show();
QApplication::setActiveWindow(&toplevel2);
QVERIFY(QTest::qWaitForWindowActive(&toplevel2));
@@ -4136,12 +4196,13 @@ void tst_QGraphicsScene::isActive()
QVERIFY(!scene2.hasFocus());
QGraphicsView topLevelView;
- topLevelView.move(availableGeometry.topLeft() + QPoint(500, 50));
+ topLevelView.move(toplevel2.geometry().topRight() + QPoint(100, 50));
+ topLevelView.resize(m_testSize);
topLevelView.show();
QApplication::setActiveWindow(&topLevelView);
topLevelView.setFocus();
QVERIFY(QTest::qWaitForWindowActive(&topLevelView));
- QCOMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&topLevelView));
+ QCOMPARE(QApplication::activeWindow(), &topLevelView);
QVERIFY(!scene1.isActive());
QVERIFY(!scene2.isActive());
@@ -4182,6 +4243,7 @@ void tst_QGraphicsScene::isActive()
{
QWidget toplevel3;
+ toplevel3.resize(m_testSize);
QHBoxLayout *layout = new QHBoxLayout;
toplevel3.setLayout(layout);
QGraphicsView *view1 = new QGraphicsView(&scene1);
@@ -4211,7 +4273,7 @@ void tst_QGraphicsScene::isActive()
QVERIFY(scene1.hasFocus());
QVERIFY(!scene2.hasFocus());
- view1->setParent(0);
+ view1->setParent(nullptr);
QVERIFY(!scene1.isActive());
QVERIFY(scene2.isActive());
QVERIFY(!scene1.hasFocus());
@@ -4243,7 +4305,7 @@ void tst_QGraphicsScene::siblingIndexAlwaysValid()
scene.addItem(parent2);
//Then we make the child a top level
- child->setParentItem(0);
+ child->setParentItem(nullptr);
//This is trigerred by a repaint...
QGraphicsScenePrivate::get(&scene)->index->estimateTopLevelItems(QRectF(), Qt::AscendingOrder);
@@ -4259,6 +4321,8 @@ void tst_QGraphicsScene::siblingIndexAlwaysValid()
scene2.setItemIndexMethod(QGraphicsScene::NoIndex);
QGraphicsView view2(&scene2);
+ view2.setWindowTitle(QTest::currentTestFunction());
+ view2.resize(m_testSize);
// first add the blue rect
QGraphicsRectItem* const item1 = new QGraphicsRectItem(QRect( 10, 10, 10, 10 ));
@@ -4302,9 +4366,11 @@ void tst_QGraphicsScene::removeFullyTransparentItem()
child->setParentItem(parent);
CustomView view;
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.resize(m_testSize);
view.setScene(&scene);
view.show();
- qApp->setActiveWindow(&view);
+ QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QCoreApplication::processEvents(); // Process all queued paint events
@@ -4353,33 +4419,35 @@ void tst_QGraphicsScene::taskQTBUG_5904_crashWithDeviceCoordinateCache()
void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts()
{
// Test using DeviceCoordinateCache and opaque item
- QWidget *w = new QWidget();
+ QScopedPointer<QWidget> w(new QWidget);
w->setPalette(QColor(0, 0, 255));
w->setGeometry(0, 0, 50, 50);
QGraphicsScene *scene = new QGraphicsScene();
- CustomView *view = new CustomView;
- view->setScene(scene);
+ CustomView view;
+ view.resize(m_testSize);
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.setScene(scene);
- QGraphicsProxyWidget *proxy = scene->addWidget(w);
+ QGraphicsProxyWidget *proxy = scene->addWidget(w.data());
proxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
proxy->setTransform(QTransform().rotate(15), true);
- view->show();
- QVERIFY(QTest::qWaitForWindowExposed(view));
- view->repaints = 0;
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ view.repaints = 0;
proxy->update(10, 10, 10, 10);
- QTRY_VERIFY(view->repaints > 0);
+ QTRY_VERIFY(view.repaints > 0);
QPixmap pix;
QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(proxy);
- QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->deviceData.value(view->viewport()).key, &pix));
+ QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->deviceData.value(view.viewport()).key, &pix));
QTransform t = proxy->sceneTransform();
// Map from scene coordinates to pixmap coordinates.
// X origin in the pixmap is the most-left point
// of the item's boundingRect in the scene.
- qreal adjust = t.mapRect(proxy->boundingRect().toRect()).left();
+ const int adjust = t.mapRect(proxy->boundingRect().toRect()).left();
QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1);
QPixmap subpix = pix.copy(rect);
@@ -4388,8 +4456,6 @@ void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts()
for(int j = 0; j < im.height(); j++)
QCOMPARE(qAlpha(im.pixel(i, j)), 255);
}
-
- delete w;
}
void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts()
@@ -4403,28 +4469,30 @@ void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts()
rectItem->setParentItem(backItem);
QGraphicsScene *scene = new QGraphicsScene();
- CustomView *view = new CustomView;
- view->setScene(scene);
+ CustomView view;
+ view.resize(m_testSize);
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.setScene(scene);
scene->addItem(backItem);
rectItem->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
backItem->setTransform(QTransform().rotate(15), true);
- view->show();
- QVERIFY(QTest::qWaitForWindowExposed(view));
- view->repaints = 0;
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ view.repaints = 0;
rectItem->update(10, 10, 10, 10);
- QTRY_VERIFY(view->repaints > 0);
+ QTRY_VERIFY(view.repaints > 0);
QPixmap pix;
QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem);
- QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->deviceData.value(view->viewport()).key, &pix));
+ QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->deviceData.value(view.viewport()).key, &pix));
QTransform t = rectItem->sceneTransform();
// Map from scene coordinates to pixmap coordinates.
// X origin in the pixmap is the most-left point
// of the item's boundingRect in the scene.
- qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left();
+ const int adjust = t.mapRect(rectItem->boundingRect().toRect()).left();
QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1);
QPixmap subpix = pix.copy(rect);
@@ -4434,8 +4502,6 @@ void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts()
QCOMPARE(qAlpha(im.pixel(i, j)), 125);
}
}
-
- delete view;
}
// Test using ItemCoordinateCache and opaque item
@@ -4444,18 +4510,20 @@ void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts()
rectItem->setBrush(QColor(0, 0, 255));
QGraphicsScene *scene = new QGraphicsScene();
- CustomView *view = new CustomView;
- view->setScene(scene);
+ CustomView view;
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.resize(m_testSize);
+ view.setScene(scene);
scene->addItem(rectItem);
rectItem->setCacheMode(QGraphicsItem::ItemCoordinateCache);
rectItem->setTransform(QTransform().rotate(15), true);
- view->show();
- QVERIFY(QTest::qWaitForWindowExposed(view));
- view->repaints = 0;
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ view.repaints = 0;
rectItem->update(10, 10, 10, 10);
- QTRY_VERIFY(view->repaints > 0);
+ QTRY_VERIFY(view.repaints > 0);
QPixmap pix;
QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem);
@@ -4465,7 +4533,7 @@ void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts()
// Map from scene coordinates to pixmap coordinates.
// X origin in the pixmap is the most-left point
// of the item's boundingRect in the scene.
- qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left();
+ const int adjust = t.mapRect(rectItem->boundingRect().toRect()).left();
QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1);
QPixmap subpix = pix.copy(rect);
@@ -4474,8 +4542,6 @@ void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts()
for(int j = 0; j < im.height(); j++)
QCOMPARE(qAlpha(im.pixel(i, j)), 255);
}
-
- delete view;
}
// Test using ItemCoordinateCache and semi-transparent item
@@ -4484,18 +4550,20 @@ void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts()
rectItem->setBrush(QColor(0, 0, 255, 125));
QGraphicsScene *scene = new QGraphicsScene();
- CustomView *view = new CustomView;
- view->setScene(scene);
+ CustomView view;
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.resize(m_testSize);
+ view.setScene(scene);
scene->addItem(rectItem);
rectItem->setCacheMode(QGraphicsItem::ItemCoordinateCache);
rectItem->setTransform(QTransform().rotate(15), true);
- view->show();
- QVERIFY(QTest::qWaitForWindowExposed(view));
- view->repaints = 0;
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ view.repaints = 0;
rectItem->update(10, 10, 10, 10);
- QTRY_VERIFY(view->repaints > 0);
+ QTRY_VERIFY(view.repaints > 0);
QPixmap pix;
QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem);
@@ -4505,7 +4573,7 @@ void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts()
// Map from scene coordinates to pixmap coordinates.
// X origin in the pixmap is the most-left point
// of the item's boundingRect in the scene.
- qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left();
+ const int adjust = int(t.mapRect(rectItem->boundingRect().toRect()).left());
QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1);
QPixmap subpix = pix.copy(rect);
@@ -4514,8 +4582,6 @@ void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts()
for(int j = 0; j < im.height(); j++)
QCOMPARE(qAlpha(im.pixel(i, j)), 125);
}
-
- delete view;
}
}
@@ -4546,7 +4612,7 @@ void tst_QGraphicsScene::zeroScale()
QGraphicsView view(&scene);
ChangedListener cl;
- connect(&scene, SIGNAL(changed(QList<QRectF>)), &cl, SLOT(changed(QList<QRectF>)));
+ connect(&scene, &QGraphicsScene::changed, &cl, &ChangedListener::changed);
QGraphicsRectItem *rect1 = new QGraphicsRectItem(0, 0, 0.0000001, 0.00000001);
scene.addItem(rect1);
@@ -4569,13 +4635,13 @@ void tst_QGraphicsScene::focusItemChangedSignal()
qRegisterMetaType<Qt::FocusReason>("Qt::FocusReason");
QGraphicsScene scene;
- QSignalSpy spy(&scene, SIGNAL(focusItemChanged(QGraphicsItem *, QGraphicsItem *, Qt::FocusReason)));
+ QSignalSpy spy(&scene, &QGraphicsScene::focusItemChanged);
QVERIFY(spy.isValid());
QCOMPARE(spy.count(), 0);
scene.setFocus();
QCOMPARE(spy.count(), 0);
QEvent activateEvent(QEvent::WindowActivate);
- qApp->sendEvent(&scene, &activateEvent);
+ QCoreApplication::sendEvent(&scene, &activateEvent);
QCOMPARE(spy.count(), 0);
QGraphicsRectItem *topLevelItem1 = new QGraphicsRectItem;
@@ -4592,7 +4658,7 @@ void tst_QGraphicsScene::focusItemChangedSignal()
QCOMPARE(spy.count(), 1);
QList<QVariant> arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 3);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), (QGraphicsItem *)topLevelItem2);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), topLevelItem2);
QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), nullptr);
QCOMPARE(qvariant_cast<Qt::FocusReason>(arguments.at(2)), Qt::OtherFocusReason);
QVERIFY(topLevelItem2->hasFocus());
@@ -4602,14 +4668,14 @@ void tst_QGraphicsScene::focusItemChangedSignal()
arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 3);
QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), nullptr);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), (QGraphicsItem *)topLevelItem2);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), topLevelItem2);
QCOMPARE(qvariant_cast<Qt::FocusReason>(arguments.at(2)), Qt::OtherFocusReason);
scene.setFocus(Qt::MenuBarFocusReason);
QCOMPARE(spy.count(), 1);
arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 3);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), (QGraphicsItem *)topLevelItem2);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), topLevelItem2);
QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), nullptr);
QCOMPARE(qvariant_cast<Qt::FocusReason>(arguments.at(2)), Qt::MenuBarFocusReason);
@@ -4617,15 +4683,15 @@ void tst_QGraphicsScene::focusItemChangedSignal()
topLevelItem1->setFocus(Qt::TabFocusReason);
arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 3);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), (QGraphicsItem *)topLevelItem1);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), (QGraphicsItem *)topLevelItem2);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), topLevelItem1);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), topLevelItem2);
QCOMPARE(qvariant_cast<Qt::FocusReason>(arguments.at(2)), Qt::TabFocusReason);
topLevelItem2->setFocus(Qt::TabFocusReason);
arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 3);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), (QGraphicsItem *)topLevelItem2);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), (QGraphicsItem *)topLevelItem1);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), topLevelItem2);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), topLevelItem1);
QCOMPARE(qvariant_cast<Qt::FocusReason>(arguments.at(2)), Qt::TabFocusReason);
}
@@ -4633,10 +4699,10 @@ void tst_QGraphicsScene::focusItemChangedSignal()
// when the scene activation changes) breaks quite a few tests so leave this fix
// for some future release. See QTBUG-28346.
QEvent deactivateEvent(QEvent::WindowDeactivate);
- qApp->sendEvent(&scene, &deactivateEvent);
+ QCoreApplication::sendEvent(&scene, &deactivateEvent);
QEXPECT_FAIL("", "QTBUG-28346", Continue);
QCOMPARE(spy.count(), 1);
- qApp->sendEvent(&scene, &activateEvent);
+ QCoreApplication::sendEvent(&scene, &activateEvent);
QEXPECT_FAIL("", "QTBUG-28346", Continue);
QCOMPARE(spy.count(), 1);
@@ -4647,8 +4713,8 @@ void tst_QGraphicsScene::focusItemChangedSignal()
QCOMPARE(spy.count(), 1);
arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 3);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), (QGraphicsItem *)panel1);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), (QGraphicsItem *)topLevelItem2);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), panel1);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), topLevelItem2);
QCOMPARE(qvariant_cast<Qt::FocusReason>(arguments.at(2)), Qt::ActiveWindowFocusReason);
QGraphicsRectItem *panel2 = new QGraphicsRectItem;
@@ -4661,16 +4727,16 @@ void tst_QGraphicsScene::focusItemChangedSignal()
QCOMPARE(spy.count(), 1);
arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 3);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), (QGraphicsItem *)panel2);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), (QGraphicsItem *)panel1);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), panel2);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), panel1);
QCOMPARE(qvariant_cast<Qt::FocusReason>(arguments.at(2)), Qt::ActiveWindowFocusReason);
scene.setActivePanel(panel1);
QCOMPARE(spy.count(), 1);
arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 3);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), (QGraphicsItem *)panel1);
- QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), (QGraphicsItem *)panel2);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(0)), panel1);
+ QCOMPARE(qvariant_cast<QGraphicsItem *>(arguments.at(1)), panel2);
QCOMPARE(qvariant_cast<Qt::FocusReason>(arguments.at(2)), Qt::ActiveWindowFocusReason);
}
@@ -4679,14 +4745,15 @@ void tst_QGraphicsScene::focusItemChangedSignal()
class ItemCountsPaintCalls : public QGraphicsRectItem
{
public:
- ItemCountsPaintCalls(const QRectF & rect, QGraphicsItem *parent = 0)
- : QGraphicsRectItem(rect, parent), repaints(0) {}
- void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 )
+ using QGraphicsRectItem::QGraphicsRectItem;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget = nullptr) override
{
QGraphicsRectItem::paint(painter, option, widget);
++repaints;
}
- int repaints;
+ int repaints = 0;
};
void tst_QGraphicsScene::minimumRenderSize()
@@ -4700,10 +4767,12 @@ void tst_QGraphicsScene::minimumRenderSize()
scene.addItem(bigParent);
CustomView view;
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.resize(m_testSize);
view.setScene(&scene);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- qApp->processEvents();
+ QCoreApplication::processEvents();
// Initially, everything should be repainted the same number of times
int viewRepaints = 0;
@@ -4716,7 +4785,7 @@ void tst_QGraphicsScene::minimumRenderSize()
// Setting a minimum render size should cause a repaint
scene.setMinimumRenderSize(0.5);
- qApp->processEvents();
+ QCoreApplication::processEvents();
QTRY_VERIFY(view.repaints > viewRepaints);
viewRepaints = view.repaints;
@@ -4727,7 +4796,7 @@ void tst_QGraphicsScene::minimumRenderSize()
// Scaling should cause a repaint of big items only.
view.scale(0.1, 0.1);
- qApp->processEvents();
+ QCoreApplication::processEvents();
QTRY_VERIFY(view.repaints > viewRepaints);
viewRepaints = view.repaints;
@@ -4738,7 +4807,7 @@ void tst_QGraphicsScene::minimumRenderSize()
// Scaling further should cause even fewer items to be repainted
view.scale(0.1, 0.1); // Stacks with previous scale
- qApp->processEvents();
+ QCoreApplication::processEvents();
QTRY_VERIFY(view.repaints > viewRepaints);
viewRepaints = view.repaints;
@@ -4752,6 +4821,8 @@ void tst_QGraphicsScene::focusOnTouch()
{
QGraphicsScene scene;
QGraphicsView view(&scene);
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.resize(m_testSize);
scene.setSceneRect(0, 0, 100, 100);
QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100);
rect->setFlag(QGraphicsItem::ItemIsFocusable, true);
@@ -4809,6 +4880,7 @@ void tst_QGraphicsScene::taskQTBUG_16401_focusItem()
{
QGraphicsScene scene;
QGraphicsView view(&scene);
+ view.resize(m_testSize);
QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100);
rect->setFlag(QGraphicsItem::ItemIsFocusable);
@@ -4839,6 +4911,8 @@ void tst_QGraphicsScene::taskQTBUG_42915_focusNextPrevChild()
{
QGraphicsScene scene;
QGraphicsView view(&scene);
+ view.setWindowTitle(QTest::currentTestFunction());
+ view.resize(m_testSize);
scene.setSceneRect(1, 1, 198, 198);
view.setFocus();
diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST
index 22fce8620b..9b76ea02ff 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST
+++ b/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST
@@ -1,24 +1,16 @@
[task255529_transformationAnchorMouseAndViewportMargins]
opensuse-leap
-rhel-7.4
-ubuntu-16.04
-opensuse-42.3
[cursor]
opensuse-leap
-ubuntu-16.04
-opensuse-42.3
[cursor2]
ubuntu-16.04
[sendEvent]
ubuntu-16.04
opensuse-42.3
[resizeAnchor]
-ubuntu-16.04
-rhel-7.6
opensuse-leap
-ubuntu-18.04
-rhel-7.4
-opensuse-42.3
+rhel-7.6
+ubuntu
[update2]
opensuse-42.3
[itemsInRect_cosmeticAdjust]
diff --git a/tests/auto/widgets/itemviews/qheaderview/BLACKLIST b/tests/auto/widgets/itemviews/qheaderview/BLACKLIST
index 297a6fe7b7..4eceaae0d3 100644
--- a/tests/auto/widgets/itemviews/qheaderview/BLACKLIST
+++ b/tests/auto/widgets/itemviews/qheaderview/BLACKLIST
@@ -1,3 +1,2 @@
[stretchAndRestoreLastSection]
opensuse-leap
-opensuse-42.3
diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
index f247889d55..df02815eb2 100644
--- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
@@ -106,6 +106,7 @@ class tst_QHeaderView : public QObject
public:
tst_QHeaderView();
+ static void initMain();
private slots:
void initTestCase();
@@ -265,6 +266,14 @@ protected:
QElapsedTimer timer;
};
+void tst_QHeaderView::initMain()
+{
+#ifdef Q_OS_WIN
+ // Ensure minimum size constraints of framed windows on High DPI screens
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+#endif
+}
+
class QtTestModel: public QAbstractTableModel
{
diff --git a/tests/auto/widgets/kernel/qapplication/BLACKLIST b/tests/auto/widgets/kernel/qapplication/BLACKLIST
index ac65a97c40..c68c7d6b14 100644
--- a/tests/auto/widgets/kernel/qapplication/BLACKLIST
+++ b/tests/auto/widgets/kernel/qapplication/BLACKLIST
@@ -1,4 +1,3 @@
[touchEventPropagation]
-opensuse-leap
# QTBUG-66745
-opensuse-42.3
+opensuse-leap
diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST
index 02e97e4b4e..26f9ce1b85 100644
--- a/tests/auto/widgets/kernel/qwidget/BLACKLIST
+++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST
@@ -14,12 +14,9 @@ rhel-7.4
ubuntu-16.04
rhel-7.6
[focusProxyAndInputMethods]
-ubuntu-16.04
rhel-7.6
opensuse-leap
-ubuntu-18.04
-rhel-7.4
-opensuse-42.3
+ubuntu
[raise]
opensuse-leap
# QTBUG-68175
@@ -45,12 +42,9 @@ opensuse-leap
[moveInResizeEvent]
ubuntu-16.04
[multipleToplevelFocusCheck]
-ubuntu-16.04
rhel-7.6
opensuse-leap
-ubuntu-18.04
-rhel-7.4
-opensuse-42.3
+ubuntu
[windowState]
# QTBUG-75270
winrt
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/button.png b/tests/auto/widgets/styles/qstyle/images/mac/button.png
deleted file mode 100644
index 7b11325e87..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/mac/button.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/combobox.png b/tests/auto/widgets/styles/qstyle/images/mac/combobox.png
deleted file mode 100644
index ded0b11f29..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/mac/combobox.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/lineedit.png b/tests/auto/widgets/styles/qstyle/images/mac/lineedit.png
deleted file mode 100644
index 8d2861b65b..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/mac/lineedit.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/mdi.png b/tests/auto/widgets/styles/qstyle/images/mac/mdi.png
deleted file mode 100644
index 8c09ae4338..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/mac/mdi.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/menu.png b/tests/auto/widgets/styles/qstyle/images/mac/menu.png
deleted file mode 100644
index 5dd9111d69..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/mac/menu.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/radiobutton.png b/tests/auto/widgets/styles/qstyle/images/mac/radiobutton.png
deleted file mode 100644
index 8828e220a2..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/mac/radiobutton.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/slider.png b/tests/auto/widgets/styles/qstyle/images/mac/slider.png
deleted file mode 100644
index fc65035631..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/mac/slider.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/mac/spinbox.png b/tests/auto/widgets/styles/qstyle/images/mac/spinbox.png
deleted file mode 100644
index ee88441ecb..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/mac/spinbox.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/button.png b/tests/auto/widgets/styles/qstyle/images/vista/button.png
deleted file mode 100644
index a6c45276ca..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/vista/button.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/combobox.png b/tests/auto/widgets/styles/qstyle/images/vista/combobox.png
deleted file mode 100644
index 9b82f64d32..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/vista/combobox.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/lineedit.png b/tests/auto/widgets/styles/qstyle/images/vista/lineedit.png
deleted file mode 100644
index b2c6ac1ae4..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/vista/lineedit.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/menu.png b/tests/auto/widgets/styles/qstyle/images/vista/menu.png
deleted file mode 100644
index b114099cc3..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/vista/menu.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/radiobutton.png b/tests/auto/widgets/styles/qstyle/images/vista/radiobutton.png
deleted file mode 100644
index c8aa7864df..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/vista/radiobutton.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/slider.png b/tests/auto/widgets/styles/qstyle/images/vista/slider.png
deleted file mode 100644
index 7c156ded9d..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/vista/slider.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/images/vista/spinbox.png b/tests/auto/widgets/styles/qstyle/images/vista/spinbox.png
deleted file mode 100644
index b8d0823ab2..0000000000
--- a/tests/auto/widgets/styles/qstyle/images/vista/spinbox.png
+++ /dev/null
Binary files differ
diff --git a/tests/auto/widgets/styles/qstyle/qstyle.pro b/tests/auto/widgets/styles/qstyle/qstyle.pro
index 9ad0940245..4dc0525c49 100644
--- a/tests/auto/widgets/styles/qstyle/qstyle.pro
+++ b/tests/auto/widgets/styles/qstyle/qstyle.pro
@@ -2,8 +2,3 @@ CONFIG += testcase
TARGET = tst_qstyle
QT += widgets testlib testlib-private
SOURCES += tst_qstyle.cpp
-
-android:!android-embedded {
- RESOURCES += \
- testdata.qrc
-}
diff --git a/tests/auto/widgets/styles/qstyle/testdata.qrc b/tests/auto/widgets/styles/qstyle/testdata.qrc
deleted file mode 100644
index 29bb46726e..0000000000
--- a/tests/auto/widgets/styles/qstyle/testdata.qrc
+++ /dev/null
@@ -1,19 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>images/mac/button.png</file>
- <file>images/mac/combobox.png</file>
- <file>images/mac/lineedit.png</file>
- <file>images/mac/mdi.png</file>
- <file>images/mac/menu.png</file>
- <file>images/mac/radiobutton.png</file>
- <file>images/mac/slider.png</file>
- <file>images/mac/spinbox.png</file>
- <file>images/vista/button.png</file>
- <file>images/vista/combobox.png</file>
- <file>images/vista/lineedit.png</file>
- <file>images/vista/menu.png</file>
- <file>images/vista/radiobutton.png</file>
- <file>images/vista/slider.png</file>
- <file>images/vista/spinbox.png</file>
- </qresource>
-</RCC>
diff --git a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp
index 68e672e16d..ae084310b1 100644
--- a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp
+++ b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp
@@ -73,7 +73,6 @@ public:
private:
bool testAllFunctions(QStyle *);
bool testScrollBarSubControls();
- void testPainting(QStyle *style, const QString &platform);
private slots:
void drawItemPixmap();
void init();
@@ -333,141 +332,15 @@ void tst_QStyle::testWindowsStyle()
delete wstyle;
}
-void writeImage(const QString &fileName, QImage image)
-{
- QImageWriter imageWriter(fileName);
- imageWriter.setFormat("png");
- qDebug() << "result " << imageWriter.write(image);
-}
-
-QImage readImage(const QString &fileName)
-{
- QImageReader reader(fileName);
- return reader.read();
-}
-
-
#if defined(Q_OS_WIN) && !defined(QT_NO_STYLE_WINDOWSVISTA) && !defined(Q_OS_WINRT)
void tst_QStyle::testWindowsVistaStyle()
{
QStyle *vistastyle = QStyleFactory::create("WindowsVista");
QVERIFY(testAllFunctions(vistastyle));
-
- if (QOperatingSystemVersion::current().majorVersion()
- == QOperatingSystemVersion::WindowsVista.majorVersion()
- && QOperatingSystemVersion::current().minorVersion()
- == QOperatingSystemVersion::WindowsVista.minorVersion())
- testPainting(vistastyle, "vista");
delete vistastyle;
}
#endif
-void comparePixmap(const QString &filename, const QPixmap &pixmap)
-{
- QImage oldFile = readImage(filename);
- QPixmap oldPixmap = QPixmap::fromImage(oldFile);
- if (!oldFile.isNull())
- QCOMPARE(pixmap, oldPixmap);
- else
- writeImage(filename, pixmap.toImage());
-}
-
-void tst_QStyle::testPainting(QStyle *style, const QString &platform)
-{
-qDebug("TEST PAINTING");
- //Test Menu
- QString fileName = "images/" + platform + "/menu.png";
- QMenu menu;
- menu.setStyle(style);
- menu.show();
- menu.addAction(new QAction("Test 1", &menu));
- menu.addAction(new QAction("Test 2", &menu));
- QPixmap pixmap = menu.grab();
- comparePixmap(fileName, pixmap);
-
- //Push button
- fileName = "images/" + platform + "/button.png";
- QPushButton button("OK");
- button.setStyle(style);
- button.show();
- pixmap = button.grab();
- button.hide();
- comparePixmap(fileName, pixmap);
-
- //Push button
- fileName = "images/" + platform + "/radiobutton.png";
- QRadioButton radiobutton("Check");
- radiobutton.setStyle(style);
- radiobutton.show();
- pixmap = radiobutton.grab();
- radiobutton.hide();
- comparePixmap(fileName, pixmap);
-
- //Combo box
- fileName = "images/" + platform + "/combobox.png";
- QComboBox combobox;
- combobox.setStyle(style);
- combobox.addItem("Test 1");
- combobox.addItem("Test 2");
- combobox.show();
- pixmap = combobox.grab();
- combobox.hide();
- comparePixmap(fileName, pixmap);
-
- //Spin box
- fileName = "images/" + platform + "/spinbox.png";
- QDoubleSpinBox spinbox;
- spinbox.setLocale(QLocale(QLocale::English, QLocale::UnitedStates));
- spinbox.setStyle(style);
- spinbox.show();
- pixmap = spinbox.grab();
- spinbox.hide();
- comparePixmap(fileName, pixmap);
- QLocale::setDefault(QLocale::system());
-
- //Slider
- fileName = "images/" + platform + "/slider.png";
- QSlider slider;
- slider.setStyle(style);
- slider.show();
- pixmap = slider.grab();
- slider.hide();
- comparePixmap(fileName, pixmap);
-
- //Line edit
- fileName = "images/" + platform + "/lineedit.png";
- QLineEdit lineedit("Test text");
- lineedit.setStyle(style);
- lineedit.show();
- pixmap = lineedit.grab();
- lineedit.hide();
- comparePixmap(fileName, pixmap);
-
- //MDI
- fileName = "images/" + platform + "/mdi.png";
- QMdiArea mdiArea;
- mdiArea.addSubWindow(new QWidget(&mdiArea));
- mdiArea.resize(200, 200);
- mdiArea.setStyle(style);
- mdiArea.show();
- pixmap = mdiArea.grab();
- mdiArea.hide();
- comparePixmap(fileName, pixmap);
-
- // QToolButton
- fileName = "images/" + platform + "/toolbutton.png";
- QToolButton tb;
- tb.setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
- tb.setText("AaQqPpXx");
- tb.setIcon(style->standardPixmap(QStyle::SP_DirHomeIcon));
- tb.setStyle(style);
- tb.show();
- pixmap = tb.grab();
- tb.hide();
- comparePixmap(fileName, pixmap);
-
-}
-
#ifdef Q_OS_MAC
void tst_QStyle::testMacStyle()
{
diff --git a/tests/auto/widgets/widgets/qframe/tst_qframe.cpp b/tests/auto/widgets/widgets/qframe/tst_qframe.cpp
index 432f4474c5..05f9cd2e4a 100644
--- a/tests/auto/widgets/widgets/qframe/tst_qframe.cpp
+++ b/tests/auto/widgets/widgets/qframe/tst_qframe.cpp
@@ -37,6 +37,10 @@
class tst_QFrame : public QObject
{
Q_OBJECT
+
+public:
+ static void initMain() { QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); }
+
private slots:
void testDefaults();
void testInitStyleOption_data();
diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
index 21c9f41646..76f8ebc804 100644
--- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
+++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
@@ -49,6 +49,9 @@ class tst_QOpenGLWidget : public QObject
{
Q_OBJECT
+public:
+ static void initMain() { QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); }
+
private slots:
void initTestCase();
void create();
diff --git a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp
index 570c7b59fa..b88669e9ce 100644
--- a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp
+++ b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp
@@ -183,6 +183,7 @@ void tst_QImageConversion::convertRgb32_data()
QTest::newRow("rgb32 -> rgb30") << rgb32 << QImage::Format_RGB30;
QTest::newRow("rgb32 -> a2bgr30") << rgb32 << QImage::Format_A2BGR30_Premultiplied;
QTest::newRow("rgb32 -> rgb888") << rgb32 << QImage::Format_RGB888;
+ QTest::newRow("rgb32 -> bgr888") << rgb32 << QImage::Format_BGR888;
QTest::newRow("rgb32 -> rgb666") << rgb32 << QImage::Format_RGB666;
QTest::newRow("rgb32 -> rgb555") << rgb32 << QImage::Format_RGB555;
QTest::newRow("rgb32 -> argb8565pm") << rgb32 << QImage::Format_ARGB8565_Premultiplied;
@@ -196,6 +197,7 @@ void tst_QImageConversion::convertRgb32_data()
QTest::newRow("argb32 -> rgb30") << argb32 << QImage::Format_RGB30;
QTest::newRow("argb32 -> a2bgr30") << argb32 << QImage::Format_A2BGR30_Premultiplied;
QTest::newRow("argb32 -> rgb888") << argb32 << QImage::Format_RGB888;
+ QTest::newRow("argb32 -> bgr888") << argb32 << QImage::Format_BGR888;
QTest::newRow("argb32 -> rgb666") << argb32 << QImage::Format_RGB666;
QTest::newRow("argb32 -> argb8565pm") << argb32 << QImage::Format_ARGB8565_Premultiplied;
QTest::newRow("argb32 -> argb4444pm") << argb32 << QImage::Format_ARGB4444_Premultiplied;
@@ -212,6 +214,7 @@ void tst_QImageConversion::convertRgb32_data()
QTest::newRow("argb32pm -> rgb30") << argb32pm << QImage::Format_RGB30;
QTest::newRow("argb32pm -> a2bgr30") << argb32pm << QImage::Format_A2BGR30_Premultiplied;
QTest::newRow("argb32pm -> rgb888") << argb32pm << QImage::Format_RGB888;
+ QTest::newRow("argb32pm -> bgr888") << argb32pm << QImage::Format_BGR888;
QTest::newRow("argb32pm -> rgb666") << argb32pm << QImage::Format_RGB666;
QTest::newRow("argb32pm -> argb8565pm") << argb32pm << QImage::Format_ARGB8565_Premultiplied;
QTest::newRow("argb32pm -> argb4444pm") << argb32pm << QImage::Format_ARGB4444_Premultiplied;
@@ -242,6 +245,8 @@ void tst_QImageConversion::convertGeneric_data()
QImage rgb666 = rgb32.convertToFormat(QImage::Format_RGB666);
QImage argb4444 = argb32.convertToFormat(QImage::Format_ARGB4444_Premultiplied);
QImage rgba64pm = argb32.convertToFormat(QImage::Format_RGBA64_Premultiplied);
+ QImage rgb888 = rgb32.convertToFormat(QImage::Format_RGB888);
+ QImage bgr888 = rgb32.convertToFormat(QImage::Format_BGR888);
QTest::newRow("indexed8 -> rgb32") << i8 << QImage::Format_RGB32;
QTest::newRow("indexed8 -> argb32") << i8 << QImage::Format_ARGB32;
@@ -299,6 +304,20 @@ void tst_QImageConversion::convertGeneric_data()
QTest::newRow("rgba64pm -> rgb30") << rgba64pm << QImage::Format_RGB30;
QTest::newRow("rgba64pm -> a2bgr30") << rgba64pm << QImage::Format_A2BGR30_Premultiplied;
QTest::newRow("rgba64pm -> rgba64") << rgba64pm << QImage::Format_RGBA64;
+
+ QTest::newRow("rgb888 -> rgb32") << rgb888 << QImage::Format_RGB32;
+ QTest::newRow("rgb888 -> argb32") << rgb888 << QImage::Format_ARGB32;
+ QTest::newRow("rgb888 -> argb32pm") << rgb888 << QImage::Format_ARGB32_Premultiplied;
+ QTest::newRow("rgb888 -> rgbx8888") << rgb888 << QImage::Format_RGBX8888;
+ QTest::newRow("rgb888 -> rgba8888pm") << rgb888 << QImage::Format_RGBA8888_Premultiplied;
+ QTest::newRow("rgb888 -> bgr888") << rgb888 << QImage::Format_BGR888;
+
+ QTest::newRow("bgr888 -> rgb32") << bgr888 << QImage::Format_RGB32;
+ QTest::newRow("bgr888 -> argb32") << bgr888 << QImage::Format_ARGB32;
+ QTest::newRow("bgr888 -> argb32pm") << bgr888 << QImage::Format_ARGB32_Premultiplied;
+ QTest::newRow("bgr888 -> rgbx8888") << bgr888 << QImage::Format_RGBX8888;
+ QTest::newRow("bgr888 -> rgba8888pm") << bgr888 << QImage::Format_RGBA8888_Premultiplied;
+ QTest::newRow("bgr888 -> rgb888") << bgr888 << QImage::Format_RGB888;
}
void tst_QImageConversion::convertGeneric()
@@ -323,6 +342,7 @@ void tst_QImageConversion::convertGenericInplace_data()
QImage argb6666 = argb32.convertToFormat(QImage::Format_ARGB6666_Premultiplied);
QImage argb4444 = argb32.convertToFormat(QImage::Format_ARGB4444_Premultiplied);
QImage rgb16 = argb32.convertToFormat(QImage::Format_RGB16);
+ QImage rgb888 = argb32.convertToFormat(QImage::Format_RGB888);
QTest::newRow("argb32 -> argb32pm -> argb32") << argb32 << QImage::Format_ARGB32_Premultiplied;
QTest::newRow("argb32 -> rgb32 -> argb32") << argb32 << QImage::Format_RGB32;
@@ -349,6 +369,8 @@ void tst_QImageConversion::convertGenericInplace_data()
QTest::newRow("rgb16 -> rgb555 -> rgb16") << rgb16 << QImage::Format_RGB555;
QTest::newRow("rgb16 -> rgb444 -> rgb16") << rgb16 << QImage::Format_RGB444;
QTest::newRow("rgb16 -> argb4444pm -> rgb16") << rgb16 << QImage::Format_ARGB4444_Premultiplied;
+
+ QTest::newRow("rgb888 -> bgr888 -> rgb888") << rgb888 << QImage::Format_BGR888;
}
void tst_QImageConversion::convertGenericInplace()
diff --git a/tests/benchmarks/gui/image/qimagereader/qimagereader.pro b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro
index 29f7f6b16e..3454cf1474 100644
--- a/tests/benchmarks/gui/image/qimagereader/qimagereader.pro
+++ b/tests/benchmarks/gui/image/qimagereader/qimagereader.pro
@@ -8,3 +8,5 @@ SOURCES += tst_qimagereader.cpp
qtConfig(gif): DEFINES += QTEST_HAVE_GIF
qtConfig(jpeg): DEFINES += QTEST_HAVE_JPEG
+
+TESTDATA += images/*
diff --git a/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp b/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp
index d81d5bb01a..48e838148f 100644
--- a/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/benchmarks/gui/image/qimagereader/tst_qimagereader.cpp
@@ -51,6 +51,7 @@ public:
virtual ~tst_QImageReader();
public slots:
+ void initTestCase();
void init();
void cleanup();
@@ -69,6 +70,7 @@ private slots:
private:
QList< QPair<QString, QByteArray> > images; // filename, format
+ QString prefix;
};
tst_QImageReader::tst_QImageReader()
@@ -102,6 +104,13 @@ tst_QImageReader::~tst_QImageReader()
{
}
+void tst_QImageReader::initTestCase()
+{
+ prefix = QFINDTESTDATA("images/");
+ if (prefix.isEmpty())
+ QFAIL("Can't find images directory!");
+}
+
void tst_QImageReader::init()
{
}
@@ -128,7 +137,7 @@ void tst_QImageReader::readImage()
QFETCH(QByteArray, format);
QBENCHMARK {
- QImageReader io("images/" + fileName, format);
+ QImageReader io(prefix + fileName, format);
QImage image = io.read();
QVERIFY(!image.isNull());
}
@@ -159,7 +168,7 @@ void tst_QImageReader::setScaledSize()
QFETCH(QByteArray, format);
QBENCHMARK {
- QImageReader reader("images/" + fileName, format);
+ QImageReader reader(prefix + fileName, format);
reader.setScaledSize(newSize);
QImage image = reader.read();
QCOMPARE(image.size(), newSize);
@@ -186,7 +195,7 @@ void tst_QImageReader::setClipRect()
QFETCH(QByteArray, format);
QBENCHMARK {
- QImageReader reader("images/" + fileName, format);
+ QImageReader reader(prefix + fileName, format);
reader.setClipRect(newRect);
QImage image = reader.read();
QCOMPARE(image.rect(), newRect);
@@ -205,7 +214,7 @@ void tst_QImageReader::setScaledClipRect()
QFETCH(QByteArray, format);
QBENCHMARK {
- QImageReader reader("images/" + fileName, format);
+ QImageReader reader(prefix + fileName, format);
reader.setScaledSize(QSize(300, 300));
reader.setScaledClipRect(newRect);
QImage image = reader.read();