summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-10-24 12:48:39 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-10-24 12:48:42 +0200
commit840f6a40e6218992b5b9d451ee3c0886a4846c89 (patch)
tree2b808decc7adf5218b810d2de6b45c5a8b4cfc42
parent109bf980b37fed405c6c1eb14cb9c83ff897e389 (diff)
parent2e3870fe37d36ccf4bd84eb90e1d5e08ad00c1bc (diff)
Merge remote-tracking branch 'origin/stable' into dev
-rw-r--r--config.tests/mac/coreservices/coreservices.pro3
-rw-r--r--config.tests/unix/ptrsize/ptrsizetest.pro1
-rwxr-xr-xconfigure45
-rw-r--r--dist/changes-5.2.019
-rw-r--r--examples/gui/gui.pro2
-rw-r--r--examples/qpa/qpa.pro2
-rw-r--r--examples/qtconcurrent/map/main.cpp22
-rw-r--r--examples/qtconcurrent/qtconcurrent.pro5
-rw-r--r--examples/threads/semaphores/semaphores.cpp2
-rw-r--r--examples/threads/semaphores/semaphores.pro2
-rw-r--r--examples/threads/waitconditions/waitconditions.cpp2
-rw-r--r--examples/threads/waitconditions/waitconditions.pro2
-rw-r--r--mkspecs/android-g++/qmake.conf2
-rw-r--r--mkspecs/blackberry-armle-v7-qcc/qmake.conf22
-rw-r--r--mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h (renamed from config.tests/mac/coreservices/coreservices.mm)12
-rw-r--r--mkspecs/blackberry-armv7le-qcc/qmake.conf23
-rw-r--r--mkspecs/blackberry-armv7le-qcc/qplatformdefs.h4
-rw-r--r--mkspecs/common/shell-win32.conf1
-rw-r--r--mkspecs/devices/blackberry-playbook-armle-v7-qcc/qmake.conf8
-rw-r--r--mkspecs/devices/blackberry-playbook-armle-v7-qcc/qplatformdefs.h42
-rw-r--r--mkspecs/devices/blackberry-playbook-armv7le-qcc/qmake.conf9
-rw-r--r--mkspecs/devices/blackberry-playbook-armv7le-qcc/qplatformdefs.h2
-rw-r--r--mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp10
-rw-r--r--mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp86
-rw-r--r--mkspecs/features/android/android_deployment_settings.prf4
-rw-r--r--mkspecs/features/create_cmake.prf18
-rw-r--r--mkspecs/features/data/cmake/ExtraSourceIncludes.cmake.in7
-rw-r--r--mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in7
-rw-r--r--mkspecs/features/default_post.prf12
-rw-r--r--mkspecs/features/egl.prf2
-rw-r--r--mkspecs/features/ios/default_pre.prf9
-rw-r--r--mkspecs/features/ios/qt.prf75
-rw-r--r--mkspecs/features/mac/default_pre.prf6
-rw-r--r--mkspecs/features/qml_plugin.prf5
-rw-r--r--mkspecs/features/qt.prf82
-rw-r--r--mkspecs/features/qt_config.prf1
-rw-r--r--mkspecs/features/qt_functions.prf4
-rw-r--r--mkspecs/features/resolve_config.prf37
-rw-r--r--mkspecs/features/testcase.prf45
-rw-r--r--mkspecs/features/unix/default_pre.prf4
-rw-r--r--mkspecs/linux-icc/qmake.conf1
-rw-r--r--mkspecs/macx-ios-clang/features/default_post.prf (renamed from mkspecs/features/ios/default_post.prf)20
-rw-r--r--mkspecs/macx-ios-clang/features/default_pre.prf6
-rw-r--r--mkspecs/macx-ios-clang/features/qt.prf49
-rw-r--r--mkspecs/macx-ios-clang/features/qt_config.prf12
-rw-r--r--mkspecs/macx-ios-clang/qmake.conf5
-rw-r--r--mkspecs/macx-xcode/features/default_post.prf7
-rw-r--r--mkspecs/macx-xcode/qmake.conf8
-rw-r--r--qmake/Makefile.unix27
-rw-r--r--qmake/Makefile.win3213
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp83
-rw-r--r--qmake/generators/makefile.cpp6
-rw-r--r--qmake/generators/unix/unixmake.cpp14
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp2
-rw-r--r--qmake/generators/win32/winmakefile.cpp16
-rw-r--r--qmake/library/qmakebuiltins.cpp91
-rw-r--r--qmake/library/qmakeevaluator.cpp41
-rw-r--r--qmake/library/qmakeevaluator.h1
-rw-r--r--qmake/library/qmakeevaluator_p.h1
-rw-r--r--qmake/main.cpp128
-rw-r--r--qmake/qmake.pri17
-rw-r--r--qmake/qmake.pro1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp2
-rw-r--r--src/android/java/AndroidManifest.xml16
-rw-r--r--src/android/java/res/values/libs.xml1
-rw-r--r--src/android/java/res/values/strings.xml4
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java8
-rw-r--r--src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch2
-rw-r--r--src/corelib/codecs/qutfcodec.cpp13
-rw-r--r--src/corelib/doc/snippets/code/doc_src_containers.cpp30
-rw-r--r--src/corelib/doc/snippets/qloggingcategory/main.cpp44
-rw-r--r--src/corelib/doc/src/containers.qdoc14
-rw-r--r--src/corelib/doc/src/implicit-sharing.qdoc20
-rw-r--r--src/corelib/doc/src/objectmodel/signalsandslots.qdoc1
-rw-r--r--src/corelib/doc/src/threads-basics.qdoc25
-rw-r--r--src/corelib/doc/src/threads.qdoc118
-rw-r--r--src/corelib/global/qcompilerdetection.h20
-rw-r--r--src/corelib/global/qglobal.cpp36
-rw-r--r--src/corelib/global/qglobal.h18
-rw-r--r--src/corelib/global/qglobalstatic.h9
-rw-r--r--src/corelib/global/qlibraryinfo.cpp4
-rw-r--r--src/corelib/global/qlogging.cpp10
-rw-r--r--src/corelib/global/qnamespace.h22
-rw-r--r--src/corelib/global/qnamespace.qdoc2
-rw-r--r--src/corelib/io/qfileinfo.cpp5
-rw-r--r--src/corelib/io/qfileinfo_p.h14
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp14
-rw-r--r--src/corelib/io/qiodevice.cpp8
-rw-r--r--src/corelib/io/qlockfile_unix.cpp17
-rw-r--r--src/corelib/io/qloggingcategory.cpp87
-rw-r--r--src/corelib/io/qloggingcategory.h6
-rw-r--r--src/corelib/io/qurl.cpp17
-rw-r--r--src/corelib/io/qurlrecode.cpp5
-rw-r--r--src/corelib/json/qjsonarray.cpp2
-rw-r--r--src/corelib/json/qjsonarray.h2
-rw-r--r--src/corelib/json/qjsondocument.cpp6
-rw-r--r--src/corelib/json/qjsondocument.h4
-rw-r--r--src/corelib/json/qjsonobject.cpp2
-rw-r--r--src/corelib/json/qjsonobject.h2
-rw-r--r--src/corelib/json/qjsonparser.cpp2
-rw-r--r--src/corelib/json/qjsonvalue.cpp2
-rw-r--r--src/corelib/json/qjsonvalue.h2
-rw-r--r--src/corelib/json/qjsonwriter.cpp7
-rw-r--r--src/corelib/kernel/qcoreevent.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry.cpp90
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry_p.h4
-rw-r--r--src/corelib/kernel/qvariant.cpp7
-rw-r--r--src/corelib/thread/qthread.cpp29
-rw-r--r--src/corelib/tools/qalgorithms.qdoc2
-rw-r--r--src/corelib/tools/qcollator_posix.cpp3
-rw-r--r--src/corelib/tools/qdatetime.cpp61
-rw-r--r--src/corelib/tools/qhash.cpp10
-rw-r--r--src/corelib/tools/qlinkedlist.cpp14
-rw-r--r--src/corelib/tools/qlist.cpp34
-rw-r--r--src/corelib/tools/qlist.h2
-rw-r--r--src/corelib/tools/qlocale_mac.mm4
-rw-r--r--src/corelib/tools/qmap.cpp25
-rw-r--r--src/corelib/tools/qmargins.h18
-rw-r--r--src/corelib/tools/qset.qdoc14
-rw-r--r--src/corelib/tools/qstring.cpp4
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp4
-rw-r--r--src/corelib/tools/qvector.cpp48
-rw-r--r--src/corelib/tools/qvector.h23
-rw-r--r--src/gui/accessible/qaccessible.h2
-rw-r--r--src/gui/kernel/qevent.cpp115
-rw-r--r--src/gui/kernel/qevent.h28
-rw-r--r--src/gui/kernel/qguiapplication.cpp22
-rw-r--r--src/gui/kernel/qguiapplication_p.h1
-rw-r--r--src/gui/kernel/qguivariant.cpp3
-rw-r--r--src/gui/kernel/qplatformtheme.cpp4
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp4
-rw-r--r--src/gui/kernel/qwindow.cpp2
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp29
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h9
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h16
-rw-r--r--src/gui/opengl/qopengltexture.cpp2
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.cpp50
-rw-r--r--src/gui/text/qfontdatabase.h2
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp6
-rw-r--r--src/gui/text/qfontengine.cpp10
-rw-r--r--src/gui/text/qfontengine_p.h1
-rw-r--r--src/gui/text/qtextdocument.cpp23
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp13
-rw-r--r--src/gui/text/qtextengine.cpp3
-rw-r--r--src/gui/text/qtexthtmlparser.cpp4
-rw-r--r--src/gui/text/qtextlayout.cpp23
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp18
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h5
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp4
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp15
-rw-r--r--src/network/kernel/qhostinfo_unix.cpp15
-rw-r--r--src/opengl/qgl.cpp5
-rw-r--r--src/platformsupport/fbconvenience/qfbcursor.cpp9
-rw-r--r--src/platformsupport/fbconvenience/qfbcursor_p.h2
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen.cpp13
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen_p.h15
-rw-r--r--src/platformsupport/fbconvenience/qfbwindow.cpp20
-rw-r--r--src/platformsupport/fbconvenience/qfbwindow_p.h3
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h28
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouch.cpp15
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.cpp228
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.h23
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp10
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.h2
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp1
-rw-r--r--src/plugins/platforms/android/src/androidjniaccessibility.cpp18
-rw-r--r--src/plugins/platforms/android/src/androidjniinput.cpp57
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.cpp7
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformintegration.cpp1
-rw-r--r--src/plugins/platforms/android/src/qandroidplatformmenu.cpp8
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm42
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm129
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp4
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm18
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp11
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h14
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp37
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.h5
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp10
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp4
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h3
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp33
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.h1
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp2
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport.cpp23
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport_p.h2
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintersupport.cpp52
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintersupport.h4
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix.cpp1
-rw-r--r--src/printsupport/kernel/qcups.cpp15
-rw-r--r--src/printsupport/kernel/qcups_p.h1
-rw-r--r--src/src.pro8
-rw-r--r--src/testlib/doc/src/qttest-index.qdoc1
-rw-r--r--src/testlib/qtestmouse.h2
-rw-r--r--src/tools/moc/generator.cpp2
-rw-r--r--src/tools/qdoc/main.cpp48
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp266
-rw-r--r--src/widgets/dialogs/qfiledialog_p.h6
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicsitemanimation.cpp63
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp54
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h2
-rw-r--r--src/widgets/itemviews/qheaderview.cpp9
-rw-r--r--src/widgets/itemviews/qlistview.cpp62
-rw-r--r--src/widgets/itemviews/qlistview_p.h9
-rw-r--r--src/widgets/itemviews/qtableview.cpp18
-rw-r--r--src/widgets/itemviews/qtableview_p.h2
-rw-r--r--src/widgets/itemviews/qtreeview.cpp8
-rw-r--r--src/widgets/kernel/kernel.pri56
-rw-r--r--src/widgets/kernel/qgesture_p.h35
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp6
-rw-r--r--src/widgets/kernel/qmacgesturerecognizer.cpp275
-rw-r--r--src/widgets/kernel/qmacgesturerecognizer_p.h102
-rw-r--r--src/widgets/kernel/qsizepolicy.qdoc2
-rw-r--r--src/widgets/kernel/qwidget.cpp16
-rw-r--r--src/widgets/kernel/qwidget_p.h1
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp33
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa_p.h4
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp173
-rw-r--r--src/widgets/kernel/qwindowcontainer_p.h5
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp2
-rw-r--r--src/widgets/util/qsystemtrayicon.h4
-rw-r--r--src/widgets/widgets.pro4
-rw-r--r--src/widgets/widgets/qdockwidget.cpp10
-rw-r--r--src/widgets/widgets/qstatusbar.cpp5
-rwxr-xr-xtests/auto/android/runtests.pl2
-rwxr-xr-xtests/auto/android/runtests_androiddeployqt.pl323
-rw-r--r--tests/auto/auto.pro1
-rw-r--r--tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro2
-rw-r--r--tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro2
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/test/test.pro2
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp57
-rw-r--r--tests/auto/corelib/codecs/utf8/tst_utf8.cpp20
-rw-r--r--tests/auto/corelib/codecs/utf8/utf8data.cpp4
-rw-r--r--tests/auto/corelib/global/qlogging/app/main.cpp4
-rw-r--r--tests/auto/corelib/global/qlogging/tst_qlogging.cpp17
-rw-r--r--tests/auto/corelib/io/io.pro4
-rw-r--r--tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp32
-rw-r--r--tests/auto/corelib/io/qsettings/tst_qsettings.cpp10
-rw-r--r--tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp7
-rw-r--r--tests/auto/corelib/itemmodels/itemmodels.pro4
-rw-r--r--tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro2
-rw-r--r--tests/auto/corelib/json/tst_qtjson.cpp24
-rw-r--r--tests/auto/corelib/kernel/kernel.pro3
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro2
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp16
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro2
-rw-r--r--tests/auto/corelib/kernel/qpointer/qpointer.pro2
-rw-r--r--tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro2
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro1
-rw-r--r--tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro1
-rw-r--r--tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro1
-rw-r--r--tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro2
-rw-r--r--tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro2
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp25
-rw-r--r--tests/auto/corelib/tools/qmargins/tst_qmargins.cpp6
-rw-r--r--tests/auto/corelib/tools/qtimezone/qtimezone.pro2
-rw-r--r--tests/auto/dbus/qdbusmarshall/qdbusmarshall.pro2
-rw-r--r--tests/auto/gui/kernel/qguivariant/test/data/qpolygonf.binbin0 -> 103 bytes
-rw-r--r--tests/auto/gui/kernel/qguivariant/test/qguivariant.qrc5
-rw-r--r--tests/auto/gui/kernel/qguivariant/test/test.pro1
-rw-r--r--tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp43
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp2
-rw-r--r--tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp4
-rw-r--r--tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp48
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp2
-rw-r--r--tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp2
-rw-r--r--tests/auto/other/modeltest/modeltest.cpp4
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp135
-rw-r--r--tests/auto/testlib/selftests/cmptest/cmptest.pro3
-rw-r--r--tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp6
-rw-r--r--tests/auto/tools/qmake/testdata/json/json.pro26
-rw-r--r--tests/auto/tools/qmake/testdata/json/test.json9
-rw-r--r--tests/auto/tools/qmake/tst_qmake.cpp29
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp17
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp20
-rw-r--r--tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp4
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp4
-rw-r--r--tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp62
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp20
-rw-r--r--tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp12
-rw-r--r--tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp27
-rw-r--r--tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp99
-rw-r--r--tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref2
-rw-r--r--tests/benchmarks/corelib/tools/qstring/main.cpp18
-rw-r--r--tools/configure/configureapp.cpp7
293 files changed, 4373 insertions, 1662 deletions
diff --git a/config.tests/mac/coreservices/coreservices.pro b/config.tests/mac/coreservices/coreservices.pro
deleted file mode 100644
index 64936eb974..0000000000
--- a/config.tests/mac/coreservices/coreservices.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-OBJECTIVE_SOURCES = coreservices.mm
-LIBS += -framework CoreServices
-CONFIG -= qt
diff --git a/config.tests/unix/ptrsize/ptrsizetest.pro b/config.tests/unix/ptrsize/ptrsizetest.pro
index 045a759ec9..a7ae38a5d9 100644
--- a/config.tests/unix/ptrsize/ptrsizetest.pro
+++ b/config.tests/unix/ptrsize/ptrsizetest.pro
@@ -1,2 +1,3 @@
SOURCES = ptrsizetest.cpp
CONFIG -= qt dylib
+CONFIG += debug console
diff --git a/configure b/configure
index 83bbf725af..fcd9f08ed1 100755
--- a/configure
+++ b/configure
@@ -1609,8 +1609,8 @@ while [ "$#" -gt 0 ]; do
[ "$XPLATFORM" = "undefined" ] && exit 101
;;
device-option)
- DEV_VAR=`echo $VAL | sed "s,^\(.*\)=.*,\1,"`
- DEV_VAL=`echo $VAL | sed "s,^.*=\(.*\),\1,"`
+ DEV_VAR=`echo $VAL | cut -d '=' -f 1`
+ DEV_VAL=`echo $VAL | cut -d '=' -f 2-`
DeviceVar set $DEV_VAR "$DEV_VAL"
;;
qpa)
@@ -2882,7 +2882,7 @@ if [ "$XPLATFORM_IOS" = "yes" ]; then
CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples tests"
CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store
CFG_CXX11="no" # C++11 support disabled for now
- CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtgraphicaleffects qtlocation qtmultimedia qtquickcontrols qtserialport qttools qtwebkit qtwebkit-examples"
+ CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtgraphicaleffects qtlocation qtmacextras qtmultimedia qtquickcontrols qtserialport qttools qtwebkit qtwebkit-examples"
fi
# disable GTK style support auto-detection on Mac
@@ -3032,6 +3032,21 @@ unset tty
eval `LC_ALL=C $TEST_COMPILER $SYSROOT_FLAG $TEST_COMPILER_CXXFLAGS -xc++ -E -v - < /dev/null 2>&1 > /dev/null | $AWK '
BEGIN { ORS = ""; FS = "="; incs = 0; libs = 0; }
+
+function normalize(dir)
+{
+ do {
+ odir = dir
+ gsub(/\\/[^\\/]+\\/\\.\\./, "", dir)
+ } while (dir != odir);
+ do {
+ odir = dir
+ gsub(/\\/\\./, "", dir)
+ } while (dir != odir);
+ sub("/$", "", dir);
+ return dir;
+}
+
function quote(s)
{
# We only handle spaces
@@ -3047,14 +3062,19 @@ function quote(s)
/^\#include </ { yup=1; print "DEFAULT_INCDIRS=\""; next }
/^End of search/ { yup=0; print "\"\n" }
/ \(framework directory\)$/ { next }
-yup { print quote(substr($0, 2)) " "; ++incs }
+yup { print quote(normalize(substr($0, 2))) " "; ++incs }
# extract from one line like LIBRARY_PATH=/one/path:/another/path:...
$1 == "LIBRARY_PATH" {
libs = split($2, library_paths, ":");
print "DEFAULT_LIBDIRS=\"";
- for (lib in library_paths)
- print quote(library_paths[lib]) " ";
+ for (lib in library_paths) {
+ dir = normalize(library_paths[lib]);
+ if (!(dir in dirs)) {
+ print quote(dir) " ";
+ dirs[dir] = 1;
+ }
+ }
print "\"\n"
}
@@ -4230,7 +4250,7 @@ fi
#-------------------------------------------------------------------------------
# Verify makespec
#-------------------------------------------------------------------------------
-QMAKE_OUTPUT=`$outpath/bin/qmake -E -nocache -spec "$XQMAKESPEC" "QT=" $DEV_NULL 2>&1 >/dev/null`
+QMAKE_OUTPUT=`$outpath/bin/qmake -E -nocache -spec "$XQMAKESPEC" "QT=" $DEV_NULL 2>&1`
if [ $? != "0" ]; then
echo "Failed to process makespec for platform '$XPLATFORM'"
if [ "$OPT_VERBOSE" = "yes" ]; then
@@ -5501,6 +5521,7 @@ elif [ "$CFG_EGL" != "no" ]; then
QMAKE_CFLAGS_EGL=`$PKG_CONFIG --cflags egl 2>/dev/null`
QMakeVar set QMAKE_INCDIR_EGL "$QMAKE_INCDIR_EGL"
QMakeVar set QMAKE_LIBS_EGL "$QMAKE_LIBS_EGL"
+ QMakeVar set QMAKE_CFLAGS_EGL "`echo " $QMAKE_CFLAGS_EGL " | sed -e 's, -I[^ ]* , ,g;s,^ ,,;s, $,,'`"
fi # detect EGL support
if compileTest qpa/egl "EGL" $QMAKE_CFLAGS_EGL $QMAKE_LIBS_EGL; then
CFG_EGL=yes
@@ -5582,14 +5603,6 @@ if [ "$CFG_KMS" = "yes" ]; then
QT_CONFIG="$QT_CONFIG kms"
fi
-if [ "$BUILD_ON_MAC" = "yes" ]; then
- if compileTest mac/coreservices "CoreServices"; then
- QT_CONFIG="$QT_CONFIG coreservices"
- else
- QMakeVar add DEFINES QT_NO_CORESERVICES
- fi
-fi
-
if [ "$BUILD_ON_MAC" = "no" ] && [ "$XPLATFORM_MINGW" = "no" ] && [ "$XPLATFORM_QNX" = "no" ] && [ "$XPLATFORM_ANDROID" = "no" ]; then
if [ "$CFG_XCB" = "no" ] && [ "$CFG_EGLFS" = "no" ] && [ "$CFG_DIRECTFB" = "no" ] && [ "$CFG_LINUXFB" = "no" ] && [ "$CFG_KMS" = "no" ]; then
if [ "$QPA_PLATFORM_GUARD" = "yes" ] &&
@@ -6898,7 +6911,7 @@ report_support " FreeType ..............." "$CFG_FREETYPE"
report_support " Iconv .................." "$CFG_ICONV"
report_support " ICU ...................." "$CFG_ICU"
report_support " Image formats:"
-report_support_plugin " GIF .................." "$CFG_GIF" system QtGui
+report_support_plugin " GIF .................." "$CFG_GIF" qt QtGui
report_support_plugin " JPEG ................." "$CFG_JPEG" "$CFG_LIBJPEG" QtGui
report_support_plugin " PNG .................." "$CFG_PNG" "$CFG_LIBPNG" QtGui
report_support " Glib ..................." "$CFG_GLIB"
diff --git a/dist/changes-5.2.0 b/dist/changes-5.2.0
index a8a3e581de..a3a7db8190 100644
--- a/dist/changes-5.2.0
+++ b/dist/changes-5.2.0
@@ -84,3 +84,22 @@ QtGui
related to session management. For platform that don't support this
feature the default behavior has not changed.
Both X11 and Windows session management are supported.
+
+QtNetwork
+---------
+
+- API was added to store and resume TLS session tickets.
+
+- The minimum support openssl version has been increased to openssl 1.0. The
+ code to support older versions has not been removed, but is no longer
+ supported.
+
+- An off-by-one error in NTLM proxy authentication has been fixed.
+
+- Various improvements to reduce the memory used by qtnetwork have been made.
+
+- Improved support for HTTP proxy authentication.
+
+- Support for preconnecting to servers before making HTTP and HTTPS
+ connections. This allows for much reduced latency when the hosts to be
+ connected to are known.
diff --git a/examples/gui/gui.pro b/examples/gui/gui.pro
index 8758a1ba95..5fb4241e74 100644
--- a/examples/gui/gui.pro
+++ b/examples/gui/gui.pro
@@ -1,3 +1,5 @@
+requires(qtHaveModule(gui))
+
TEMPLATE = subdirs
CONFIG += no_docs_target
diff --git a/examples/qpa/qpa.pro b/examples/qpa/qpa.pro
index 6f07e50fd8..27293482ef 100644
--- a/examples/qpa/qpa.pro
+++ b/examples/qpa/qpa.pro
@@ -1,2 +1,4 @@
+requires(qtHaveModule(gui))
+
TEMPLATE = subdirs
SUBDIRS = windows
diff --git a/examples/qtconcurrent/map/main.cpp b/examples/qtconcurrent/map/main.cpp
index 199273b9a6..01595f0c2e 100644
--- a/examples/qtconcurrent/map/main.cpp
+++ b/examples/qtconcurrent/map/main.cpp
@@ -45,8 +45,6 @@
#include <QGuiApplication>
#include <qtconcurrentmap.h>
-#ifndef QT_NO_CONCURRENT
-
QImage scale(const QImage &image)
{
qDebug() << "Scaling image in thread" << QThread::currentThread();
@@ -70,23 +68,3 @@ int main(int argc, char *argv[])
return 0;
}
-
-#else
-
-#include <QLabel>
-
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
- QString text("Qt Concurrent is not yet supported on this platform");
-
- QLabel *label = new QLabel(text);
- label->setWordWrap(true);
-
- label->show();
- qDebug() << text;
-
- app.exec();
-}
-
-#endif
diff --git a/examples/qtconcurrent/qtconcurrent.pro b/examples/qtconcurrent/qtconcurrent.pro
index 1df6f2d8cf..6e4e5f0f16 100644
--- a/examples/qtconcurrent/qtconcurrent.pro
+++ b/examples/qtconcurrent/qtconcurrent.pro
@@ -10,6 +10,11 @@ SUBDIRS = imagescaling \
SUBDIRS += progressdialog
}
+!qtHaveModule(gui) {
+ SUBDIRS -= \
+ map
+}
+
!qtHaveModule(widgets) {
SUBDIRS -= \
imagescaling \
diff --git a/examples/threads/semaphores/semaphores.cpp b/examples/threads/semaphores/semaphores.cpp
index f7b25238f6..fb7f1f2376 100644
--- a/examples/threads/semaphores/semaphores.cpp
+++ b/examples/threads/semaphores/semaphores.cpp
@@ -38,7 +38,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtCore>
#include <stdio.h>
#include <stdlib.h>
diff --git a/examples/threads/semaphores/semaphores.pro b/examples/threads/semaphores/semaphores.pro
index 71bc5b3f35..7dfe7c3ba0 100644
--- a/examples/threads/semaphores/semaphores.pro
+++ b/examples/threads/semaphores/semaphores.pro
@@ -1,5 +1,5 @@
SOURCES += semaphores.cpp
-QT = core gui
+QT = core
CONFIG -= app_bundle
CONFIG += console
diff --git a/examples/threads/waitconditions/waitconditions.cpp b/examples/threads/waitconditions/waitconditions.cpp
index 3921334d42..6f5f56e737 100644
--- a/examples/threads/waitconditions/waitconditions.cpp
+++ b/examples/threads/waitconditions/waitconditions.cpp
@@ -38,7 +38,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtCore>
#include <stdio.h>
#include <stdlib.h>
diff --git a/examples/threads/waitconditions/waitconditions.pro b/examples/threads/waitconditions/waitconditions.pro
index c8de0b3774..7f9491a0b1 100644
--- a/examples/threads/waitconditions/waitconditions.pro
+++ b/examples/threads/waitconditions/waitconditions.pro
@@ -1,4 +1,4 @@
-QT = core gui
+QT = core
CONFIG -= moc app_bundle
CONFIG += console
diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf
index 0df2509257..11d62a1efb 100644
--- a/mkspecs/android-g++/qmake.conf
+++ b/mkspecs/android-g++/qmake.conf
@@ -178,7 +178,7 @@ QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
QMAKE_LFLAGS_RPATH = -Wl,-rpath=
QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link=
-QMAKE_LIBS = -lgnustl_shared -lsupc++ -llog -lz -lm -ldl -lc -lgcc
+QMAKE_LIBS_PRIVATE = -lgnustl_shared -llog -lz -lm -ldl -lc -lgcc
QMAKE_LIBS_X11 =
QMAKE_LIBS_THREAD =
QMAKE_LIBS_EGL = -lEGL
diff --git a/mkspecs/blackberry-armle-v7-qcc/qmake.conf b/mkspecs/blackberry-armle-v7-qcc/qmake.conf
new file mode 100644
index 0000000000..2e24e4e0d3
--- /dev/null
+++ b/mkspecs/blackberry-armle-v7-qcc/qmake.conf
@@ -0,0 +1,22 @@
+#
+# qmake configuration for blackberry armv7le systems
+#
+
+load(qt_config)
+
+DEFINES += Q_OS_BLACKBERRY
+CONFIG += blackberry
+LIBS += -lbps
+
+# Blackberry also has support for stack smashing protection in its libc
+contains(QT_CONFIG, stack-protector-strong) {
+ QMAKE_CFLAGS += -fstack-protector-strong
+} else {
+ QMAKE_CFLAGS += -fstack-protector -fstack-protector-all
+}
+
+QMAKE_CFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mthumb -D_FORTIFY_SOURCE=2
+
+QMAKE_LFLAGS_SHLIB += -Wl,-z,relro -Wl,-z,now
+
+include(../common/qcc-base-qnx-armv7le.conf)
diff --git a/config.tests/mac/coreservices/coreservices.mm b/mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h
index c5806dcaea..32becb2042 100644
--- a/config.tests/mac/coreservices/coreservices.mm
+++ b/mkspecs/blackberry-armle-v7-qcc/qplatformdefs.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the config.tests of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,10 +39,4 @@
**
****************************************************************************/
-#include <CoreServices/CoreServices.h>
-
-int main()
-{
- FSRef ref;
- return 0;
-}
+#include "../qnx-armv7le-qcc/qplatformdefs.h"
diff --git a/mkspecs/blackberry-armv7le-qcc/qmake.conf b/mkspecs/blackberry-armv7le-qcc/qmake.conf
index 2e24e4e0d3..ec462457c4 100644
--- a/mkspecs/blackberry-armv7le-qcc/qmake.conf
+++ b/mkspecs/blackberry-armv7le-qcc/qmake.conf
@@ -1,22 +1,5 @@
#
-# qmake configuration for blackberry armv7le systems
+# deprecated, please use blackberry-armle-v7-qcc instead
#
-
-load(qt_config)
-
-DEFINES += Q_OS_BLACKBERRY
-CONFIG += blackberry
-LIBS += -lbps
-
-# Blackberry also has support for stack smashing protection in its libc
-contains(QT_CONFIG, stack-protector-strong) {
- QMAKE_CFLAGS += -fstack-protector-strong
-} else {
- QMAKE_CFLAGS += -fstack-protector -fstack-protector-all
-}
-
-QMAKE_CFLAGS += -mcpu=cortex-a9 -mtune=cortex-a9 -mthumb -D_FORTIFY_SOURCE=2
-
-QMAKE_LFLAGS_SHLIB += -Wl,-z,relro -Wl,-z,now
-
-include(../common/qcc-base-qnx-armv7le.conf)
+warning("You are using deprecated mkspecs. Please use blackberry-armle-v7-qcc instead.")
+include(../blackberry-armle-v7-qcc/qmake.conf)
diff --git a/mkspecs/blackberry-armv7le-qcc/qplatformdefs.h b/mkspecs/blackberry-armv7le-qcc/qplatformdefs.h
index b15869f163..a3e7b16ef7 100644
--- a/mkspecs/blackberry-armv7le-qcc/qplatformdefs.h
+++ b/mkspecs/blackberry-armv7le-qcc/qplatformdefs.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Research In Motion Limited. <blackberry-qt@qnx.com>
+** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../qnx-armv7le-qcc/qplatformdefs.h"
+#include "../blackberry-armle-v7-qcc/qplatformdefs.h"
diff --git a/mkspecs/common/shell-win32.conf b/mkspecs/common/shell-win32.conf
index 131aa746c4..1da8057c43 100644
--- a/mkspecs/common/shell-win32.conf
+++ b/mkspecs/common/shell-win32.conf
@@ -14,3 +14,4 @@ QMAKE_SYMBOLIC_LINK = $$QMAKE_COPY
QMAKE_LN_SHLIB = $$QMAKE_SYMBOLIC_LINK
# xcopy copies the contained files if source is a directory. Deal with it.
CONFIG += copy_dir_files
+QMAKE_STREAM_EDITOR = $(QMAKE) -install sed
diff --git a/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qmake.conf b/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qmake.conf
new file mode 100644
index 0000000000..c9c883a206
--- /dev/null
+++ b/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qmake.conf
@@ -0,0 +1,8 @@
+#
+# qmake configuration for the Blackberry Playbook armv7le
+#
+
+include(../../blackberry-armle-v7-qcc/qmake.conf)
+
+DEFINES += Q_OS_BLACKBERRY_TABLET
+CONFIG += blackberry-playbook
diff --git a/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qplatformdefs.h b/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qplatformdefs.h
new file mode 100644
index 0000000000..a78e441501
--- /dev/null
+++ b/mkspecs/devices/blackberry-playbook-armle-v7-qcc/qplatformdefs.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Klarälvdalens Datakonsult AB <info@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../../blackberry-armle-v7-qcc/qplatformdefs.h"
diff --git a/mkspecs/devices/blackberry-playbook-armv7le-qcc/qmake.conf b/mkspecs/devices/blackberry-playbook-armv7le-qcc/qmake.conf
index cc7435d1dc..1b3299659f 100644
--- a/mkspecs/devices/blackberry-playbook-armv7le-qcc/qmake.conf
+++ b/mkspecs/devices/blackberry-playbook-armv7le-qcc/qmake.conf
@@ -1,8 +1,5 @@
#
-# qmake configuration for the Blackberry Playbook armv7le
+# deprecated, please use blackberry-playbook-armle-v7-qcc instead
#
-
-include(../../blackberry-armv7le-qcc/qmake.conf)
-
-DEFINES += Q_OS_BLACKBERRY_TABLET
-CONFIG += blackberry-playbook
+warning("You are using deprecated mkspecs. Please use blackberry-playbook-armle-v7-qcc instead.")
+include(../blackberry-playbook-armle-v7-qcc/qmake.conf)
diff --git a/mkspecs/devices/blackberry-playbook-armv7le-qcc/qplatformdefs.h b/mkspecs/devices/blackberry-playbook-armv7le-qcc/qplatformdefs.h
index 127ca957dd..61cd7119cc 100644
--- a/mkspecs/devices/blackberry-playbook-armv7le-qcc/qplatformdefs.h
+++ b/mkspecs/devices/blackberry-playbook-armv7le-qcc/qplatformdefs.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../../blackberry-armv7le-qcc/qplatformdefs.h"
+#include "../blackberry-playbook-armle-v7-qcc/qplatformdefs.h"
diff --git a/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp b/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp
index 2a5ee74648..c351e3dbc4 100644
--- a/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp
+++ b/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp
@@ -41,6 +41,7 @@
#include "qeglfshooks.h"
#include <EGL/eglvivante.h>
+#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -62,6 +63,15 @@ private:
QEglFSImx6Hooks::QEglFSImx6Hooks()
{
int width, height;
+
+ bool multiBufferNotEnabledYet = qEnvironmentVariableIsEmpty("FB_MULTI_BUFFER");
+ bool multiBuffer = qEnvironmentVariableIsEmpty("QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER");
+ if (multiBufferNotEnabledYet && multiBuffer) {
+ qWarning() << "QEglFSImx6Hooks will set environment variable FB_MULTI_BUFFER=2 to enable double buffering and vsync.\n"
+ << "If this is not desired, you can override this via: export QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER=1";
+ qputenv("FB_MULTI_BUFFER", "2");
+ }
+
mNativeDisplay = fbGetDisplayByIndex(0);
fbGetDisplayGeometry(mNativeDisplay, &width, &height);
mScreenSize.setHeight(height);
diff --git a/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp b/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp
index 671f525250..5e57ba382a 100644
--- a/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp
+++ b/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp
@@ -136,89 +136,6 @@ static void destroyDispmanxLayer(EGLNativeWindowType window)
delete eglWindow;
}
-class QEglFSPiCursor : public QEglFSCursor
-{
-public:
- QEglFSPiCursor(QEglFSScreen *screen) : QEglFSCursor(screen) {
- QSurfaceFormat platformFormat;
- platformFormat.setDepthBufferSize(24);
- platformFormat.setStencilBufferSize(8);
- platformFormat.setRedBufferSize(8);
- platformFormat.setGreenBufferSize(8);
- platformFormat.setBlueBufferSize(8);
- platformFormat.setAlphaBufferSize(8);
- m_config = q_configFromGLFormat(m_screen->display(), platformFormat);
-
- createSurface();
- createContext();
- drawInLayer();
- }
-
- ~QEglFSPiCursor() {
- eglDestroySurface(m_screen->display(), m_surface);
- destroyDispmanxLayer(m_window);
- eglDestroyContext(m_screen->display(), m_context);
- }
-
- void createSurface() {
- const QRect cr = cursorRect();
- m_window = createDispmanxLayer(cr.topLeft(), cr.size(), 50, DISPMANX_FLAGS_ALPHA_FROM_SOURCE);
- m_surface = eglCreateWindowSurface(m_screen->display(), m_config, m_window, NULL);
- }
-
- void createContext() {
- eglBindAPI(EGL_OPENGL_ES_API);
- QVector<EGLint> attrs;
- attrs.append(EGL_CONTEXT_CLIENT_VERSION);
- attrs.append(2);
- attrs.append(EGL_NONE);
- m_context = eglCreateContext(m_screen->display(), m_config, EGL_NO_CONTEXT, attrs.constData());
- }
-
- void drawInLayer() {
- eglMakeCurrent(m_screen->display(), m_surface, m_surface, m_context);
-
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
- draw(QRectF(QPointF(-1, 1), QPointF(1, -1)));
-
- eglSwapBuffers(m_screen->display(), m_surface);
- eglMakeCurrent(m_screen->display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
-
- void changeCursor(QCursor *cursor, QWindow *window) Q_DECL_OVERRIDE {
- if (!setCurrentCursor(cursor))
- return;
-
- EGL_DISPMANX_WINDOW_T *eglWindow = static_cast<EGL_DISPMANX_WINDOW_T *>(m_window);
- if (QSize(eglWindow->width, eglWindow->height) != m_cursor.size) {
- eglDestroySurface(m_screen->display(), m_surface);
- destroyDispmanxLayer(m_window);
- createSurface();
- }
- drawInLayer();
- }
-
- void setPos(const QPoint &pos) Q_DECL_OVERRIDE {
- m_cursor.pos = pos;
- moveDispmanxLayer(m_window, cursorRect().topLeft());
- }
-
- void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE {
- if (event.type() != QEvent::MouseMove)
- return;
- m_cursor.pos = event.pos();
- moveDispmanxLayer(m_window, cursorRect().topLeft());
- }
-
- void paintOnScreen() Q_DECL_OVERRIDE { }
-private:
- EGLConfig m_config;
- EGLContext m_context;
- EGLNativeWindowType m_window;
- EGLSurface m_surface;
-};
-
class QEglFSPiHooks : public QEglFSHooks
{
public:
@@ -230,9 +147,6 @@ public:
virtual void destroyNativeWindow(EGLNativeWindowType window);
virtual bool hasCapability(QPlatformIntegration::Capability cap) const;
- QEglFSCursor *createCursor(QEglFSScreen *screen) const {
- return new QEglFSPiCursor(screen);
- }
};
void QEglFSPiHooks::platformInit()
diff --git a/mkspecs/features/android/android_deployment_settings.prf b/mkspecs/features/android/android_deployment_settings.prf
index eb18d38a7f..a903ed025d 100644
--- a/mkspecs/features/android/android_deployment_settings.prf
+++ b/mkspecs/features/android/android_deployment_settings.prf
@@ -25,6 +25,7 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-no-sdk {
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
@@ -61,9 +62,6 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-no-sdk {
!isEmpty(ANDROID_EXTRA_LIBS): \
FILE_CONTENT += " \"android-extra-libs\": $$emitString($$join(ANDROID_EXTRA_LIBS, ",")),"
- !isEmpty(QMAKE_SUPPORTED_ORIENTATIONS): \
- FILE_CONTENT += " \"supported-orientations\": $$emitString($$join(QMAKE_SUPPORTED_ORIENTATIONS, ",")),"
-
FILE_CONTENT += " \"application-binary\": $$emitString($$absolute_path($$DESTDIR, $$OUT_PWD)/$$TARGET)"
FILE_CONTENT += "}"
diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf
index d799e20c46..4643c3915c 100644
--- a/mkspecs/features/create_cmake.prf
+++ b/mkspecs/features/create_cmake.prf
@@ -30,11 +30,19 @@ split_incpath {
CMAKE_ADD_SOURCE_INCLUDE_DIRS = true
CMAKE_NO_PRIVATE_INCLUDES = true # Don't add private includes in the build dir which don't exist
CMAKE_SOURCE_INCLUDES = \
- $$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE) \
- $$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME})
+ $$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE $$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME})
CMAKE_SOURCE_PRIVATE_INCLUDES = \
- $$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)) \
- $$cmakeTargetPath($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)/Qt$${CMAKE_MODULE_NAME})
+ $$cmakeTargetPaths($$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION) \
+ $$QT_MODULE_INCLUDE_BASE/Qt$${CMAKE_MODULE_NAME}/$$eval(QT.$${MODULE}.VERSION)/Qt$${CMAKE_MODULE_NAME})
+
+ cmake_extra_source_includes.input = $$PWD/data/cmake/ExtraSourceIncludes.cmake.in
+ cmake_extra_source_includes.output = $$DESTDIR/cmake/Qt5$${CMAKE_MODULE_NAME}/ExtraSourceIncludes.cmake
+
+ !build_pass:QMAKE_SUBSTITUTES += \
+ cmake_extra_source_includes
+
+ cmake_qt5_module_files.files = \
+ $$cmake_extra_source_includes.output
}
CMAKE_INCLUDE_DIR = $$cmakeRelativePath($$[QT_INSTALL_HEADERS], $$[QT_INSTALL_PREFIX])
@@ -68,7 +76,7 @@ contains(CMAKE_PLUGIN_DIR, "^\\.\\./.*") {
CMAKE_PLUGIN_DIR_IS_ABSOLUTE = True
}
-!isEmpty(DLLDESTDIR):!static:!staticlib {
+win32:!wince:!static:!staticlib {
CMAKE_DLL_DIR = $$cmakeRelativePath($$[QT_INSTALL_BINS], $$[QT_INSTALL_PREFIX])
contains(CMAKE_DLL_DIR, "^\\.\\./.*") {
CMAKE_DLL_DIR = $$[QT_INSTALL_BINS]/
diff --git a/mkspecs/features/data/cmake/ExtraSourceIncludes.cmake.in b/mkspecs/features/data/cmake/ExtraSourceIncludes.cmake.in
new file mode 100644
index 0000000000..ec8075f3f7
--- /dev/null
+++ b/mkspecs/features/data/cmake/ExtraSourceIncludes.cmake.in
@@ -0,0 +1,7 @@
+
+list(APPEND _Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS
+ $$CMAKE_SOURCE_INCLUDES
+)
+set(Qt5$${CMAKE_MODULE_NAME}_PRIVATE_INCLUDE_DIRS
+ $$CMAKE_SOURCE_PRIVATE_INCLUDES
+)
diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
index 245c0ae768..0cdaafee7f 100644
--- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
+++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
@@ -121,12 +121,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
!!ENDIF
!!ENDIF
!!IF !isEmpty(CMAKE_ADD_SOURCE_INCLUDE_DIRS)
- list(APPEND _Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS
- $$CMAKE_SOURCE_INCLUDES
- )
- set(Qt5$${CMAKE_MODULE_NAME}_PRIVATE_INCLUDE_DIRS
- $$CMAKE_SOURCE_PRIVATE_INCLUDES
- )
+ include(\"${CMAKE_CURRENT_LIST_DIR}/ExtraSourceIncludes.cmake\" OPTIONAL)
!!ENDIF
!!ELSE
set(_Qt5$${CMAKE_MODULE_NAME}_OWN_INCLUDE_DIRS)
diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf
index c756455dd2..4501b2a568 100644
--- a/mkspecs/features/default_post.prf
+++ b/mkspecs/features/default_post.prf
@@ -6,6 +6,18 @@ contains(TEMPLATE, ".*(lib|app)"):CONFIG += have_target
load(resolve_config)
+# If the TARGET looks like a path, split it into DESTDIR and the resulting TARGET
+target_dir_part = $$dirname(TARGET)
+!isEmpty(target_dir_part) {
+ isEmpty(DESTDIR): \
+ DESTDIR = $$target_dir_part
+ else: \
+ DESTDIR = $$DESTDIR/$$target_dir_part
+
+ TARGET = $$basename(TARGET)
+ DESTDIR = $$clean_path($$DESTDIR)
+}
+
QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
!isEmpty(QT_BREAKPAD_ROOT_PATH): \ # quick test first whether requested ...
!static:release:have_target: \ # is it applicable?
diff --git a/mkspecs/features/egl.prf b/mkspecs/features/egl.prf
index 7e7d098236..3dd66bce53 100644
--- a/mkspecs/features/egl.prf
+++ b/mkspecs/features/egl.prf
@@ -14,6 +14,8 @@ wince*:contains(QT_CONFIG, opengles1) {
} else {
INCLUDEPATH += $$QMAKE_INCDIR_EGL
LIBS_PRIVATE += $$QMAKE_LIBS_EGL
+ QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL
+ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL
LIBS += $$QMAKE_LFLAGS_EGL
for(p, QMAKE_LIBDIR_EGL) {
exists($$p):LIBS_PRIVATE += -L$$p
diff --git a/mkspecs/features/ios/default_pre.prf b/mkspecs/features/ios/default_pre.prf
deleted file mode 100644
index de5a9170d7..0000000000
--- a/mkspecs/features/ios/default_pre.prf
+++ /dev/null
@@ -1,9 +0,0 @@
-
-load(default_pre)
-
-# Check for supported Xcode versions
-lessThan(QMAKE_XCODE_VERSION, "4.3"): \
- error("This mkspec requires Xcode 4.3 or later")
-!contains(QMAKE_XCODE_VERSION, ^(4\\.[3456]|5\\.[0])$): \
- warning("The version of Xcode installed on this system ($$QMAKE_XCODE_VERSION)" \
- "has not been tested fully - custom compiler settings may be necessary")
diff --git a/mkspecs/features/ios/qt.prf b/mkspecs/features/ios/qt.prf
deleted file mode 100644
index 9fa882c99f..0000000000
--- a/mkspecs/features/ios/qt.prf
+++ /dev/null
@@ -1,75 +0,0 @@
-
-equals(TEMPLATE, app):contains(QT, gui(-private)?) {
- !macx-xcode: \
- error("Linking the iOS platform plugin requires bulding through Xcode")
-
- LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms
-
- lib_name = qios
- lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix()
- LIBS += -l$${lib_name}$$qtPlatformTargetSuffix() $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS)
-
- # By marking qt_registerPlatformPlugin as undefined, we ensure that
- # the plugin.o translation unit is considered for inclusion in
- # the final binary, which in turn ensures that the plugin's
- # static initializer is included and run.
- QMAKE_LFLAGS += -u _qt_registerPlatformPlugin
-
- # We do link and dependency resolution for the platform plugin
- # manually, since we know we always need the plugin, so we don't
- # need to generate an import for it.
- CONFIG -= import_qpa_plugin
-
- !no_main_wrapper {
- # Instead of messing with the user's main function we go the other
- # way and change the application entry point to call our main wrapper.
- # This entry point is the 'start' symbol, provided by crt1.o, so we
- # make a copy of the file and rename the '_main' unresolved symbol
- # to our wrapper function, '_qtmn', injecting ourselves into the app
- # startup. Once Apple starts shipping the LLVM linker (lld) we may
- # get rid of this step completely and just pass -e _qtmn to the
- # linker, taking advantage of the new LC_MAIN load command.
-
- # We know that iOS 3.1 and up uses crt1.3.1.o (technically not
- # true for simulator, but the SDK has a symlink to the correct file).
- original_crt_path = "$(SDK_DIR)/usr/lib/crt1.3.1.o"
-
- xcode_objects_path = "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)"
- custom_crt_filename = "crt1_qt.o"
- custom_crt_path = "$$xcode_objects_path/$$custom_crt_filename"
-
- EOC = $$escape_expand(\\n\\t)
- create_custom_crt.commands = \
- # Copy original crt1 to build directory
- "$$QMAKE_COPY_FILE $$original_crt_path $$custom_crt_path $$EOC" \
- # And rename all occurrences of _main to _qtmn
- "strings -t d - $${custom_crt_path}" \
- "| sed -n 's/^\\([0-9]\\{1,\\}\\) _main\$\$/\1/p'" \
- "| while read offset; do" \
- "printf '_qtmn'" \
- "| dd of=$${custom_crt_path} bs=1 seek=\$\$offset conv=notrunc >/dev/null 2>&1" \
- "; done"
- create_custom_crt.depends = $$original_crt_path
- create_custom_crt.target = $$custom_crt_path
- preprocess.depends = create_custom_crt
- QMAKE_EXTRA_TARGETS += create_custom_crt preprocess
-
- clean_custom_crt.commands = "$$QMAKE_DEL_FILE $$custom_crt_path"
- preprocess_clean.depends += clean_custom_crt
- QMAKE_EXTRA_TARGETS += clean_custom_crt preprocess_clean
-
- # Prevent usage of new LC_MAIN load command, which skips start/crt1
- # and calls main from the loader. We rely on injecting into start.
- QMAKE_LFLAGS += -Wl,-no_new_main
-
- # Explicitly link against our modified crt1 object
- QMAKE_LFLAGS += -nostartfiles -l$${custom_crt_filename}
-
- # Workaround for QMAKE_PBX_LIBPATHS mangling the Xcode variables
- lib_search_path.name = LIBRARY_SEARCH_PATHS
- lib_search_path.value = $$xcode_objects_path
- QMAKE_MAC_XCODE_SETTINGS += lib_search_path
- }
-}
-
-load(qt)
diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf
index e535c4d9e9..c0596d5ef0 100644
--- a/mkspecs/features/mac/default_pre.prf
+++ b/mkspecs/features/mac/default_pre.prf
@@ -23,3 +23,9 @@ isEmpty(QMAKE_XCODE_VERSION) {
isEmpty(QMAKE_XCODE_VERSION): error("Could not resolve Xcode version.")
unset(xcode_version)
}
+
+# These two variables are used by the xcode_dynamic_library_suffix
+# feature, which allows Xcode to choose the Qt libraries to link to
+# at build time, depending on the current Xcode SDK and configuration.
+QMAKE_XCODE_LIBRARY_SUFFIX = $$qtPlatformTargetSuffix()
+QMAKE_XCODE_LIBRARY_SUFFIX_SETTING = QT_LIBRARY_SUFFIX
diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf
index 28fbb392a7..af941058db 100644
--- a/mkspecs/features/qml_plugin.prf
+++ b/mkspecs/features/qml_plugin.prf
@@ -25,6 +25,11 @@ if(win32|mac):!macx-xcode {
}
isEmpty(TARGETPATH): TARGETPATH = $$eval(QT.$${CXX_MODULE}.name)
+# Insert the plugins URI into its meta data to enable usage
+# of static plugins in QtDeclarative:
+URI = $$replace(TARGETPATH, "/", ".")
+QMAKE_MOC_OPTIONS += -Muri=$$URI
+
QMLTYPEFILE = $$_PRO_FILE_PWD_/plugins.qmltypes
exists($$QMLTYPEFILE): QML_FILES += $$QMLTYPEFILE
diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf
index dc80f8d9e1..04375d4ce1 100644
--- a/mkspecs/features/qt.prf
+++ b/mkspecs/features/qt.prf
@@ -73,6 +73,88 @@ wince*:static:gui {
QTLIB += qmenu_wce.res
}
+# static builds: link qml import plugins into the app.
+if(contains(QT, qml)|contains(QT_PRIVATE, qml)): \
+ contains(QT_CONFIG, static):contains(TEMPLATE, .*app):!host_build:!no_import_scan {
+ # run qmlimportscanner
+ qtPrepareTool(QMLIMPORTSCANNER, qmlimportscanner)
+ for (MODULE, QT_MODULES) {
+ PATH = $$eval(QT.$${MODULE}.qml)
+ !isEmpty(PATH): QMLPATHS += $$PATH
+ }
+ QMLPATHS = $$unique(QMLPATHS)
+ for (QMLPATH, QMLPATHS): \
+ IMPORTPATHS += -importPath $$QMLPATH
+
+ #message(run $$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS)
+ JSON = $$system($$QMLIMPORTSCANNER $$_PRO_FILE_PWD_ $$IMPORTPATHS)
+
+ parseJson(JSON, IMPORTS)| error("Failed to parse qmlimportscanner output.")
+
+ !isEmpty(IMPORTS._KEYS_) {
+ # add import plugins to LIBS line
+ for (key, IMPORTS._KEYS_): {
+ PATH = $$eval(IMPORTS.$${key}.path)
+ PLUGIN = $$eval(IMPORTS.$${key}.plugin)
+ !isEmpty(PATH):!isEmpty(PLUGIN): LIBS *= -L$$PATH -l$$PLUGIN
+ }
+
+ # create qml_plugin_import.cpp
+ IMPORT_FILE_CONT = \
+ "// This file is autogenerated by qmake. It imports static plugin classes for" \
+ "// static plugins used by QML imports." \
+ "$${LITERAL_HASH}include <QtPlugin>"
+ for (key, IMPORTS._KEYS_) {
+ PLUGIN = $$eval(IMPORTS.$${key}.plugin)
+ CLASSNAME = $$eval(IMPORTS.$${key}.classname)
+ !isEmpty(PLUGIN) {
+ !isEmpty(CLASSNAME) {
+ !contains(ADDED_IMPORTS, $$PLUGIN) {
+ ADDED_IMPORTS += $$PLUGIN
+ IMPORT_FILE_CONT += "Q_IMPORT_PLUGIN($$CLASSNAME)"
+ }
+ } else {
+ error("Plugin $$PLUGIN is missing a classname entry, please add one to the qmldir file.")
+ }
+ }
+ }
+ QML_IMPORT_CPP = $$OUT_PWD/$$lower($$basename(TARGET))_qml_plugin_import.cpp
+ write_file($$QML_IMPORT_CPP, IMPORT_FILE_CONT)|error("Aborting.")
+ SOURCES += $$QML_IMPORT_CPP
+ QMAKE_CLEAN += $$QML_IMPORT_CPP
+
+ # copy qml files. this part is platform spesific.
+ macx {
+ # copy to Contents/Resources in the bundle.
+ QmlImports.path = Contents/Resources/
+ QmlImports.files *= $$QMLPATHS
+ QMAKE_BUNDLE_DATA += QmlImports
+
+ # place qt.conf in Contents/Resources in the app bundle
+ QT_CONF_CONTENTS = \
+ "[Paths]" \
+ "Imports = Resources/qml" \
+ "Qml2Imports = Resources/qml"
+ QT_CONF = "$$OUT_PWD/$${TARGET}.app/Contents/Resources/qt.conf"
+ write_file($$QT_CONF, QT_CONF_CONTENTS)|error("Aborting.")
+ } else: ios {
+ # flat bundle layout (no Contents/Resources)
+ QmlImports.files *= $$QMLPATHS
+ QMAKE_BUNDLE_DATA += QmlImports
+
+ # write qt.conf to OUT_PWD and make xcode copy it via QMAKE_BUNDLE_DATA
+ QT_CONF_CONTENTS = \
+ "[Paths]" \
+ "Imports = qml" \
+ "Qml2Imports = qml"
+ QT_CONF = "$$OUT_PWD/qt.conf"
+ write_file($$QT_CONF, QT_CONF_CONTENTS)|error("Aborting.")
+ QtConf.files = $$QT_CONF
+ QMAKE_BUNDLE_DATA += QtConf
+ }
+ }
+}
+
QT_PLUGIN_VERIFY = DEPLOYMENT_PLUGIN
contains(QT_CONFIG, static) {
QT_PLUGIN_VERIFY += QTPLUGIN
diff --git a/mkspecs/features/qt_config.prf b/mkspecs/features/qt_config.prf
index cbbd136270..208681d98a 100644
--- a/mkspecs/features/qt_config.prf
+++ b/mkspecs/features/qt_config.prf
@@ -29,6 +29,7 @@ QMAKE_QT_CONFIG = $$[QT_HOST_DATA/get]/mkspecs/qconfig.pri
include($$mod)
}
}
+ QT_MODULES = $$unique(QT_MODULES) # In case modules appear in multiple places
unset(QT_MODULE_INCLUDE_BASE)
unset(QT_MODULE_LIB_BASE)
unset(QT_MODULE_HOST_LIB_BASE)
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 7bedf6f760..f1f7c00b9e 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -23,13 +23,13 @@ defineReplace(qtLibraryTarget) {
}
defineTest(qtAddLibrary) {
- warning("qtAddLibrary() is deprecated. Use qtAddModule() or QT+= instead.")
+ warning("qtAddLibrary() is deprecated. Use QT+= instead.")
# Reverse-engineer the module name from the library name.
for(var, QT_MODULES) {
isEqual(QT.$${var}.name, $$1) {
qtAddModule($$var, , LIBS)
- return(true):break() # Yes, the break is insanity. But necessary.
+ return(true)
}
}
error("No module matching library '$$1' found.")
diff --git a/mkspecs/features/resolve_config.prf b/mkspecs/features/resolve_config.prf
index 41e82b2382..3884598a94 100644
--- a/mkspecs/features/resolve_config.prf
+++ b/mkspecs/features/resolve_config.prf
@@ -36,11 +36,34 @@ CONFIG(debug, debug|release): \
else: \
CONFIG -= debug
-debug_and_release {
- !macx-xcode: addExclusiveBuilds(debug, Debug, release, Release)
-} else: fix_output_dirs {
- debug: \
- fixExclusiveOutputDirs(debug, release)
- else: \
- fixExclusiveOutputDirs(release, debug)
+!macx-xcode {
+ debug_and_release {
+ addExclusiveBuilds(debug, Debug, release, Release)
+ } else: fix_output_dirs {
+ debug: \
+ fixExclusiveOutputDirs(debug, release)
+ else: \
+ fixExclusiveOutputDirs(release, debug)
+ }
+} else {
+ # The Xcode generator always generates project files with
+ # debug and release configurations, regardless of whether
+ # or not debug_and_release is active.
+ for(build, $$list(debug release)) {
+ suffix =
+ contains(QT_CONFIG, debug_and_release) {
+ equals(build, debug): \
+ suffix = _debug
+ } else {
+ contains(QT_CONFIG, debug): \
+ suffix = _debug
+ }
+
+ library_suffix_$${build}.name = $$QMAKE_XCODE_LIBRARY_SUFFIX_SETTING
+ library_suffix_$${build}.value = $$suffix
+ library_suffix_$${build}.build = $$build
+ QMAKE_MAC_XCODE_SETTINGS += library_suffix_$${build}
+
+ CONFIG *= xcode_dynamic_library_suffix
+ }
}
diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf
index e31d1f4539..10f421a8e2 100644
--- a/mkspecs/features/testcase.prf
+++ b/mkspecs/features/testcase.prf
@@ -10,34 +10,35 @@ check.files =
check.path = .
# If the test ends up in a different directory, we should cd to that directory.
-# Note that qmake modifies DESTDIR after this file is processed,
-# therefore, testing DESTDIR for emptiness is not sufficient.
-# Also note that in debug-and-release mode we don't want to cd into the debug/release
-# directory (e.g. if the test goes to foo/release/tst_thing.exe, we want to do
-# cd foo && release/tst_thing.exe ).
-MUNGED_DESTDIR=$$DESTDIR
-MUNGED_TARGET=$$TARGET
-win32:debug_and_release {
- contains(DESTDIR,^release$)|contains(DESTDIR,^debug$):MUNGED_DESTDIR=
-
- # In debug-and-release mode, the first ../ in TARGET breaks out of the debug/release
- # subdirectory. However, since make's working directory is already outside of the
- # debug/release subdirectory, this first ../ should be ignored when deciding if
- # we have to change directory before running the test.
- MUNGED_TARGET=$$replace(MUNGED_TARGET,^\\.\\./,)
+TESTRUN_CWD = $$DESTDIR
+
+debug_and_release:debug_and_release_target {
+ # But in debug-and-release-target mode we don't want to cd into the debug/release
+ # directory (e.g. if the test goes to foo/release/tst_thing.exe, we want to do
+ # 'cd foo && release/tst_thing.exe', not 'cd foo/release && tst_thing.exe').
+
+ TESTRUN_CWD ~= s/(release|debug)$//
+ TEST_TARGET_DIR = $$relative_path($$absolute_path($$DESTDIR, $$OUT_PWD), $$absolute_path($$TESTRUN_CWD, $$OUT_PWD))
}
-!isEmpty(MUNGED_DESTDIR):!contains(MUNGED_DESTDIR,^\\./?):check.commands = cd $(DESTDIR) &&
-contains(MUNGED_TARGET,.*/.*):check.commands = cd $(DESTDIR) &&
+
+!isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD,^\\./?): \
+ check.commands = cd $$system_path($$TESTRUN_CWD) &&
# Allow for a custom test runner script
check.commands += $(TESTRUNNER)
-mac {
- app_bundle: check.commands += ./$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET)
- else: check.commands += ./$(QMAKE_TARGET)
+unix {
+ isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = .
+
+ mac:app_bundle: \
+ check.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET)
+ else: \
+ check.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET)
+} else {
+ # Windows
+ !isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = $${TEST_TARGET_DIR}$${QMAKE_DIR_SEP}
+ check.commands += $${TEST_TARGET_DIR}$(TARGET)
}
-else:unix: check.commands += ./$(QMAKE_TARGET)
-else: check.commands += $(DESTDIR_TARGET)
# Allow for custom arguments to tests
check.commands += $(TESTARGS)
diff --git a/mkspecs/features/unix/default_pre.prf b/mkspecs/features/unix/default_pre.prf
deleted file mode 100644
index d978d14166..0000000000
--- a/mkspecs/features/unix/default_pre.prf
+++ /dev/null
@@ -1,4 +0,0 @@
-linux*:CONFIG = wayland-scanner $$CONFIG
-
-load(default_pre)
-
diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf
index 4d51ffb269..7876ef1c34 100644
--- a/mkspecs/linux-icc/qmake.conf
+++ b/mkspecs/linux-icc/qmake.conf
@@ -42,6 +42,7 @@ QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
QMAKE_CXXFLAGS_CXX11 = -std=c++0x
QMAKE_INCDIR =
diff --git a/mkspecs/features/ios/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf
index a61db3daea..0d38c058c9 100644
--- a/mkspecs/features/ios/default_post.prf
+++ b/mkspecs/macx-ios-clang/features/default_post.prf
@@ -17,10 +17,13 @@ equals(TEMPLATE, app) {
# building by calling out to xcodebuild.
TEMPLATE = aux
- CONFIG -= have_target qt staticlib dll
+ CONFIG =
SOURCES =
+ OBJECTIVE_SOURCES =
RESOURCES =
INSTALLS =
+ QMAKE_EXTRA_COMPILERS =
+ QMAKE_EXTRA_TARGETS =
TARGET_XCODE_PROJECT_DIR = $${TARGET}.xcodeproj
@@ -41,6 +44,7 @@ equals(TEMPLATE, app) {
# And distclean
xcodebuild_distclean.commands = "$(DEL_FILE) -R $$TARGET_XCODE_PROJECT_DIR"
+ xcodebuild_distclean.depends = xcodebuild_clean
QMAKE_EXTRA_TARGETS += xcodebuild_distclean
distclean.depends = xcodebuild_distclean
QMAKE_EXTRA_TARGETS += distclean
@@ -53,21 +57,11 @@ macx-xcode {
QMAKE_MAC_XCODE_SETTINGS += ios_device_family
}
-isEmpty(QT_ARCH) {
- # The iPhoneOS and iPhoneSimulator targets share the same toolchain,
- # so when configure runs the arch tests it passes the correct sysroot,
- # but we fail to pick up the architecture since we're not passing -arch
- # yet. Xcode does not seem to have a way to run the shared toolchain
- # in a way that will automatically do this (for example xcrun -sdk).
- contains(QMAKE_MAC_SDK, iphoneos.*): QT_ARCH = arm
- else: QT_ARCH = i386 # Simulator
-}
-
# Be more specific about which architecture we're targeting
equals(QT_ARCH, arm): \
- actual_archs = armv7
+ actual_archs = $$QMAKE_IOS_DEVICE_ARCHS
else: \
- actual_archs = $$QT_ARCH
+ actual_archs = $$QMAKE_IOS_SIMULATOR_ARCHS
macx-xcode {
QMAKE_XCODE_ARCHS = $$actual_archs
diff --git a/mkspecs/macx-ios-clang/features/default_pre.prf b/mkspecs/macx-ios-clang/features/default_pre.prf
new file mode 100644
index 0000000000..b37f67495c
--- /dev/null
+++ b/mkspecs/macx-ios-clang/features/default_pre.prf
@@ -0,0 +1,6 @@
+
+load(default_pre)
+
+# Check for supported Xcode versions
+lessThan(QMAKE_XCODE_VERSION, "4.3"): \
+ error("This mkspec requires Xcode 4.3 or later")
diff --git a/mkspecs/macx-ios-clang/features/qt.prf b/mkspecs/macx-ios-clang/features/qt.prf
new file mode 100644
index 0000000000..2897c62819
--- /dev/null
+++ b/mkspecs/macx-ios-clang/features/qt.prf
@@ -0,0 +1,49 @@
+
+equals(TEMPLATE, app):contains(QT, gui(-private)?) {
+ LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms
+
+ lib_name = qios
+ lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix()
+ LIBS += -l$${lib_name}$$qtPlatformTargetSuffix() $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS)
+
+ # By marking qt_registerPlatformPlugin as undefined, we ensure that
+ # the plugin.o translation unit is considered for inclusion in
+ # the final binary, which in turn ensures that the plugin's
+ # static initializer is included and run.
+ QMAKE_LFLAGS += -u _qt_registerPlatformPlugin
+
+ # We do link and dependency resolution for the platform plugin
+ # manually, since we know we always need the plugin, so we don't
+ # need to generate an import for it.
+ CONFIG -= import_qpa_plugin
+
+ !no_main_wrapper {
+ # We use ld to rename the _main symbol to _qt_main, so that we don't get a symbol clash
+ # with the _main we provide that calls UIApplicationMain. We need to make a copy of the
+ # original object file, as ld will not copy over DWARF debug information to the output
+ # file. Instead, it will inject a reference back to the original object file, so when
+ # Xcode runs dsymutil to make the final dSYM file it will still find the debug info
+ # for the object file that provided the original _main. This back-reference has the
+ # interesting side-effect of the debug information still referring to the original
+ # symbol name, so stack-traces will show both our wrapper main and the original
+ # user main as 'main', and adding a symbolic breakpoint for 'main' will break on
+ # both functions. Although a bit weird, it's a good thing, as the user will still be
+ # able to add symbolic breakpoints for 'main', not caring that the symbol is actually
+ # called 'qt_main' now.
+
+ isEmpty(OBJECTS_DIR): \
+ OBJECTS_DIR = .
+
+ !isEmpty(QMAKE_PRE_LINK): \
+ QMAKE_PRE_LINK += ";"
+
+ QMAKE_PRE_LINK += \
+ "for f in $(find $${OBJECTS_DIR} -name '*.o'); do" \
+ "(nm $f | grep -q 'T _main' && cp $f $f.original" \
+ "&& ld -r -alias _main _qt_main -unexported_symbol _main $f.original -o $f)" \
+ "|| true" \
+ "; done"
+ }
+}
+
+load(qt)
diff --git a/mkspecs/macx-ios-clang/features/qt_config.prf b/mkspecs/macx-ios-clang/features/qt_config.prf
new file mode 100644
index 0000000000..d9a13f65eb
--- /dev/null
+++ b/mkspecs/macx-ios-clang/features/qt_config.prf
@@ -0,0 +1,12 @@
+load(qt_config)
+
+isEmpty(QT_ARCH) {
+ # The configure tests are run without QT_ARCH being resolved yet, which
+ # means we fail to pass -arch to the compiler, resulting in broke tests.
+ # As the Xcode toolchain doesn't seem to have a way to auto-detect the
+ # arch based on the SDK, we have to hard-code the arch for configure.
+ contains(QMAKE_MAC_SDK, iphoneos.*): \
+ QT_ARCH = arm
+ else: \ # Simulator
+ QT_ARCH = i386
+}
diff --git a/mkspecs/macx-ios-clang/qmake.conf b/mkspecs/macx-ios-clang/qmake.conf
index 38de1e9b0a..7b2e7a17e7 100644
--- a/mkspecs/macx-ios-clang/qmake.conf
+++ b/mkspecs/macx-ios-clang/qmake.conf
@@ -10,11 +10,14 @@ QMAKE_MACOSX_DEPLOYMENT_TARGET =
QMAKE_IOS_DEPLOYMENT_TARGET = 5.0
INCLUDEPATH += $$PWD/ios
-DEFINES += DARWIN_NO_CARBON QT_NO_CORESERVICES QT_NO_PRINTER QT_NO_PRINTDIALOG
+DEFINES += DARWIN_NO_CARBON QT_NO_PRINTER QT_NO_PRINTDIALOG
# Universal target (iPhone and iPad)
QMAKE_IOS_TARGETED_DEVICE_FAMILY = 1,2
+QMAKE_IOS_DEVICE_ARCHS = armv7
+QMAKE_IOS_SIMULATOR_ARCHS = i386
+
include(../common/ios.conf)
include(../common/gcc-base-mac.conf)
include(../common/clang.conf)
diff --git a/mkspecs/macx-xcode/features/default_post.prf b/mkspecs/macx-xcode/features/default_post.prf
deleted file mode 100644
index 4c4746bb2b..0000000000
--- a/mkspecs/macx-xcode/features/default_post.prf
+++ /dev/null
@@ -1,7 +0,0 @@
-
-isEmpty(QMAKE_INFO_PLIST) {
- plist_template = $$absolute_path(../../$$[QMAKE_XSPEC]/Info.plist.$${TEMPLATE})
- exists($$plist_template): QMAKE_INFO_PLIST = $$plist_template
-}
-
-load(default_post)
diff --git a/mkspecs/macx-xcode/qmake.conf b/mkspecs/macx-xcode/qmake.conf
index bfc1c58935..fde682b64b 100644
--- a/mkspecs/macx-xcode/qmake.conf
+++ b/mkspecs/macx-xcode/qmake.conf
@@ -4,6 +4,12 @@
# OS X + Xcode
#
-include(../$$[QMAKE_XSPEC]/qmake.conf)
+QMAKESPEC = $$dirname(PWD)/$$[QMAKE_XSPEC]
+
+include($$QMAKESPEC/qmake.conf)
MAKEFILE_GENERATOR = XCODE
+
+# The active spec is now the original spec, but we still want
+# Xcode specific blocks to be triggered.
+CONFIG += macx-xcode
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix
index a77b1b22dc..2f04a88a42 100644
--- a/qmake/Makefile.unix
+++ b/qmake/Makefile.unix
@@ -19,6 +19,7 @@ QOBJS=qtextcodec.o qutfcodec.o qstring.o qstringbuilder.o qtextstream.o qiodevic
qabstractfileengine.o qtemporaryfile.o qmap.o qmetatype.o qsettings.o qsystemerror.o qlibraryinfo.o \
qvariant.o qvsnprintf.o qlocale.o qlocale_tools.o qlinkedlist.o qnumeric.o \
qcryptographichash.o qxmlstream.o qxmlutils.o qlogging.o \
+ qjson.o qjsondocument.o qjsonparser.o qjsonarray.o qjsonobject.o qjsonvalue.o \
$(QTOBJS)
@@ -80,6 +81,12 @@ DEPEND_SRC = \
$(SOURCE_PATH)/src/corelib/global/qlogging.cpp \
$(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp \
$(SOURCE_PATH)/tools/shared/windows/registry.cpp \
+ $(SOURCE_PATH)/src/corelib/json/qjson.cpp \
+ $(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp \
+ $(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp \
+ $(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp \
+ $(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp \
+ $(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp \
$(QTSRCS)
CPPFLAGS = -g $(EXTRA_CPPFLAGS) \
@@ -93,7 +100,7 @@ CPPFLAGS = -g $(EXTRA_CPPFLAGS) \
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \
-DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
- -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1
+ -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 -DQT_JSON_READONLY
CXXFLAGS = $(EXTRA_CXXFLAGS) $(CPPFLAGS)
@@ -385,4 +392,22 @@ qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp
+qjson.o: $(SOURCE_PATH)/src/corelib/json/qjson.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjson.cpp
+
+qjsondocument.o: $(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp
+
+qjsonparser.o: $(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp
+
+qjsonarray.o: $(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp
+
+qjsonobject.o: $(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp
+
+qjsonvalue.o: $(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp
+
# DO NOT DELETE THIS LINE -- make depend depends on it
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 9a772d9760..c0d20111e9 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -41,7 +41,7 @@ CFLAGS_BARE = -c -Fo./ \
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \
-DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
- -DUNICODE -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1
+ -DUNICODE -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 -DQT_JSON_READONLY
CFLAGS = -Yuqmake_pch.h -FIqmake_pch.h -Fpqmake_pch.pch $(CFLAGS_BARE) $(CFLAGS) $(EXTRA_CPPFLAGS)
CXXFLAGS_BARE = $(CFLAGS_BARE)
@@ -120,7 +120,13 @@ QTOBJS= \
qxmlstream.obj \
qxmlutils.obj \
qnumeric.obj \
- qlogging.obj
+ qlogging.obj \
+ qjson.obj \
+ qjsondocument.obj \
+ qjsonparser.obj \
+ qjsonarray.obj \
+ qjsonobject.obj \
+ qjsonvalue.obj
first all: qmake.exe
@@ -207,5 +213,8 @@ qmake_pch.obj:
{$(SOURCE_PATH)\src\corelib\xml}.cpp{}.obj::
$(CXX) $(CXXFLAGS) $<
+{$(SOURCE_PATH)\src\corelib\json}.cpp{}.obj::
+ $(CXX) $(CXXFLAGS) $<
+
{$(SOURCE_PATH)\tools\shared\windows}.cpp{}.obj::
$(CXX) $(CXXFLAGS) $<
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index 719507c61d..524603aa63 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -301,6 +301,8 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
QString defaultConfig;
for(int as_release = 0; as_release < 2; as_release++)
{
+ QString configName = (as_release ? "Release" : "Debug");
+
QMap<QString, QString> settings;
settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO"));
if(as_release)
@@ -311,6 +313,12 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
const ProStringList &l = project->values("QMAKE_MAC_XCODE_SETTINGS");
for(int i = 0; i < l.size(); ++i) {
ProString name = l.at(i);
+ const ProKey buildKey(name + ".build");
+ if (!project->isEmpty(buildKey)) {
+ const QString build = project->values(buildKey).first().toQString();
+ if (build.toLower() != configName.toLower())
+ continue;
+ }
const ProKey nkey(name + ".name");
if (!project->isEmpty(nkey))
name = project->first(nkey);
@@ -319,10 +327,9 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
}
}
- QString name = (as_release ? "Release" : "Debug");
if (project->isActiveConfig("debug") != (bool)as_release)
- defaultConfig = name;
- QString key = keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_" + name);
+ defaultConfig = configName;
+ QString key = keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_" + configName);
project->values("QMAKE_SUBDIR_PBX_BUILDCONFIGS").append(key);
t << "\t\t" << key << " = {\n"
<< "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";\n"
@@ -330,7 +337,7 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
for (QMap<QString, QString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it)
t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n";
t << "\t\t\t};\n"
- << "\t\t\t" << writeSettings("name", name) << ";\n"
+ << "\t\t\t" << writeSettings("name", configName) << ";\n"
<< "\t\t};\n";
}
t << "\t\t" << keyFor("QMAKE_SUBDIR_PBX_BUILDCONFIG_LIST") << " = {\n"
@@ -867,6 +874,20 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)",
opt.toLatin1().constData(), lib_file.toLatin1().constData(), library.toLatin1().constData());
remove = true;
+
+ if (project->isActiveConfig("xcode_dynamic_library_suffix")) {
+ QString suffixSetting = project->first("QMAKE_XCODE_LIBRARY_SUFFIX_SETTING").toQString();
+ if (!suffixSetting.isEmpty()) {
+ QString librarySuffix = project->first("QMAKE_XCODE_LIBRARY_SUFFIX").toQString();
+ suffixSetting = "$(" + suffixSetting + ")";
+ if (!librarySuffix.isEmpty()) {
+ library = library.replace(librarySuffix, suffixSetting);
+ name = name.remove(librarySuffix);
+ } else {
+ library = library.replace(name, name + suffixSetting);
+ }
+ }
+ }
}
}
}
@@ -998,6 +1019,27 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("shellScript", "make -C " + IoUtils::shellQuoteUnix(qmake_getpwd()) + " -f " + IoUtils::shellQuoteUnix(mkfile)) << ";\n"
<< "\t\t};\n";
}
+
+ if (!project->isEmpty("QMAKE_PRE_LINK")) {
+ QString phase_key = keyFor("QMAKE_PBX_PRELINK_BUILDPHASE");
+ project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
+ t << "\t\t" << phase_key << " = {\n"
+ << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
+ << "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";\n"
+ // The build phases are not executed in the order they are defined, but by their
+ // resolved dependenices, so we have to ensure that this phase is run after the
+ // compilation phase, and before the link phase. Making the phase depend on all the
+ // object files, and "write" to the list of files to link achieves that.
+ << "\t\t\t" << writeSettings("inputPaths", ProStringList("$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/*" + Option::obj_ext), SettingsAsList, 4) << ";\n"
+ << "\t\t\t" << writeSettings("outputPaths", ProStringList("$(LINK_FILE_LIST_$(CURRENT_VARIANT)_$(CURRENT_ARCH))"), SettingsAsList, 4) << ";\n"
+ << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n"
+ << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
+ << "\t\t\t" << writeSettings("name", "Qt Prelink") << ";\n"
+ << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
+ << "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_PRE_LINK")) << ";\n"
+ << "\t\t};\n";
+ }
+
//LIBRARY BUILDPHASE
if(!project->isEmpty("QMAKE_PBX_LIBRARIES")) {
tmp = project->values("QMAKE_PBX_LIBRARIES");
@@ -1023,6 +1065,24 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";\n"
<< "\t\t};\n";
}
+
+ if (!project->isEmpty("QMAKE_POST_LINK")) {
+ QString phase_key = keyFor("QMAKE_PBX_POSTLINK_BUILDPHASE");
+ project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
+ t << "\t\t" << phase_key << " = {\n"
+ << "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";\n"
+ << "\t\t\t" << writeSettings("files", ProStringList(), SettingsAsList, 4) << ";\n"
+ // The build phases are not executed in the order they are defined, but by their
+ // resolved dependenices, so we have to ensure the phase is run after linking.
+ << "\t\t\t" << writeSettings("inputPaths", ProStringList("$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)"), SettingsAsList, 4) << ";\n"
+ << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";\n"
+ << "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";\n"
+ << "\t\t\t" << writeSettings("name", "Qt Postlink") << ";\n"
+ << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";\n"
+ << "\t\t\t" << writeSettings("shellScript", project->values("QMAKE_POST_LINK")) << ";\n"
+ << "\t\t};\n";
+ }
+
if (!project->isEmpty("DESTDIR")) {
QString phase_key = keyFor("QMAKE_PBX_TARGET_COPY_PHASE");
QString destDir = project->first("DESTDIR").toQString();
@@ -1244,6 +1304,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QString defaultConfig;
for(int as_release = 0; as_release < 2; as_release++)
{
+ QString configName = (as_release ? "Release" : "Debug");
+
QMap<QString, QString> settings;
settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO"));
settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", as_release ? "NO" : "YES");
@@ -1255,6 +1317,12 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
const ProStringList &l = project->values("QMAKE_MAC_XCODE_SETTINGS");
for(int i = 0; i < l.size(); ++i) {
ProString name = l.at(i);
+ const ProKey buildKey(name + ".build");
+ if (!project->isEmpty(buildKey)) {
+ const QString build = project->values(buildKey).first().toQString();
+ if (build.toLower() != configName.toLower())
+ continue;
+ }
const QString value = project->values(ProKey(name + ".value")).join(QString(Option::field_sep));
const ProKey nkey(name + ".name");
if (!project->isEmpty(nkey))
@@ -1271,11 +1339,10 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
settings.insert("PRODUCT_NAME", escapeFilePath(lib.toQString()));
}
- QString name = (as_release ? "Release" : "Debug");
if (project->isActiveConfig("debug") != (bool)as_release)
- defaultConfig = name;
+ defaultConfig = configName;
for (int i = 0; i < buildConfigGroups.size(); i++) {
- QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + name + buildConfigGroups.at(i));
+ QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + configName + buildConfigGroups.at(i));
project->values(ProKey("QMAKE_PBX_BUILDCONFIGS_" + buildConfigGroups.at(i))).append(key);
t << "\t\t" << key << " = {\n"
<< "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";\n"
@@ -1429,7 +1496,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
}
}
t << "\t\t\t};\n"
- << "\t\t\t" << writeSettings("name", name) << ";\n"
+ << "\t\t\t" << writeSettings("name", configName) << ";\n"
<< "\t\t};\n";
}
}
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index 570f3216e3..9ebaf60843 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -3240,7 +3240,8 @@ MakefileGenerator::writePkgConfigFile()
}
}
}
- t << var << "=" << val << endl;
+ if (!val.isEmpty())
+ t << var << "=" << val << endl;
}
t << endl;
@@ -3331,8 +3332,7 @@ QString MakefileGenerator::installMetaFile(const ProKey &replace_rule, const QSt
{
QString ret;
if (project->isEmpty(replace_rule)
- || project->isActiveConfig("no_sed_meta_install")
- || project->isEmpty("QMAKE_STREAM_EDITOR")) {
+ || project->isActiveConfig("no_sed_meta_install")) {
ret += "-$(INSTALL_FILE) \"" + src + "\" \"" + dst + "\"";
} else {
ret += "-$(SED)";
diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp
index adeb55af86..1c95392932 100644
--- a/qmake/generators/unix/unixmake.cpp
+++ b/qmake/generators/unix/unixmake.cpp
@@ -106,20 +106,8 @@ UnixMakefileGenerator::init()
return; /* subdirs is done */
}
- //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET
- if(!project->isEmpty("TARGET")) {
+ if (!project->isEmpty("TARGET"))
project->values("TARGET") = escapeFilePaths(project->values("TARGET"));
- ProString targ = unescapeFilePath(project->first("TARGET"));
- int slsh = qMax(targ.lastIndexOf('/'), targ.lastIndexOf(Option::dir_sep));
- if(slsh != -1) {
- if(project->isEmpty("DESTDIR"))
- project->values("DESTDIR").append("");
- else if(project->first("DESTDIR").right(1) != Option::dir_sep)
- project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + Option::dir_sep);
- project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + targ.left(slsh+1));
- project->values("TARGET") = ProStringList(targ.mid(slsh+1));
- }
- }
project->values("QMAKE_ORIG_TARGET") = project->values("TARGET");
project->values("QMAKE_ORIG_DESTDIR") = project->values("DESTDIR");
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index 86d31b01dc..a30129fa27 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -449,7 +449,7 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt
if (!qmake_setpwd(dir))
fprintf(stderr, "Cannot find directory: %s", dir.toLatin1().constData());
}
- Option::output_dir = Option::globals->shadowedPath(QDir::cleanPath(fi.absoluteFilePath()));
+ Option::output_dir = Option::globals->shadowedPath(QDir::cleanPath(dir));
if (tmp_proj.read(fn)) {
// Check if all requirements are fulfilled
if (!tmp_proj.isEmpty("QMAKE_FAILED_REQUIREMENTS")) {
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index 2ef2d82b5a..30d28e6e11 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -274,20 +274,6 @@ Win32MakefileGenerator::processPrlFiles()
void Win32MakefileGenerator::processVars()
{
- //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET
- if(!project->isEmpty("TARGET")) {
- ProString targ = project->first("TARGET");
- int slsh = qMax(targ.lastIndexOf('/'), targ.lastIndexOf(Option::dir_sep));
- if(slsh != -1) {
- if(project->isEmpty("DESTDIR"))
- project->values("DESTDIR").append("");
- else if(project->first("DESTDIR").right(1) != Option::dir_sep)
- project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + Option::dir_sep);
- project->values("DESTDIR") = ProStringList(project->first("DESTDIR") + targ.left(slsh+1));
- project->values("TARGET") = ProStringList(targ.mid(slsh+1));
- }
- }
-
project->values("QMAKE_ORIG_TARGET") = project->values("TARGET");
if (project->isEmpty("QMAKE_PROJECT_NAME"))
project->values("QMAKE_PROJECT_NAME") = project->values("QMAKE_ORIG_TARGET");
@@ -315,6 +301,8 @@ void Win32MakefileGenerator::processVars()
project->values("QMAKE_COPY_FILE").append("$(COPY)");
if(project->isEmpty("QMAKE_COPY_DIR"))
project->values("QMAKE_COPY_DIR").append("xcopy /s /q /y /i");
+ if (project->isEmpty("QMAKE_STREAM_EDITOR"))
+ project->values("QMAKE_STREAM_EDITOR").append("$(QMAKE) -install sed");
if(project->isEmpty("QMAKE_INSTALL_FILE"))
project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)");
if(project->isEmpty("QMAKE_INSTALL_PROGRAM"))
diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp
index 10ef523e15..9cefbc8572 100644
--- a/qmake/library/qmakebuiltins.cpp
+++ b/qmake/library/qmakebuiltins.cpp
@@ -56,6 +56,11 @@
#include <qset.h>
#include <qstringlist.h>
#include <qtextstream.h>
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+# include <qjsondocument.h>
+# include <qjsonobject.h>
+# include <qjsonarray.h>
+#endif
#ifdef PROEVALUATOR_THREAD_SAFE
# include <qthreadpool.h>
#endif
@@ -101,7 +106,7 @@ enum TestFunc {
T_INVALID = 0, T_REQUIRES, T_GREATERTHAN, T_LESSTHAN, T_EQUALS,
T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
T_DEFINED, T_CONTAINS, T_INFILE,
- T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF,
+ T_COUNT, T_ISEMPTY, T_PARSE_JSON, T_INCLUDE, T_LOAD, T_DEBUG, T_LOG, T_MESSAGE, T_WARNING, T_ERROR, T_IF,
T_MKPATH, T_WRITE_FILE, T_TOUCH, T_CACHE
};
@@ -178,6 +183,9 @@ void QMakeEvaluator::initFunctionStatics()
{ "infile", T_INFILE },
{ "count", T_COUNT },
{ "isEmpty", T_ISEMPTY },
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ { "parseJson", T_PARSE_JSON },
+#endif
{ "load", T_LOAD },
{ "include", T_INCLUDE },
{ "debug", T_DEBUG },
@@ -286,6 +294,75 @@ quoteValue(const ProString &val)
return ret;
}
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProValueMap *map);
+
+static void insertJsonKeyValue(const QString &key, const QStringList &values, ProValueMap *map)
+{
+ map->insert(ProKey(key), ProStringList(values));
+}
+
+static void addJsonArray(const QJsonArray &array, const QString &keyPrefix, ProValueMap *map)
+{
+ QStringList keys;
+ for (int i = 0; i < array.count(); ++i) {
+ keys.append(QString::number(i));
+ addJsonValue(array.at(i), keyPrefix + QString::number(i), map);
+ }
+ insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), keys, map);
+}
+
+static void addJsonObject(const QJsonObject &object, const QString &keyPrefix, ProValueMap *map)
+{
+ foreach (const QString &key, object.keys())
+ addJsonValue(object.value(key), keyPrefix + key, map);
+
+ insertJsonKeyValue(keyPrefix + QLatin1String("_KEYS_"), object.keys(), map);
+}
+
+static void addJsonValue(const QJsonValue &value, const QString &keyPrefix, ProValueMap *map)
+{
+ switch (value.type()) {
+ case QJsonValue::Bool:
+ insertJsonKeyValue(keyPrefix, QStringList() << (value.toBool() ? QLatin1String("true") : QLatin1String("false")), map);
+ break;
+ case QJsonValue::Double:
+ insertJsonKeyValue(keyPrefix, QStringList() << QString::number(value.toDouble()), map);
+ break;
+ case QJsonValue::String:
+ insertJsonKeyValue(keyPrefix, QStringList() << value.toString(), map);
+ break;
+ case QJsonValue::Array:
+ addJsonArray(value.toArray(), keyPrefix + QLatin1Char('.'), map);
+ break;
+ case QJsonValue::Object:
+ addJsonObject(value.toObject(), keyPrefix + QLatin1Char('.'), map);
+ break;
+ default:
+ break;
+ }
+}
+
+static QMakeEvaluator::VisitReturn parseJsonInto(const QByteArray &json, const QString &into, ProValueMap *value)
+{
+ QJsonDocument document = QJsonDocument::fromJson(json);
+ if (document.isNull())
+ return QMakeEvaluator::ReturnFalse;
+
+ QString currentKey = into + QLatin1Char('.');
+
+ // top-level item is either an array or object
+ if (document.isArray())
+ addJsonArray(document.array(), currentKey, value);
+ else if (document.isObject())
+ addJsonObject(document.object(), currentKey, value);
+ else
+ return QMakeEvaluator::ReturnFalse;
+
+ return QMakeEvaluator::ReturnTrue;
+}
+#endif
+
QMakeEvaluator::VisitReturn
QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode,
const QString &contents)
@@ -1278,6 +1355,18 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
m_valuemapStack.top()[var] = statics.fakeValue;
return ReturnTrue;
}
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ case T_PARSE_JSON: {
+ if (args.count() != 2) {
+ evalError(fL1S("parseJson(variable, into) requires two arguments."));
+ return ReturnFalse;
+ }
+
+ QByteArray json = values(args.at(0).toKey()).join(QLatin1Char(' ')).toUtf8();
+ QString parseInto = args.at(1).toQString(m_tmp2);
+ return parseJsonInto(json, parseInto, &m_valuemapStack.top());
+ }
+#endif
case T_INCLUDE: {
if (args.count() < 1 || args.count() > 3) {
evalError(fL1S("include(file, [into, [silent]]) requires one, two or three arguments."));
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 9bf870ce39..c4dca12900 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -129,6 +129,7 @@ void QMakeEvaluator::initStatics()
statics.strhost_build = QLatin1String("host_build");
statics.strTEMPLATE = ProKey("TEMPLATE");
statics.strQMAKE_PLATFORM = ProKey("QMAKE_PLATFORM");
+ statics.strQMAKESPEC = ProKey("QMAKESPEC");
#ifdef PROEVALUATOR_FULL
statics.strREQUIRES = ProKey("REQUIRES");
#endif
@@ -939,6 +940,12 @@ void QMakeEvaluator::visitProVariable(
setTemplate();
else if (varName == statics.strQMAKE_PLATFORM)
m_featureRoots = 0;
+ else if (varName == statics.strQMAKESPEC) {
+ if (!values(varName).isEmpty()) {
+ m_qmakespec = values(varName).first().toQString();
+ m_featureRoots = 0;
+ }
+ }
#ifdef PROEVALUATOR_FULL
else if (varName == statics.strREQUIRES)
checkRequirements(values(varName));
@@ -1160,7 +1167,7 @@ bool QMakeEvaluator::loadSpecInternal()
m_qmakespec = orig_spec.toQString();
# endif
#endif
- valuesRef(ProKey("QMAKESPEC")) << ProString(m_qmakespec);
+ valuesRef(ProKey("QMAKESPEC")) = ProString(m_qmakespec);
m_qmakespecName = IoUtils::fileName(m_qmakespec).toString();
// This also ensures that m_featureRoots is valid.
if (evaluateFeatureFile(QLatin1String("spec_post.prf")) != ReturnTrue)
@@ -1271,6 +1278,14 @@ void QMakeEvaluator::evaluateCommand(const QString &cmds, const QString &where)
}
}
+void QMakeEvaluator::applyExtraConfigs()
+{
+ if (m_extraConfigs.isEmpty())
+ return;
+
+ evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(QLatin1Char(' ')), fL1S("(extra configs)"));
+}
+
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConfigFeatures()
{
QSet<QString> processed;
@@ -1365,10 +1380,6 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
loadDefaults();
}
- for (ProValueMap::ConstIterator it = m_extraVars.constBegin();
- it != m_extraVars.constEnd(); ++it)
- m_valuemapStack.first().insert(it.key(), it.value());
-
VisitReturn vr;
m_handler->aboutToEval(currentProFile(), pro, type);
@@ -1377,14 +1388,23 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
if (flags & LoadPreFiles) {
setupProject();
+ for (ProValueMap::ConstIterator it = m_extraVars.constBegin();
+ it != m_extraVars.constEnd(); ++it)
+ m_valuemapStack.first().insert(it.key(), it.value());
+
+ // In case default_pre needs to make decisions based on the current
+ // build pass configuration.
+ applyExtraConfigs();
+
if ((vr = evaluateFeatureFile(QLatin1String("default_pre.prf"))) == ReturnError)
goto failed;
- evaluateCommand(m_option->precmds, fL1S("(command line)"));
+ if (!m_option->precmds.isEmpty()) {
+ evaluateCommand(m_option->precmds, fL1S("(command line)"));
- // After user configs, to override them
- if (!m_extraConfigs.isEmpty())
- evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(QLatin1Char(' ')), fL1S("(extra configs)"));
+ // Again, after user configs, to override them
+ applyExtraConfigs();
+ }
}
debugMsg(1, "visiting file %s", qPrintable(pro->fileName()));
@@ -1398,8 +1418,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
// Again, to ensure the project does not mess with us.
// Specifically, do not allow a project to override debug/release within a
// debug_and_release build pass - it's too late for that at this point anyway.
- if (!m_extraConfigs.isEmpty())
- evaluateCommand(fL1S("CONFIG += ") + m_extraConfigs.join(QLatin1Char(' ')), fL1S("(extra configs)"));
+ applyExtraConfigs();
if ((vr = evaluateFeatureFile(QLatin1String("default_post.prf"))) == ReturnError)
goto failed;
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index 8ca2b182c7..c1e7037762 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -170,6 +170,7 @@ public:
void initFrom(const QMakeEvaluator &other);
void setupProject();
void evaluateCommand(const QString &cmds, const QString &where);
+ void applyExtraConfigs();
VisitReturn visitProFile(ProFile *pro, QMakeHandler::EvalFileType type,
LoadFlags flags);
VisitReturn visitProBlock(ProFile *pro, const ushort *tokPtr);
diff --git a/qmake/library/qmakeevaluator_p.h b/qmake/library/qmakeevaluator_p.h
index c6cb60744f..dd0bdd4c7f 100644
--- a/qmake/library/qmakeevaluator_p.h
+++ b/qmake/library/qmakeevaluator_p.h
@@ -91,6 +91,7 @@ struct QMakeStatics {
QString strhost_build;
ProKey strTEMPLATE;
ProKey strQMAKE_PLATFORM;
+ ProKey strQMAKESPEC;
#ifdef PROEVALUATOR_FULL
ProKey strREQUIRES;
#endif
diff --git a/qmake/main.cpp b/qmake/main.cpp
index 66364b83a7..b1929e0d21 100644
--- a/qmake/main.cpp
+++ b/qmake/main.cpp
@@ -57,6 +57,128 @@
QT_BEGIN_NAMESPACE
+#ifdef Q_OS_WIN
+
+struct SedSubst {
+ QRegExp from;
+ QString to;
+};
+Q_DECLARE_TYPEINFO(SedSubst, Q_MOVABLE_TYPE);
+
+static int doSed(int argc, char **argv)
+{
+ QVector<SedSubst> substs;
+ QList<const char *> inFiles;
+ for (int i = 0; i < argc; i++) {
+ if (!strcmp(argv[i], "-e")) {
+ if (++i == argc) {
+ fprintf(stderr, "Error: sed option -e requires an argument\n");
+ return 3;
+ }
+ QString cmd = QString::fromLocal8Bit(argv[i]);
+ for (int j = 0; j < cmd.length(); j++) {
+ QChar c = cmd.at(j);
+ if (c.isSpace())
+ continue;
+ if (c != QLatin1Char('s')) {
+ fprintf(stderr, "Error: unrecognized sed command '%c'\n", c.toLatin1());
+ return 3;
+ }
+ QChar sep = ++j < cmd.length() ? cmd.at(j) : QChar();
+ bool escaped = false;
+ int phase = 1;
+ QStringList phases;
+ QString curr;
+ while (++j < cmd.length()) {
+ c = cmd.at(j);
+ if (!escaped) {
+ if (c == QLatin1Char(';'))
+ break;
+ if (c == QLatin1Char('\\')) {
+ escaped = true;
+ continue;
+ }
+ if (c == sep) {
+ phase++;
+ phases << curr;
+ curr.clear();
+ continue;
+ }
+ }
+ if (phase == 1
+ && (c == QLatin1Char('+') || c == QLatin1Char('?')
+ || c == QLatin1Char('{') || c == QLatin1Char('}')
+ || c == QLatin1Char('(') || c == QLatin1Char(')'))) {
+ // translate sed rx to QRegExp
+ escaped ^= 1;
+ }
+ if (escaped) {
+ escaped = false;
+ curr += QLatin1Char('\\');
+ }
+ curr += c;
+ }
+ if (escaped) {
+ fprintf(stderr, "Error: unterminated escape sequence in sed s command\n");
+ return 3;
+ }
+ if (phase != 3) {
+ fprintf(stderr, "Error: sed s command requires three arguments (%d, %c, %s)\n", phase, sep.toLatin1(), qPrintable(curr));
+ return 3;
+ }
+ if (curr != QLatin1String("g")) {
+ fprintf(stderr, "Error: sed s command must be used with the g option (only)\n");
+ return 3;
+ }
+ SedSubst subst;
+ subst.from = QRegExp(phases.at(0));
+ subst.to = phases.at(1);
+ substs << subst;
+ }
+ } else if (argv[i][0] == '-' && argv[i][1] != 0) {
+ fprintf(stderr, "Error: unrecognized sed option '%s'\n", argv[i]);
+ return 3;
+ } else {
+ inFiles << argv[i];
+ }
+ }
+ if (inFiles.isEmpty())
+ inFiles << "-";
+ foreach (const char *inFile, inFiles) {
+ FILE *f;
+ if (!strcmp(inFile, "-")) {
+ f = stdin;
+ } else if (!(f = fopen(inFile, "r"))) {
+ perror(inFile);
+ return 1;
+ }
+ QTextStream is(f);
+ while (!is.atEnd()) {
+ QString line = is.readLine();
+ for (int i = 0; i < substs.size(); i++)
+ line.replace(substs.at(i).from, substs.at(i).to);
+ puts(qPrintable(line));
+ }
+ if (f != stdin)
+ fclose(f);
+ }
+ return 0;
+}
+
+static int doInstall(int argc, char **argv)
+{
+ if (!argc) {
+ fprintf(stderr, "Error: -install requires further arguments\n");
+ return 3;
+ }
+ if (!strcmp(argv[0], "sed"))
+ return doSed(argc - 1, argv + 1);
+ fprintf(stderr, "Error: unrecognized -install subcommand '%s'\n", argv[0]);
+ return 3;
+}
+
+#endif // Q_OS_WIN
+
/* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function
is much too slow, and called much too often inside of Qt (every fileFixify). With this we use a locally
cached copy because I can control all the times it is set (because Qt never sets the pwd under me).
@@ -85,6 +207,12 @@ int runQMake(int argc, char **argv)
// This is particularly important for things like QtCreator and scripted builds.
setvbuf(stdout, (char *)NULL, _IONBF, 0);
+#ifdef Q_OS_WIN
+ // Workaround for inferior/missing command line tools on Windows: make our own!
+ if (argc >= 2 && !strcmp(argv[1], "-install"))
+ return doInstall(argc - 2, argv + 2);
+#endif
+
QMakeVfs vfs;
Option::vfs = &vfs;
QMakeGlobals globals;
diff --git a/qmake/qmake.pri b/qmake/qmake.pri
index 39959efe7b..5012bd0206 100644
--- a/qmake/qmake.pri
+++ b/qmake/qmake.pri
@@ -83,7 +83,13 @@ bootstrap { #Qt code
qvsnprintf.cpp \
qxmlstream.cpp \
qxmlutils.cpp \
- qlogging.cpp
+ qlogging.cpp \
+ qjson.cpp \
+ qjsondocument.cpp \
+ qjsonparser.cpp \
+ qjsonarray.cpp \
+ qjsonobject.cpp \
+ qjsonvalue.cpp
HEADERS+= \
qbitarray.h \
@@ -126,7 +132,14 @@ bootstrap { #Qt code
quuid.h \
qvector.h \
qxmlstream.h \
- qxmlutils.h
+ qxmlutils.h \
+ qjson.h \
+ qjsondocument.h \
+ qjsonparser.h \
+ qjsonwriter.h \
+ qjsonarray.h \
+ qjsonobject.h \
+ qjsonvalue.h
unix {
SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp
diff --git a/qmake/qmake.pro b/qmake/qmake.pro
index 568ad41ce1..e680942716 100644
--- a/qmake/qmake.pro
+++ b/qmake/qmake.pro
@@ -20,6 +20,7 @@ VPATH += $$QT_SOURCE_TREE/src/corelib/global \
$$QT_SOURCE_TREE/src/corelib/plugin \
$$QT_SOURCE_TREE/src/corelib/xml \
$$QT_SOURCE_TREE/src/corelib/io \
+ $$QT_SOURCE_TREE/src/corelib/json \
$$QT_SOURCE_TREE/tools/shared/windows
INCLUDEPATH += . \
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
index 95a6961e7b..51d7f0b653 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexRangeCache.cpp
@@ -84,7 +84,7 @@ bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const
#if defined(_MSC_VER) && _MSC_VER < 1600
return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
#else
- return std::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
+ return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
#endif
}
diff --git a/src/android/java/AndroidManifest.xml b/src/android/java/AndroidManifest.xml
index 726801404a..6463793e0b 100644
--- a/src/android/java/AndroidManifest.xml
+++ b/src/android/java/AndroidManifest.xml
@@ -9,21 +9,21 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
+ <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
- <meta-data android:value="@string/repository" android:name="android.app.repository"/>
+ <meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
- <meta-data android:value="@string/app_lib_name" android:name="android.app.lib_name"/>
<!-- Deploy Qt libs as part of package -->
- <meta-data android:value="1" android:name="android.app.bundle_local_qt_libs"/>
+ <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:value="1" android:name="android.app.use_local_qt_libs"/>
- <meta-data android:value="/data/local/tmp/qt/" android:name="android.app.libs_prefix"/>
- <meta-data android:value="@string/local_libs" android:name="android.app.load_local_libs"/>
- <meta-data android:value="@string/local_jars" android:name="android.app.load_local_jars"/>
- <meta-data android:value="@string/init_classes" android:name="android.app.static_init_classes"/>
+ <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_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
+ <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Messages maps -->
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
diff --git a/src/android/java/res/values/libs.xml b/src/android/java/res/values/libs.xml
index c8e2fb9661..231406d224 100644
--- a/src/android/java/res/values/libs.xml
+++ b/src/android/java/res/values/libs.xml
@@ -3,7 +3,6 @@
<array name="qt_sources">
<item>https://download.qt-project.org/ministro/android/qt5/latest</item>
</array>
- <string name="repository">default</string>
<!-- The following is handled automatically by the deployment tool. It should
not be edited manually. -->
diff --git a/src/android/java/res/values/strings.xml b/src/android/java/res/values/strings.xml
index 0b92c5542e..300f0673a4 100644
--- a/src/android/java/res/values/strings.xml
+++ b/src/android/java/res/values/strings.xml
@@ -1,10 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="app_name"><!-- %%INSERT_APP_NAME%% --></string>
- <string name="app_lib_name"><!-- %%INSERT_APP_LIB_NAME%% --></string>
- <string name="local_libs"><!-- %%INSERT_LOCAL_LIBS%% --></string>
- <string name="local_jars"><!-- %%INSERT_LOCAL_JARS%% --></string>
- <string name="init_classes"><!-- %%INSERT_INIT_CLASSES%% --></string>
<string name="ministro_not_found_msg">Can\'t find Ministro service.\nThe application can\'t start.</string>
<string name="ministro_needed_msg">This application requires Ministro service. Would you like to install it?</string>
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
index 83ed1582bf..9c7b57a4f5 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
@@ -489,6 +489,14 @@ public class QtActivity extends Activity
+ "\tQML2_IMPORT_PATH=" + localPrefix + "/qml"
+ "\tQML_IMPORT_PATH=" + localPrefix + "/imports"
+ "\tQT_PLUGIN_PATH=" + localPrefix + "/plugins");
+
+ Intent intent = getIntent();
+ if (intent != null) {
+ String parameters = intent.getStringExtra("applicationArguments");
+ if (parameters != null)
+ loaderParams.putString(APPLICATION_PARAMETERS_KEY, parameters.replace(' ', '\t'));
+ }
+
loadApplication(loaderParams);
return;
}
diff --git a/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch b/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch
index 0e72c57be6..2fa23aed8f 100644
--- a/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch
+++ b/src/angle/patches/0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch
@@ -22,7 +22,7 @@ index 610a5ef..95a6961 100644
+#if defined(_MSC_VER) && _MSC_VER < 1600
+ return std::tr1::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
+#else
-+ return std::make_tuple(type, offset, count) < std::tr1::make_tuple(rhs.type, rhs.offset, rhs.count);
++ return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
+#endif
}
diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp
index aeedcf1aa1..e425f8634c 100644
--- a/src/corelib/codecs/qutfcodec.cpp
+++ b/src/corelib/codecs/qutfcodec.cpp
@@ -106,14 +106,6 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve
if (u < 0x0800) {
*cursor++ = 0xc0 | ((uchar) (u >> 6));
} else {
- // is it one of the Unicode non-characters?
- if (QChar::isNonCharacter(u)) {
- *cursor++ = replacement;
- ++ch;
- ++invalid;
- continue;
- }
-
if (QChar::requiresSurrogates(u)) {
*cursor++ = 0xf0 | ((uchar) (u >> 18));
*cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
@@ -180,15 +172,14 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte
--need;
if (!need) {
// utf-8 bom composes into 0xfeff code point
- bool nonCharacter;
if (!headerdone && uc == 0xfeff) {
// don't do anything, just skip the BOM
- } else if (!(nonCharacter = QChar::isNonCharacter(uc)) && QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
+ } else if (QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
// surrogate pair
Q_ASSERT((qch - (ushort*)result.unicode()) + 2 < result.length());
*qch++ = QChar::highSurrogate(uc);
*qch++ = QChar::lowSurrogate(uc);
- } else if ((uc < min_uc) || QChar::isSurrogate(uc) || nonCharacter || uc > QChar::LastValidCodePoint) {
+ } else if ((uc < min_uc) || QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) {
// error: overlong sequence, UTF16 surrogate or non-character
*qch++ = replacement;
++invalid;
diff --git a/src/corelib/doc/snippets/code/doc_src_containers.cpp b/src/corelib/doc/snippets/code/doc_src_containers.cpp
index 350b2a91f2..6e59a8a548 100644
--- a/src/corelib/doc/snippets/code/doc_src_containers.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_containers.cpp
@@ -273,3 +273,33 @@ QString onlyLetters(const QString &in)
return out;
}
//! [23]
+
+//! [24]
+QVector<int> a, b;
+a.resize(100000); // make a big vector filled with 0.
+
+QVector<int>::iterator i = a.begin();
+// WRONG way of using the iterator i:
+b = a;
+/*
+ Now we should be careful with iterator i since it will point to shared data
+ If we do *i = 4 then we would change the shared instance (both vectors)
+ The behavior differs from STL containers. Avoid doing such things in Qt.
+*/
+
+a[0] = 5;
+/*
+ Container a is now detached from the shared data,
+ and even though i was an iterator from the container a, it now works as an iterator in b.
+ Here the situation is that (*i) == 0.
+*/
+
+b.clear(); // Now the iterator i is completely invalid.
+
+int j = *i; // Undefined behavior!
+/*
+ The data from b (which i pointed to) is gone.
+ This would be well-defined with STL containers (and (*i) == 5),
+ but with QVector this is likely to crash.
+*/
+//! [24]
diff --git a/src/corelib/doc/snippets/qloggingcategory/main.cpp b/src/corelib/doc/snippets/qloggingcategory/main.cpp
index 27d64e8253..c1dad7f43a 100644
--- a/src/corelib/doc/snippets/qloggingcategory/main.cpp
+++ b/src/corelib/doc/snippets/qloggingcategory/main.cpp
@@ -67,24 +67,45 @@ QList<UsbEntry> usbEntries() {
return entries;
}
-void main(int argc, char *argv[])
+//![20]
+void myCategoryFilter(QLoggingCategory *);
+//![20]
+
+//![21]
+QLoggingCategory::CategoryFilter oldCategoryFilter;
+
+void myCategoryFilter(QLoggingCategory *category)
+{
+ // configure qt.driver.usb category here, otherwise forward to to default filter.
+ if (qstrcmp(category->categoryName(), "qt.driver.usb") == 0)
+ category->setEnabled(QtDebugMsg, true);
+ else
+ oldCategoryFilter(category);
+}
+//![21]
+
+int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//![2]
- // don't run the expensive code if the string won't print
- if (QT_DRIVER_USB().isDebugEnabled()) {
- QStringList items;
- foreach (const UsbEntry &entry, usbEntries())
- items << QString("%1 (%2)").arg(entry.id, entry.classtype);
- qCDebug(QT_DRIVER_USB) << "devices: " << items;
- }
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.driver.usb.debug=true"));
//![2]
+//![22]
+
+// ...
+oldCategoryFilter = QLoggingCategory::installFilter(myCategoryFilter);
+//![22]
+
+//![3]
+ qSetMessagePattern("%{category} %{message}");
//![3]
+
+//![4]
// usbEntries() will only be called if QT_DRIVER_USB category is enabled
qCDebug(QT_DRIVER_USB) << "devices: " << usbEntries();
-//![3]
+//![4]
{
//![10]
@@ -106,8 +127,7 @@ void main(int argc, char *argv[])
qCCritical(category) << "a critical message";
//![12]
}
+
+ return 0;
}
-//![20]
-void myCategoryFilter(QLoggingCategory *);
-//![20]
diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc
index ff2df9c020..fa26409d83 100644
--- a/src/corelib/doc/src/containers.qdoc
+++ b/src/corelib/doc/src/containers.qdoc
@@ -533,10 +533,18 @@
This problem doesn't occur with functions that return a const or
non-const reference to a container.
+ \section3 Implicit sharing iterator problem
+
\l{Implicit sharing} has another consequence on STL-style
- iterators: You must not take a copy of a container while
- non-const iterators are active on that container. Java-style
- iterators don't suffer from that limitation.
+ iterators: you should avoid copying a container while
+ iterators are active on that container. The iterators
+ point to an internal structure, and if you copy a container
+ you should be very careful with your iterators. E.g:
+
+ \snippet code/doc_src_containers.cpp 24
+
+ The above example only shows a problem with QVector, but
+ the problem exists for all the implicitly shared Qt containers.
\keyword foreach
\section1 The foreach Keyword
diff --git a/src/corelib/doc/src/implicit-sharing.qdoc b/src/corelib/doc/src/implicit-sharing.qdoc
index 814f8140f3..1185fe8348 100644
--- a/src/corelib/doc/src/implicit-sharing.qdoc
+++ b/src/corelib/doc/src/implicit-sharing.qdoc
@@ -89,9 +89,12 @@
of data. Objects can easily be assigned, sent as function arguments,
and returned from functions.
- Implicit sharing takes place behind the scenes; the programmer
- does not need to worry about it. Even in multithreaded
- applications, implicit sharing takes place, as explained in
+ Implicit sharing mostly takes place behind the scenes;
+ the programmer rarely needs to worry about it. However, Qt's
+ container iterators have different behavior than those from
+ the STL. Read \l{Implicit sharing iterator problem}.
+
+ In multithreaded applications, implicit sharing takes place, as explained in
\l{Thread-Support in Qt Modules#Threads and Implicitly Shared Classes}
{Threads and Implicitly Shared Classes}.
@@ -105,9 +108,10 @@
greater than one. (This is often called \e {copy-on-write} or
\e {value semantics}.)
- An implicitly shared class has total control of its internal data. In
+ An implicitly shared class has control of its internal data. In
any member functions that modify its data, it automatically detaches
- before modifying the data.
+ before modifying the data. Notice, however, the special case with
+ container iterators; see \l{Implicit sharing iterator problem}.
The QPen class, which uses implicit sharing, detaches from the shared
data in all member functions that change the internal data.
@@ -133,9 +137,9 @@
In this example, \c p1 and \c p2 share data until QPainter::begin()
is called for \c p2, because painting a pixmap will modify it.
- \warning Do not copy an implicitly shared container (QMap,
- QVector, etc.) while you are iterating over it using an non-const
- \l{STL-style iterators}{STL-style iterator}.
+ \warning Be careful with copying an implicitly shared container
+ (QMap, QVector, etc.) while you use
+ \l{STL-style iterators}{STL-style iterator}. See \l{Implicit sharing iterator problem}.
\keyword implicitly shared classes
\annotatedlist shared
diff --git a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
index b86aae830f..dd93b80cae 100644
--- a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
+++ b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
@@ -28,6 +28,7 @@
/*!
\page signalsandslots.html
\title Signals & Slots
+ \keyword Signals and Slots
\ingroup qt-basic-concepts
\brief An overview of Qt's signals and slots inter-object
communication mechanism.
diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc
index e511c10423..4f381421b4 100644
--- a/src/corelib/doc/src/threads-basics.qdoc
+++ b/src/corelib/doc/src/threads-basics.qdoc
@@ -199,31 +199,6 @@
still important.
On Linux, Valgrind and Helgrind can help detect threading errors.
- The anatomy of QThread is quite interesting:
-
- \list
- \li QThread does not live in the new thread where \l{QThread::}{run()} is
- executed. It lives in the old thread.
- \li Most QThread methods are the thread's control interface and are meant to
- be called from the old thread. Do not move this interface to the newly
- created thread using \l{QObject::}{moveToThread()}; i.e., calling
- \l{QObject::moveToThread()}{moveToThread(this)} is regarded as bad
- practice.
- \li \l{QThread::}{exec()} and the static methods
- \l{QThread::}{usleep()}, \l{QThread::}{msleep()},
- \l{QThread::}{sleep()} are meant to be called from the newly created
- thread.
- \li Additional members defined in the QThread subclass are
- accessible by both threads. The developer is responsible for
- coordinating access. A typical strategy is to set the members before
- \l{QThread::}{start()} is called. Once the worker thread is running,
- the main thread should not touch the additional members anymore. After
- the worker has terminated, the main thread can access the additional
- members again. This is a convenient strategy for passing parameters to a
- thread before it is started as well as for collecting the result once it
- has terminated.
- \endlist
-
\section2 Protecting the Integrity of Data
When writing a multithread application, extra care must be taken to avoid
diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc
index 8962dceb01..890fd9f6ff 100644
--- a/src/corelib/doc/src/threads.qdoc
+++ b/src/corelib/doc/src/threads.qdoc
@@ -123,7 +123,7 @@
\nextpage Synchronizing Threads
Qt offers many classes and functions for working with threads. Below are
- three different approaches that Qt programmers can use to implement
+ four different approaches that Qt programmers can use to implement
multithreaded applications.
@@ -163,19 +163,47 @@
\section1 Qt Concurrent: Using a High-level API
The \l{Qt Concurrent} module provides high-level functions that deal with some
- common parallel computation patterns: map, filter, and reduce. Unlike QThread
- and QRunnable, these functions do not require the use of low-level threading
- primitives such as mutexes or semaphores. \l {Qt Concurrent} will automatically
- adjust the number of threads used according to the number of processor cores
- available, so applications written today will continue to scale when deployed
- later on a system with more cores.
-
- This module also provides the QtConcurrent::run() function, which can run
- any function in a thread managed by the global QThreadPool.
+ common parallel computation patterns: map, filter, and reduce. Unlike using
+ QThread and QRunnable, these functions never require the use of \l{Synchronizing
+ Threads#Low-Level Synchronization Primitives}{low-level threading primitives}
+ such as mutexes or semaphores. Instead, they return a QFuture object which can
+ be used to retrieve the functions' results when they are ready. QFuture can
+ also be used to query computation progress and to pause/resume/cancel the
+ computation. For convenience, QFutureWatcher enables interactions with
+ \l{QFuture}s via signals and slots.
+
+ \l{Qt Concurrent}'s map, filter and reduce algorithms automatically distribute
+ computation across all available processor cores, so applications written today
+ will continue to scale when deployed later on a system with more cores.
+
+ This module also provides the QtConcurrent::run() function, which can run any
+ function in another thread. However, QtConcurrent::run() only supports a subset
+ of features available to the map, filter and reduce functions. The QFuture
+ can be used to retrieve the function's return value and to check if the thread
+ is running. However, a call to QtConcurrent::run() uses one thread only, cannot
+ be paused/resumed/canceled, and cannot be queried for progress.
See the \l{Qt Concurrent} module documentation for details on the individual functions.
+ \section1 WorkerScript: Threading in QML
+
+ The WorkerScript QML type lets JavaScript code run in parallel with the GUI
+ thread.
+
+ Each WorkerScript instance can have one \c{.js} script attached to it. When
+ WorkerScript::sendMessage() is called, the script will run in a separate thread
+ (and a separate \l{QQmlContext}{QML context}). When the script finishes
+ running, it can send a reply back to the GUI thread which will invoke the
+ WorkerScript::onMessage() signal handler.
+
+ Using a WorkerScript is similar to using a worker QObject that has been moved
+ to another thread. Data is transferred between threads via signals.
+
+ See the WorkerScript documentation for details on how to implement the script,
+ and for a list of data types that can be passed between threads.
+
+
\section1 Choosing an Appropriate Approach
As demonstrated above, Qt provides different solutions for developing threaded
@@ -187,52 +215,62 @@
\table
\header
- \li Feature/Characteristic
+ \li Feature
\li QThread
- \li QRunnable
- \li Qt Concurrent\sup{*}
+ \li QRunnable and QThreadPool
+ \li QtConcurrent::run()
+ \li Qt Concurrent (Map, Filter, Reduce)
+ \li WorkerScript
+ \row
+ \li API
+ \li C++
+ \li C++
+ \li C++
+ \li C++
+ \li QML
\row
- \li Supports different thread priorities
+ \li Thread priority can be specified
\li Yes
+ \li Yes
+ \li
\li
\li
\row
- \li Supports an event loop
+ \li Thread can run an event loop
\li Yes
\li
\li
+ \li
+ \li
\row
- \li Supports transferring data to the thread using signals
+ \li Thread can receive data updates through signals
\li Yes (received by a worker QObject)
\li
\li
+ \li
+ \li Yes (received by WorkerScript)
\row
- \li Supports controlling the thread using signals
+ \li Thread can be controlled using signals
\li Yes (received by QThread)
\li
- \li Yes (received by QFutureWatcher)
- \row
- \li Supports thread reuse
\li
- \li Yes
- \li Yes
- \row
- \li Task-oriented
+ \li Yes (received by QFutureWatcher)
\li
- \li Yes
- \li Yes
\row
- \li High level API
+ \li Thread can be monitored through a QFuture
\li
\li
+ \li Partially
\li Yes
+ \li
\row
- \li Supports pausing/resuming/canceling
+ \li Built-in ability to pause/resume/cancel
+ \li
\li
\li
\li Yes
+ \li
\endtable
- \sup{\e{*Except QtConcurrent::run(), which is like QRunnable}}
\section2 Example Use Cases
@@ -244,7 +282,7 @@
\li Solution
\row
\li One call
- \li Run a linear function within another thread, optionally with progress
+ \li Run a new linear function within another thread, optionally with progress
updates during the run.
\li Qt provides different solutions:
\list
@@ -258,13 +296,29 @@
\endlist
\row
\li One call
+ \li Run an existing function within another thread and get its return value.
+ \li Run the function using QtConcurrent::run(). Have a QFutureWatcher emit
+ the \l{QFutureWatcher::}{finished()} signal when the function has
+ returned, and call QFutureWatcher::result() to get the function's return
+ value.
+ \row
+ \li One call
\li Perform an operation on all items of a container, using all available
cores. For example, producing thumbnails from a list of images.
\li Use Qt Concurrent's \l{QtConcurrent::}{filter()} function to select
container elements, and the \l{QtConcurrent::}{map()} function to apply
an operation to each element. To fold the output into a single result,
- use \l{QtConcurrent::}{filterReduced()} and \l{QtConcurrent::}{mapReduced()}
- instead.
+ use \l{QtConcurrent::}{filteredReduced()} and
+ \l{QtConcurrent::}{mappedReduced()} instead.
+ \row
+ \li One call/Permanent
+ \li Perfrom a long computation in a pure QML application, and update the GUI
+ when the results are ready.
+ \li Place the computation code in a \c{.js} script and attach it to a
+ WorkerScript instance. Call \l{WorkerScript::}{sendMessage()} to start the
+ computation in a new thread. Let the script call WorkerScript::sendMessage()
+ too, to pass the result back to the GUI thread. Handle the result in
+ \l{WorkerScript::}{onMessage} and update the GUI there.
\row
\li Permanent
\li Have an object living in another thread that can perform different
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index ef425e8d85..102a6487ee 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -165,6 +165,13 @@
# /* Compatibility with older Clang versions */
# define __has_extension __has_feature
# endif
+# if defined(__APPLE__)
+ /* Apple/clang specific features */
+# define Q_DECL_CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+# ifdef __OBJC__
+# define Q_DECL_NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased))
+# endif
+# endif
# else
/* Plain GCC */
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
@@ -628,14 +635,6 @@
# endif
#endif // Q_CC_CLANG
-#if defined(Q_CC_CLANG) && defined(__APPLE__)
-/* Apple/clang specific features */
-# define Q_DECL_CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
-# ifdef __OBJC__
-# define Q_DECL_NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased))
-# endif
-#endif
-
#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
@@ -704,15 +703,20 @@
# if _MSC_VER >= 1400
/* C++11 features supported in VC8 = VC2005: */
# define Q_COMPILER_VARIADIC_MACROS
+
+# ifndef __cplusplus_cli
/* 2005 supports the override and final contextual keywords, in
the same positions as the C++11 variants, but 'final' is
called 'sealed' instead:
http://msdn.microsoft.com/en-us/library/0w2w91tf%28v=vs.80%29.aspx
+ The behavior is slightly different in C++/CLI, which requires the
+ "virtual" keyword to be present too, so don't define for that.
So don't define Q_COMPILER_EXPLICIT_OVERRIDES (since it's not
the same as the C++11 version), but define the Q_DECL_* flags
accordingly: */
# define Q_DECL_OVERRIDE override
# define Q_DECL_FINAL sealed
+# endif
# endif
# if _MSC_VER >= 1600
/* C++11 features supported in VC10 = VC2010: */
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 2637a6a0d8..6f74c7de88 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -76,6 +76,10 @@
#include <CoreServices/CoreServices.h>
#endif
+#if defined(Q_OS_ANDROID)
+#include <private/qjni_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
#if !QT_DEPRECATED_SINCE(5, 0)
@@ -2348,6 +2352,9 @@ typedef uint SeedStorageType;
typedef QThreadStorage<SeedStorageType *> SeedStorage;
Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value
+#elif defined(Q_OS_ANDROID)
+typedef QThreadStorage<QJNIObjectPrivate> AndroidRandomStorage;
+Q_GLOBAL_STATIC(AndroidRandomStorage, randomTLS)
#endif
/*!
@@ -2381,6 +2388,16 @@ void qsrand(uint seed)
//global static object, fallback to srand(seed)
srand(seed);
}
+#elif defined(Q_OS_ANDROID)
+ QJNIObjectPrivate random = QJNIObjectPrivate("java/util/Random",
+ "(J)V",
+ jlong(seed));
+ if (!random.isValid()) {
+ srand(seed);
+ return;
+ }
+
+ randomTLS->setLocalData(random);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
@@ -2422,6 +2439,25 @@ int qrand()
//global static object, fallback to rand()
return rand();
}
+#elif defined(Q_OS_ANDROID)
+ AndroidRandomStorage *randomStorage = randomTLS();
+ if (!randomStorage)
+ return rand();
+
+ QJNIObjectPrivate random;
+ if (!randomStorage->hasLocalData()) {
+ random = QJNIObjectPrivate("java/util/Random",
+ "(J)V",
+ jlong(1));
+ if (!random.isValid())
+ return rand();
+
+ randomStorage->setLocalData(random);
+ } else {
+ random = randomStorage->localData();
+ }
+
+ return random.callMethod<jint>("nextInt", "(I)I", RAND_MAX);
#else
// On Windows srand() and rand() already use Thread-Local-Storage
// to store the seed between calls
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index ed17709a4d..b654ba3ac8 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -1004,13 +1004,19 @@ template <bool B, typename T = void> struct QEnableIf;
template <typename T> struct QEnableIf<true, T> { typedef T Type; };
}
-#ifdef __OBJC__
-#define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
-#else
-#define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
+#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
+# ifdef __OBJC__
+# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) @class classname
+# else
+# define Q_FORWARD_DECLARE_OBJC_CLASS(classname) typedef struct objc_object classname
+# endif
+#endif
+#ifndef Q_FORWARD_DECLARE_CF_TYPE
+# define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref
+#endif
+#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE
+# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
#endif
-#define Q_FORWARD_DECLARE_CF_TYPE(type) typedef const struct __ ## type * type ## Ref
-#define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
QT_END_NAMESPACE
// Q_GLOBAL_STATIC
diff --git a/src/corelib/global/qglobalstatic.h b/src/corelib/global/qglobalstatic.h
index 5d0b1e8514..ad39452cf4 100644
--- a/src/corelib/global/qglobalstatic.h
+++ b/src/corelib/global/qglobalstatic.h
@@ -57,11 +57,16 @@ enum GuardValues {
};
}
-#if defined(QT_NO_THREAD) || defined(Q_CC_GNU)
+#if defined(QT_NO_THREAD) || (defined(Q_CC_GNU) && !defined(Q_OS_MAC))
// some compilers support thread-safe statics
// The IA-64 C++ ABI requires this, so we know that all GCC versions since 3.4
// support it. C++11 also requires this behavior.
-// Clang and Intel CC masquerade as GCC when compiling on Linux and Mac OS X.
+// Clang and Intel CC masquerade as GCC when compiling on Linux.
+//
+// Apple's libc++abi however uses a global lock for initializing local statics,
+// which will block other threads also trying to initialize a local static
+// until the constructor returns ...
+// We better avoid these kind of problems by using our own locked implementation.
#define Q_GLOBAL_STATIC_INTERNAL(ARGS) \
Q_DECL_HIDDEN inline Type *innerFunction() \
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 9bc7506e39..a279498e93 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -446,7 +446,11 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
if (urlRef) {
QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
+#ifdef Q_OS_MACX
return QDir::cleanPath(QString(path) + QLatin1String("/Contents/") + ret);
+#else
+ return QDir::cleanPath(QString(path) + QLatin1Char('/') + ret); // iOS
+#endif
}
}
#endif
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 063e94069f..0a261acc77 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -549,6 +549,7 @@ static const char functionTokenC[] = "%{function}";
static const char pidTokenC[] = "%{pid}";
static const char appnameTokenC[] = "%{appname}";
static const char threadidTokenC[] = "%{threadid}";
+static const char ifCategoryTokenC[] = "%{if-category}";
static const char ifDebugTokenC[] = "%{if-debug}";
static const char ifWarningTokenC[] = "%{if-warning}";
static const char ifCriticalTokenC[] = "%{if-critical}";
@@ -556,7 +557,7 @@ static const char ifFatalTokenC[] = "%{if-fatal}";
static const char endifTokenC[] = "%{endif}";
static const char emptyTokenC[] = "";
-static const char defaultPattern[] = "%{message}";
+static const char defaultPattern[] = "%{if-category}%{category}: %{endif}%{message}";
struct QMessagePattern {
@@ -675,6 +676,7 @@ void QMessagePattern::setPattern(const QString &pattern)
tokens[i] = LEVEL; \
inIf = true; \
}
+ IF_TOKEN(ifCategoryTokenC)
IF_TOKEN(ifDebugTokenC)
IF_TOKEN(ifWarningTokenC)
IF_TOKEN(ifCriticalTokenC)
@@ -837,6 +839,9 @@ Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogCont
message.append(QLatin1String("0x"));
message.append(QString::number(qlonglong(QThread::currentThread()->currentThread()), 16));
#endif
+ } else if (token == ifCategoryTokenC) {
+ if (!context.category || (strcmp(context.category, "default") == 0))
+ skip = true;
#define HANDLE_IF_TOKEN(LEVEL) \
} else if (token == if##LEVEL##TokenC) { \
skip = type != Qt##LEVEL##Msg;
@@ -927,7 +932,7 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
#ifndef QT_BOOTSTRAPPED
// qDebug, qWarning, ... macros do not check whether category is enabled
if (!context.category || (strcmp(context.category, "default") == 0)) {
- if (QLoggingCategory *defaultCategory = &QLoggingCategory::defaultCategory()) {
+ if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory()) {
if (!defaultCategory->isEnabled(msgType))
return;
}
@@ -1108,6 +1113,7 @@ void qErrnoWarning(int code, const char *msg, ...)
\table
\header \li Placeholder \li Description
\row \li \c %{appname} \li QCoreApplication::applicationName()
+ \row \li \c %{category} \li Logging category
\row \li \c %{file} \li Path to source file
\row \li \c %{function} \li Function
\row \li \c %{line} \li Line in source file
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 1409e5d977..758f13596e 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -907,7 +907,7 @@ public:
Key_BrightnessAdjust = 0x010000c2,
Key_Finance = 0x010000c3,
Key_Community = 0x010000c4,
- Key_AudioRewind = 0x010000c5,
+ Key_AudioRewind = 0x010000c5, // Media rewind
Key_BackForward = 0x010000c6,
Key_ApplicationLeft = 0x010000c7,
Key_ApplicationRight = 0x010000c8,
@@ -919,7 +919,7 @@ public:
Key_Close = 0x010000ce,
Key_Copy = 0x010000cf,
Key_Cut = 0x010000d0,
- Key_Display = 0x010000d1,
+ Key_Display = 0x010000d1, // Output switch key
Key_DOS = 0x010000d2,
Key_Documents = 0x010000d3,
Key_Excel = 0x010000d4,
@@ -968,9 +968,9 @@ public:
Key_Bluetooth = 0x010000ff,
Key_WLAN = 0x01000100,
Key_UWB = 0x01000101,
- Key_AudioForward = 0x01000102,
- Key_AudioRepeat = 0x01000103,
- Key_AudioRandomPlay = 0x01000104,
+ Key_AudioForward = 0x01000102, // Media fast-forward
+ Key_AudioRepeat = 0x01000103, // Toggle repeat mode
+ Key_AudioRandomPlay = 0x01000104, // Toggle shuffle mode
Key_Subtitle = 0x01000105,
Key_AudioCycleTrack = 0x01000106,
Key_Time = 0x01000107,
@@ -1557,6 +1557,18 @@ public:
IgnoredGesturesPropagateToParent = 0x04
};
Q_DECLARE_FLAGS(GestureFlags, GestureFlag)
+
+ enum NativeGestureType
+ {
+ BeginNativeGesture,
+ EndNativeGesture,
+ PanNativeGesture,
+ ZoomNativeGesture,
+ SmartZoomNativeGesture,
+ RotateNativeGesture,
+ SwipeNativeGesture
+ };
+
#endif // QT_NO_GESTURES
enum NavigationMode
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 78f6a60287..e33fd085f2 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -1735,6 +1735,8 @@
\value LeftEdge The left edge of the rectangle.
\value RightEdge The right edge of the rectangle.
\value BottomEdge The bottom edge of the rectangle.
+
+ \since 5.1
*/
/*!
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 90122a9f0d..897af352c9 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -675,6 +675,8 @@ bool QFileInfo::exists() const
}
/*!
+ \since 5.2
+
Returns \c true if the \a file exists; otherwise returns \c false.
\note If \a file is a symlink that points to a non-existing
@@ -691,7 +693,8 @@ bool QFileInfo::exists(const QString &file)
QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, data);
// Expensive fallback to non-QFileSystemEngine implementation
if (engine)
- return QFileInfo(file).exists();
+ return QFileInfo(new QFileInfoPrivate(entry, data, engine)).exists();
+
QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute);
return data.exists();
}
diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h
index 442e6b5ef0..47359a55ce 100644
--- a/src/corelib/io/qfileinfo_p.h
+++ b/src/corelib/io/qfileinfo_p.h
@@ -120,6 +120,20 @@ public:
metaData = QFileSystemMetaData();
}
+ inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, QAbstractFileEngine *engine)
+ : fileEntry(file),
+ metaData(data),
+ fileEngine(engine),
+ cachedFlags(0),
+#ifndef QT_NO_FSFILEENGINE
+ isDefaultConstructed(false),
+#else
+ isDefaultConstructed(!fileEngine),
+#endif
+ cache_enabled(true), fileFlags(0), fileSize(0)
+ {
+ }
+
inline void clearFlags() const {
fileFlags = 0;
cachedFlags = 0;
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 105c8d34dd..77304b2cb9 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -1038,8 +1038,10 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
return data.hasFlags(what);
}
-static inline bool mkDir(const QString &path)
+static inline bool mkDir(const QString &path, DWORD *lastError = 0)
{
+ if (lastError)
+ *lastError = 0;
#if defined(Q_OS_WINCE)
// Unfortunately CreateDirectory returns true for paths longer than
// 256, but does not create a directory. It starts to fail, when
@@ -1059,7 +1061,11 @@ static inline bool mkDir(const QString &path)
if (platformId == 1 && QFSFileEnginePrivate::longFileName(path).size() > 256)
return false;
#endif
- return ::CreateDirectory((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), 0);
+ const QString longPath = QFSFileEnginePrivate::longFileName(path);
+ const bool result = ::CreateDirectory((wchar_t*)longPath.utf16(), 0);
+ if (lastError) // Capture lastError before any QString is freed since custom allocators might change it.
+ *lastError = GetLastError();
+ return result;
}
static inline bool rmDir(const QString &path)
@@ -1131,9 +1137,9 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea
slash = dirName.length();
}
if (slash) {
+ DWORD lastError;
QString chunk = dirName.left(slash);
- if (!mkDir(chunk)) {
- const DWORD lastError = GetLastError();
+ if (!mkDir(chunk, &lastError)) {
if (lastError == ERROR_ALREADY_EXISTS || lastError == ERROR_ACCESS_DENIED) {
bool existed = false;
if (isDirPath(chunk, &existed) && existed)
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 8fb80123fa..a81b8580c4 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -99,8 +99,10 @@ void debugBinaryString(const char *data, qint64 maxlen)
#define CHECK_WRITABLE(function, returnType) \
do { \
if ((d->openMode & WriteOnly) == 0) { \
- if (d->openMode == NotOpen) \
+ if (d->openMode == NotOpen) { \
+ qWarning("QIODevice::"#function": device not open"); \
return returnType; \
+ } \
qWarning("QIODevice::"#function": ReadOnly device"); \
return returnType; \
} \
@@ -109,8 +111,10 @@ void debugBinaryString(const char *data, qint64 maxlen)
#define CHECK_READABLE(function, returnType) \
do { \
if ((d->openMode & ReadOnly) == 0) { \
- if (d->openMode == NotOpen) \
+ if (d->openMode == NotOpen) { \
+ qWarning("QIODevice::"#function": device not open"); \
return returnType; \
+ } \
qWarning("QIODevice::"#function": WriteOnly device"); \
return returnType; \
} \
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index 1676b71133..dc8817706c 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -140,6 +140,13 @@ static bool setNativeLocks(int fd)
QLockFile::LockError QLockFilePrivate::tryLock_sys()
{
+ // Assemble data, to write in a single call to write
+ // (otherwise we'd have to check every write call)
+ // Use operator% from the fast builder to avoid multiple memory allocations.
+ QByteArray fileData = QByteArray::number(QCoreApplication::applicationPid()) % '\n'
+ % qAppName().toUtf8() % '\n'
+ % localHostName().toUtf8() % '\n';
+
const QByteArray lockFileName = QFile::encodeName(fileName);
const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0644);
if (fd < 0) {
@@ -160,16 +167,6 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
// We hold the lock, continue.
fileHandle = fd;
- // Assemble data, to write in a single call to write
- // (otherwise we'd have to check every write call)
- QByteArray fileData;
- fileData += QByteArray::number(QCoreApplication::applicationPid());
- fileData += '\n';
- fileData += qAppName().toUtf8();
- fileData += '\n';
- fileData += localHostName().toUtf8();
- fileData += '\n';
-
QLockFile::LockError error = QLockFile::NoError;
if (qt_write_loop(fd, fileData.constData(), fileData.size()) < fileData.size())
error = QLockFile::UnknownError; // partition full
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 6c5df1e8e7..8d337ec630 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -71,30 +71,36 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
\section1 Checking category configuration
- QLoggingCategory provides a generic \l isEnabled() and message
- type dependent \l isDebugEnabled(), \l isWarningEnabled(),
- \l isCriticalEnabled() and \l isTraceEnabled()
- methods for checking whether the current category is enabled.
+ QLoggingCategory provides \l isDebugEnabled(), \l isWarningEnabled(),
+ \l isCriticalEnabled(), \l isTraceEnabled(), as well as \l isEnabled()
+ to check whether messages for the given message type should be logged.
\note The qCDebug(), qCWarning(), qCCritical(), qCTrace() and
qCTraceGuard() macros prevent arguments from being evaluated if the
respective message types are not enabled for the category, so explicit
checking is not needed:
- \snippet qloggingcategory/main.cpp 3
+ \snippet qloggingcategory/main.cpp 4
- \section1 Default configuration
+ \section1 Default category configuration
In the default configuration \l isWarningEnabled() and \l isCriticalEnabled()
- will return \c true. By default, \l isDebugEnabled() will return \c true only
+ will return \c true. \l isDebugEnabled() will return \c true only
for the \c "default" category.
- \section1 Changing configuration
+ \section1 Changing the configuration of a category
+
+ Use either \l setFilterRules() or \l installFilter() to
+ configure categories, for example
+
+ \snippet qloggingcategory/main.cpp 2
+
+ \section1 Printing the category
+
+ Use the \c %{category} place holder to print the category in the default
+ message handler:
- The default configuration can be changed by calling \l setEnabled(). However,
- this only affects the current category object, not e.g. another object for the
- same category name. Use either \l setFilterRules() or \l installFilter() to
- configure categories globally.
+ \snippet qloggingcategory/main.cpp 3
*/
typedef QVector<QTracer *> Tracers;
@@ -117,7 +123,10 @@ QLoggingCategory::QLoggingCategory(const char *category)
enabledDebug(false),
enabledWarning(true),
enabledCritical(true),
- enabledTrace(false)
+ enabledTrace(false),
+ placeholder1(false),
+ placeholder2(false),
+ placeholder3(false)
{
bool isDefaultCategory
= (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
@@ -215,14 +224,12 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
/*!
Changes the message type \a type for the category to \a enable.
- Changes only affect the current QLoggingCategory object, and won't
- change e.g. the settings of another objects for the same category name.
+ \note Changes only affect the current QLoggingCategory object, and won't
+ change the settings of other objects for the same category name.
+ Use either \l setFilterRules() or \l installFilter() to change the
+ configuration globally.
\note \c QtFatalMsg cannot be changed. It will always return \c true.
-
- Example:
-
- \snippet qtracer/ftracer.cpp 5
*/
void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
{
@@ -244,12 +251,19 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
*/
/*!
- Returns the category \c "default" that is used e.g. by qDebug(), qWarning(),
- qCritical(), qFatal().
+ Returns a pointer to the global category \c "default" that
+ is used e.g. by qDebug(), qWarning(), qCritical(), qFatal().
+
+ \note The returned pointer may be null during destruction of
+ static objects.
+
+ \note Ownership of the category is not transferred, do not
+ \c delete the returned pointer.
+
*/
-QLoggingCategory &QLoggingCategory::defaultCategory()
+QLoggingCategory *QLoggingCategory::defaultCategory()
{
- return *qtDefaultCategory();
+ return qtDefaultCategory();
}
/*!
@@ -272,6 +286,12 @@ QLoggingCategory &QLoggingCategory::defaultCategory()
filter is free to change the respective category configuration with
\l setEnabled().
+ The filter might be called concurrently from different threads, and
+ therefore has to be reentrant.
+
+ Example:
+ \snippet qloggingcategory/main.cpp 21
+
An alternative way of configuring the default filter is via
\l setFilterRules().
*/
@@ -281,7 +301,6 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
return QLoggingRegistry::instance()->installFilter(filter);
}
-
/*!
Configures which categories and message types should be enabled through a
a set of \a rules.
@@ -296,8 +315,13 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
wildcard symbol at the start and/or the end. The optional \c <type> must
be either \c debug, \c warning, \c critical, or \c trace.
- The rules might be ignored if a custom category filter is installed with
- \l installFilter().
+ Example:
+
+ \snippet qloggingcategory/main.cpp 2
+
+ \note The rules might be ignored if a custom category filter is installed
+ with \l installFilter().
+
*/
void QLoggingCategory::setFilterRules(const QString &rules)
{
@@ -380,7 +404,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
The macro expands to code that checks whether
\l QLoggingCategory::isTraceEnabled() evaluates to \c true.
- If so, the stream arguments are processed and sent to the tracers
+ If so, the stream arguments are processed and sent to the \l QTracer objects
registered with the category.
\note Arguments are not processed if trace output for the category is not
@@ -390,7 +414,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\snippet qtracer/ftracer.cpp 6
- \sa qCTraceGuard()
+ \sa qCTraceGuard() QTraceGuard
*/
/*!
@@ -402,11 +426,12 @@ void QLoggingCategory::setFilterRules(const QString &rules)
storage. The guard constructor checks whether
\l QLoggingCategory::isTraceEnabled() evaluates to \c true.
If so, the stream arguments are processed and the \c{start()}
- functions of the tracers registered with the \a category are called.
+ functions of the \l QTracer objects registered with the \a category are
+ called.
The guard destructor also checks whether the category is enabled for
tracing and if so, the \c{end()}
- functions of the tracers registered with the \a category are called.
+ functions of the \l QTracer objects registered with the \a category are called.
\note Arguments are always processed, even if trace output for the
category is disabled. They will, however, in that case not be passed
@@ -416,7 +441,7 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\snippet qtracer/ftracer.cpp 4
- \sa qCTrace()
+ \sa qCTrace() QTracer
*/
/*!
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index 35da04c8f2..7a119f4937 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -72,7 +72,7 @@ public:
// allows usage of both factory method and variable in qCX macros
QLoggingCategory &operator()() { return *this; }
- static QLoggingCategory &defaultCategory();
+ static QLoggingCategory *defaultCategory();
typedef void (*CategoryFilter)(QLoggingCategory*);
static CategoryFilter installFilter(CategoryFilter);
@@ -92,6 +92,10 @@ private:
bool enabledWarning;
bool enabledCritical;
bool enabledTrace;
+ // reserve space for future use
+ bool placeholder1;
+ bool placeholder2;
+ bool placeholder3;
};
class Q_CORE_EXPORT QTracer
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 6b7c5bde2d..fe5faa2be7 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -1840,12 +1840,21 @@ void QUrl::setUrl(const QString &url, ParsingMode parsingMode)
input. It must also start with an ASCII letter.
The scheme describes the type (or protocol) of the URL. It's
- represented by one or more ASCII characters at the start the URL,
- and is followed by a ':'. The following example shows a URL where
- the scheme is "ftp":
+ represented by one or more ASCII characters at the start the URL.
+
+ A scheme is strictly \l {http://www.ietf.org/rfc/rfc3986.txt} {RFC 3986}-compliant:
+ \tt {scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )}
+
+ The following example shows a URL where the scheme is "ftp":
\image qurl-authority2.png
+ To set the scheme, the following call is used:
+ \code
+ QUrl url;
+ url.setScheme("ftp");
+ \endcode
+
The scheme can also be empty, in which case the URL is interpreted
as relative.
@@ -3327,7 +3336,7 @@ QString QUrl::fromPercentEncoding(const QByteArray &input)
them to \a include.
Unreserved is defined as:
- ALPHA / DIGIT / "-" / "." / "_" / "~"
+ \tt {ALPHA / DIGIT / "-" / "." / "_" / "~"}
\snippet code/src_corelib_io_qurl.cpp 6
*/
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index 7e77b9c251..80fc0319fe 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -304,7 +304,7 @@ static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *b
// we've decoded something; safety-check it
if (uc < min_uc)
return false;
- if (QChar::isSurrogate(uc) || QChar::isNonCharacter(uc) || uc > QChar::LastValidCodePoint)
+ if (QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint)
return false;
if (!QChar::requiresSurrogates(uc)) {
@@ -410,10 +410,9 @@ static int recode(QString &result, const ushort *begin, const ushort *end, QUrl:
const ushort *input = begin;
ushort *output = 0;
+ EncodingAction action = EncodeCharacter;
for ( ; input != end; ++input) {
ushort c;
- EncodingAction action;
-
// try a run where no change is necessary
for ( ; input != end; ++input) {
c = *input;
diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp
index 8dd7f6092f..d81de89628 100644
--- a/src/corelib/json/qjsonarray.cpp
+++ b/src/corelib/json/qjsonarray.cpp
@@ -1089,7 +1089,7 @@ void QJsonArray::compact()
}
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonArray &a)
{
if (!a.a) {
diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h
index 1474ccae41..562e6accd7 100644
--- a/src/corelib/json/qjsonarray.h
+++ b/src/corelib/json/qjsonarray.h
@@ -211,7 +211,7 @@ private:
QJsonPrivate::Array *a;
};
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &);
#endif
diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp
index 4806ac68d6..6e257df39d 100644
--- a/src/corelib/json/qjsondocument.cpp
+++ b/src/corelib/json/qjsondocument.cpp
@@ -303,10 +303,12 @@ QVariant QJsonDocument::toVariant() const
\sa fromJson()
*/
+#ifndef QT_JSON_READONLY
QByteArray QJsonDocument::toJson() const
{
return toJson(Indented);
}
+#endif
/*!
\enum QJsonDocument::JsonFormat
@@ -338,6 +340,7 @@ QByteArray QJsonDocument::toJson() const
\sa fromJson(), JsonFormat
*/
+#ifndef QT_JSON_READONLY
QByteArray QJsonDocument::toJson(JsonFormat format) const
{
if (!d)
@@ -352,6 +355,7 @@ QByteArray QJsonDocument::toJson(JsonFormat format) const
return json;
}
+#endif
/*!
Parses a UTF-8 encoded JSON document and creates a QJsonDocument
@@ -562,7 +566,7 @@ bool QJsonDocument::isNull() const
return (d == 0);
}
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonDocument &o)
{
if (!o.d) {
diff --git a/src/corelib/json/qjsondocument.h b/src/corelib/json/qjsondocument.h
index 0354262e2c..ea42d76b20 100644
--- a/src/corelib/json/qjsondocument.h
+++ b/src/corelib/json/qjsondocument.h
@@ -117,7 +117,7 @@ public:
#ifdef Q_QDOC
QByteArray toJson(JsonFormat format = Indented) const;
-#else
+#elif !defined(QT_JSON_READONLY)
QByteArray toJson() const; //### Merge in Qt6
QByteArray toJson(JsonFormat format) const;
#endif
@@ -148,7 +148,7 @@ private:
QJsonPrivate::Data *d;
};
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonDocument &);
#endif
diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp
index 362d01384e..afc0d5f71f 100644
--- a/src/corelib/json/qjsonobject.cpp
+++ b/src/corelib/json/qjsonobject.cpp
@@ -1036,7 +1036,7 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val)
insert(e->key(), val);
}
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonObject &o)
{
if (!o.o) {
diff --git a/src/corelib/json/qjsonobject.h b/src/corelib/json/qjsonobject.h
index 8226b614b4..ad3184b1f2 100644
--- a/src/corelib/json/qjsonobject.h
+++ b/src/corelib/json/qjsonobject.h
@@ -206,7 +206,7 @@ private:
QJsonPrivate::Object *o;
};
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
#endif
diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp
index 8721f06064..516c53775c 100644
--- a/src/corelib/json/qjsonparser.cpp
+++ b/src/corelib/json/qjsonparser.cpp
@@ -853,7 +853,7 @@ static inline bool scanUtf8Char(const char *&json, const char *end, uint *result
uc = (uc << 6) | (ch & 0x3f);
}
- if (uc < min_uc || QChar::isNonCharacter(uc) ||
+ if (uc < min_uc ||
QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) {
return false;
}
diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp
index 8aa1f654c6..0a603b958a 100644
--- a/src/corelib/json/qjsonvalue.cpp
+++ b/src/corelib/json/qjsonvalue.cpp
@@ -661,7 +661,7 @@ QJsonValue QJsonValueRef::toValue() const
return o->valueAt(index);
}
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonValue &o)
{
switch (o.t) {
diff --git a/src/corelib/json/qjsonvalue.h b/src/corelib/json/qjsonvalue.h
index b18bbde0f7..c0ecdd2b61 100644
--- a/src/corelib/json/qjsonvalue.h
+++ b/src/corelib/json/qjsonvalue.h
@@ -179,7 +179,7 @@ private:
uint index : 31;
};
-#ifndef QT_NO_DEBUG_STREAM
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
#endif
diff --git a/src/corelib/json/qjsonwriter.cpp b/src/corelib/json/qjsonwriter.cpp
index 8426b351f6..86cca4bb26 100644
--- a/src/corelib/json/qjsonwriter.cpp
+++ b/src/corelib/json/qjsonwriter.cpp
@@ -138,13 +138,6 @@ static QByteArray escapedString(const QString &s)
if (u < 0x0800) {
*cursor++ = 0xc0 | ((uchar) (u >> 6));
} else {
- // is it one of the Unicode non-characters?
- if (QChar::isNonCharacter(u)) {
- *cursor++ = replacement;
- ++ch;
- continue;
- }
-
if (QChar::requiresSurrogates(u)) {
*cursor++ = 0xf0 | ((uchar) (u >> 18));
*cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index 2ca0a7d0b0..e974c4d226 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -249,7 +249,7 @@ public:
TouchEnd = 196,
#ifndef QT_NO_GESTURES
- NativeGesture = 197, // Internal for platform gesture support
+ NativeGesture = 197, // QtGui native gesture
#endif
RequestSoftwareInputPanel = 199,
CloseSoftwareInputPanel = 200,
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
index d9e38b68b2..b9137ec139 100644
--- a/src/corelib/kernel/qeventdispatcher_blackberry.cpp
+++ b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Research In Motion
+** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -78,6 +78,19 @@ private:
int outerChannel;
};
+class BBScopedLoopLevelCounter
+{
+ QEventDispatcherBlackberryPrivate *d;
+
+public:
+ inline BBScopedLoopLevelCounter(QEventDispatcherBlackberryPrivate *p)
+ : d(p)
+ { ++d->loop_level; }
+
+ inline ~BBScopedLoopLevelCounter()
+ { --d->loop_level; }
+};
+
struct bpsIOHandlerData
{
bpsIOHandlerData()
@@ -147,7 +160,8 @@ static int bpsIOHandler(int fd, int io_events, void *data)
}
QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate()
- : ioData(new bpsIOHandlerData)
+ : loop_level(0)
+ , ioData(new bpsIOHandlerData)
{
// prepare to use BPS
int result = bps_initialize();
@@ -156,6 +170,11 @@ QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate()
bps_channel = bps_channel_get_active();
+ if (bps_channel_create(&holding_channel, 0) != BPS_SUCCESS) {
+ qWarning("QEventDispatcherBlackberry: bps_channel_create failed");
+ holding_channel = -1;
+ }
+
// get domain for IO ready and wake up events - ignoring race condition here for now
if (bpsUnblockDomain == -1) {
bpsUnblockDomain = bps_register_domain();
@@ -166,6 +185,11 @@ QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate()
QEventDispatcherBlackberryPrivate::~QEventDispatcherBlackberryPrivate()
{
+ if ((holding_channel != -1) &&
+ (bps_channel_destroy(holding_channel) != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_channel_destroy failed");
+ }
+
// we're done using BPS
bps_shutdown();
}
@@ -280,11 +304,21 @@ static inline int timespecToMillisecs(const timespec &tv)
return (tv.tv_sec * 1000) + (tv.tv_nsec / 1000000);
}
+static inline void destroyHeldBpsEvent(int holding_channel)
+{
+ // Switch to the holding channel and use bps_get_event() to trigger its destruction. We
+ // don't care about the return value from this call to bps_get_event().
+ BpsChannelScopeSwitcher holdingChannelSwitcher(holding_channel);
+ bps_event_t *held_event = 0;
+ (void)bps_get_event(&held_event, 0);
+ }
+
int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
timespec *timeout)
{
Q_UNUSED(nfds);
Q_D(QEventDispatcherBlackberry);
+ const BBScopedLoopLevelCounter bbLoopCounter(d);
BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
@@ -307,6 +341,31 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef
bps_event_t *event = 0;
unsigned int eventCount = 0;
+ // If an event handler called through filterEvent() starts a nested event loop by creating a
+ // new QEventLoop, we will recursively enter this function again. However, each time
+ // bps_get_event() is called, it destroys the last event it handed out before returning the
+ // next event. We don't want it to destroy the event that triggered the nested event loop,
+ // since there may still be more handlers that need to get that event, once the nested event
+ // loop is done and control returns to the outer event loop.
+ //
+ // So we move an event to a holding channel, which takes ownership of the event. Putting
+ // the event on our own channel allows us to manage when it is destroyed, keeping it alive
+ // until we know we are done with it. Each recursive call of this function needs to have
+ // it's own holding channel, since a channel is a queue, not a stack.
+ //
+ // However, a recursive call into this function happens very rarely compared to the many
+ // times this function is called. We don't want to create a holding channel for each time
+ // this function is called, only when it is called recursively. Thus we have the instance
+ // variable d->holding_channel to use in the common case. We keep track of recursive calls
+ // with d->loop_level. If we are in a recursive call, then we create a new holding channel
+ // for this run.
+ int holding_channel = d->holding_channel;
+ if ((d->loop_level > 1) &&
+ Q_UNLIKELY(bps_channel_create(&holding_channel, 0) != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_channel_create failed");
+ holding_channel = -1;
+ }
+
// Convert timeout to milliseconds
int timeoutTotal = -1;
if (timeout)
@@ -331,6 +390,11 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef
emit awake();
filterNativeEvent(QByteArrayLiteral("bps_event_t"), static_cast<void*>(event), 0);
emit aboutToBlock();
+
+ if (Q_LIKELY(holding_channel != -1)) {
+ // We are now done with this BPS event. Destroy it.
+ destroyHeldBpsEvent(holding_channel);
+ }
}
// Update the timeout
@@ -370,6 +434,12 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef
if (bps_event_get_domain(event) == bpsUnblockDomain) {
timeoutTotal = 0; // in order to immediately drain the event queue of native events
event = 0; // (especially touch move events) we don't break out here
+ } else {
+ // Move the event to our holding channel so we can manage when it is destroyed.
+ if (Q_LIKELY(holding_channel != 1) &&
+ Q_UNLIKELY(bps_channel_push_event(holding_channel, event) != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_channel_push_event failed");
+ }
}
++eventCount;
@@ -379,12 +449,26 @@ int QEventDispatcherBlackberry::select(int nfds, fd_set *readfds, fd_set *writef
const unsigned int maximumEventCount = 12;
if (Q_UNLIKELY((eventCount > maximumEventCount && timeoutLeft == 0)
|| !QElapsedTimer::isMonotonic())) {
- if (event)
+ if (event) {
filterNativeEvent(QByteArrayLiteral("bps_event_t"), static_cast<void*>(event), 0);
+
+ if (Q_LIKELY(holding_channel != -1)) {
+ // We are now done with this BPS event. Destroy it.
+ destroyHeldBpsEvent(holding_channel);
+ }
+ }
break;
}
}
+ // If this was a recursive call into this function, a new holding channel was created for
+ // this run, so destroy it now.
+ if ((holding_channel != d->holding_channel) &&
+ Q_LIKELY(holding_channel != -1) &&
+ Q_UNLIKELY(bps_channel_destroy(holding_channel) != BPS_SUCCESS)) {
+ qWarning("QEventDispatcherBlackberry: bps_channel_destroy failed");
+ }
+
// the number of bits set in the file sets
return d->ioData->count;
}
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry_p.h b/src/corelib/kernel/qeventdispatcher_blackberry_p.h
index 5a4c3a9dcd..1764c244d8 100644
--- a/src/corelib/kernel/qeventdispatcher_blackberry_p.h
+++ b/src/corelib/kernel/qeventdispatcher_blackberry_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Research In Motion
+** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -95,6 +95,8 @@ public:
int processThreadWakeUp(int nsel);
int bps_channel;
+ int holding_channel;
+ int loop_level;
QScopedPointer<bpsIOHandlerData> ioData;
};
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 20e13a050f..5754af42ac 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1892,6 +1892,7 @@ void QVariant::load(QDataStream &s)
void QVariant::save(QDataStream &s) const
{
quint32 typeId = type();
+ bool fakeUserType = false;
if (s.version() < QDataStream::Qt_4_0) {
int i;
for (i = 0; i <= MapFromThreeCount - 1; ++i) {
@@ -1916,12 +1917,16 @@ void QVariant::save(QDataStream &s) const
} else if (typeId >= QMetaType::QKeySequence && typeId <= QMetaType::QQuaternion) {
// and as a result these types received lower ids too
typeId +=1;
+ } else if (typeId == QMetaType::QPolygonF) {
+ // This existed in Qt 4 only as a custom type
+ typeId = 127;
+ fakeUserType = true;
}
}
s << typeId;
if (s.version() >= QDataStream::Qt_4_2)
s << qint8(d.is_null);
- if (d.type >= QVariant::UserType) {
+ if (d.type >= QVariant::UserType || fakeUserType) {
s << QMetaType::typeName(userType());
}
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index d33cc90127..adad4b81a1 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -206,20 +206,20 @@ QThreadPrivate::~QThreadPrivate()
There will not be any event loop running in the thread unless you call
exec().
- It is important to remember that a QThread object usually lives
- in the thread where it was created, not in the thread that it
- manages. This oft-overlooked detail means that a QThread's slots
- will be executed in the context of its home thread, not in the
- context of the thread it is managing. For this reason,
- implementing new slots in a QThread subclass is error-prone and
- discouraged.
+ It is important to remember that a QThread instance \l{QObject#Thread
+ Affinity}{lives in} the old thread that instantiated it, not in the
+ new thread that calls run(). This means that all of QThread's queued
+ slots will execute in the old thread. Thus, a developer who wishes to
+ invoke slots in the new thread must use the worker-object approach; new
+ slots should not be implemented directly into a subclassed QThread.
- \note If you interact with an object, using any technique other
- than queued signal/slot connections (e.g. direct function calls),
- then the usual multithreading precautions need to be taken.
+ When subclassing QThread, keep in mind that the constructor executes in
+ the old thread while run() executes in the new thread. If a member
+ variable is accessed from both functions, then the variable is accessed
+ from two different threads. Check that it is safe to do so.
- \note It is not possible to change the thread affinity of GUI
- objects; they must remain in the main thread.
+ \note Care must be taken when interacting with objects across different
+ threads. See \l{Synchronizing Threads} for details.
\section1 Managing threads
@@ -264,7 +264,7 @@ QThreadPrivate::~QThreadPrivate()
\l{Mandelbrot Example}, as that is the name of the QThread subclass).
Note that this is currently not available with release builds on Windows.
- \sa {Thread Support in Qt}, QThreadStorage, QMutex, QSemaphore, QWaitCondition,
+ \sa {Thread Support in Qt}, QThreadStorage, {Synchronizing Threads}
{Mandelbrot Example}, {Semaphores Example}, {Wait Conditions Example}
*/
@@ -491,7 +491,8 @@ uint QThread::stackSize() const
that was passed to exit(). The value returned is 0 if exit() is called via
quit().
- It is necessary to call this function to start event handling.
+ This function is meant to be called from within run(). It is necessary to
+ call this function to start event handling.
\sa quit(), exit()
*/
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index 4eb7a170dc..cd389470a4 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -764,7 +764,7 @@
\relates <QtAlgorithms>
\since 5.2
- Returns the number of bits set in \a v. This number also called
+ Returns the number of bits set in \a v. This number is also called
the Hamming Weight of \a v.
*/
diff --git a/src/corelib/tools/qcollator_posix.cpp b/src/corelib/tools/qcollator_posix.cpp
index c6e589c174..a43618dcf1 100644
--- a/src/corelib/tools/qcollator_posix.cpp
+++ b/src/corelib/tools/qcollator_posix.cpp
@@ -44,6 +44,7 @@
#include "qstring.h"
#include <cstring>
+#include <cwchar>
QT_BEGIN_NAMESPACE
@@ -141,7 +142,7 @@ bool QCollatorSortKey::operator<(const QCollatorSortKey &otherKey) const
int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
{
- return wcscmp(d->m_key.constData(),
+ return std::wcscmp(d->m_key.constData(),
otherKey.d->m_key.constData());
}
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 56f715e5c8..6620c55a0f 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -894,7 +894,7 @@ QString QDate::toString(Qt::DateFormat format) const
case Qt::DefaultLocaleLongDate:
return QLocale().toString(*this, QLocale::LongFormat);
case Qt::RFC2822Date:
- return toString(QStringLiteral("dd MMM yyyy"));
+ return QLocale::c().toString(*this, QStringLiteral("dd MMM yyyy"));
default:
#ifndef QT_NO_TEXTDATE
case Qt::TextDate:
@@ -1641,9 +1641,6 @@ QString QTime::toString(Qt::DateFormat format) const
case Qt::DefaultLocaleLongDate:
return QLocale().toString(*this, QLocale::LongFormat);
case Qt::RFC2822Date:
- return QString::fromLatin1("%1:%2:%3").arg(hour(), 2, 10, QLatin1Char('0'))
- .arg(minute(), 2, 10, QLatin1Char('0'))
- .arg(second(), 2, 10, QLatin1Char('0'));
case Qt::ISODate:
case Qt::TextDate:
default:
@@ -3551,27 +3548,8 @@ QString QDateTime::toString(Qt::DateFormat format) const
case Qt::DefaultLocaleLongDate:
return QLocale().toString(*this, QLocale::LongFormat);
case Qt::RFC2822Date: {
- buf = toString(QStringLiteral("dd MMM yyyy hh:mm:ss "));
-
- int utcOffset = d->m_offsetFromUtc;
- if (timeSpec() == Qt::LocalTime) {
- QDateTime utc = toUTC();
- utc.setTimeSpec(timeSpec());
- utcOffset = utc.secsTo(*this);
- }
-
- const int offset = qAbs(utcOffset);
- buf += QLatin1Char((offset == utcOffset) ? '+' : '-');
-
- const int hour = offset / 3600;
- if (hour < 10)
- buf += QLatin1Char('0');
- buf += QString::number(hour);
-
- const int min = (offset - (hour * 3600)) / 60;
- if (min < 10)
- buf += QLatin1Char('0');
- buf += QString::number(min);
+ buf = QLocale::c().toString(*this, QStringLiteral("dd MMM yyyy hh:mm:ss "));
+ buf += toOffsetString(Qt::TextDate, d->m_offsetFromUtc);
return buf;
}
default:
@@ -3924,7 +3902,16 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const
QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
{
- return fromMSecsSinceEpoch(toMSecsSinceEpoch(), spec, 0);
+ if (d->m_spec == spec && (spec == Qt::UTC || spec == Qt::LocalTime))
+ return *this;
+
+ if (!isValid()) {
+ QDateTime ret = *this;
+ ret.setTimeSpec(spec);
+ return ret;
+ }
+
+ return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), spec, 0);
}
/*!
@@ -3942,7 +3929,16 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
{
- return fromMSecsSinceEpoch(toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds);
+ if (d->m_spec == Qt::OffsetFromUTC && d->m_offsetFromUtc == offsetSeconds)
+ return *this;
+
+ if (!isValid()) {
+ QDateTime ret = *this;
+ ret.setOffsetFromUtc(offsetSeconds);
+ return ret;
+ }
+
+ return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds);
}
#ifndef QT_BOOTSTRAPPED
@@ -3956,7 +3952,16 @@ QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const
{
- return fromMSecsSinceEpoch(toMSecsSinceEpoch(), timeZone);
+ if (d->m_spec == Qt::TimeZone && d->m_timeZone == timeZone)
+ return *this;
+
+ if (!isValid()) {
+ QDateTime ret = *this;
+ ret.setTimeZone(timeZone);
+ return ret;
+ }
+
+ return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), timeZone);
}
#endif // QT_BOOTSTRAPPED
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 7f6feaf8a0..f14fac00b8 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -1594,6 +1594,11 @@ void QHashData::checkSanity()
need to keep iterators over a long period of time, we recommend
that you use QMap rather than QHash.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QHash::const_iterator, QMutableHashIterator
*/
@@ -1791,6 +1796,11 @@ void QHashData::checkSanity()
internal data structure. If you need to keep iterators over a long
period of time, we recommend that you use QMap rather than QHash.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QHash::iterator, QHashIterator
*/
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
index 28319f3fda..e967163b8b 100644
--- a/src/corelib/tools/qlinkedlist.cpp
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -691,9 +691,12 @@ const QLinkedListData QLinkedListData::shared_null = {
Multiple iterators can be used on the same list. If you add items
to the list, existing iterators will remain valid. If you remove
items from the list, iterators that point to the removed items
- will become dangling iterators. However, because of how \l{implicit
- sharing} works, you must not take a copy of a container while
- iterators are active on that container.
+ will become dangling iterators.
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
\sa QLinkedList::const_iterator, QMutableLinkedListIterator
*/
@@ -910,6 +913,11 @@ const QLinkedListData QLinkedListData::shared_null = {
items from the list, iterators that point to the removed items
will become dangling iterators.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QLinkedList::iterator, QLinkedListIterator
*/
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 5bced19404..0811c3793e 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -647,7 +647,10 @@ void **QListData::erase(void **xi)
\a i must be a valid index position in the list (i.e., 0 <= \a i <
size()).
- This function is very fast (\l{constant time}).
+ If this function is called on a list that is currently being shared, it
+ will trigger a copy of all elements. Otherwise, this function runs in
+ \l{constant time}. If you do not want to modify the list you should use
+ QList::at().
\sa at(), value()
*/
@@ -656,7 +659,7 @@ void **QListData::erase(void **xi)
\overload
- Same as at().
+ Same as at(). This function runs in \l{constant time}.
*/
/*! \fn QList::reserve(int alloc)
@@ -681,10 +684,10 @@ void **QListData::erase(void **xi)
This is the same as list.insert(size(), \a value).
- This operation is typically very fast (\l{constant time}),
- because QList preallocates extra space on both sides of its
- internal buffer to allow for fast growth at both ends of the
- list.
+ If this list is not shared, this operation is typically
+ very fast (amortized \l{constant time}), because QList
+ preallocates extra space on both sides of its internal
+ buffer to allow for fast growth at both ends of the list.
\sa operator<<(), prepend(), insert()
*/
@@ -709,8 +712,9 @@ void **QListData::erase(void **xi)
This is the same as list.insert(0, \a value).
- This operation is usually very fast (\l{constant time}), because
- QList preallocates extra space on both sides of its internal
+ If this list is not shared, this operation is typically
+ very fast (amortized \l{constant time}), because QList
+ preallocates extra space on both sides of its internal
buffer to allow for fast growth at both ends of the list.
\sa append(), insert()
@@ -802,7 +806,7 @@ void **QListData::erase(void **xi)
same as takeAt(0). This function assumes the list is not empty. To
avoid failure, call isEmpty() before calling this function.
- This operation takes \l{constant time}.
+ If this list is not shared, this operation takes \l{constant time}.
If you don't use the return value, removeFirst() is more
efficient.
@@ -817,7 +821,7 @@ void **QListData::erase(void **xi)
not empty. To avoid failure, call isEmpty() before calling this
function.
- This operation takes \l{constant time}.
+ If this list is not shared, this operation takes \l{constant time}.
If you don't use the return value, removeLast() is more
efficient.
@@ -1288,6 +1292,11 @@ void **QListData::erase(void **xi)
iterators over a long period of time, we recommend that you use
QLinkedList rather than QList.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QList::const_iterator, QMutableListIterator
*/
@@ -1538,6 +1547,11 @@ void **QListData::erase(void **xi)
iterators over a long period of time, we recommend that you use
QLinkedList rather than QList.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QList::iterator, QListIterator
*/
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index b795bbc86e..333ce72849 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -639,7 +639,7 @@ inline void QList<T>::move(int from, int to)
template<typename T>
Q_OUTOFLINE_TEMPLATE QList<T> QList<T>::mid(int pos, int alength) const
{
- if (alength < 0 || pos + alength > size())
+ if (alength < 0 || pos > size() - alength)
alength = size() - pos;
if (pos == 0 && alength == size())
return *this;
diff --git a/src/corelib/tools/qlocale_mac.mm b/src/corelib/tools/qlocale_mac.mm
index deb5d5eb1d..92dfba162c 100644
--- a/src/corelib/tools/qlocale_mac.mm
+++ b/src/corelib/tools/qlocale_mac.mm
@@ -193,7 +193,7 @@ static QString macToQtFormat(const QString &sys_fmt)
// Qt does not support the following options
case 'G': // Era (1..5): 4 = long, 1..3 = short, 5 = narrow
case 'Y': // Year of Week (1..n): 1..n = padded number
- case 'U': // Cyclic Yar Name (1..5): 4 = long, 1..3 = short, 5 = narrow
+ case 'U': // Cyclic Year Name (1..5): 4 = long, 1..3 = short, 5 = narrow
case 'Q': // Quarter (1..4): 4 = long, 3 = short, 1..2 = padded number
case 'q': // Standalone Quarter (1..4): 4 = long, 3 = short, 1..2 = padded number
case 'w': // Week of Year (1..2): 1..2 = padded number
@@ -257,7 +257,7 @@ static QString macToQtFormat(const QString &sys_fmt)
case 's': // Seconds (1..2): 1..2 = padded number
result += QString(repeat, c);
break;
- case 'S': // Fractional second (1..n): 1..n = tuncates to decimal places
+ case 'S': // Fractional second (1..n): 1..n = truncates to decimal places
// Qt uses msecs either unpadded or padded to 3 places
if (repeat < 3)
result += QLatin1Char('z');
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index ab9b1d23ab..9aebbb7b3c 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -395,7 +395,7 @@ void QMapDataBase::freeData(QMapDataBase *d)
differences are:
\list
- \li QHash provides faster lookups than QMap. (See \l{Algorithmic
+ \li QHash provides average faster lookups than QMap. (See \l{Algorithmic
Complexity} for details.)
\li When iterating over a QHash, the items are arbitrarily ordered.
With QMap, the items are always sorted by key.
@@ -901,6 +901,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
Returns a reference to the smallest key in the map.
This function assumes that the map is not empty.
+ This executes in \l{constant time}.
+
\sa lastKey(), first(), isEmpty()
*/
@@ -909,6 +911,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
Returns a reference to the largest key in the map.
This function assumes that the map is not empty.
+ This executes in \l{logarithmic time}.
+
\sa firstKey(), last(), isEmpty()
*/
@@ -917,6 +921,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
Returns a reference to the first value in the map, that is the value mapped
to the smallest key. This function assumes that the map is not empty.
+ When unshared (or const version is called), this executes in \l{constant time}.
+
\sa last(), firstKey(), isEmpty()
*/
@@ -930,6 +936,8 @@ void QMapDataBase::freeData(QMapDataBase *d)
Returns a reference to the last value in the map, that is the value mapped
to the largest key. This function assumes that the map is not empty.
+ When unshared (or const version is called), this executes in \l{logarithmic time}.
+
\sa first(), lastKey(), isEmpty()
*/
@@ -1057,8 +1065,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
If there are multiple items with the key \a key, then exactly one of them
is replaced with \a value.
+ If the hint is correct and the map is unshared, the insert executes in amortized \l{constant time}.
+
When creating a map from sorted data inserting the largest key first with constBegin()
- is faster than inserting in sorted order with constEnd()
+ is faster than inserting in sorted order with constEnd(), since constEnd() - 1 (which is needed
+ to check if the hint is valid) needs \l{logarithmic time}.
\b {Note:} Be careful with the hint. Providing an iterator from an older shared instance might
crash but there is also a risk that it will silently corrupt both the map and the \a pos map.
@@ -1215,6 +1226,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
items from the map, iterators that point to the removed items
will become dangling iterators.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QMap::const_iterator, QMutableMapIterator
*/
@@ -1433,6 +1449,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
items from the map, iterators that point to the removed items
will become dangling iterators.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QMap::iterator, QMapIterator
*/
diff --git a/src/corelib/tools/qmargins.h b/src/corelib/tools/qmargins.h
index 0d68be961e..ad5e94cefe 100644
--- a/src/corelib/tools/qmargins.h
+++ b/src/corelib/tools/qmargins.h
@@ -242,6 +242,24 @@ inline QMargins &QMargins::operator-=(const QMargins &margins)
return *this = *this - margins;
}
+inline QMargins &QMargins::operator+=(int margin)
+{
+ m_left += margin;
+ m_top += margin;
+ m_right += margin;
+ m_bottom += margin;
+ return *this;
+}
+
+inline QMargins &QMargins::operator-=(int margin)
+{
+ m_left -= margin;
+ m_top -= margin;
+ m_right -= margin;
+ m_bottom -= margin;
+ return *this;
+}
+
inline QMargins &QMargins::operator*=(int factor)
{
return *this = *this * factor;
diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc
index a0bc206014..e66a59a09c 100644
--- a/src/corelib/tools/qset.qdoc
+++ b/src/corelib/tools/qset.qdoc
@@ -643,8 +643,12 @@
\snippet code/doc_src_qset.cpp 10
- Multiple iterators can be used on the same set. However, you may
- not attempt to modify the container while iterating on it.
+ Multiple iterators can be used on the same set.
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
\sa QSet::const_iterator, QMutableSetIterator
*/
@@ -682,8 +686,10 @@
\snippet code/doc_src_qset.cpp 12
- Multiple iterators can be used on the same set. However, you may
- not attempt to modify the container while iterating on it.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
\sa QSet::iterator, QSetIterator
*/
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 31acc95ad3..92556ce50a 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -9803,8 +9803,8 @@ QString QString::toHtmlEscaped() const
if (attribute.name() == QLatin1String("http-contents-length")) //...
\endcode
- \note There some restrictions when using the MSVC 2010 or 2012 compilers. The example snippets provided here
- fail to compile with them.
+ \note There are some restrictions when using the MSVC 2010 or 2012 compilers. The example snippets
+ provided here fail to compile with them.
\list
\li Concatenated string literals cannot be used with QStringLiteral.
\code
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 62b8f5f7b6..4bf19178fa 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -883,9 +883,9 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
while (olsenId.isEmpty() && !ts.atEnd() && ts.status() == QTextStream::Ok) {
line = ts.readLine();
if (line.left(5) == QStringLiteral("ZONE=")) {
- olsenId = line.mid(6, line.size() - 2).toUtf8();
+ olsenId = line.mid(6, line.size() - 7).toUtf8();
} else if (line.left(9) == QStringLiteral("TIMEZONE=")) {
- olsenId = line.mid(6, line.size() - 2).toUtf8();
+ olsenId = line.mid(10, line.size() - 11).toUtf8();
}
}
}
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
index 69b656c191..b9281c6915 100644
--- a/src/corelib/tools/qvector.cpp
+++ b/src/corelib/tools/qvector.cpp
@@ -562,6 +562,44 @@
\sa insert(), replace(), fill()
*/
+/*! \fn void QVector::removeAt(int i)
+ \since 5.2
+
+ Equivalent to
+ \code
+ remove(i);
+ \endcode
+
+ Provided for compatibility with QList.
+
+ \sa remove(int), QList::removeAt(int)
+*/
+
+/*! \fn int QVector::length() const
+ \since 5.2
+
+ Same as size() and count().
+
+ Provided for compatibility with QList.
+
+ \sa size(), count(), QList::length()
+*/
+
+/*! \fn T QVector::takeAt(int i)
+ \since 5.2
+
+ Equivalent to
+ \code
+ T t = at(i);
+ remove(i);
+ return t;
+ \endcode
+
+ Provided for compatibility with QList.
+
+ \sa takeFirst(), takeLast(), QList::takeAt(int)
+*/
+
/*! \fn void QVector::removeFirst()
\since 5.1
Removes the first item in the vector. Calling this function is
@@ -919,6 +957,11 @@
iterators}. The STL-style non-const iterator is simply a typedef
for "T *" (pointer to T).
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QVector::begin(), QVector::end(), QVector::const_iterator, QMutableVectorIterator
*/
@@ -931,6 +974,11 @@
iterators}. The STL-style const iterator is simply a typedef for
"const T *" (pointer to const T).
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QVector::constBegin(), QVector::constEnd(), QVector::iterator, QVectorIterator
*/
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 3d86440fcd..f56511edbf 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -152,6 +152,11 @@ public:
bool contains(const T &t) const;
int count(const T &t) const;
+ // QList compatibility
+ void removeAt(int i) { remove(i); }
+ int length() const { return size(); }
+ T takeAt(int i) { T t = at(i); remove(i); return t; }
+
// STL-style
typedef typename Data::iterator iterator;
typedef typename Data::const_iterator const_iterator;
@@ -187,7 +192,7 @@ public:
inline const T &last() const { Q_ASSERT(!isEmpty()); return *(end()-1); }
inline bool startsWith(const T &t) const { return !isEmpty() && first() == t; }
inline bool endsWith(const T &t) const { return !isEmpty() && last() == t; }
- QVector<T> mid(int pos, int length = -1) const;
+ QVector<T> mid(int pos, int len = -1) const;
T value(int i) const;
T value(int i, const T &defaultValue) const;
@@ -772,17 +777,17 @@ int QVector<T>::count(const T &t) const
}
template <typename T>
-Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int length) const
+Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int len) const
{
- if (length < 0)
- length = size() - pos;
- if (pos == 0 && length == size())
+ if (len < 0)
+ len = size() - pos;
+ if (pos == 0 && len == size())
return *this;
- if (pos + length > size())
- length = size() - pos;
+ if (pos + len > size())
+ len = size() - pos;
QVector<T> copy;
- copy.reserve(length);
- for (int i = pos; i < pos + length; ++i)
+ copy.reserve(len);
+ for (int i = pos; i < pos + len; ++i)
copy += at(i);
return copy;
}
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index ff3e910883..d5b0af550e 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -589,7 +589,7 @@ public:
virtual QString imageDescription() const = 0;
virtual QSize imageSize() const = 0;
- virtual QRect imagePosition() const = 0;
+ virtual QPoint imagePosition() const = 0;
};
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 15ed79c981..816419d155 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -2281,6 +2281,121 @@ QTabletEvent::~QTabletEvent()
#endif // QT_NO_TABLETEVENT
+/*!
+ \class QNativeGestureEvent
+ \since 5.2
+ \brief The QNativeGestureEvent class contains parameters that describe a gesture event.
+ \inmodule QtGui
+ \ingroup events
+
+ Native gesture events are generated by the operating system, typically by
+ interpreting touch events. Gesture events are high-level events such
+ as zoom or rotate.
+
+ \table
+ \header
+ \li Event Type
+ \li Description
+ \li Touch equence
+ \row
+ \li Qt::ZoomNativeGesture
+ \li Magnification delta in percent.
+ \li OS X: Two-finger pinch.
+ \row
+ \li Qt::SmartZoomNativeGesture
+ \li Boolean magnification state.
+ \li OS X: Two-finger douple tap (trackpad) / One-finger douple tap (magic mouse).
+ \row
+ \li Qt::RotateNativeGesture
+ \li Rotation delta in degrees.
+ \li OS X: Two-finger rotate.
+ \endtable
+
+
+ In addition, BeginNativeGesture and EndNativeGesture are sent before and after
+ gesture event streams:
+
+ BeginNativeGesture
+ ZoomNativeGesture
+ ZoomNativeGesture
+ ZoomNativeGesture
+ EndNativeGesture
+
+ \sa Qt::NativeGestureType, QGestureEvent
+*/
+
+/*!
+ Constructs a native gesture event of type \a type.
+
+ The points \a localPos, \a windowPos and \a screenPos specify the
+ gesture position relative to the receiving widget or item,
+ window, and screen, respectively.
+
+ \a realValue is the OS X event parameter, \a sequenceId and \a intValue are the Windows event parameters.
+*/
+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),
+ mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue),
+ mSequenceId(sequenceId), mIntValue(intValue)
+{ }
+
+/*!
+ \fn QNativeGestureEvent::gestureType() const
+ \since 5.2
+
+ Returns the gesture type.
+*/
+
+/*!
+ \fn QNativeGestureEvent::value() const
+ \since 5.2
+
+ Returns the gesture value. The value should be interpreted based on the
+ gesture type. For example, a Zoom gesture provides a scale factor while a Rotate
+ gesture provides a rotation delta.
+
+ \sa QNativeGestureEvent, gestureType()
+*/
+
+/*!
+ \fn QPoint QNativeGestureEvent::globalPos() const
+ \since 5.2
+
+ Returns the position of the gesture as a QPointF in screen coordinates
+*/
+
+/*!
+ \fn QPoint QNativeGestureEvent::pos() const
+ \since 5.2
+
+ Returns the position of the mouse cursor, relative to the widget
+ or item that received the event.
+*/
+
+/*!
+ \fn QPointF QNativeGestureEvent::localPos() const
+ \since 5.2
+
+ Returns the position of the gesture as a QPointF, relative to the
+ widget or item that received the event.
+*/
+
+/*!
+ \fn QPointF QNativeGestureEvent::screenPos() const
+ \since 5.2
+
+ Returns the position of the gesture as a QPointF in screen coordinates.
+*/
+
+/*!
+ \fn QPointF QNativeGestureEvent::windowPos() const
+ \since 5.2
+
+ Returns the position of the gesture as a QPointF, relative to the
+ window that received the event.
+*/
+
#ifndef QT_NO_DRAGANDDROP
/*!
Creates a QDragMoveEvent of the required \a type indicating
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 7d05e1c5a9..b6b1e0c76b 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -270,6 +270,34 @@ protected:
};
#endif // QT_NO_TABLETEVENT
+#ifndef QT_NO_GESTURES
+class Q_GUI_EXPORT QNativeGestureEvent : public QInputEvent
+{
+public:
+ QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos,
+ const QPointF &screenPos, qreal value, ulong sequenceId, quint64 intArgument);
+ Qt::NativeGestureType gestureType() const { return mGestureType; }
+ qreal value() const { return mRealValue; }
+
+#ifndef QT_NO_INTEGER_EVENT_COORDINATES
+ inline const QPoint pos() const { return mLocalPos.toPoint(); }
+ inline const QPoint globalPos() const { return mScreenPos.toPoint(); }
+#endif
+ const QPointF &localPos() const { return mLocalPos; }
+ const QPointF &windowPos() const { return mWindowPos; }
+ const QPointF &screenPos() const { return mScreenPos; }
+
+protected:
+ Qt::NativeGestureType mGestureType;
+ QPointF mLocalPos;
+ QPointF mWindowPos;
+ QPointF mScreenPos;
+ qreal mRealValue;
+ ulong mSequenceId;
+ quint64 mIntValue;
+};
+#endif // QT_NO_GESTURES
+
class Q_GUI_EXPORT QKeyEvent : public QInputEvent
{
public:
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 591e83c0bd..db655bd2ad 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1477,6 +1477,10 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
QGuiApplicationPrivate::processTabletLeaveProximityEvent(
static_cast<QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *>(e));
break;
+ case QWindowSystemInterfacePrivate::Gesture:
+ QGuiApplicationPrivate::processGestureEvent(
+ static_cast<QWindowSystemInterfacePrivate::GestureEvent *>(e));
+ break;
case QWindowSystemInterfacePrivate::PlatformPanel:
QGuiApplicationPrivate::processPlatformPanelEvent(
static_cast<QWindowSystemInterfacePrivate::PlatformPanelEvent *>(e));
@@ -1493,6 +1497,7 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
#endif
case QWindowSystemInterfacePrivate::EnterWhatsThisMode:
QGuiApplication::postEvent(QGuiApplication::instance(), new QEvent(QEvent::EnterWhatsThisMode));
+ break;
default:
qWarning() << "Unknown user input event type:" << e->type;
break;
@@ -1570,9 +1575,11 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
ev.setTimestamp(e->timestamp);
setMouseEventSource(&ev, e->source);
#ifndef QT_NO_CURSOR
- if (const QScreen *screen = window->screen())
- if (QPlatformCursor *cursor = screen->handle()->cursor())
- cursor->pointerEvent(ev);
+ if (!e->synthetic) {
+ if (const QScreen *screen = window->screen())
+ if (QPlatformCursor *cursor = screen->handle()->cursor())
+ cursor->pointerEvent(ev);
+ }
#endif
if (window->d_func()->blockedByModalWindow) {
@@ -1961,6 +1968,15 @@ void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInter
#endif
}
+#ifndef QT_NO_GESTURES
+void QGuiApplicationPrivate::processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e)
+{
+ QNativeGestureEvent ev(e->type, e->pos, e->pos, e->globalPos, e->realValue, e->sequenceId, e->intValue);
+ ev.setTimestamp(e->timestamp);
+ QGuiApplication::sendSpontaneousEvent(e->window, &ev);
+}
+#endif // QT_NO_GESTURES
+
void QGuiApplicationPrivate::processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e)
{
if (!e->window)
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 1068e1eb2e..b158138bb7 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -148,6 +148,7 @@ public:
static void processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e);
static void processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e);
static void processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e);
+ static void processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e);
static void processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e);
#ifndef QT_NO_CONTEXTMENU
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index 65f57aed84..1739e8c6fd 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -115,7 +115,7 @@ static void clear(QVariant::Private *d)
QMetaTypeSwitcher::switcher<void>(destructor, d->type, 0);
}
-// This class is a hack that customizes access to QPolygon
+// This class is a hack that customizes access to QPolygon and QPolygonF
template<class Filter>
class QGuiVariantIsNull : public QVariantIsNull<Filter> {
typedef QVariantIsNull<Filter> Base;
@@ -126,6 +126,7 @@ public:
template<typename T>
bool delegate(const T *p) { return Base::delegate(p); }
bool delegate(const QPolygon*) { return v_cast<QPolygon>(Base::m_d)->isEmpty(); }
+ bool delegate(const QPolygonF*) { return v_cast<QPolygonF>(Base::m_d)->isEmpty(); }
bool delegate(const void *p) { return Base::delegate(p); }
};
static bool isNull(const QVariant::Private *d)
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 3fb4939b69..562df1c913 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -48,8 +48,8 @@
#include <QtCore/qfileinfo.h>
#include <qpalette.h>
#include <qtextformat.h>
-#include <qiconloader_p.h>
-#include "private/qguiapplication_p.h"
+#include <private/qiconloader_p.h>
+#include <private/qguiapplication_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index b2abed7812..2f1b30ae4a 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -337,7 +337,7 @@ bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOptions opt) const
/*!
Set the minimum depth buffer size to \a size.
- \sa depthBufferSize(), setDepth(), depth()
+ \sa depthBufferSize()
*/
void QSurfaceFormat::setDepthBufferSize(int size)
{
@@ -350,7 +350,7 @@ void QSurfaceFormat::setDepthBufferSize(int size)
/*!
Returns the depth buffer size.
- \sa setDepthBufferSize(), setDepth(), depth()
+ \sa setDepthBufferSize()
*/
int QSurfaceFormat::depthBufferSize() const
{
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index f2e60e0ff3..13218fa178 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -227,6 +227,8 @@ QWindow::~QWindow()
QGuiApplicationPrivate::focus_window = 0;
if (QGuiApplicationPrivate::currentMouseWindow == this)
QGuiApplicationPrivate::currentMouseWindow = 0;
+ if (QGuiApplicationPrivate::tabletPressTarget == this)
+ QGuiApplicationPrivate::tabletPressTarget = 0;
QGuiApplicationPrivate::window_list.removeAll(this);
destroy();
}
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 5ee9bce540..07717bb63d 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -673,6 +673,35 @@ void QWindowSystemInterface::handleTabletLeaveProximityEvent(int device, int poi
handleTabletLeaveProximityEvent(time, device, pointerType, uid);
}
+#ifndef QT_NO_GESTURES
+void QWindowSystemInterface::handleGestureEvent(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
+ QPointF &local, QPointF &global)
+{
+ QWindowSystemInterfacePrivate::GestureEvent *e =
+ new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
+ QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
+ qreal value, QPointF &local, QPointF &global)
+{
+ QWindowSystemInterfacePrivate::GestureEvent *e =
+ new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
+ e->realValue = value;
+ QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+}
+
+void QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
+ ulong sequenceId, quint64 value, QPointF &local, QPointF &global)
+{
+ QWindowSystemInterfacePrivate::GestureEvent *e =
+ new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
+ e->sequenceId = sequenceId;
+ e->intValue = value;
+ QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
+}
+#endif // QT_NO_GESTURES
+
void QWindowSystemInterface::handlePlatformPanelEvent(QWindow *w)
{
QWindowSystemInterfacePrivate::PlatformPanelEvent *e =
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index 813f538651..0c3494a46d 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -185,6 +185,15 @@ public:
static void handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid);
static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid);
+#ifndef QT_NO_GESTURES
+ static void handleGestureEvent(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
+ QPointF &local, QPointF &global);
+ static void handleGestureEventWithRealValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
+ qreal value, QPointF &local, QPointF &global);
+ static void handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp,Qt::NativeGestureType type,
+ ulong sequenceId, quint64 value, QPointF &local, QPointF &global);
+#endif // QT_NO_GESTURES
+
static void handlePlatformPanelEvent(QWindow *w);
#ifndef QT_NO_CONTEXTMENU
static void handleContextMenuEvent(QWindow *w, bool mouseTriggered,
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index a4221b0e76..f0398ffc51 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -91,6 +91,7 @@ public:
PlatformPanel = UserInputEvent | 0x17,
ContextMenu = UserInputEvent | 0x18,
EnterWhatsThisMode = UserInputEvent | 0x19,
+ Gesture = UserInputEvent | 0x1a,
ApplicationStateChanged = 0x19,
FlushEvents = 0x20,
WindowScreenChanged = 0x21
@@ -401,6 +402,21 @@ public:
};
#endif
+ class GestureEvent : public InputEvent {
+ public:
+ GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, QPointF pos, QPointF globalPos)
+ : InputEvent(window, time, Gesture, Qt::NoModifier), type(type), pos(pos), globalPos(globalPos),
+ realValue(0), sequenceId(0), intValue(0) { }
+ Qt::NativeGestureType type;
+ QPointF pos;
+ QPointF globalPos;
+ // Mac
+ qreal realValue;
+ // Windows
+ ulong sequenceId;
+ quint64 intValue;
+ };
+
class WindowSystemEventList {
QList<WindowSystemEvent *> impl;
mutable QMutex mutex;
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index fcd556e892..d5a7399c18 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -2488,7 +2488,7 @@ void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g,
qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
return;
}
- GLint swizzleMask[] = {r, g, b, a};
+ GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
d->swizzleMask[0] = r;
d->swizzleMask[1] = g;
d->swizzleMask[2] = b;
diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp
index 16ed79ac10..ee8abde77b 100644
--- a/src/gui/opengl/qopenglvertexarrayobject.cpp
+++ b/src/gui/opengl/qopenglvertexarrayobject.cpp
@@ -58,13 +58,19 @@ public:
{
Q_ASSERT(context);
#if !defined(QT_OPENGL_ES_2)
- GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress("glGenVertexArrays"));
- DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress("glDeleteVertexArrays"));
- BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress("glBindVertexArray"));
+ if (context->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) {
+ GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysAPPLE")));
+ DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysAPPLE")));
+ BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayAPPLE")));
+ } else {
+ GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress(QByteArrayLiteral("glGenVertexArrays")));
+ DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArrays")));
+ BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress(QByteArrayLiteral("glBindVertexArray")));
+ }
#else
- GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress("glGenVertexArraysOES"));
- DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress("glDeleteVertexArraysOES"));
- BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress("glBindVertexArrayOES"));
+ GenVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , GLuint *)>(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES")));
+ DeleteVertexArrays = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLsizei , const GLuint *)>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES")));
+ BindVertexArray = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint )>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES")));
#endif
}
@@ -84,7 +90,7 @@ public:
}
private:
- // Function signatures are equivalent between desktop core, ARB and ES 2 extensions
+ // Function signatures are equivalent between desktop core, ARB, APPLE and ES 2 extensions
void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays);
void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays);
void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array);
@@ -109,8 +115,8 @@ public:
#if defined(QT_OPENGL_ES_2)
delete vaoFuncs;
#else
- if (vaoFuncsType == ARB)
- delete vaoFuncs.arb;
+ if ((vaoFuncsType == ARB) || (vaoFuncsType == APPLE))
+ delete vaoFuncs.helper;
#endif
}
@@ -130,13 +136,14 @@ public:
union {
QOpenGLFunctions_3_0 *core_3_0;
QOpenGLFunctions_3_2_Core *core_3_2;
- QVertexArrayObjectHelper *arb;
+ QVertexArrayObjectHelper *helper;
} vaoFuncs;
enum {
NotSupported,
Core_3_0,
Core_3_2,
- ARB
+ ARB,
+ APPLE
} vaoFuncsType;
#endif
QOpenGLContext *context;
@@ -162,7 +169,7 @@ bool QOpenGLVertexArrayObjectPrivate::create()
QObject::connect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
#if defined(QT_OPENGL_ES_2)
- if (ctx->hasExtension("GL_OES_vertex_array_object")) {
+ if (ctx->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
vaoFuncs = new QVertexArrayObjectHelper(ctx);
vaoFuncs->glGenVertexArrays(1, &vao);
}
@@ -180,10 +187,14 @@ bool QOpenGLVertexArrayObjectPrivate::create()
vaoFuncsType = Core_3_0;
vaoFuncs.core_3_0->initializeOpenGLFunctions();
vaoFuncs.core_3_0->glGenVertexArrays(1, &vao);
- } else if (ctx->hasExtension("GL_ARB_vertex_array_object")) {
- vaoFuncs.arb = new QVertexArrayObjectHelper(ctx);
+ } else if (ctx->hasExtension(QByteArrayLiteral("GL_ARB_vertex_array_object"))) {
+ vaoFuncs.helper = new QVertexArrayObjectHelper(ctx);
vaoFuncsType = ARB;
- vaoFuncs.arb->glGenVertexArrays(1, &vao);
+ vaoFuncs.helper->glGenVertexArrays(1, &vao);
+ } else if (ctx->hasExtension(QByteArrayLiteral("GL_APPLE_vertex_array_object"))) {
+ vaoFuncs.helper = new QVertexArrayObjectHelper(ctx);
+ vaoFuncsType = APPLE;
+ vaoFuncs.helper->glGenVertexArrays(1, &vao);
}
#endif
return (vao != 0);
@@ -205,7 +216,8 @@ void QOpenGLVertexArrayObjectPrivate::destroy()
vaoFuncs.core_3_0->glDeleteVertexArrays(1, &vao);
break;
case ARB:
- vaoFuncs.arb->glDeleteVertexArrays(1, &vao);
+ case APPLE:
+ vaoFuncs.helper->glDeleteVertexArrays(1, &vao);
break;
case NotSupported:
break;
@@ -236,7 +248,8 @@ void QOpenGLVertexArrayObjectPrivate::bind()
vaoFuncs.core_3_0->glBindVertexArray(vao);
break;
case ARB:
- vaoFuncs.arb->glBindVertexArray(vao);
+ case APPLE:
+ vaoFuncs.helper->glBindVertexArray(vao);
break;
case NotSupported:
break;
@@ -258,7 +271,8 @@ void QOpenGLVertexArrayObjectPrivate::release()
vaoFuncs.core_3_0->glBindVertexArray(0);
break;
case ARB:
- vaoFuncs.arb->glBindVertexArray(0);
+ case APPLE:
+ vaoFuncs.helper->glBindVertexArray(0);
break;
case NotSupported:
break;
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 4e8f718962..708b8cbd58 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -151,7 +151,7 @@ public:
static bool removeAllApplicationFonts();
#if QT_DEPRECATED_SINCE(5, 2)
- QT_DEPRECATED static inline bool supportsThreadedFontRendering() { return true; }
+ QT_DEPRECATED static bool supportsThreadedFontRendering();
#endif
static QFont systemFont(SystemFont type);
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
index 7f5281131e..6c0be950dc 100644
--- a/src/gui/text/qfontdatabase_qpa.cpp
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -267,6 +267,12 @@ bool QFontDatabase::removeAllApplicationFonts()
return true;
}
+// QT_DEPRECATED_SINCE(5, 2)
+bool QFontDatabase::supportsThreadedFontRendering()
+{
+ return true;
+}
+
/*!
\internal
*/
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index b3889a02a4..303c85ce75 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -891,6 +891,16 @@ QByteArray QFontEngine::getSfntTable(uint tag) const
return table;
}
+void QFontEngine::clearGlyphCache(const void *key)
+{
+ for (QLinkedList<GlyphCacheEntry>::iterator it = m_glyphCaches.begin(), end = m_glyphCaches.end(); it != end; ) {
+ if (it->context == key)
+ it = m_glyphCaches.erase(it);
+ else
+ ++it;
+ }
+}
+
void QFontEngine::setGlyphCache(const void *key, QFontEngineGlyphCache *data)
{
Q_ASSERT(data);
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index d3faef93bb..c181d61d73 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -256,6 +256,7 @@ public:
virtual int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints);
+ void clearGlyphCache(const void *key);
void setGlyphCache(const void *key, QFontEngineGlyphCache *data);
QFontEngineGlyphCache *glyphCache(const void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const;
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 03602712cc..30e0f32547 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -2531,6 +2531,29 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block)
html += QLatin1Char(';');
}
+ if (format.lineHeightType() != QTextBlockFormat::SingleHeight) {
+ switch (format.lineHeightType()) {
+ case QTextBlockFormat::ProportionalHeight:
+ case QTextBlockFormat::FixedHeight:
+ html += QLatin1String(" line-height:");
+ break;
+ case QTextBlockFormat::MinimumHeight:
+ html += QLatin1String(" min-height:");
+ break;
+ case QTextBlockFormat::LineDistanceHeight:
+ html += QLatin1String(" line-spacing:");
+ break;
+ case QTextBlockFormat::SingleHeight:
+ default:
+ break; // Should never reach here
+ }
+ html += QString::number(format.lineHeight());
+ if (format.lineHeightType() == QTextBlockFormat::ProportionalHeight)
+ html += QLatin1String("%;");
+ else
+ html += QLatin1String("px;");
+ }
+
emitPageBreakPolicy(format.pageBreakPolicy());
QTextCharFormat diff;
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index 6156f56ae1..313700429c 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -1427,19 +1427,6 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p
xoff = -xoff - size.width();
r.translate( xoff, (fontMetrics.height() / 2) - (size.height() / 2));
- // Prevent clipping the left side of the list decorator (on left to
- // right layouts) and clipping the right side of the list
- // decorator (on right to left layouts).
- if ((r.left() < 0) && (dir == Qt::LeftToRight)) {
- int horizontalOffset = -r.left();
- r.translate(horizontalOffset, 0);
- layout->setPosition(layout->position() + QPointF(horizontalOffset, 0));
- } else if ((r.right() > document->pageSize().width()) && (dir == Qt::RightToLeft)) {
- int horizontalOffset = r.right() - document->pageSize().width();
- r.translate(-horizontalOffset, 0);
- layout->setPosition(layout->position() - QPointF(horizontalOffset, 0));
- }
-
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index c0e2c5b803..2b0f9ffeb6 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1883,11 +1883,12 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix
scaledEngine = feCache.prevScaledFontEngine;
} else {
QFontEngine *scEngine = rawFont.d->fontEngine->cloneWithSize(smallCapsFraction * rawFont.pixelSize());
+ scEngine->ref.ref();
scaledEngine = QFontEngineMultiQPA::createMultiFontEngine(scEngine, script);
scaledEngine->ref.ref();
feCache.prevScaledFontEngine = scaledEngine;
// If scEngine is not ref'ed by scaledEngine, make sure it is deallocated and not leaked.
- if (!scEngine->ref.load())
+ if (!scEngine->ref.deref())
delete scEngine;
}
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 5292ba20a2..a131503b85 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -46,7 +46,7 @@
#include <qstack.h>
#include <qdebug.h>
#include <qthread.h>
-#include <qcoreapplication.h>
+#include <qguiapplication.h>
#include "qtextdocument.h"
#include "qtextformat_p.h"
@@ -1066,7 +1066,7 @@ void QTextHtmlParserNode::initializeProperties(const QTextHtmlParserNode *parent
&& !attributes.at(i + 1).isEmpty()) {
hasHref = true;
charFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
- charFormat.setForeground(Qt::blue);
+ charFormat.setForeground(QGuiApplication::palette().link());
}
}
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index dc8ae06868..66341e186a 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -44,6 +44,7 @@
#include <qthread.h>
#include <qfont.h>
+#include <qmath.h>
#include <qpainter.h>
#include <qvarlengtharray.h>
#include <qtextformat.h>
@@ -207,7 +208,7 @@ void QTextInlineObject::setAscent(qreal a)
}
/*!
- Sets the inline object's decent to \a d.
+ Sets the inline object's descent to \a d.
\sa descent(), setAscent(), width(), rect()
*/
@@ -946,15 +947,23 @@ static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPo
continue;
}
- if (lastSelectionWidth > 0)
- region->addRect(boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight));
+ if (lastSelectionWidth > 0) {
+ QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight);
+ rect.moveLeft(qFloor(rect.left()));
+ rect.moveTop(qFloor(rect.top()));
+ region->addRect(rect);
+ }
lastSelectionX = selectionX;
lastSelectionWidth = selectionWidth;
}
}
- if (lastSelectionWidth > 0)
- region->addRect(boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight));
+ if (lastSelectionWidth > 0) {
+ QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight);
+ rect.moveLeft(qFloor(rect.left()));
+ rect.moveTop(qFloor(rect.top()));
+ region->addRect(rect);
+ }
}
static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip)
@@ -1288,7 +1297,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition
After being created, the line can be filled using the setLineWidth()
or setNumColumns() functions. A line has a number of attributes including the
rectangle it occupies, rect(), its coordinates, x() and y(), its
- textLength(), width() and naturalTextWidth(), and its ascent() and decent()
+ textLength(), width() and naturalTextWidth(), and its ascent() and descent()
relative to the text. The position of the cursor in terms of the
line is available from cursorToX() and its inverse from
xToCursor(). A line can be moved with setPosition().
@@ -2077,7 +2086,7 @@ static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const Q
QBrush bg = chf.background();
if (bg.style() != Qt::NoBrush && !chf.property(SuppressBackground).toBool())
- p->fillRect(r, bg);
+ p->fillRect(QRectF(qFloor(r.x()), qFloor(r.y()), r.width(), r.height()), bg);
if (c.style() != Qt::NoBrush) {
p->setPen(QPen(c, 0));
}
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index ba9e5cbdc4..e0996c4072 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -181,7 +181,7 @@ int QHttpNetworkConnectionPrivate::indexOf(QAbstractSocket *socket) const
return 0;
}
-// If the connection is in the InProgress state channel errors should not always be
+// If the connection is in the HostLookupPendening state channel errors should not always be
// emitted. This function will check the status of the connection channels if we
// have not decided the networkLayerState and will return true if the channel error
// should be emitted by the channel.
@@ -200,12 +200,12 @@ bool QHttpNetworkConnectionPrivate::shouldEmitChannelError(QAbstractSocket *sock
}
if (channelCount == 1) {
- if (networkLayerState == QHttpNetworkConnectionPrivate::InProgress)
+ if (networkLayerState == HostLookupPending || networkLayerState == IPv4or6)
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
channels[0].close();
emitError = true;
} else {
- if (networkLayerState == QHttpNetworkConnectionPrivate::InProgress) {
+ if (networkLayerState == HostLookupPending || networkLayerState == IPv4or6) {
if (channels[otherSocket].isSocketBusy() && (channels[otherSocket].state != QHttpNetworkConnectionChannel::ClosingState)) {
// this was the first socket to fail.
channels[i].close();
@@ -560,7 +560,7 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor
// untill we have started the first connection attempt. So no
// request will be started untill we know if IPv4 or IPv6
// should be used.
- if (networkLayerState == Unknown || networkLayerState == InProgress) {
+ if (networkLayerState == Unknown || networkLayerState == HostLookupPending) {
startHostInfoLookup();
} else if ( networkLayerState == IPv4 || networkLayerState == IPv6 ) {
// this used to be called via invokeMethod and a QueuedConnection
@@ -878,7 +878,7 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply)
void QHttpNetworkConnectionPrivate::_q_startNextRequest()
{
// If there is no network layer state decided we should not start any new requests.
- if (networkLayerState == Unknown || networkLayerState == InProgress)
+ if (networkLayerState == Unknown || networkLayerState == HostLookupPending || networkLayerState == IPv4or6)
return;
// If the QHttpNetworkConnection is currently paused then bail out immediately
@@ -986,7 +986,7 @@ void QHttpNetworkConnectionPrivate::readMoreLater(QHttpNetworkReply *reply)
// lookup as then the hostinfo will already be in the cache.
void QHttpNetworkConnectionPrivate::startHostInfoLookup()
{
- networkLayerState = InProgress;
+ networkLayerState = HostLookupPending;
// check if we already now can decide if this is IPv4 or IPv6
QString lookupHost = hostName;
@@ -1028,6 +1028,8 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(QHostInfo info)
bool bIpv4 = false;
bool bIpv6 = false;
bool foundAddress = false;
+ if (networkLayerState == IPv4 || networkLayerState == IPv6 || networkLayerState == IPv4or6)
+ return;
foreach (const QHostAddress &address, info.addresses()) {
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
@@ -1077,7 +1079,7 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup()
Q_ASSERT(!channels[0].isSocketBusy());
Q_ASSERT(!channels[1].isSocketBusy());
- networkLayerState = InProgress;
+ networkLayerState = IPv4or6;
channels[0].networkLayerPreference = QAbstractSocket::IPv4Protocol;
channels[1].networkLayerPreference = QAbstractSocket::IPv6Protocol;
@@ -1101,7 +1103,7 @@ void QHttpNetworkConnectionPrivate::startNetworkLayerStateLookup()
else
channels[0].ensureConnection();
} else {
- networkLayerState = InProgress;
+ networkLayerState = IPv4or6;
channels[0].networkLayerPreference = QAbstractSocket::AnyIPProtocol;
channels[0].ensureConnection();
}
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index c54250f6ed..2aaaad24ac 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -165,9 +165,10 @@ public:
enum NetworkLayerPreferenceState {
Unknown,
- InProgress,
+ HostLookupPending,
IPv4,
- IPv6
+ IPv6,
+ IPv4or6
};
QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt);
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index da82fdf8d2..6e786893ed 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -1045,7 +1045,7 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
void QHttpNetworkConnectionChannel::_q_connected()
{
// For the Happy Eyeballs we need to check if this is the first channel to connect.
- if (connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::InProgress) {
+ if (connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::HostLookupPending || connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv4or6) {
if (connection->d_func()->delayedConnectionTimer.isActive())
connection->d_func()->delayedConnectionTimer.stop();
if (networkLayerPreference == QAbstractSocket::IPv4Protocol)
@@ -1212,7 +1212,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
QPointer<QHttpNetworkConnection> that = connection;
QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString());
- // In the InProgress state the channel should not emit the error.
+ // In the HostLookupPending state the channel should not emit the error.
// This will instead be handled by the connection.
if (!connection->d_func()->shouldEmitChannelError(socket))
return;
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index 729729d929..052c492f07 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -52,6 +52,10 @@
#include <arpa/nameser_compat.h>
#include <resolv.h>
+#ifdef __GNU_LIBRARY__
+# include <gnu/lib-names.h>
+#endif
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_LIBRARY
@@ -77,9 +81,16 @@ struct QDnsLookupStateDeleter
static void resolveLibrary()
{
- QLibrary lib(QLatin1String("resolv"));
+ QLibrary lib;
+#ifdef LIBRESOLV_SO
+ lib.setFileName(QStringLiteral(LIBRESOLV_SO));
if (!lib.load())
- return;
+#endif
+ {
+ lib.setFileName(QLatin1String("resolv"));
+ if (!lib.load())
+ return;
+ }
local_dn_expand = dn_expand_proto(lib.resolve("__dn_expand"));
if (!local_dn_expand)
diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp
index 04daf2ecdd..dc2702b552 100644
--- a/src/network/kernel/qhostinfo_unix.cpp
+++ b/src/network/kernel/qhostinfo_unix.cpp
@@ -63,6 +63,10 @@
# include <resolv.h>
#endif
+#ifdef __GNU_LIBRARY__
+# include <gnu/lib-names.h>
+#endif
+
#if defined (QT_NO_GETADDRINFO)
static QBasicMutex getHostByNameMutex;
#endif
@@ -93,9 +97,16 @@ static res_state_ptr local_res = 0;
static void resolveLibrary()
{
#if !defined(QT_NO_LIBRARY) && !defined(Q_OS_QNX)
- QLibrary lib(QLatin1String("resolv"));
+ QLibrary lib;
+#ifdef LIBRESOLV_SO
+ lib.setFileName(QStringLiteral(LIBRESOLV_SO));
if (!lib.load())
- return;
+#endif
+ {
+ lib.setFileName(QLatin1String("resolv"));
+ if (!lib.load())
+ return;
+ }
local_res_init = res_init_proto(lib.resolve("__res_init"));
if (!local_res_init)
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index c96200fe1b..8ee0a8b290 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1638,6 +1638,7 @@ QGLContext* QGLContext::currentCtx = 0;
static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha)
{
+ Q_ASSERT(!img.isNull());
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
// OpenGL gives RGBA; Qt wants ARGB
uint *p = (uint*)img.bits();
@@ -1682,6 +1683,8 @@ QImage qt_gl_read_frame_buffer(const QSize &size, bool alpha_format, bool includ
{
QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
: QImage::Format_RGB32);
+ if (img.isNull())
+ return QImage();
int w = size.width();
int h = size.height();
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
@@ -1692,6 +1695,8 @@ QImage qt_gl_read_frame_buffer(const QSize &size, bool alpha_format, bool includ
QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha)
{
QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
+ if (img.isNull())
+ return QImage();
int w = size.width();
int h = size.height();
#if !defined(QT_OPENGL_ES_2)
diff --git a/src/platformsupport/fbconvenience/qfbcursor.cpp b/src/platformsupport/fbconvenience/qfbcursor.cpp
index fecf9f6380..b86f5830ea 100644
--- a/src/platformsupport/fbconvenience/qfbcursor.cpp
+++ b/src/platformsupport/fbconvenience/qfbcursor.cpp
@@ -137,5 +137,12 @@ void QFbCursor::changeCursor(QCursor * widgetCursor, QWindow *window)
}
#endif
-QT_END_NAMESPACE
+void QFbCursor::setDirty()
+{
+ if (!mDirty) {
+ mDirty = true;
+ mScreen->scheduleUpdate();
+ }
+}
+QT_END_NAMESPACE
diff --git a/src/platformsupport/fbconvenience/qfbcursor_p.h b/src/platformsupport/fbconvenience/qfbcursor_p.h
index cee9f56ab5..40377e2075 100644
--- a/src/platformsupport/fbconvenience/qfbcursor_p.h
+++ b/src/platformsupport/fbconvenience/qfbcursor_p.h
@@ -63,7 +63,7 @@ public:
virtual void changeCursor(QCursor *widgetCursor, QWindow *window);
#endif
- virtual void setDirty() { mDirty = true; /* screen->setDirty(QRect()); */ }
+ virtual void setDirty();
virtual bool isDirty() const { return mDirty; }
virtual bool isOnScreen() const { return mOnScreen; }
virtual QRect lastPainted() const { return mPrevRect; }
diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp
index e5b9f09c14..37d16ddeb6 100644
--- a/src/platformsupport/fbconvenience/qfbscreen.cpp
+++ b/src/platformsupport/fbconvenience/qfbscreen.cpp
@@ -149,9 +149,13 @@ void QFbScreen::setDirty(const QRect &rect)
QRect intersection = rect.intersected(mGeometry);
QPoint screenOffset = mGeometry.topLeft();
mRepaintRegion += intersection.translated(-screenOffset); // global to local translation
- if (!mRedrawTimer.isActive()) {
+ scheduleUpdate();
+}
+
+void QFbScreen::scheduleUpdate()
+{
+ if (!mRedrawTimer.isActive())
mRedrawTimer.start();
- }
}
void QFbScreen::setPhysicalSize(const QSize &size)
@@ -254,8 +258,9 @@ QRegion QFbScreen::doRedraw()
QRect windowRect = mWindowStack[layerIndex]->geometry().translated(-screenOffset);
QRect windowIntersect = rect.translated(-windowRect.left(),
-windowRect.top());
- mCompositePainter->drawImage(rect, mWindowStack[layerIndex]->backingStore()->image(),
- windowIntersect);
+ QFbBackingStore *backingStore = mWindowStack[layerIndex]->backingStore();
+ if (backingStore)
+ mCompositePainter->drawImage(rect, backingStore->image(), windowIntersect);
if (firstLayer) {
firstLayer = false;
}
diff --git a/src/platformsupport/fbconvenience/qfbscreen_p.h b/src/platformsupport/fbconvenience/qfbscreen_p.h
index 01a352e96a..dd940c4a1d 100644
--- a/src/platformsupport/fbconvenience/qfbscreen_p.h
+++ b/src/platformsupport/fbconvenience/qfbscreen_p.h
@@ -45,6 +45,7 @@
#include <qpa/qplatformscreen.h>
#include <QtCore/QTimer>
#include <QtCore/QSize>
+#include "qfbcursor_p.h"
QT_BEGIN_NAMESPACE
@@ -60,13 +61,14 @@ public:
QFbScreen();
~QFbScreen();
- virtual QRect geometry() const { return mGeometry; }
- virtual int depth() const { return mDepth; }
- virtual QImage::Format format() const { return mFormat; }
- virtual QSizeF physicalSize() const { return mPhysicalSize; }
+ QRect geometry() const Q_DECL_OVERRIDE { return mGeometry; }
+ int depth() const Q_DECL_OVERRIDE { return mDepth; }
+ QImage::Format format() const Q_DECL_OVERRIDE { return mFormat; }
+ QSizeF physicalSize() const Q_DECL_OVERRIDE { return mPhysicalSize; }
+ QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return mCursor; }
QWindow *topWindow() const;
- virtual QWindow *topLevelAt(const QPoint & p) const;
+ QWindow *topLevelAt(const QPoint & p) const Q_DECL_OVERRIDE;
// compositor api
virtual void addWindow(QFbWindow *window);
@@ -77,6 +79,8 @@ public:
void addBackingStore(QFbBackingStore *bs) {mBackingStores << bs;}
+ void scheduleUpdate();
+
public slots:
virtual void setDirty(const QRect &rect);
void setPhysicalSize(const QSize &size);
@@ -114,4 +118,3 @@ private:
QT_END_NAMESPACE
#endif // QFBSCREEN_P_H
-
diff --git a/src/platformsupport/fbconvenience/qfbwindow.cpp b/src/platformsupport/fbconvenience/qfbwindow.cpp
index 246f50b4a9..8b6186db79 100644
--- a/src/platformsupport/fbconvenience/qfbwindow.cpp
+++ b/src/platformsupport/fbconvenience/qfbwindow.cpp
@@ -77,6 +77,26 @@ void QFbWindow::setGeometry(const QRect &rect)
QPlatformWindow::setGeometry(rect);
}
+void QFbWindow::setVisible(bool visible)
+{
+ if (visible) {
+ if (mWindowState & Qt::WindowFullScreen)
+ setGeometry(platformScreen()->geometry());
+ else if (mWindowState & Qt::WindowMaximized)
+ setGeometry(platformScreen()->availableGeometry());
+ }
+ QPlatformWindow::setVisible(visible);
+}
+
+
+void QFbWindow::setWindowState(Qt::WindowState state)
+{
+ QPlatformWindow::setWindowState(state);
+ mWindowState = state;
+ platformScreen()->invalidateRectCache();
+}
+
+
void QFbWindow::setWindowFlags(Qt::WindowFlags flags)
{
mWindowFlags = flags;
diff --git a/src/platformsupport/fbconvenience/qfbwindow_p.h b/src/platformsupport/fbconvenience/qfbwindow_p.h
index 25e2afca14..5ad921b0d7 100644
--- a/src/platformsupport/fbconvenience/qfbwindow_p.h
+++ b/src/platformsupport/fbconvenience/qfbwindow_p.h
@@ -59,7 +59,9 @@ public:
virtual void lower();
virtual void setGeometry(const QRect &rect);
+ virtual void setVisible(bool visible);
+ virtual void setWindowState(Qt::WindowState state);
virtual void setWindowFlags(Qt::WindowFlags type);
virtual Qt::WindowFlags windowFlags() const;
@@ -78,6 +80,7 @@ protected:
QFbBackingStore *mBackingStore;
QRect mOldGeometry;
Qt::WindowFlags mWindowFlags;
+ Qt::WindowState mWindowState;
WId mWindowId;
};
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h
index 22d1622516..225b3d41ef 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h
@@ -42,6 +42,9 @@
#ifndef QEVDEVKEYBOARDHANDLER_DEFAULTMAP_P_H
#define QEVDEVKEYBOARDHANDLER_DEFAULTMAP_P_H
+#include "qnamespace.h"
+#include "linux/input.h"
+
// no QT_BEGIN_NAMESPACE, since we include it internally...
const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = {
@@ -631,7 +634,30 @@ const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = {
{ 111, 0xffff, 0x01000007, 0x00, 0x00, 0x0000 },
{ 111, 0xffff, 0x01000000, 0x06, 0x08, 0x0200 },
{ 111, 0xffff, 0x01000000, 0x0c, 0x08, 0x0200 },
- { 119, 0xffff, 0x01000008, 0x00, 0x00, 0x0000 },
+
+ // 113 -> 248
+ { KEY_MUTE, 0xffff, Qt::Key_VolumeMute, 0x00, 0x00, 0x0000 },
+ { KEY_VOLUMEDOWN, 0xffff, Qt::Key_VolumeDown, 0x00, 0x00, 0x0000 },
+ { KEY_VOLUMEUP, 0xffff, Qt::Key_VolumeUp, 0x00, 0x00, 0x0000 },
+ { KEY_PAUSE, 0xffff, Qt::Key_Pause, 0x00, 0x00, 0x0000 },
+ { KEY_STOP, 0xffff, Qt::Key_Stop, 0x00, 0x00, 0x0000 },
+ { KEY_RECORD, 0xffff, Qt::Key_MediaRecord, 0x00, 0x00, 0x0000 },
+ { KEY_REWIND, 0xffff, Qt::Key_AudioRewind, 0x00, 0x00, 0x0000 },
+ { KEY_PLAYPAUSE, 0xffff, Qt::Key_MediaTogglePlayPause, 0x00, 0x00, 0x0000 },
+ { KEY_PLAY, 0xffff, Qt::Key_MediaPlay, 0x00, 0x00, 0x0000 },
+ { KEY_FASTFORWARD, 0xffff, Qt::Key_AudioForward, 0x00, 0x00, 0x0000 },
+ { KEY_CANCEL, 0xffff, Qt::Key_Cancel, 0x00, 0x00, 0x0000 },
+ { 248, 0xffff, Qt::Key_MicMute, 0x00, 0x00, 0x0000 },
+ // 0x160 ->
+ { KEY_SELECT, 0xffff, Qt::Key_Select, 0x00, 0x00, 0x0000 },
+ { KEY_CLEAR, 0xffff, Qt::Key_Clear, 0x00, 0x00, 0x0000 },
+ { KEY_CALENDAR, 0xffff, Qt::Key_Calendar, 0x00, 0x00, 0x0000 },
+ { KEY_RED, 0xffff, Qt::Key_Red, 0x00, 0x00, 0x0000 },
+ { KEY_GREEN, 0xffff, Qt::Key_Green, 0x00, 0x00, 0x0000 },
+ { KEY_YELLOW, 0xffff, Qt::Key_Yellow, 0x00, 0x00, 0x0000 },
+ { KEY_BLUE, 0xffff, Qt::Key_Blue, 0x00, 0x00, 0x0000 },
+ { KEY_CHANNELUP, 0xffff, Qt::Key_ChannelUp, 0x00, 0x00, 0x0000 },
+ { KEY_CHANNELDOWN, 0xffff, Qt::Key_ChannelDown, 0x00, 0x00, 0x0000 },
};
const QEvdevKeyboardMap::Composing QEvdevKeyboardHandler::s_keycompose_default[] = {
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp
index 3b79a2ac80..89215557c1 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp
@@ -300,6 +300,21 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification,
qDebug("evdevtouch: device name: %s", name);
}
+ // Fix up the coordinate ranges for am335x in case the kernel driver does not have them fixed.
+ if (d->hw_name == QLatin1String("ti-tsc")) {
+ if (d->hw_range_x_min == 0 && d->hw_range_x_max == 4095) {
+ d->hw_range_x_min = 165;
+ d->hw_range_x_max = 4016;
+ }
+ if (d->hw_range_y_min == 0 && d->hw_range_y_max == 4095) {
+ d->hw_range_y_min = 220;
+ d->hw_range_y_max = 3907;
+ }
+ if (printDeviceInfo)
+ qDebug("evdevtouch: found ti-tsc, overriding: min X: %d max X: %d min Y: %d max Y: %d",
+ d->hw_range_x_min, d->hw_range_x_max, d->hw_range_y_min, d->hw_range_y_max);
+ }
+
bool grabSuccess = !ioctl(m_fd, EVIOCGRAB, (void *) 1);
if (grabSuccess)
ioctl(m_fd, EVIOCGRAB, (void *) 0);
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
index cbb3092b1d..79a5c82fe0 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -558,37 +558,56 @@ QWidget *QAccessibleCalendarWidget::navigationBar() const
#endif // QT_NO_CALENDARWIDGET
#ifndef QT_NO_DOCKWIDGET
+
+// Dock Widget - order of children:
+// - Content widget
+// - Float button
+// - Close button
+// If there is a custom title bar widget, that one becomes child 1, after the content 0
+// (in that case the buttons are ignored)
QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget)
: QAccessibleWidget(widget, QAccessible::Window)
{
+}
+QDockWidgetLayout *QAccessibleDockWidget::dockWidgetLayout() const
+{
+ return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
}
-QAccessibleInterface *QAccessibleDockWidget::child(int index) const
+int QAccessibleDockWidget::childCount() const
{
- if (index == 0) {
- return new QAccessibleTitleBar(dockWidget());
- } else if (index == 1 && dockWidget()->widget()) {
- return QAccessible::queryAccessibleInterface(dockWidget()->widget());
+ if (dockWidget()->titleBarWidget()) {
+ return dockWidget()->widget() ? 2 : 1;
}
- return 0;
+ return dockWidgetLayout()->count();
}
-int QAccessibleDockWidget::childCount() const
+QAccessibleInterface *QAccessibleDockWidget::child(int index) const
{
- return dockWidget()->widget() ? 2 : 1;
+ if (dockWidget()->titleBarWidget()) {
+ if ((!dockWidget()->widget() && index == 0) || (index == 1))
+ return QAccessible::queryAccessibleInterface(dockWidget()->titleBarWidget());
+ if (index == 0)
+ return QAccessible::queryAccessibleInterface(dockWidget()->widget());
+ } else {
+ QLayoutItem *item = dockWidgetLayout()->itemAt(index);
+ if (item)
+ return QAccessible::queryAccessibleInterface(item->widget());
+ }
+ return 0;
}
int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const
{
- if (child) {
- if (child->role() == QAccessible::TitleBar) {
- return 0;
- } else {
- return 1; // FIXME
- }
+ if (!child || !child->object() || child->object()->parent() != object())
+ return -1;
+
+ if (dockWidget()->titleBarWidget() == child->object()) {
+ return dockWidget()->widget() ? 1 : 0;
}
- return -1;
+
+ return dockWidgetLayout()->indexOf(qobject_cast<QWidget*>(child->object()));
}
QRect QAccessibleDockWidget::rect() const
@@ -610,190 +629,13 @@ QDockWidget *QAccessibleDockWidget::dockWidget() const
return static_cast<QDockWidget *>(object());
}
-////
-// QAccessibleTitleBar
-////
-QAccessibleTitleBar::QAccessibleTitleBar(QDockWidget *widget)
- : m_dockWidget(widget)
-{
-
-}
-
-QAccessibleInterface *QAccessibleTitleBar::parent() const
-{
- return new QAccessibleDockWidget(dockWidget());
-}
-
-QAccessibleInterface *QAccessibleTitleBar::child(int index) const
-{
- if (index >= 0) {
- QDockWidgetLayout *layout = dockWidgetLayout();
- int role;
- int currentIndex = 0;
- for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
- QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
- if (!w || !w->isVisible())
- continue;
- if (currentIndex == index)
- return QAccessible::queryAccessibleInterface(w);
- ++currentIndex;
- }
- }
- return 0;
-}
-
-int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const
-{
- return -1;
-}
-
-int QAccessibleTitleBar::childCount() const
-{
- QDockWidgetLayout *layout = dockWidgetLayout();
- int count = 0;
- for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) {
- QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role);
- if (w && w->isVisible())
- ++count;
- }
- return count;
-}
-
-QString QAccessibleTitleBar::text(QAccessible::Text t) const
+QString QAccessibleDockWidget::text(QAccessible::Text t) const
{
if (t == QAccessible::Name || t == QAccessible::Value) {
return qt_accStripAmp(dockWidget()->windowTitle());
}
return QString();
}
-
-QAccessible::State QAccessibleTitleBar::state() const
-{
- QAccessible::State state;
-
- QDockWidget *w = dockWidget();
- if (w->testAttribute(Qt::WA_WState_Visible) == false)
- state.invisible = true;
- if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow())
- state.focusable = true;
- if (w->hasFocus())
- state.focused = true;
- if (!w->isEnabled())
- state.disabled = true;
-
- return state;
-}
-
-QRect QAccessibleTitleBar::rect() const
-{
- bool mapToGlobal = true;
- QRect rect;
-
- if (dockWidget()->isFloating()) {
- rect = dockWidget()->frameGeometry();
- if (dockWidget()->widget()) {
- QPoint globalPos = dockWidget()->mapToGlobal(dockWidget()->widget()->rect().topLeft());
- globalPos.ry()--;
- rect.setBottom(globalPos.y());
- mapToGlobal = false;
- }
- } else {
- QDockWidgetLayout *layout = qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
- rect = layout->titleArea();
- }
-
- if (rect.isNull())
- return rect;
-
- if (mapToGlobal)
- rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft()));
- return rect;
-}
-
-QAccessibleInterface *QAccessibleTitleBar::childAt(int x, int y) const
-{
- for (int i = 0; i < childCount(); ++i) {
- QAccessibleInterface *childIface = child(i);
- if (childIface->rect().contains(x,y)) {
- return childIface;
- }
- }
- return 0;
-}
-
-QObject *QAccessibleTitleBar::object() const
-{
- return 0;
-}
-
-QDockWidgetLayout *QAccessibleTitleBar::dockWidgetLayout() const
-{
- return qobject_cast<QDockWidgetLayout*>(dockWidget()->layout());
-}
-
-QDockWidget *QAccessibleTitleBar::dockWidget() const
-{
- return m_dockWidget;
-}
-
-//QString QAccessibleTitleBar::actionText(int action, Text t, int child) const
-//{
-// QString str;
-// if (child >= 1 && child <= childCount()) {
-// if (t == Name) {
-// switch (action) {
-// case Press:
-// case DefaultAction:
-// if (child == QDockWidgetLayout::CloseButton) {
-// str = QDockWidget::tr("Close");
-// } else if (child == QDockWidgetLayout::FloatButton) {
-// str = dockWidget()->isFloating() ? QDockWidget::tr("Dock")
-// : QDockWidget::tr("Float");
-// }
-// break;
-// default:
-// break;
-// }
-// }
-// }
-// return str;
-//}
-
-//bool QAccessibleTitleBar::doAction(int action, int child, const QVariantList& /*params*/)
-//{
-// if (!child || !dockWidget()->isEnabled())
-// return false;
-
-// switch (action) {
-// case DefaultAction:
-// case Press: {
-// QDockWidgetLayout *layout = dockWidgetLayout();
-// QAbstractButton *btn = static_cast<QAbstractButton *>(layout->widgetForRole((QDockWidgetLayout::Role)child));
-// if (btn)
-// btn->animateClick();
-// return true;
-// break;}
-// default:
-// break;
-// }
-
-// return false;
-//}
-
-QAccessible::Role QAccessibleTitleBar::role() const
-{
- return QAccessible::TitleBar;
-}
-
-void QAccessibleTitleBar::setText(QAccessible::Text /*t*/, const QString &/*text*/)
-{
-}
-
-bool QAccessibleTitleBar::isValid() const
-{
- return dockWidget();
-}
-
#endif // QT_NO_DOCKWIDGET
#ifndef QT_NO_CURSOR
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h
index 3e982e82d6..3f50010685 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.h
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h
@@ -283,31 +283,10 @@ public:
int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
int childCount() const Q_DECL_OVERRIDE;
QRect rect () const Q_DECL_OVERRIDE;
-
- QDockWidget *dockWidget() const;
-};
-
-class QAccessibleTitleBar : public QAccessibleInterface
-{
-public:
- explicit QAccessibleTitleBar(QDockWidget *widget);
-
- QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
- QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
- int indexOfChild(const QAccessibleInterface *child) const Q_DECL_OVERRIDE;
- int childCount() const Q_DECL_OVERRIDE;
- QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
- void setText(QAccessible::Text t, const QString &text) Q_DECL_OVERRIDE;
QString text(QAccessible::Text t) const Q_DECL_OVERRIDE;
- QAccessible::Role role() const Q_DECL_OVERRIDE;
- QRect rect () const Q_DECL_OVERRIDE;
- QAccessible::State state() const Q_DECL_OVERRIDE;
- QObject *object() const Q_DECL_OVERRIDE;
- bool isValid() const Q_DECL_OVERRIDE;
-
- QPointer<QDockWidget> m_dockWidget;
QDockWidget *dockWidget() const;
+protected:
QDockWidgetLayout *dockWidgetLayout() const;
};
diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp
index e3e614d700..1dac199a09 100644
--- a/src/plugins/accessible/widgets/simplewidgets.cpp
+++ b/src/plugins/accessible/widgets/simplewidgets.cpp
@@ -474,16 +474,16 @@ QSize QAccessibleDisplay::imageSize() const
}
/*! \internal */
-QRect QAccessibleDisplay::imagePosition() const
+QPoint QAccessibleDisplay::imagePosition() const
{
QLabel *label = qobject_cast<QLabel *>(widget());
if (!label)
- return QRect();
+ return QPoint();
const QPixmap *pixmap = label->pixmap();
if (!pixmap)
- return QRect();
+ return QPoint();
- return QRect(label->mapToGlobal(label->pos()), label->size());
+ return QPoint(label->mapToGlobal(label->pos()));
}
#ifndef QT_NO_GROUPBOX
@@ -605,7 +605,7 @@ QString QAccessibleLineEdit::text(QAccessible::Text t) const
break;
}
if (str.isEmpty())
- str = QAccessibleWidget::text(t);;
+ str = QAccessibleWidget::text(t);
return qt_accStripAmp(str);
}
diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h
index 66b4c2bd3e..6024788048 100644
--- a/src/plugins/accessible/widgets/simplewidgets.h
+++ b/src/plugins/accessible/widgets/simplewidgets.h
@@ -110,7 +110,7 @@ public:
// QAccessibleImageInterface
QString imageDescription() const Q_DECL_OVERRIDE;
QSize imageSize() const Q_DECL_OVERRIDE;
- QRect imagePosition() const Q_DECL_OVERRIDE;
+ QPoint imagePosition() const Q_DECL_OVERRIDE;
};
#ifndef QT_NO_GROUPBOX
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index 4cfc2a6cc4..459a450222 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -55,6 +55,7 @@
#include <xkbcommon_workaround.h>
#endif
+#include <locale.h> // LC_CTYPE
#include <string.h> // strchr, strncmp, etc.
#include <strings.h> // strncasecmp
#include <clocale> // LC_CTYPE
diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.cpp b/src/plugins/platforms/android/src/androidjniaccessibility.cpp
index 07f3371e72..a27d9f5aed 100644
--- a/src/plugins/platforms/android/src/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/src/androidjniaccessibility.cpp
@@ -164,7 +164,7 @@ if (!clazz) { \
//__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE);
-#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, VALUE) \
+#define CALL_METHOD(OBJECT, METHOD_NAME, METHOD_SIGNATURE, ...) \
{ \
jclass clazz = env->GetObjectClass(OBJECT); \
jmethodID method = env->GetMethodID(clazz, METHOD_NAME, METHOD_SIGNATURE); \
@@ -172,7 +172,7 @@ if (!clazz) { \
__android_log_print(ANDROID_LOG_WARN, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); \
return; \
} \
- env->CallVoidMethod(OBJECT, method, VALUE); \
+ env->CallVoidMethod(OBJECT, method, __VA_ARGS__); \
}
@@ -201,9 +201,21 @@ if (!clazz) { \
}
QAccessible::State state = iface->state();
- QString desc = iface->text(QAccessible::Name);
+ // try to fill in the text property, this is what the screen reader reads
+ QString desc = iface->text(QAccessible::Value);
+ if (desc.isEmpty())
+ desc = iface->text(QAccessible::Name);
if (desc.isEmpty())
desc = iface->text(QAccessible::Description);
+ if (QAccessibleTextInterface *textIface = iface->textInterface()) {
+ if (textIface->selectionCount() > 0) {
+ int startSelection;
+ int endSelection;
+ textIface->selection(0, &startSelection, &endSelection);
+ CALL_METHOD(node, "setTextSelection", "(II)V", startSelection, endSelection)
+ }
+ }
+
if ((iface->role() != QAccessible::NoRole) &&
(iface->role() != QAccessible::Client) &&
(iface->role() != QAccessible::Pane)) {
diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/src/androidjniinput.cpp
index 4a2d87d6a4..30d4e69afe 100644
--- a/src/plugins/platforms/android/src/androidjniinput.cpp
+++ b/src/plugins/platforms/android/src/androidjniinput.cpp
@@ -228,6 +228,9 @@ namespace QtAndroidInput
return;
QAndroidPlatformIntegration *platformIntegration = QtAndroid::androidPlatformIntegration();
+ if (!platformIntegration)
+ return;
+
QTouchDevice *touchDevice = platformIntegration->touchDevice();
if (touchDevice == 0) {
touchDevice = new QTouchDevice;
@@ -271,8 +274,8 @@ namespace QtAndroidInput
case 0x00000005:
return Qt::Key_Call;
- case 0x0000001b:
- return Qt::Key_WebCam;
+ case 0x0000001b: // KEYCODE_CAMERA
+ return Qt::Key_Camera;
case 0x0000001c:
return Qt::Key_Clear;
@@ -280,7 +283,7 @@ namespace QtAndroidInput
case 0x00000037:
return Qt::Key_Comma;
- case 0x00000043:
+ case 0x00000043: // KEYCODE_DEL
return Qt::Key_Backspace;
case 0x00000017: // KEYCODE_DPAD_CENTER
@@ -398,6 +401,27 @@ namespace QtAndroidInput
case 0x00000018:
return Qt::Key_VolumeUp;
+ case 0x00000011: // KEYCODE_STAR
+ return Qt::Key_Asterisk;
+
+ case 0x00000012: // KEYCODE_POUND
+ return Qt::Key_NumberSign;
+
+ case 0x00000050: // KEYCODE_FOCUS
+ return Qt::Key_CameraFocus;
+
+ case 0x00000070: // KEYCODE_FORWARD_DEL
+ return Qt::Key_Delete;
+
+ case 0x00000080: // KEYCODE_MEDIA_CLOSE
+ return Qt::Key_Close;
+
+ case 0x00000081: // KEYCODE_MEDIA_EJECT
+ return Qt::Key_Eject;
+
+ case 0x00000082: // KEYCODE_MEDIA_RECORD
+ return Qt::Key_MediaRecord;
+
case 0x000000b7: // KEYCODE_PROG_RED
return Qt::Key_Red;
@@ -416,13 +440,30 @@ namespace QtAndroidInput
case 0x000000a7: // KEYCODE_CHANNEL_DOWN
return Qt::Key_ChannelDown;
+ case 0x000000a8: // KEYCODE_ZOOM_IN
+ return Qt::Key_ZoomIn;
+
+ case 0x000000a9: // KEYCODE_ZOOM_OUT
+ return Qt::Key_ZoomOut;
+
+ case 0x000000af: // KEYCODE_CAPTIONS
+ return Qt::Key_Subtitle;
+
+ case 0x000000d0: // KEYCODE_CALENDAR
+ return Qt::Key_Calendar;
+
+ case 0x000000d1: // KEYCODE_MUSIC
+ return Qt::Key_Music;
+
+ case 0x000000d2: // KEYCODE_CALCULATOR
+ return Qt::Key_Calculator;
+
case 0x00000000: // KEYCODE_UNKNOWN
- case 0x00000011: // KEYCODE_STAR ?!?!?
- case 0x00000012: // KEYCODE_POUND ?!?!?
+ return Qt::Key_unknown;
+
case 0x00000053: // KEYCODE_NOTIFICATION ?!?!?
case 0x0000004f: // KEYCODE_HEADSETHOOK ?!?!?
case 0x00000044: // KEYCODE_GRAVE ?!?!?
- case 0x00000050: // KEYCODE_FOCUS ?!?!?
return Qt::Key_Any;
default:
@@ -447,7 +488,7 @@ namespace QtAndroidInput
mapAndroidKey(key),
modifiers,
QChar(unicode),
- true);
+ false);
}
static void keyUp(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier)
@@ -467,7 +508,7 @@ namespace QtAndroidInput
mapAndroidKey(key),
modifiers,
QChar(unicode),
- true);
+ false);
}
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp
index b51c15c5d9..5c9ca798a8 100644
--- a/src/plugins/platforms/android/src/androidjnimain.cpp
+++ b/src/plugins/platforms/android/src/androidjnimain.cpp
@@ -419,14 +419,11 @@ static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobj
static void *startMainMethod(void */*data*/)
{
- char const **params;
- params = static_cast<char const **>(malloc(m_applicationParams.length() * sizeof(char *)));
+ QVarLengthArray<const char *> params(m_applicationParams.size());
for (int i = 0; i < m_applicationParams.size(); i++)
params[i] = static_cast<const char *>(m_applicationParams[i].constData());
- int ret = m_main(m_applicationParams.length(), const_cast<char **>(params));
-
- free(params);
+ int ret = m_main(m_applicationParams.length(), const_cast<char **>(params.data()));
Q_UNUSED(ret);
if (m_mainLibraryHnd) {
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
index 9ce382bd53..a3db421de9 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
@@ -42,7 +42,6 @@
#include "qandroidplatformintegration.h"
#include "qabstracteventdispatcher.h"
#include "androidjnimain.h"
-#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/qguiapplication.h>
#include <qpa/qwindowsysteminterface.h>
#include <QThread>
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
index 36247e86f9..253c22a12f 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
+++ b/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
@@ -67,9 +67,11 @@ void QAndroidPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatform
void QAndroidPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
{
QMutexLocker lock(&m_menuItemsMutex);
- m_menuItems.erase(qFind(m_menuItems.begin(),
- m_menuItems.end(),
- static_cast<QAndroidPlatformMenuItem *>(menuItem)));
+ PlatformMenuItemsType::iterator it = qFind(m_menuItems.begin(),
+ m_menuItems.end(),
+ static_cast<QAndroidPlatformMenuItem *>(menuItem));
+ if (it != m_menuItems.end())
+ m_menuItems.erase(it);
}
void QAndroidPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem)
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 05bf657c1f..7f0f07e912 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -201,9 +201,11 @@ public: // for QNSView
bool m_isExposed;
int m_registerTouchCount;
bool m_resizableTransientParent;
+ bool m_overrideBecomeKey;
static const int NoAlertRequest;
NSInteger m_alertRequest;
+ id monitor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 7bdfd12314..845cc1202f 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -160,7 +160,9 @@ static bool isMouseEvent(NSEvent *ev)
// Only tool or dialog windows should become key:
if (m_cocoaPlatformWindow
- && (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog))
+ && (m_cocoaPlatformWindow->m_overrideBecomeKey ||
+ m_cocoaPlatformWindow->window()->type() == Qt::Tool ||
+ m_cocoaPlatformWindow->window()->type() == Qt::Dialog))
return YES;
return NO;
}
@@ -212,7 +214,9 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_isExposed(false)
, m_registerTouchCount(0)
, m_resizableTransientParent(false)
+ , m_overrideBecomeKey(false)
, m_alertRequest(NoAlertRequest)
+ , monitor(nil)
{
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
@@ -367,6 +371,11 @@ void QCocoaWindow::setVisible(bool visible)
if ((window()->type() == Qt::Popup || window()->type() == Qt::Dialog || window()->type() == Qt::Tool)
&& [m_nsWindow isKindOfClass:[NSPanel class]]) {
[(NSPanel *)m_nsWindow setWorksWhenModal:YES];
+ if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) {
+ monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDown handler:^(NSEvent *) {
+ QWindowSystemInterface::handleMouseEvent(window(), QPointF(-1, -1), QPointF(window()->framePosition() - QPointF(1, 1)), Qt::LeftButton);
+ }];
+ }
}
}
}
@@ -403,6 +412,10 @@ void QCocoaWindow::setVisible(bool visible)
} else {
[m_contentView setHidden:YES];
}
+ if (monitor && window()->type() == Qt::Popup) {
+ [NSEvent removeMonitor:monitor];
+ monitor = nil;
+ }
if (parentCocoaWindow && window()->type() == Qt::Popup) {
parentCocoaWindow->m_activePopupWindow = 0;
if (m_resizableTransientParent
@@ -450,7 +463,6 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
{
Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
NSInteger styleMask = NSBorderlessWindowMask;
-
if ((type & Qt::Popup) == Qt::Popup) {
if (!windowIsPopupType(type) && !(flags & Qt::FramelessWindowHint))
styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask |
@@ -458,14 +470,21 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
} else {
// Filter flags for supported properties
flags &= Qt::WindowType_Mask | Qt::FramelessWindowHint | Qt::WindowTitleHint |
- Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint;
+ Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint;
if (flags == Qt::Window) {
styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask);
} else if ((flags & Qt::Dialog) == Qt::Dialog) {
- if (window()->modality() == Qt::NonModal)
+ if (flags & Qt::CustomizeWindowHint) {
+ styleMask = NSResizableWindowMask;
+ if (flags & Qt::WindowTitleHint)
+ styleMask |= NSTitledWindowMask;
+ if (flags & Qt::WindowCloseButtonHint)
+ styleMask |= NSClosableWindowMask;
+ if (flags & Qt::WindowMinimizeButtonHint)
+ styleMask |= NSMiniaturizableWindowMask;
+ } else {
styleMask = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask;
- else
- styleMask = NSResizableWindowMask | NSTitledWindowMask;
+ }
} else if (!(flags & Qt::FramelessWindowHint)) {
if ((flags & Qt::Dialog) || (flags & Qt::WindowMaximizeButtonHint))
styleMask |= NSResizableWindowMask;
@@ -661,6 +680,8 @@ bool QCocoaWindow::setKeyboardGrabEnabled(bool grab)
if (!m_nsWindow)
return false;
+ m_overrideBecomeKey = grab;
+
if (grab && ![m_nsWindow isKeyWindow])
[m_nsWindow makeKeyWindow];
else if (!grab && [m_nsWindow isKeyWindow])
@@ -673,6 +694,8 @@ bool QCocoaWindow::setMouseGrabEnabled(bool grab)
if (!m_nsWindow)
return false;
+ m_overrideBecomeKey = grab;
+
if (grab && ![m_nsWindow isKeyWindow])
[m_nsWindow makeKeyWindow];
else if (!grab && [m_nsWindow isKeyWindow])
@@ -843,10 +866,9 @@ NSWindow * QCocoaWindow::createNSWindow()
// before the window is shown and needs a proper window.).
if ((type & Qt::Popup) == Qt::Popup)
[window setHasShadow:YES];
- else {
- setWindowShadow(flags);
- [window setHidesOnDeactivate: NO];
- }
+ else
+ setWindowShadow(flags);
+ [window setHidesOnDeactivate: NO];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 8813a934bf..f90fc6b205 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -208,6 +208,22 @@ static QTouchDevice *touchDevice = 0;
if ([self window])
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[self window]];
}
+
+- (QWindow *)topLevelWindow
+{
+ QWindow *focusWindow = m_window;
+
+ // For widgets we need to do a bit of trickery as the window
+ // to activate is the window of the top-level widget.
+ if (m_window->metaObject()->className() == QStringLiteral("QWidgetWindow")) {
+ while (focusWindow->parent()) {
+ focusWindow = focusWindow->parent();
+ }
+ }
+
+ return focusWindow;
+}
+
- (void)updateGeometry
{
QRect geometry;
@@ -457,16 +473,7 @@ static QTouchDevice *touchDevice = 0;
{
if (m_window->flags() & Qt::WindowTransparentForInput)
return NO;
- QWindow *focusWindow = m_window;
-
- // For widgets we need to do a bit of trickery as the window
- // to activate is the window of the top-level widget.
- if (m_window->metaObject()->className() == QStringLiteral("QWidgetWindow")) {
- while (focusWindow->parent()) {
- focusWindow = focusWindow->parent();
- }
- }
- QWindowSystemInterface::handleWindowActivated(focusWindow);
+ QWindowSystemInterface::handleWindowActivated([self topLevelWindow]);
return YES;
}
@@ -968,6 +975,102 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, touchDevice, points);
}
+#ifndef QT_NO_GESTURES
+//#define QT_COCOA_ENABLE_GESTURE_DEBUG
+- (void)magnifyWithEvent:(NSEvent *)event
+{
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "magnifyWithEvent" << [event magnification];
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::ZoomNativeGesture,
+ [event magnification], windowPoint, screenPoint);
+}
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
+- (void)smartMagnifyWithEvent:(NSEvent *)event
+{
+ static bool zoomIn = true;
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "smartMagnifyWithEvent" << zoomIn;
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SmartZoomNativeGesture,
+ zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint);
+ zoomIn = !zoomIn;
+}
+#endif
+
+- (void)rotateWithEvent:(NSEvent *)event
+{
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "rotateWithEvent" << [event rotation];
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::RotateNativeGesture,
+ -[event rotation], windowPoint, screenPoint);
+}
+
+- (void)swipeWithEvent:(NSEvent *)event
+{
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "swipeWithEvent" << [event deltaX] << [event deltaY];
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+
+ qreal angle = 0.0f;
+ if ([event deltaX] == 1)
+ angle = 180.0f;
+ else if ([event deltaX] == -1)
+ angle = 0.0f;
+ else if ([event deltaY] == 1)
+ angle = 90.0f;
+ else if ([event deltaY] == -1)
+ angle = 270.0f;
+
+ QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SwipeNativeGesture,
+ angle, windowPoint, screenPoint);
+}
+
+- (void)beginGestureWithEvent:(NSEvent *)event
+{
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "beginGestureWithEvent";
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::BeginNativeGesture,
+ windowPoint, screenPoint);
+}
+
+- (void)endGestureWithEvent:(NSEvent *)event
+{
+#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
+ qDebug() << "endGestureWithEvent";
+#endif
+ const NSTimeInterval timestamp = [event timestamp];
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::EndNativeGesture,
+ windowPoint, screenPoint);
+}
+#endif // QT_NO_GESTURES
+
#ifndef QT_NO_WHEELEVENT
- (void)scrollWheel:(NSEvent *)theEvent
{
@@ -1124,10 +1227,12 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
if (ch.unicode() < 0xf700 || ch.unicode() > 0xf8ff)
text = QCFString::toQString(characters);
+ QWindow *focusWindow = [self topLevelWindow];
+
if (eventType == QEvent::KeyPress) {
if (m_composingText.isEmpty())
- m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(m_window, timestamp, keyCode, modifiers, text);
+ m_sendKeyEvent = !QWindowSystemInterface::tryHandleShortcutEvent(focusWindow, timestamp, keyCode, modifiers, text);
QObject *fo = QGuiApplication::focusObject();
if (m_sendKeyEvent && fo) {
@@ -1144,7 +1249,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
}
if (m_sendKeyEvent && m_composingText.isEmpty())
- QWindowSystemInterface::handleExtendedKeyEvent(m_window, timestamp, QEvent::Type(eventType), keyCode, modifiers,
+ QWindowSystemInterface::handleExtendedKeyEvent(focusWindow, timestamp, QEvent::Type(eventType), keyCode, modifiers,
nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat]);
m_sendKeyEvent = false;
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
index 5b4c958616..b56d75a16e 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -282,9 +282,12 @@ QDirectFbKeyMap::QDirectFbKeyMap()
insert(DIKS_MENU , Qt::Key_Menu);
insert(DIKS_HELP , Qt::Key_Help);
+ insert(DIKS_CD , Qt::Key_CD);
insert(DIKS_INTERNET , Qt::Key_HomePage);
insert(DIKS_MAIL , Qt::Key_LaunchMail);
insert(DIKS_FAVORITES , Qt::Key_Favorites);
+ insert(DIKS_PHONE , Qt::Key_Phone);
+ insert(DIKS_TIME , Qt::Key_Time);
insert(DIKS_RED , Qt::Key_Red);
insert(DIKS_GREEN , Qt::Key_Green);
@@ -307,6 +310,7 @@ QDirectFbKeyMap::QDirectFbKeyMap()
insert(DIKS_NEXT , Qt::Key_MediaNext);
insert(DIKS_REWIND , Qt::Key_AudioRewind);
insert(DIKS_FASTFORWARD , Qt::Key_AudioForward);
+ insert(DIKS_SUBTITLE , Qt::Key_Subtitle);
insert(DIKS_F1 , Qt::Key_F1);
insert(DIKS_F2 , Qt::Key_F2);
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index f7df792362..3dd9c7ad9f 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -213,7 +213,7 @@ static int infoPlistValue(NSString* key, int defaultValue)
return value ? [value intValue] : defaultValue;
}
-extern "C" int qtmn(int argc, char *argv[])
+extern "C" int __attribute__((weak)) main(int argc, char *argv[])
{
@autoreleasepool {
size_t defaultStackSize = 512 * kBytesPerKiloByte; // Same as secondary threads
@@ -248,7 +248,18 @@ enum SetJumpResult
kJumpedFromUserMainTrampoline,
};
-extern "C" int main(int argc, char *argv[]);
+// We define qt_main so that user_main_trampoline() will not cause
+// missing symbols in the case of hybrid applications that don't
+// user our main wrapper. Since the symbol is weak, it will not
+// get used or cause a clash in the normal Qt application usecase,
+// where we rename main to qt_main.
+extern "C" int __attribute__((weak)) qt_main(int argc, char *argv[])
+{
+ Q_UNUSED(argc);
+ Q_UNUSED(argv);
+
+ Q_UNREACHABLE();
+}
static void __attribute__((noinline, noreturn)) user_main_trampoline()
{
@@ -261,7 +272,7 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline()
strcpy(argv[i], [arg cStringUsingEncoding:[NSString defaultCStringEncoding]]);
}
- int exitCode = main(argc, argv);
+ int exitCode = qt_main(argc, argv);
delete[] argv;
qEventDispatcherDebug() << "Returned from main with exit code " << exitCode;
@@ -496,6 +507,7 @@ void QIOSEventDispatcher::checkIfEventLoopShouldExit()
void QIOSEventDispatcher::handleRunLoopExit(CFRunLoopActivity activity)
{
+ Q_UNUSED(activity);
Q_ASSERT(activity == kCFRunLoopExit);
m_runLoopExitObserver.removeFromMode(kCFRunLoopCommonModes);
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index aa2687da30..977df8abd0 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -56,9 +56,8 @@ QT_BEGIN_NAMESPACE
QLinuxFbIntegration::QLinuxFbIntegration(const QStringList &paramList)
: m_fontDb(new QGenericUnixFontDatabase())
{
- m_primaryScreen = new QLinuxFbScreen;
- if (m_primaryScreen->initialize(paramList))
- screenAdded(m_primaryScreen);
+ m_primaryScreen = new QLinuxFbScreen(paramList);
+ screenAdded(m_primaryScreen);
}
QLinuxFbIntegration::~QLinuxFbIntegration()
@@ -66,6 +65,12 @@ QLinuxFbIntegration::~QLinuxFbIntegration()
delete m_primaryScreen;
}
+void QLinuxFbIntegration::initialize()
+{
+ if (!m_primaryScreen->initialize())
+ qWarning("linuxfb: Failed to initialize screen");
+}
+
bool QLinuxFbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
index 6de9ac9992..a213f83c6f 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -56,14 +56,16 @@ public:
QLinuxFbIntegration(const QStringList &paramList);
~QLinuxFbIntegration();
- bool hasCapability(QPlatformIntegration::Capability cap) const;
+ void initialize() Q_DECL_OVERRIDE;
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+ QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
+ QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
- QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
- QAbstractEventDispatcher *createEventDispatcher() const;
QList<QPlatformScreen *> screens() const;
- QPlatformFontDatabase *fontDatabase() const;
private:
QLinuxFbScreen *m_primaryScreen;
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index ad5206ba41..4f9284da7f 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -62,6 +62,10 @@
#include <linux/fb.h>
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+#include <QtPlatformSupport/private/qdevicediscovery_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
static int openFramebufferDevice(const QString &dev)
@@ -292,8 +296,8 @@ static void blankScreen(int fd, bool on)
ioctl(fd, FBIOBLANK, on ? VESA_POWERDOWN : VESA_NO_BLANKING);
}
-QLinuxFbScreen::QLinuxFbScreen()
- : mFbFd(-1), mBlitter(0)
+QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)
+ : mArgs(args), mFbFd(-1), mBlitter(0)
{
}
@@ -312,7 +316,7 @@ QLinuxFbScreen::~QLinuxFbScreen()
delete mBlitter;
}
-bool QLinuxFbScreen::initialize(const QStringList &args)
+bool QLinuxFbScreen::initialize()
{
QRegExp ttyRx(QLatin1String("tty=(.*)"));
QRegExp fbRx(QLatin1String("fb=(.*)"));
@@ -326,7 +330,7 @@ bool QLinuxFbScreen::initialize(const QStringList &args)
bool doSwitchToGraphicsMode = true;
// Parse arguments
- foreach (const QString &arg, args) {
+ foreach (const QString &arg, mArgs) {
if (arg == QLatin1String("nographicsmodeswitch"))
doSwitchToGraphicsMode = false;
else if (sizeRx.indexIn(arg) != -1)
@@ -341,8 +345,15 @@ bool QLinuxFbScreen::initialize(const QStringList &args)
userMmSize = QSize(mmSizeRx.cap(1).toInt(), mmSizeRx.cap(2).toInt());
}
- if (fbDevice.isEmpty())
- fbDevice = QLatin1String("/dev/fb0"); // ## auto-detect
+ if (fbDevice.isEmpty()) {
+ fbDevice = QLatin1String("/dev/fb0");
+ if (!QFile::exists(fbDevice))
+ fbDevice = QLatin1String("/dev/graphics/fb0");
+ if (!QFile::exists(fbDevice)) {
+ qWarning("Unable to figure out framebuffer device. Specify it manually.");
+ return false;
+ }
+ }
// Open the device
mFbFd = openFramebufferDevice(fbDevice);
@@ -387,7 +398,19 @@ bool QLinuxFbScreen::initialize(const QStringList &args)
QFbScreen::initializeCompositor();
mFbScreenImage = QImage(mMmap.data, geometry.width(), geometry.height(), mBytesPerLine, mFormat);
- mCursor = new QFbCursor(this);
+
+ QByteArray hideCursorVal = qgetenv("QT_QPA_FB_HIDECURSOR");
+ bool hideCursor = true; // default to true to prevent the cursor showing up with the subclass on Android
+ if (hideCursorVal.isEmpty()) {
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+ QScopedPointer<QDeviceDiscovery> dis(QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse));
+ hideCursor = dis->scanConnectedDevices().isEmpty();
+#endif
+ } else {
+ hideCursor = hideCursorVal.toInt() != 0;
+ }
+ if (!hideCursor)
+ mCursor = new QFbCursor(this);
mTtyFd = openTtyDevice(ttyDevice);
if (mTtyFd == -1)
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
index d34104c6e1..32cd263063 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
@@ -53,15 +53,16 @@ class QLinuxFbScreen : public QFbScreen
{
Q_OBJECT
public:
- QLinuxFbScreen();
+ QLinuxFbScreen(const QStringList &args);
~QLinuxFbScreen();
- bool initialize(const QStringList &args);
+ bool initialize();
public slots:
QRegion doRedraw();
private:
+ QStringList mArgs;
int mFbFd;
int mTtyFd;
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index 355f52c46e..34e8150928 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -124,7 +124,15 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
if (m_eglConfig == 0)
qFatal("QQnxGLContext: failed to find EGL config");
- m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttrs());
+ EGLContext shareContext = EGL_NO_CONTEXT;
+ if (m_glContext) {
+ QQnxGLContext *qshareContext = dynamic_cast<QQnxGLContext*>(m_glContext->shareHandle());
+ if (qshareContext) {
+ shareContext = qshareContext->m_eglContext;
+ }
+ }
+
+ m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, shareContext, contextAttrs());
if (m_eglContext == EGL_NO_CONTEXT) {
checkEGLError("eglCreateContext");
qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError());
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index 6c3fd08a41..dd8cf2131a 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -446,7 +446,7 @@ void QQnxScreen::addWindow(QQnxWindow *window)
m_childWindows.push_back(window);
updateHierarchy();
} else {
-#if !defined(Q_OS_BLACKBERRY_TABLET)
+#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET)
m_coverWindow = window;
#endif
}
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index a129380575..3969a09098 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -562,13 +562,11 @@ void QQnxWindow::initWindow()
setScreen(static_cast<QQnxScreen *>(window()->screen()->handle()));
if (window()->type() == Qt::CoverWindow) {
-#if !defined(Q_OS_BLACKBERRY_TABLET)
+#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET)
screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(),
SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window);
-#if defined(Q_OS_BLACKBERRY)
m_cover.reset(new QQnxNavigatorCover);
#endif
-#endif // Q_OS_BLACKBERRY_TABLET
m_exposed = false;
}
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index ee5b6189b2..f6ed9447ef 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -204,6 +204,9 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
case WM_DISPLAYCHANGE:
return QtWindows::DisplayChangedEvent;
case WM_THEMECHANGED:
+#ifdef WM_SYSCOLORCHANGE // Windows 7: Handle color change as theme change (QTBUG-34170).
+ case WM_SYSCOLORCHANGE:
+#endif
return QtWindows::ThemeChanged;
case WM_DWMCOMPOSITIONCHANGED:
return QtWindows::CompositionSettingsChanged;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 783d50a26a..85b03673ac 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -954,7 +954,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
qGuiAppPriv->commitData();
if (lParam & ENDSESSION_LOGOFF)
- _flushall();
+ fflush(NULL);
return !sessionManager->wasCanceled();
}
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 0ecbf44194..832ce24354 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -578,8 +578,8 @@ bool QWindowsDialogHelperBase<BaseClass>::show(Qt::WindowFlags,
m_ownerWindow = 0;
}
if (QWindowsContext::verboseDialogs)
- qDebug("%s modal=%d native=%p parent=%p" ,
- __FUNCTION__, modal, m_nativeDialog.data(), m_ownerWindow);
+ qDebug("%s modal=%d modal supported? %d native=%p parent=%p" ,
+ __FUNCTION__, modal, supportsNonModalDialog(parent), m_nativeDialog.data(), m_ownerWindow);
if (!modal && !supportsNonModalDialog(parent))
return false; // Was it changed in-between?
if (!ensureNativeDialog())
@@ -1766,7 +1766,9 @@ static int CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UINT uMsg,
return dialog->existingDirCallback(hwnd, uMsg, lParam);
}
-#ifdef Q_CC_MINGW
+/* The correct declaration of the SHGetPathFromIDList symbol is
+ * being used in mingw-w64 as of r6215, which is a v3 snapshot. */
+#if defined(Q_CC_MINGW) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3)
typedef ITEMIDLIST *qt_LpItemIdList;
#else
typedef PIDLIST_ABSOLUTE qt_LpItemIdList;
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index 4a5d7b5a78..1a5c1a2e0c 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -395,8 +395,19 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
const int currentDevice = m_devices.at(m_currentDevice).currentDevice;
const int currentPointer = m_devices.at(m_currentDevice).currentPointerType;
- // When entering proximity, the tablet driver snaps the mouse pointer to the
- // tablet position scaled to the virtual desktop and keeps it in sync.
+ // The tablet can be used in 2 different modes, depending on it settings:
+ // 1) Absolute (pen) mode:
+ // The coordinates are scaled to the virtual desktop (by default). The user
+ // can also choose to scale to the monitor or a region of the screen.
+ // When entering proximity, the tablet driver snaps the mouse pointer to the
+ // tablet position scaled to that area and keeps it in sync.
+ // 2) Relative (mouse) mode:
+ // The pen follows the mouse. The constant 'absoluteRange' specifies the
+ // manhattanLength difference for detecting if a tablet input device is in this mode,
+ // in which case we snap the position to the mouse position.
+ // It seems there is no way to find out the mode programmatically, the LOGCONTEXT orgX/Y/Ext
+ // area is always the virtual desktop.
+ enum { absoluteRange = 20 };
const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
if (QWindowsContext::verboseTablet)
@@ -409,10 +420,24 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
const PACKET &packet = localPacketBuf[i];
const int z = currentDevice == QTabletEvent::FourDMouse ? int(packet.pkZ) : 0;
- const QPointF globalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea);
+
+ // This code is to delay the tablet data one cycle to sync with the mouse location.
+ QPointF globalPosF = m_oldGlobalPosF;
+ m_oldGlobalPosF = m_devices.at(m_currentDevice).scaleCoordinates(packet.pkX, packet.pkY, virtualDesktopArea);
QWindow *target = QGuiApplicationPrivate::tabletPressTarget; // Pass to window that grabbed it.
- const QPoint globalPos = globalPosF.toPoint();
+ QPoint globalPos = globalPosF.toPoint();
+
+ // Get Mouse Position and compare to tablet info
+ const QPoint mouseLocation = QWindowsCursor::mousePosition();
+
+ // Positions should be almost the same if we are in absolute
+ // mode. If they are not, use the mouse location.
+ if ((mouseLocation - globalPos).manhattanLength() > absoluteRange) {
+ globalPos = mouseLocation;
+ globalPosF = globalPos;
+ }
+
if (!target)
if (QPlatformWindow *pw = QWindowsContext::instance()->findPlatformWindowAt(GetDesktopWindow(), globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT))
target = pw->window();
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h
index 12f96b618d..5e29cd9554 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.h
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.h
@@ -134,6 +134,7 @@ private:
bool m_tiltSupport;
QVector<QWindowsTabletDeviceData> m_devices;
int m_currentDevice;
+ QPointF m_oldGlobalPosF;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index be739d0551..1909e0313b 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1056,9 +1056,10 @@ void QWindowsWindow::setVisible(bool visible)
// When the window is layered, we won't get WM_PAINT, and "we" are in control
// over the rendering of the window
// There is nobody waiting for this, so we don't need to flush afterwards.
- QWindow *w = window();
- if (w->format().hasAlpha() || qFuzzyCompare(w->opacity(), qreal(1)))
+ if (isLayered()) {
+ QWindow *w = window();
fireExpose(QRect(0, 0, w->width(), w->height()));
+ }
} else {
if (hasMouseCapture())
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 4961e0377c..d18693f6b8 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -835,7 +835,7 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event)
void QXcbDrag::handleStatus(const xcb_client_message_event_t *event)
{
- if (event->window != connection()->clipboard()->owner())
+ if (event->window != connection()->clipboard()->owner() || !drag())
return;
xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index a3d6a65695..8c10b134bd 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -48,6 +48,7 @@
#include <qplatformdefs.h>
#include <qsocketnotifier.h>
#include <X11/SM/SMlib.h>
+#include <errno.h> // ERANGE
#include <cerrno> // ERANGE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 6d986ba601..aa53093868 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1148,7 +1148,7 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
QByteArray ba("Qt NET_WM user time window");
Q_XCB_CALL(xcb_change_property(xcb_connection(),
XCB_PROP_MODE_REPLACE,
- m_window,
+ m_netWmUserTimeWindow,
atom(QXcbAtom::_NET_WM_NAME),
atom(QXcbAtom::UTF8_STRING),
8,
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
index f41d4f5047..b9f0c394f8 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
@@ -66,8 +66,7 @@ QCupsPrinterSupport::QCupsPrinterSupport() : QPlatformPrinterSupport(),
QCupsPrinterSupport::~QCupsPrinterSupport()
{
- if (cupsFreeDests)
- cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters);
+ freeCupsPrinters();
}
QPrintEngine *QCupsPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode printerMode)
@@ -98,14 +97,20 @@ void QCupsPrinterSupport::loadCups()
cupsGetOption = (CupsGetOption) m_cups.resolve("cupsGetOption");
}
+void QCupsPrinterSupport::freeCupsPrinters()
+{
+ if (cupsFreeDests && m_cupsPrintersCount) {
+ cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters);
+ m_cupsPrintersCount = 0;
+ m_cupsPrinters = 0;
+ }
+}
+
void QCupsPrinterSupport::loadCupsPrinters()
{
- m_cupsPrintersCount = 0;
+ freeCupsPrinters();
m_printers.clear();
- if (cupsFreeDests)
- cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters);
-
if (cupsGetDests)
m_cupsPrintersCount = cupsGetDests(&m_cupsPrinters);
@@ -122,6 +127,12 @@ void QCupsPrinterSupport::loadCupsPrinters()
}
}
+QList<QPrinterInfo> QCupsPrinterSupport::availablePrinters()
+{
+ loadCupsPrinters();
+ return QPlatformPrinterSupport::availablePrinters();
+}
+
QString QCupsPrinterSupport::printerOption(const QPrinterInfo &printer, const QString &key) const
{
return cupsOption(printerIndex(printer), key);
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h
index e9fe24203e..d42c0d2630 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h
+++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h
@@ -68,12 +68,14 @@ public:
virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode);
virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
virtual QList<QPair<QString, QSizeF> > supportedSizesWithNames(const QPrinterInfo &) const;
+ virtual QList<QPrinterInfo> availablePrinters();
virtual QString printerOption(const QPrinterInfo &printer, const QString &key) const;
virtual PrinterOptions printerOptions(const QPrinterInfo &printer) const;
private:
void loadCups();
void loadCupsPrinters();
+ void freeCupsPrinters();
QString cupsOption(int i, const QString &key) const;
QLibrary m_cups;
diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp
index 36e7a3fb8e..2faebf6f64 100644
--- a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp
+++ b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp
@@ -42,6 +42,7 @@
#include "qwindowsprintersupport.h"
#include <QtCore/QList>
+#include <QtCore/QScopedArrayPointer>
#include <QtPrintSupport/QPrinterInfo>
#include <qprintengine_win_p.h>
#include <private/qpaintengine_alpha_p.h>
@@ -52,25 +53,7 @@ QT_BEGIN_NAMESPACE
QWindowsPrinterSupport::QWindowsPrinterSupport()
: QPlatformPrinterSupport()
{
- DWORD needed = 0;
- DWORD returned = 0;
- if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) {
- LPBYTE buffer = new BYTE[needed];
- if (EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer, needed, &needed, &returned)) {
- PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer);
- QString defaultPrinterName;
- QString program;
- QString port;
- QWin32PrintEngine::queryDefaultPrinter(defaultPrinterName, program, port);
- for (uint i = 0; i < returned; ++i) {
- QString printerName(QString::fromWCharArray(infoList[i].pPrinterName));
- bool isDefault = (printerName == defaultPrinterName);
- QPrinterInfo printerInfo = createPrinterInfo(printerName, QString(), QString(), QString(), isDefault, i);
- m_printers.append(printerInfo);
- }
- }
- delete [] buffer;
- }
+ m_printers = QWindowsPrinterSupport::queryPrinters();
}
QWindowsPrinterSupport::~QWindowsPrinterSupport()
@@ -98,4 +81,35 @@ QList<QPair<QString, QSizeF> >QWindowsPrinterSupport::supportedSizesWithNames(co
return QWin32PrintEngine::supportedSizesWithNames(printerInfo);
}
+QList<QPrinterInfo> QWindowsPrinterSupport::availablePrinters()
+{
+ m_printers = QWindowsPrinterSupport::queryPrinters();
+ return QPlatformPrinterSupport::availablePrinters();
+}
+
+QList<QPrinterInfo> QWindowsPrinterSupport::queryPrinters()
+{
+ QList<QPrinterInfo> result;
+ DWORD needed = 0;
+ DWORD returned = 0;
+ if ((!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ || !needed) {
+ return result;
+ }
+ QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
+ if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer.data(), needed, &needed, &returned))
+ return result;
+ PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer.data());
+ QString defaultPrinterName;
+ QString program;
+ QString port;
+ QWin32PrintEngine::queryDefaultPrinter(defaultPrinterName, program, port);
+ for (uint i = 0; i < returned; ++i) {
+ const QString printerName(QString::fromWCharArray(infoList[i].pPrinterName));
+ const bool isDefault = (printerName == defaultPrinterName);
+ result.append(QPlatformPrinterSupport::createPrinterInfo(printerName, QString(), QString(), QString(), isDefault, i));
+ }
+ return result;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h
index 1d5a4f3da4..1b1b1fa215 100644
--- a/src/plugins/printsupport/windows/qwindowsprintersupport.h
+++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h
@@ -58,6 +58,10 @@ public:
virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode);
virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
virtual QList<QPair<QString, QSizeF> >supportedSizesWithNames(const QPrinterInfo &printerInfo) const;
+ virtual QList<QPrinterInfo> availablePrinters();
+
+private:
+ static QList<QPrinterInfo> queryPrinters();
};
QT_END_NAMESPACE
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
index cdb80f96a8..8809b52751 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
@@ -408,6 +408,7 @@ void QPageSetupWidget::selectPrinter()
if (QCUPSSupport::isAvailable()) {
m_cups = true;
QCUPSSupport cups;
+ cups.setCurrentPrinter(m_printer->printerName());
const ppd_option_t* pageSizes = cups.pageSizes();
const int numChoices = pageSizes ? pageSizes->num_choices : 0;
diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp
index 643ffef192..e237d44dcd 100644
--- a/src/printsupport/kernel/qcups.cpp
+++ b/src/printsupport/kernel/qcups.cpp
@@ -144,11 +144,13 @@ QCUPSSupport::QCUPSSupport()
for (int i = 0; i < prnCount; ++i) {
if (printers[i].is_default) {
currPrinterIndex = i;
- setCurrentPrinter(i);
break;
}
}
+ if (prnCount > 0)
+ setCurrentPrinter(currPrinterIndex);
+
#ifndef QT_NO_TEXTCODEC
cups_lang_t *cupsLang = _cupsLangGet(0);
codec = QTextCodec::codecForName(_cupsLangEncoding(cupsLang));
@@ -213,6 +215,17 @@ const ppd_file_t* QCUPSSupport::setCurrentPrinter(int index)
return currPPD;
}
+const ppd_file_t* QCUPSSupport::setCurrentPrinter(const QString &printerName)
+{
+ Q_FOREACH (const QCUPSSupport::Printer &printer, QCUPSSupport::availableUnixPrinters()) {
+ if (printer.name == printerName) {
+ return setCurrentPrinter(printer.cupsPrinterIndex);
+ }
+ }
+
+ return 0;
+}
+
int QCUPSSupport::currentPrinterIndex() const
{
return currPrinterIndex;
diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h
index 726bc7eba6..95ca323c22 100644
--- a/src/printsupport/kernel/qcups_p.h
+++ b/src/printsupport/kernel/qcups_p.h
@@ -149,6 +149,7 @@ public:
const cups_dest_t* availablePrinters() const;
int currentPrinterIndex() const;
const ppd_file_t* setCurrentPrinter(int index);
+ const ppd_file_t* setCurrentPrinter(const QString &printerName);
const ppd_file_t* currentPPD() const;
const ppd_option_t* ppdOption(const char *key) const;
diff --git a/src/src.pro b/src/src.pro
index 641a8a98a6..74ca7fbf0b 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -2,36 +2,44 @@ TEMPLATE = subdirs
src_tools_bootstrap.subdir = tools/bootstrap
src_tools_bootstrap.target = sub-bootstrap
+src_tools_bootstrap.CONFIG = host_build
src_tools_moc.subdir = tools/moc
src_tools_moc.target = sub-moc
src_tools_moc.depends = src_tools_bootstrap
+src_tools_moc.CONFIG = host_build
src_tools_rcc.subdir = tools/rcc
src_tools_rcc.target = sub-rcc
src_tools_rcc.depends = src_tools_bootstrap
+src_tools_rcc.CONFIG = host_build
src_tools_uic.subdir = tools/uic
src_tools_uic.target = sub-uic
+src_tools_uic.CONFIG = host_build
force_bootstrap: src_tools_uic.depends = src_tools_bootstrap
else: src_tools_uic.depends = src_corelib
src_tools_qdoc.subdir = tools/qdoc
src_tools_qdoc.target = sub-qdoc
+src_tools_qdoc.CONFIG = host_build
force_bootstrap: src_tools_qdoc.depends = src_tools_bootstrap
else: src_tools_qdoc.depends = src_corelib src_xml
src_tools_bootstrap_dbus.subdir = tools/bootstrap-dbus
src_tools_bootstrap_dbus.target = sub-bootstrap_dbus
src_tools_bootstrap_dbus.depends = src_tools_bootstrap
+src_tools_bootstrap_dbus.CONFIG = host_build
src_tools_qdbusxml2cpp.subdir = tools/qdbusxml2cpp
src_tools_qdbusxml2cpp.target = sub-qdbusxml2cpp
+src_tools_qdbusxml2cpp.CONFIG = host_build
force_bootstrap: src_tools_qdbusxml2cpp.depends = src_tools_bootstrap_dbus
else: src_tools_qdbusxml2cpp.depends = src_dbus
src_tools_qdbuscpp2xml.subdir = tools/qdbuscpp2xml
src_tools_qdbuscpp2xml.target = sub-qdbuscpp2xml
+src_tools_qdbuscpp2xml.CONFIG = host_build
force_bootstrap: src_tools_qdbuscpp2xml.depends = src_tools_bootstrap_dbus
else: src_tools_qdbuscpp2xml.depends = src_dbus
diff --git a/src/testlib/doc/src/qttest-index.qdoc b/src/testlib/doc/src/qttest-index.qdoc
index db42db1687..4cf0726429 100644
--- a/src/testlib/doc/src/qttest-index.qdoc
+++ b/src/testlib/doc/src/qttest-index.qdoc
@@ -56,6 +56,7 @@
\list
\li \l{Qt Test C++ Classes}{C++ Classes}
+ \li \l{Qt Quick Test}{QML Types}
\endlist
*/
diff --git a/src/testlib/qtestmouse.h b/src/testlib/qtestmouse.h
index 8efa80789c..a07d6bc8c6 100644
--- a/src/testlib/qtestmouse.h
+++ b/src/testlib/qtestmouse.h
@@ -61,7 +61,7 @@
#include <QtWidgets/qwidget.h>
#endif
-#include <QDebug>
+#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 34d3c06e97..b39a3b5e9f 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -310,7 +310,7 @@ void Generator::generateCode()
int escapeLen = lengthOfEscapeSequence(s, backSlashPos);
spanLen = qBound(spanLen, backSlashPos + escapeLen - idx, s.length() - idx);
}
- fwrite(s.constData() + idx, 1, spanLen, out);
+ fprintf(out, "%.*s", spanLen, s.constData() + idx);
idx += spanLen;
col += spanLen;
}
diff --git a/src/tools/qdoc/main.cpp b/src/tools/qdoc/main.cpp
index dd72be7f6e..246e4d2d82 100644
--- a/src/tools/qdoc/main.cpp
+++ b/src/tools/qdoc/main.cpp
@@ -68,27 +68,6 @@
QT_BEGIN_NAMESPACE
-/*
- The default indent for code is 4.
- The default value for false is 0.
- The default supported file extensions are cpp, h, qdoc and qml.
- The default language is c++.
- The default output format is html.
- The default tab size is 8.
- And those are all the default values for configuration variables.
- */
-static const struct {
- const QString key;
- const QString value;
-} defaults[] = {
- { CONFIG_CODEINDENT, QLatin1String("4") },
- { CONFIG_FALSEHOODS, QLatin1String("0") },
- { CONFIG_FILEEXTENSIONS, QLatin1String("*.cpp *.h *.qdoc *.qml") },
- { CONFIG_LANGUAGE, QLatin1String("Cpp") },
- { CONFIG_OUTPUTFORMATS, QLatin1String("HTML") },
- { CONFIG_TABSIZE, QLatin1String("8") },
- { QString(), QString() }
-};
bool creationTimeBefore(const QFileInfo &fi1, const QFileInfo &fi2)
{
@@ -268,11 +247,30 @@ static void processQdocconfFile(const QString &fileName)
initialize the configuration with some default values.
*/
Config config(QCoreApplication::translate("QDoc", "qdoc"));
- int i = 0;
- while (!defaults[i].key.isEmpty()) {
- config.setStringList(defaults[i].key, QStringList() << defaults[i].value);
- ++i;
+
+ /*
+ The default indent for code is 4.
+ The default value for false is 0.
+ The default supported file extensions are cpp, h, qdoc and qml.
+ The default language is c++.
+ The default output format is html.
+ The default tab size is 8.
+ And those are all the default values for configuration variables.
+ */
+ static QHash<QString,QString> defaults;
+ if (defaults.isEmpty()) {
+ defaults.insert(CONFIG_CODEINDENT, QLatin1String("4"));
+ defaults.insert(CONFIG_FALSEHOODS, QLatin1String("0"));
+ defaults.insert(CONFIG_FILEEXTENSIONS, QLatin1String("*.cpp *.h *.qdoc *.qml"));
+ defaults.insert(CONFIG_LANGUAGE, QLatin1String("Cpp"));
+ defaults.insert(CONFIG_OUTPUTFORMATS, QLatin1String("HTML"));
+ defaults.insert(CONFIG_TABSIZE, QLatin1String("8"));
}
+
+ QHash<QString,QString>::iterator iter;
+ for (iter = defaults.begin(); iter != defaults.end(); ++iter)
+ config.setStringList(iter.key(), QStringList() << iter.value());
+
config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(highlighting ? "true" : "false"));
config.setStringList(CONFIG_SHOWINTERNAL, QStringList(showInternal ? "true" : "false"));
config.setStringList(CONFIG_REDIRECTDOCUMENTATIONTODEVNULL, QStringList(redirectDocumentationToDevNull ? "true" : "false"));
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index e8b6218299..d45f623b8d 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -379,7 +379,6 @@ QFileDialog::QFileDialog(QWidget *parent, Qt::WindowFlags f)
{
Q_D(QFileDialog);
d->init();
- d->lineEdit()->selectAll();
}
/*!
@@ -397,7 +396,6 @@ QFileDialog::QFileDialog(QWidget *parent,
{
Q_D(QFileDialog);
d->init(directory, filter, caption);
- d->lineEdit()->selectAll();
}
/*!
@@ -411,7 +409,6 @@ QFileDialog::QFileDialog(const QFileDialogArgs &args)
setFileMode(args.mode);
setOptions(args.options);
selectFile(args.selection);
- d->lineEdit()->selectAll();
}
/*!
@@ -443,7 +440,8 @@ QFileDialog::~QFileDialog()
void QFileDialog::setSidebarUrls(const QList<QUrl> &urls)
{
Q_D(QFileDialog);
- d->qFileDialogUi->sidebar->setUrls(urls);
+ if (!d->nativeDialogInUse)
+ d->qFileDialogUi->sidebar->setUrls(urls);
}
/*!
@@ -453,7 +451,7 @@ void QFileDialog::setSidebarUrls(const QList<QUrl> &urls)
QList<QUrl> QFileDialog::sidebarUrls() const
{
Q_D(const QFileDialog);
- return d->qFileDialogUi->sidebar->urls();
+ return (d->nativeDialogInUse ? QList<QUrl>() : d->qFileDialogUi->sidebar->urls());
}
static const qint32 QFileDialogMagic = 0xbe;
@@ -474,11 +472,19 @@ QByteArray QFileDialog::saveState() const
stream << qint32(QFileDialogMagic);
stream << qint32(version);
- stream << d->qFileDialogUi->splitter->saveState();
- stream << d->qFileDialogUi->sidebar->urls();
+ if (d->usingWidgets()) {
+ stream << d->qFileDialogUi->splitter->saveState();
+ stream << d->qFileDialogUi->sidebar->urls();
+ } else {
+ stream << QByteArray();
+ stream << QList<QUrl>();
+ }
stream << history();
stream << *lastVisitedDir();
- stream << d->qFileDialogUi->treeView->header()->saveState();
+ if (d->usingWidgets())
+ stream << d->qFileDialogUi->treeView->header()->saveState();
+ else
+ stream << QByteArray();
stream << qint32(viewMode());
return data;
}
@@ -520,6 +526,12 @@ bool QFileDialog::restoreState(const QByteArray &state)
>> headerData
>> viewMode;
+ setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir());
+ setViewMode(static_cast<QFileDialog::ViewMode>(viewMode));
+
+ if (!d->usingWidgets())
+ return true;
+
if (!d->qFileDialogUi->splitter->restoreState(splitterState))
return false;
QList<int> list = d->qFileDialogUi->splitter->sizes();
@@ -533,7 +545,6 @@ bool QFileDialog::restoreState(const QByteArray &state)
while (history.count() > 5)
history.pop_front();
setHistory(history);
- setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir());
QHeaderView *headerView = d->qFileDialogUi->treeView->header();
if (!headerView->restoreState(headerData))
return false;
@@ -548,7 +559,6 @@ bool QFileDialog::restoreState(const QByteArray &state)
for (int i = 1; i < total; ++i)
actions.at(i - 1)->setChecked(!headerView->isSectionHidden(i));
- setViewMode(ViewMode(viewMode));
return true;
}
@@ -595,15 +605,16 @@ void QFileDialogPrivate::initHelper(QPlatformDialogHelper *h)
QObject::connect(h, SIGNAL(directoryEntered(QUrl)), d, SLOT(_q_nativeEnterDirectory(QUrl)));
QObject::connect(h, SIGNAL(filterSelected(QString)), d, SIGNAL(filterSelected(QString)));
static_cast<QPlatformFileDialogHelper *>(h)->setOptions(options);
+ nativeDialogInUse = true;
}
void QFileDialogPrivate::helperPrepareShow(QPlatformDialogHelper *)
{
Q_Q(QFileDialog);
options->setWindowTitle(q->windowTitle());
- options->setViewMode(static_cast<QFileDialogOptions::ViewMode>(q->viewMode()));
options->setHistory(q->history());
- options->setSidebarUrls(qFileDialogUi->sidebar->urls());
+ if (usingWidgets())
+ options->setSidebarUrls(qFileDialogUi->sidebar->urls());
const QDir directory = q->directory();
options->setInitialDirectory(directory.exists() ?
QUrl::fromLocalFile(directory.absolutePath()) :
@@ -644,9 +655,17 @@ void QFileDialogPrivate::setLastVisitedDirectory(const QString &dir)
*lastVisitedDir() = dir;
}
+void QFileDialogPrivate::updateLookInLabel()
+{
+ if (options->isLabelExplicitlySet(QFileDialogOptions::LookIn))
+ setLabelTextControl(QFileDialog::LookIn, options->labelText(QFileDialogOptions::LookIn));
+}
+
void QFileDialogPrivate::updateFileNameLabel()
{
- if (!options->isLabelExplicitlySet(QFileDialogOptions::FileName)) {
+ if (options->isLabelExplicitlySet(QFileDialogOptions::FileName)) {
+ setLabelTextControl(QFileDialog::FileName, options->labelText(QFileDialogOptions::FileName));
+ } else {
switch (q_func()->fileMode()) {
case QFileDialog::DirectoryOnly:
case QFileDialog::Directory:
@@ -659,6 +678,12 @@ void QFileDialogPrivate::updateFileNameLabel()
}
}
+void QFileDialogPrivate::updateFileTypeLabel()
+{
+ if (options->isLabelExplicitlySet(QFileDialogOptions::FileType))
+ setLabelTextControl(QFileDialog::FileType, options->labelText(QFileDialogOptions::FileType));
+}
+
void QFileDialogPrivate::updateOkButtonText(bool saveAsOnFolder)
{
Q_Q(QFileDialog);
@@ -684,12 +709,20 @@ void QFileDialogPrivate::updateOkButtonText(bool saveAsOnFolder)
}
}
+void QFileDialogPrivate::updateCancelButtonText()
+{
+ if (options->isLabelExplicitlySet(QFileDialogOptions::Reject))
+ setLabelTextControl(QFileDialog::Reject, options->labelText(QFileDialogOptions::Reject));
+}
+
void QFileDialogPrivate::retranslateStrings()
{
Q_Q(QFileDialog);
/* WIDGETS */
if (defaultFileTypes)
q->setNameFilter(QFileDialog::tr("All Files (*)"));
+ if (nativeDialogInUse)
+ return;
QList<QAction*> actions = qFileDialogUi->treeView->header()->actions();
QAbstractItemModel *abstractModel = model;
@@ -708,7 +741,10 @@ void QFileDialogPrivate::retranslateStrings()
showHiddenAction->setText(QFileDialog::tr("Show &hidden files"));
newFolderAction->setText(QFileDialog::tr("&New Folder"));
qFileDialogUi->retranslateUi(q);
+ updateLookInLabel();
updateFileNameLabel();
+ updateFileTypeLabel();
+ updateCancelButtonText();
}
void QFileDialogPrivate::emitFilesSelected(const QStringList &files)
@@ -734,6 +770,11 @@ bool QFileDialogPrivate::canBeNativeDialog()
return (staticName == dynamicName);
}
+bool QFileDialogPrivate::usingWidgets() const
+{
+ return !nativeDialogInUse && qFileDialogUi;
+}
+
/*!
\since 4.5
Sets the given \a option to be enabled if \a on is true; otherwise,
@@ -784,29 +825,36 @@ void QFileDialog::setOptions(Options options)
return;
d->options->setOptions(QFileDialogOptions::FileDialogOptions(int(options)));
- if (changed & DontResolveSymlinks)
- d->model->setResolveSymlinks(!(options & DontResolveSymlinks));
- if (changed & ReadOnly) {
- bool ro = (options & ReadOnly);
- d->model->setReadOnly(ro);
- d->qFileDialogUi->newFolderButton->setEnabled(!ro);
- d->renameAction->setEnabled(!ro);
- d->deleteAction->setEnabled(!ro);
+
+ if ((options & DontUseNativeDialog) && !d->usingWidgets())
+ d->createWidgets();
+
+ if (d->usingWidgets()) {
+ if (changed & DontResolveSymlinks)
+ d->model->setResolveSymlinks(!(options & DontResolveSymlinks));
+ if (changed & ReadOnly) {
+ bool ro = (options & ReadOnly);
+ d->model->setReadOnly(ro);
+ d->qFileDialogUi->newFolderButton->setEnabled(!ro);
+ d->renameAction->setEnabled(!ro);
+ d->deleteAction->setEnabled(!ro);
+ }
+
+ if (changed & DontUseCustomDirectoryIcons) {
+ QFileIconProvider::Options providerOptions = iconProvider()->options();
+ if (options & DontUseCustomDirectoryIcons)
+ providerOptions |= QFileIconProvider::DontUseCustomDirectoryIcons;
+ else
+ providerOptions &= ~QFileIconProvider::DontUseCustomDirectoryIcons;
+ iconProvider()->setOptions(providerOptions);
+ }
}
+
if (changed & HideNameFilterDetails)
setNameFilters(d->options->nameFilters());
if (changed & ShowDirsOnly)
setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files);
-
- if (changed & DontUseCustomDirectoryIcons) {
- QFileIconProvider::Options providerOptions = iconProvider()->options();
- if (options & DontUseCustomDirectoryIcons)
- providerOptions |= QFileIconProvider::DontUseCustomDirectoryIcons;
- else
- providerOptions &= ~QFileIconProvider::DontUseCustomDirectoryIcons;
- iconProvider()->setOptions(providerOptions);
- }
}
QFileDialog::Options QFileDialog::options() const
@@ -858,21 +906,25 @@ void QFileDialog::setVisible(bool visible)
// updates the state correctly, but skips showing the non-native version:
setAttribute(Qt::WA_DontShowOnScreen);
#ifndef QT_NO_FSCOMPLETER
- //So the completer don't try to complete and therefore to show a popup
- d->completer->setModel(0);
+ // So the completer doesn't try to complete and therefore show a popup
+ if (!d->nativeDialogInUse)
+ d->completer->setModel(0);
#endif
} else {
+ d->createWidgets();
setAttribute(Qt::WA_DontShowOnScreen, false);
#ifndef QT_NO_FSCOMPLETER
- if (d->proxyModel != 0)
- d->completer->setModel(d->proxyModel);
- else
- d->completer->setModel(d->model);
+ if (!d->nativeDialogInUse) {
+ if (d->proxyModel != 0)
+ d->completer->setModel(d->proxyModel);
+ else
+ d->completer->setModel(d->model);
+ }
#endif
}
}
- if (!d->nativeDialogInUse)
+ if (d->usingWidgets())
d->qFileDialogUi->fileNameEdit->setFocus();
QDialog::setVisible(visible);
@@ -914,24 +966,27 @@ void QFileDialog::setDirectory(const QString &directory)
d->setLastVisitedDirectory(newDirectory);
- if (d->nativeDialogInUse){
+ d->options->setInitialDirectory(QUrl::fromLocalFile(directory));
+ if (!d->usingWidgets()) {
d->setDirectory_sys(QUrl::fromLocalFile(newDirectory));
return;
}
if (d->rootPath() == newDirectory)
return;
QModelIndex root = d->model->setRootPath(newDirectory);
- d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled);
- if (root != d->rootIndex()) {
+ if (!d->nativeDialogInUse) {
+ d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled);
+ if (root != d->rootIndex()) {
#ifndef QT_NO_FSCOMPLETER
- if (directory.endsWith(QLatin1Char('/')))
- d->completer->setCompletionPrefix(newDirectory);
- else
- d->completer->setCompletionPrefix(newDirectory + QLatin1Char('/'));
+ if (directory.endsWith(QLatin1Char('/')))
+ d->completer->setCompletionPrefix(newDirectory);
+ else
+ d->completer->setCompletionPrefix(newDirectory + QLatin1Char('/'));
#endif
- d->setRootIndex(root);
+ d->setRootIndex(root);
+ }
+ d->qFileDialogUi->listView->selectionModel()->clear();
}
- d->qFileDialogUi->listView->selectionModel()->clear();
}
/*!
@@ -989,8 +1044,11 @@ void QFileDialog::selectFile(const QString &filename)
if (filename.isEmpty())
return;
- if (d->nativeDialogInUse){
+ if (!d->usingWidgets()) {
d->selectFile_sys(QUrl::fromLocalFile(filename));
+ QList<QUrl> i;
+ i << QUrl(filename);
+ d->options->setInitiallySelectedFiles(i);
return;
}
@@ -1141,7 +1199,7 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
{
QList<QUrl> files;
- if (nativeDialogInUse)
+ if (!usingWidgets())
return addDefaultSuffixToUrls(selectedFiles_sys());
foreach (const QModelIndex &index, qFileDialogUi->listView->selectionModel()->selectedRows())
@@ -1339,6 +1397,9 @@ void QFileDialog::setNameFilters(const QStringList &filters)
}
d->options->setNameFilters(cleanedFilters);
+ if (!d->usingWidgets())
+ return;
+
d->qFileDialogUi->fileTypeCombo->clear();
if (cleanedFilters.isEmpty())
return;
@@ -1373,7 +1434,7 @@ QStringList QFileDialog::nameFilters() const
void QFileDialog::selectNameFilter(const QString &filter)
{
Q_D(QFileDialog);
- if (d->nativeDialogInUse) {
+ if (!d->usingWidgets()) {
d->selectNameFilter_sys(filter);
return;
}
@@ -1401,7 +1462,7 @@ void QFileDialog::selectNameFilter(const QString &filter)
QString QFileDialog::selectedNameFilter() const
{
Q_D(const QFileDialog);
- if (d->nativeDialogInUse)
+ if (!d->usingWidgets())
return d->selectedNameFilter_sys();
return d->qFileDialogUi->fileTypeCombo->currentText();
@@ -1417,7 +1478,9 @@ QString QFileDialog::selectedNameFilter() const
QDir::Filters QFileDialog::filter() const
{
Q_D(const QFileDialog);
- return d->model->filter();
+ if (d->usingWidgets())
+ return d->model->filter();
+ return d->options->filter();
}
/*!
@@ -1432,13 +1495,13 @@ QDir::Filters QFileDialog::filter() const
void QFileDialog::setFilter(QDir::Filters filters)
{
Q_D(QFileDialog);
- d->model->setFilter(filters);
d->options->setFilter(filters);
- if (d->nativeDialogInUse){
+ if (!d->usingWidgets()) {
d->setFilter_sys();
return;
}
+ d->model->setFilter(filters);
d->showHiddenAction->setChecked((filters & QDir::Hidden));
}
@@ -1523,6 +1586,9 @@ void QFileDialog::selectMimeTypeFilter(const QString &filter)
void QFileDialog::setViewMode(QFileDialog::ViewMode mode)
{
Q_D(QFileDialog);
+ d->options->setViewMode(static_cast<QFileDialogOptions::ViewMode>(mode));
+ if (!d->usingWidgets())
+ return;
if (mode == Detail)
d->_q_showDetailsView();
else
@@ -1532,6 +1598,8 @@ void QFileDialog::setViewMode(QFileDialog::ViewMode mode)
QFileDialog::ViewMode QFileDialog::viewMode() const
{
Q_D(const QFileDialog);
+ if (!d->usingWidgets())
+ return QFileDialog::List;
return (d->qFileDialogUi->stackedWidget->currentWidget() == d->qFileDialogUi->listView->parent() ? QFileDialog::List : QFileDialog::Detail);
}
@@ -1554,11 +1622,15 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode)
{
Q_D(QFileDialog);
d->options->setFileMode(static_cast<QFileDialogOptions::FileMode>(mode));
- d->retranslateWindowTitle();
// keep ShowDirsOnly option in sync with fileMode (BTW, DirectoryOnly is obsolete)
setOption(ShowDirsOnly, mode == DirectoryOnly);
+ if (!d->usingWidgets())
+ return;
+
+ d->retranslateWindowTitle();
+
// set selection mode and behavior
QAbstractItemView::SelectionMode selectionMode;
if (mode == QFileDialog::ExistingFiles)
@@ -1577,11 +1649,6 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode)
}
d->updateFileNameLabel();
d->updateOkButtonText();
- if (d->nativeDialogInUse){
- d->setFilter_sys();
- return;
- }
-
d->qFileDialogUi->fileTypeCombo->setEnabled(!testOption(ShowDirsOnly));
d->_q_updateOkButton();
}
@@ -1606,6 +1673,13 @@ void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode)
{
Q_D(QFileDialog);
d->options->setAcceptMode(static_cast<QFileDialogOptions::AcceptMode>(mode));
+ // clear WA_DontShowOnScreen so that d->canBeNativeDialog() doesn't return false incorrectly
+ setAttribute(Qt::WA_DontShowOnScreen, false);
+ if (!d->usingWidgets()) {
+ // we need to recreate the native dialog when changing the AcceptMode
+ d->deletePlatformHelper();
+ return;
+ }
QDialogButtonBox::StandardButton button = (mode == AcceptOpen ? QDialogButtonBox::Open : QDialogButtonBox::Save);
d->qFileDialogUi->buttonBox->setStandardButtons(button | QDialogButtonBox::Cancel);
d->qFileDialogUi->buttonBox->button(button)->setEnabled(false);
@@ -1614,10 +1688,6 @@ void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode)
d->qFileDialogUi->lookInCombo->setEditable(false);
}
d->retranslateWindowTitle();
- // we need to recreate the native dialog when changing the AcceptMode
- d->deletePlatformHelper();
- // clear WA_DontShowOnScreen so that d->canBeNativeDialog() doesn't return false incorrectly
- setAttribute(Qt::WA_DontShowOnScreen, false);
}
/*
@@ -1778,7 +1848,8 @@ QString QFileDialog::defaultSuffix() const
void QFileDialog::setHistory(const QStringList &paths)
{
Q_D(QFileDialog);
- d->qFileDialogUi->lookInCombo->setHistory(paths);
+ if (d->usingWidgets())
+ d->qFileDialogUi->lookInCombo->setHistory(paths);
}
void QFileDialogComboBox::setHistory(const QStringList &paths)
@@ -1800,6 +1871,8 @@ void QFileDialogComboBox::setHistory(const QStringList &paths)
QStringList QFileDialog::history() const
{
Q_D(const QFileDialog);
+ if (!d->usingWidgets())
+ return QStringList();
QStringList currentHistory = d->qFileDialogUi->lookInCombo->history();
//On windows the popup display the "C:\", convert to nativeSeparators
QString newHistory = QDir::toNativeSeparators(d->rootIndex().data(QFileSystemModel::FilePathRole).toString());
@@ -1826,6 +1899,8 @@ QStringList QFileDialog::history() const
void QFileDialog::setItemDelegate(QAbstractItemDelegate *delegate)
{
Q_D(QFileDialog);
+ if (!d->usingWidgets())
+ return;
d->qFileDialogUi->listView->setItemDelegate(delegate);
d->qFileDialogUi->treeView->setItemDelegate(delegate);
}
@@ -1836,6 +1911,8 @@ void QFileDialog::setItemDelegate(QAbstractItemDelegate *delegate)
QAbstractItemDelegate *QFileDialog::itemDelegate() const
{
Q_D(const QFileDialog);
+ if (!d->usingWidgets())
+ return 0;
return d->qFileDialogUi->listView->itemDelegate();
}
@@ -1845,6 +1922,8 @@ QAbstractItemDelegate *QFileDialog::itemDelegate() const
void QFileDialog::setIconProvider(QFileIconProvider *provider)
{
Q_D(QFileDialog);
+ if (!d->usingWidgets())
+ return;
d->model->setIconProvider(provider);
//It forces the refresh of all entries in the side bar, then we can get new icons
d->qFileDialogUi->sidebar->setUrls(d->qFileDialogUi->sidebar->urls());
@@ -1861,6 +1940,8 @@ QFileIconProvider *QFileDialog::iconProvider() const
void QFileDialogPrivate::setLabelTextControl(QFileDialog::DialogLabel label, const QString &text)
{
+ if (!qFileDialogUi)
+ return;
switch (label) {
case QFileDialog::LookIn:
qFileDialogUi->lookInLabel->setText(text);
@@ -1903,8 +1984,10 @@ void QFileDialog::setLabelText(DialogLabel label, const QString &text)
*/
QString QFileDialog::labelText(DialogLabel label) const
{
- QPushButton *button;
Q_D(const QFileDialog);
+ if (!d->usingWidgets())
+ return d->options->labelText(static_cast<QFileDialogOptions::DialogLabel>(label));
+ QPushButton *button;
switch (label) {
case LookIn:
return d->qFileDialogUi->lookInLabel->text();
@@ -2518,7 +2601,7 @@ void QFileDialog::accept()
QStringList files = selectedFiles();
if (files.isEmpty())
return;
- if (d->nativeDialogInUse){
+ if (!d->usingWidgets()) {
d->emitFilesSelected(files);
QDialog::accept();
return;
@@ -2631,16 +2714,19 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte
q->setWindowTitle(caption);
}
- createWidgets();
- createMenuActions();
- retranslateStrings();
+ q->setAcceptMode(QFileDialog::AcceptOpen);
+ nativeDialogInUse = (canBeNativeDialog() && platformFileDialogHelper() != 0);
+ if (!nativeDialogInUse)
+ createWidgets();
q->setFileMode(QFileDialog::AnyFile);
+ if (!nameFilter.isEmpty())
+ q->setNameFilter(nameFilter);
+ q->setDirectory(workingDirectory(directory));
+ q->selectFile(initialSelection(directory));
#ifndef QT_NO_SETTINGS
QSettings settings(QSettings::UserScope, QLatin1String("QtProject"));
settings.beginGroup(QLatin1String("Qt"));
- if (!directory.isEmpty())
- setLastVisitedDirectory(workingDirectory(directory));
q->restoreState(settings.value(QLatin1String("filedialog")).toByteArray());
#endif
@@ -2650,14 +2736,7 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte
qFileDialogUi->fileTypeLabel->setVisible(false);
qFileDialogUi->sidebar->hide();
#endif
- // Default case
- if (!nameFilter.isEmpty())
- q->setNameFilter(nameFilter);
- q->setAcceptMode(QFileDialog::AcceptOpen);
- q->setDirectory(workingDirectory(directory));
- q->selectFile(initialSelection(directory));
- _q_updateOkButton();
q->resize(q->sizeHint());
}
@@ -2668,6 +2747,8 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte
*/
void QFileDialogPrivate::createWidgets()
{
+ if (qFileDialogUi)
+ return;
Q_Q(QFileDialog);
model = new QFileSystemModel(q);
options->setFilter(model->filter());
@@ -2676,6 +2757,8 @@ void QFileDialogPrivate::createWidgets()
model->setNameFilterDisables(helper->defaultNameFilterDisables());
else
model->setNameFilterDisables(false);
+ if (nativeDialogInUse)
+ deletePlatformHelper();
model->d_func()->disableRecursiveSort = true;
QFileDialog::connect(model, SIGNAL(fileRenamed(QString,QString,QString)), q, SLOT(_q_fileRenamed(QString,QString,QString)));
QFileDialog::connect(model, SIGNAL(rootPathChanged(QString)),
@@ -2789,6 +2872,31 @@ void QFileDialogPrivate::createWidgets()
qFileDialogUi->splitter->setStretchFactor(qFileDialogUi->splitter->indexOf(qFileDialogUi->splitter->widget(1)), QSizePolicy::Expanding);
createToolButtons();
+ createMenuActions();
+
+ // Initial widget states from options
+ q->setFileMode(static_cast<QFileDialog::FileMode>(options->fileMode()));
+ q->setAcceptMode(static_cast<QFileDialog::AcceptMode>(options->acceptMode()));
+ q->setViewMode(static_cast<QFileDialog::ViewMode>(options->viewMode()));
+ q->setOptions(static_cast<QFileDialog::Options>(static_cast<int>(options->options())));
+ if (!options->sidebarUrls().isEmpty())
+ q->setSidebarUrls(options->sidebarUrls());
+ q->setDirectoryUrl(options->initialDirectory());
+ if (!options->mimeTypeFilters().isEmpty())
+ q->setMimeTypeFilters(options->mimeTypeFilters());
+ else if (!options->nameFilters().isEmpty())
+ q->setNameFilters(options->nameFilters());
+ q->selectNameFilter(options->initiallySelectedNameFilter());
+ q->setDefaultSuffix(options->defaultSuffix());
+ q->setHistory(options->history());
+ if (options->initiallySelectedFiles().count() == 1)
+ q->selectFile(options->initiallySelectedFiles().first().fileName());
+ foreach (QUrl url, options->initiallySelectedFiles())
+ q->selectUrl(url);
+ lineEdit()->selectAll();
+ _q_updateOkButton();
+ retranslateStrings();
+ q->resize(q->sizeHint());
}
void QFileDialogPrivate::_q_showHeader(QAction *action)
@@ -2814,6 +2922,8 @@ void QFileDialogPrivate::_q_showHeader(QAction *action)
void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel)
{
Q_D(QFileDialog);
+ if (!d->usingWidgets())
+ return;
if ((!proxyModel && !d->proxyModel)
|| (proxyModel == d->proxyModel))
return;
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index e5a558bb91..36336bdbf6 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -135,8 +135,11 @@ public:
QList<QUrl> addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const;
bool removeDirectory(const QString &path);
void setLabelTextControl(QFileDialog::DialogLabel label, const QString &text);
+ inline void updateLookInLabel();
inline void updateFileNameLabel();
+ inline void updateFileTypeLabel();
void updateOkButtonText(bool saveAsOnFolder = false);
+ void updateCancelButtonText();
inline QModelIndex mapToSource(const QModelIndex &index) const;
inline QModelIndex mapFromSource(const QModelIndex &index) const;
@@ -249,6 +252,7 @@ public:
// dialog. Returning false means that a non-native dialog must be
// used instead.
bool canBeNativeDialog();
+ inline bool usingWidgets() const;
void setDirectory_sys(const QUrl &directory);
QUrl directory_sys() const;
@@ -347,7 +351,7 @@ inline QModelIndex QFileDialogPrivate::mapFromSource(const QModelIndex &index) c
}
inline QString QFileDialogPrivate::rootPath() const {
- return model->rootPath();
+ return (model ? model->rootPath() : QStringLiteral("/"));
}
inline void QFileDialogPrivate::setDirectory_sys(const QUrl &directory)
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 6dcc354f94..bda448bde3 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -204,6 +204,8 @@ bool QFileSystemModel::remove(const QModelIndex &aindex)
#ifndef QT_NO_FILESYSTEMWATCHER
d->fileInfoGatherer.removePath(path);
#endif
+ if (QFileInfo(path).isFile())
+ return QFile::remove(path);
return QDir(path).removeRecursively();
}
diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
index 5dc3e1159e..ff98c147fe 100644
--- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp
+++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
@@ -97,6 +97,15 @@
QT_BEGIN_NAMESPACE
+static inline bool check_step_valid(qreal step, const char *method)
+{
+ if (!(step >= 0 && step <= 1)) {
+ qWarning("QGraphicsItemAnimation::%s: invalid step = %f", method, step);
+ return false;
+ }
+ return true;
+}
+
class QGraphicsItemAnimationPrivate
{
public:
@@ -169,10 +178,8 @@ qreal QGraphicsItemAnimationPrivate::linearValueForStep(qreal step, QList<Pair>
void QGraphicsItemAnimationPrivate::insertUniquePair(qreal step, qreal value, QList<Pair> *binList, const char* method)
{
- if (step < 0.0 || step > 1.0) {
- qWarning("QGraphicsItemAnimation::%s: invalid step = %f", method, step);
+ if (!check_step_valid(step, method))
return;
- }
Pair pair(step, value);
@@ -259,9 +266,7 @@ void QGraphicsItemAnimation::setTimeLine(QTimeLine *timeLine)
*/
QPointF QGraphicsItemAnimation::posAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::posAt: invalid step = %f", step);
-
+ check_step_valid(step, "posAt");
return QPointF(d->linearValueForStep(step, &d->xPosition, d->startPos.x()),
d->linearValueForStep(step, &d->yPosition, d->startPos.y()));
}
@@ -298,8 +303,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::posList() const
*/
QMatrix QGraphicsItemAnimation::matrixAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::matrixAt: invalid step = %f", step);
+ check_step_valid(step, "matrixAt");
QMatrix matrix;
if (!d->rotation.isEmpty())
@@ -320,9 +324,7 @@ QMatrix QGraphicsItemAnimation::matrixAt(qreal step) const
*/
qreal QGraphicsItemAnimation::rotationAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::rotationAt: invalid step = %f", step);
-
+ check_step_valid(step, "rotationAt");
return d->linearValueForStep(step, &d->rotation);
}
@@ -357,9 +359,7 @@ QList<QPair<qreal, qreal> > QGraphicsItemAnimation::rotationList() const
*/
qreal QGraphicsItemAnimation::xTranslationAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::xTranslationAt: invalid step = %f", step);
-
+ check_step_valid(step, "xTranslationAt");
return d->linearValueForStep(step, &d->xTranslation);
}
@@ -370,9 +370,7 @@ qreal QGraphicsItemAnimation::xTranslationAt(qreal step) const
*/
qreal QGraphicsItemAnimation::yTranslationAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::yTranslationAt: invalid step = %f", step);
-
+ check_step_valid(step, "yTranslationAt");
return d->linearValueForStep(step, &d->yTranslation);
}
@@ -409,8 +407,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::translationList() const
*/
qreal QGraphicsItemAnimation::verticalScaleAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::verticalScaleAt: invalid step = %f", step);
+ check_step_valid(step, "verticalScaleAt");
return d->linearValueForStep(step, &d->verticalScale, 1);
}
@@ -422,9 +419,7 @@ qreal QGraphicsItemAnimation::verticalScaleAt(qreal step) const
*/
qreal QGraphicsItemAnimation::horizontalScaleAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::horizontalScaleAt: invalid step = %f", step);
-
+ check_step_valid(step, "horizontalScaleAt");
return d->linearValueForStep(step, &d->horizontalScale, 1);
}
@@ -461,9 +456,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::scaleList() const
*/
qreal QGraphicsItemAnimation::verticalShearAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::verticalShearAt: invalid step = %f", step);
-
+ check_step_valid(step, "verticalShearAt");
return d->linearValueForStep(step, &d->verticalShear, 0);
}
@@ -474,9 +467,7 @@ qreal QGraphicsItemAnimation::verticalShearAt(qreal step) const
*/
qreal QGraphicsItemAnimation::horizontalShearAt(qreal step) const
{
- if (step < 0.0 || step > 1.0)
- qWarning("QGraphicsItemAnimation::horizontalShearAt: invalid step = %f", step);
-
+ check_step_valid(step, "horizontalShearAt");
return d->linearValueForStep(step, &d->horizontalShear, 0);
}
@@ -529,19 +520,17 @@ void QGraphicsItemAnimation::clear()
Sets the current \a step value for the animation, causing the
transformations scheduled at this step to be performed.
*/
-void QGraphicsItemAnimation::setStep(qreal x)
+void QGraphicsItemAnimation::setStep(qreal step)
{
- if (x < 0.0 || x > 1.0) {
- qWarning("QGraphicsItemAnimation::setStep: invalid step = %f", x);
+ if (!check_step_valid(step, "setStep"))
return;
- }
- beforeAnimationStep(x);
+ beforeAnimationStep(step);
- d->step = x;
+ d->step = step;
if (d->item) {
if (!d->xPosition.isEmpty() || !d->yPosition.isEmpty())
- d->item->setPos(posAt(x));
+ d->item->setPos(posAt(step));
if (!d->rotation.isEmpty()
|| !d->verticalScale.isEmpty()
|| !d->horizontalScale.isEmpty()
@@ -549,11 +538,11 @@ void QGraphicsItemAnimation::setStep(qreal x)
|| !d->horizontalShear.isEmpty()
|| !d->xTranslation.isEmpty()
|| !d->yTranslation.isEmpty()) {
- d->item->setMatrix(d->startMatrix * matrixAt(x));
+ d->item->setMatrix(d->startMatrix * matrixAt(step));
}
}
- afterAnimationStep(x);
+ afterAnimationStep(step);
}
/*!
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 35ba1ed74e..726c2704c4 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1651,7 +1651,7 @@ bool QAbstractItemView::viewportEvent(QEvent *event)
case QEvent::WhatsThis: {
QHelpEvent *he = static_cast<QHelpEvent*>(event);
const QModelIndex index = indexAt(he->pos());
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
option.rect = visualRect(index);
option.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
@@ -1851,7 +1851,7 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
emit clicked(index);
if (edited)
return;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
if (d->pressedAlreadySelected)
option.state |= QStyle::State_Selected;
if ((model()->flags(index) & Qt::ItemIsEnabled)
@@ -2627,7 +2627,7 @@ void QAbstractItemView::updateEditorGeometries()
Q_D(QAbstractItemView);
if(d->editorIndexHash.isEmpty())
return;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
QEditorIndexHash::iterator it = d->editorIndexHash.begin();
QWidgetList editorsToRelease;
QWidgetList editorsToHide;
@@ -2972,7 +2972,7 @@ QSize QAbstractItemView::sizeHintForIndex(const QModelIndex &index) const
Q_D(const QAbstractItemView);
if (!d->isIndexValid(index) || !d->itemDelegate)
return QSize();
- return d->delegateForIndex(index)->sizeHint(d->viewOptions(), index);
+ return d->delegateForIndex(index)->sizeHint(d->viewOptionsV1(), index);
}
/*!
@@ -3000,7 +3000,7 @@ int QAbstractItemView::sizeHintForRow(int row) const
ensurePolished();
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
int height = 0;
int colCount = d->model->columnCount(d->root);
QModelIndex index;
@@ -3031,7 +3031,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const
ensurePolished();
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
int width = 0;
int rows = d->model->rowCount(d->root);
QModelIndex index;
@@ -3054,7 +3054,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const
void QAbstractItemView::openPersistentEditor(const QModelIndex &index)
{
Q_D(QAbstractItemView);
- QStyleOptionViewItem options = d->viewOptions();
+ QStyleOptionViewItem options = d->viewOptionsV1();
options.rect = visualRect(index);
options.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
@@ -3600,45 +3600,45 @@ void QAbstractItemView::startDrag(Qt::DropActions supportedActions)
QStyleOptionViewItem QAbstractItemView::viewOptions() const
{
Q_D(const QAbstractItemView);
- return d->viewOptions();
-}
-
-QStyleOptionViewItem QAbstractItemViewPrivate::viewOptions() const
-{
- Q_Q(const QAbstractItemView);
QStyleOptionViewItem option;
- option.init(q);
+ option.init(this);
option.state &= ~QStyle::State_MouseOver;
- option.font = q->font();
+ option.font = font();
#ifndef Q_WS_MAC
// On mac the focus appearance follows window activation
// not widget activation
- if (!q->hasFocus())
+ if (!hasFocus())
option.state &= ~QStyle::State_Active;
#endif
option.state &= ~QStyle::State_HasFocus;
- if (iconSize.isValid()) {
- option.decorationSize = iconSize;
+ if (d->iconSize.isValid()) {
+ option.decorationSize = d->iconSize;
} else {
- int pm = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q);
+ int pm = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
option.decorationSize = QSize(pm, pm);
}
option.decorationPosition = QStyleOptionViewItem::Left;
option.decorationAlignment = Qt::AlignCenter;
option.displayAlignment = Qt::AlignLeft|Qt::AlignVCenter;
- option.textElideMode = textElideMode;
+ option.textElideMode = d->textElideMode;
option.rect = QRect();
- option.showDecorationSelected = q->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, q);
- if (wrapItemText)
+ option.showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, this);
+ if (d->wrapItemText)
option.features = QStyleOptionViewItem::WrapText;
- option.locale = q->locale();
+ option.locale = locale();
option.locale.setNumberOptions(QLocale::OmitGroupSeparator);
- option.widget = q;
+ option.widget = this;
return option;
}
+QStyleOptionViewItem QAbstractItemViewPrivate::viewOptionsV1() const
+{
+ Q_Q(const QAbstractItemView);
+ return q->viewOptions();
+}
+
/*!
Returns the item view's state.
@@ -4274,7 +4274,7 @@ bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEven
{
Q_Q(const QAbstractItemView);
QModelIndex buddy = model->buddy(index);
- QStyleOptionViewItem options = viewOptions();
+ QStyleOptionViewItem options = viewOptionsV1();
options.rect = q->visualRect(buddy);
options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
QAbstractItemDelegate *delegate = delegateForIndex(index);
@@ -4286,7 +4286,7 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even
Q_Q(QAbstractItemView);
QModelIndex buddy = model->buddy(index);
- QStyleOptionViewItem options = viewOptions();
+ QStyleOptionViewItem options = viewOptionsV1();
options.rect = q->visualRect(buddy);
options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
@@ -4338,7 +4338,7 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,
QPixmap pixmap(r->size());
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
- QStyleOptionViewItem option = viewOptions();
+ QStyleOptionViewItem option = viewOptionsV1();
option.state |= QStyle::State_Selected;
for (int j = 0; j < paintPairs.count(); ++j) {
option.rect = paintPairs.at(j).first.translated(-r->topLeft());
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
index 5da22615e2..1b5987de16 100644
--- a/src/widgets/itemviews/qabstractitemview_p.h
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -347,7 +347,7 @@ public:
QModelIndexList selectedDraggableIndexes() const;
- QStyleOptionViewItem viewOptions() const;
+ QStyleOptionViewItem viewOptionsV1() const;
void doDelayedReset()
{
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 123594637a..1131ef030e 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -3693,8 +3693,7 @@ void QHeaderViewPrivate::write(QDataStream &out) const
out << int(globalResizeMode);
out << sectionItems;
- if (out.version() >= QDataStream::Qt_5_2)
- out << resizeContentsPrecision;
+ out << resizeContentsPrecision;
}
bool QHeaderViewPrivate::read(QDataStream &in)
@@ -3747,8 +3746,10 @@ bool QHeaderViewPrivate::read(QDataStream &in)
sectionItems = newSectionItems;
recalcSectionStartPos();
- if (in.version() >= QDataStream::Qt_5_2)
- in >> resizeContentsPrecision;
+ int tmpint;
+ in >> tmpint;
+ if (in.status() == QDataStream::Ok) // we haven't read past end
+ resizeContentsPrecision = tmpint;
return true;
}
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index e5a8647f87..616a832b88 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Samuel Gaist <samuel.gaist@deltech.ch>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -900,20 +901,14 @@ void QListView::startDrag(Qt::DropActions supportedActions)
QStyleOptionViewItem QListView::viewOptions() const
{
Q_D(const QListView);
- return d->viewOptions();
-}
-
-QStyleOptionViewItem QListViewPrivate::viewOptions() const
-{
- Q_Q(const QListView);
- QStyleOptionViewItem option = QAbstractItemViewPrivate::viewOptions();
- if (!iconSize.isValid()) { // otherwise it was already set in abstractitemview
- int pm = (viewMode == QListView::ListMode
- ? q->style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, q)
- : q->style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, q));
+ QStyleOptionViewItem option = QAbstractItemView::viewOptions();
+ if (!d->iconSize.isValid()) { // otherwise it was already set in abstractitemview
+ int pm = (d->viewMode == QListView::ListMode
+ ? style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, this)
+ : style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, this));
option.decorationSize = QSize(pm, pm);
}
- if (viewMode == QListView::IconMode) {
+ if (d->viewMode == QListView::IconMode) {
option.showDecorationSelected = false;
option.decorationPosition = QStyleOptionViewItem::Top;
option.displayAlignment = Qt::AlignCenter;
@@ -932,7 +927,7 @@ void QListView::paintEvent(QPaintEvent *e)
Q_D(QListView);
if (!d->itemDelegate)
return;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
QPainter painter(d->viewport);
const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
@@ -1461,7 +1456,7 @@ void QListView::updateGeometries()
verticalScrollBar()->setRange(0, 0);
} else {
QModelIndex index = d->model->index(0, d->column, d->root);
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
QSize step = d->itemSize(option, index);
d->commonListView->updateHorizontalScrollBar(step);
d->commonListView->updateVerticalScrollBar(step);
@@ -1833,6 +1828,15 @@ void QCommonListViewBase::removeHiddenRow(int row)
dd->hiddenRows.remove(dd->model->index(row, 0, qq->rootIndex()));
}
+#ifndef QT_NO_DRAGANDDROP
+void QCommonListViewBase::paintDragDrop(QPainter *painter)
+{
+ // FIXME: Until the we can provide a proper drop indicator
+ // in IconMode, it makes no sense to show it
+ dd->paintDropIndicator(painter);
+}
+#endif
+
void QCommonListViewBase::updateHorizontalScrollBar(const QSize & /*step*/)
{
horizontalScrollBar()->setPageStep(viewport()->width());
@@ -1902,13 +1906,6 @@ int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView:
*/
#ifndef QT_NO_DRAGANDDROP
-void QListModeViewBase::paintDragDrop(QPainter *painter)
-{
- // FIXME: Until the we can provide a proper drop indicator
- // in IconMode, it makes no sense to show it
- dd->paintDropIndicator(painter);
-}
-
QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const
{
QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport;
@@ -2651,23 +2648,6 @@ void QIconModeViewBase::removeHiddenRow(int row)
}
#ifndef QT_NO_DRAGANDDROP
-void QIconModeViewBase::paintDragDrop(QPainter *painter)
-{
- if (!draggedItems.isEmpty() && viewport()->rect().contains(draggedItemsPos)) {
- //we need to draw the items that arre dragged
- painter->translate(draggedItemsDelta());
- QStyleOptionViewItem option = viewOptions();
- option.state &= ~QStyle::State_MouseOver;
- QVector<QModelIndex>::const_iterator it = draggedItems.constBegin();
- QListViewItem item = indexToListViewItem(*it);
- for (; it != draggedItems.constEnd(); ++it) {
- item = indexToListViewItem(*it);
- option.rect = viewItemRect(item);
- delegate(*it)->paint(painter, option, *it);
- }
- }
-}
-
bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
{
// This function does the same thing as in QAbstractItemView::startDrag(),
@@ -2682,8 +2662,14 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
&& (*it).column() == dd->column)
draggedItems.push_back(*it);
}
+
+ QRect rect;
+ QPixmap pixmap = dd->renderToPixmap(indexes, &rect);
+ rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
QDrag *drag = new QDrag(qq);
drag->setMimeData(dd->model->mimeData(indexes));
+ drag->setPixmap(pixmap);
+ drag->setHotSpot(dd->pressedPosition - rect.topLeft());
Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction);
draggedItems.clear();
if (action == Qt::MoveAction)
diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h
index 35d11140ef..4f3ccedb62 100644
--- a/src/widgets/itemviews/qlistview_p.h
+++ b/src/widgets/itemviews/qlistview_p.h
@@ -147,7 +147,7 @@ public:
virtual void setPositionForIndex(const QPoint &, const QModelIndex &) { }
#ifndef QT_NO_DRAGANDDROP
- virtual void paintDragDrop(QPainter *painter) = 0;
+ virtual void paintDragDrop(QPainter *painter);
virtual bool filterDragMoveEvent(QDragMoveEvent *) { return false; }
virtual bool filterDragLeaveEvent(QDragLeaveEvent *) { return false; }
virtual bool filterDropEvent(QDropEvent *) { return false; }
@@ -231,8 +231,6 @@ public:
void updateVerticalScrollBar(const QSize &step);
#ifndef QT_NO_DRAGANDDROP
- void paintDragDrop(QPainter *painter);
-
// The next two methods are to be used on LefToRight flow only.
// WARNING: Plenty of duplicated code from QAbstractItemView{,Private}.
QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
@@ -279,7 +277,6 @@ public:
void setPositionForIndex(const QPoint &position, const QModelIndex &index);
#ifndef QT_NO_DRAGANDDROP
- void paintDragDrop(QPainter *painter);
bool filterDragMoveEvent(QDragMoveEvent *);
bool filterDragLeaveEvent(QDragLeaveEvent *);
bool filterDropEvent(QDropEvent *e);
@@ -394,8 +391,6 @@ public:
}
}
- QStyleOptionViewItem viewOptions() const;
-
void scrollElasticBandBy(int dx, int dy);
QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const;
@@ -470,7 +465,7 @@ inline QModelIndex QCommonListViewBase::modelIndex(int row) const
{ return dd->model->index(row, dd->column, dd->root); }
inline int QCommonListViewBase::rowCount() const { return dd->model->rowCount(dd->root); }
-inline QStyleOptionViewItem QCommonListViewBase::viewOptions() const { return dd->viewOptions(); }
+inline QStyleOptionViewItem QCommonListViewBase::viewOptions() const { return dd->viewOptionsV1(); }
inline QWidget *QCommonListViewBase::viewport() const { return dd->viewport; }
inline QRect QCommonListViewBase::clipRect() const { return dd->clipRect(); }
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index 34e881571e..08600b3ef7 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -1346,20 +1346,14 @@ void QTableView::scrollContentsBy(int dx, int dy)
}
}
-QStyleOptionViewItem QTableViewPrivate::viewOptions() const
-{
- QStyleOptionViewItem option = QAbstractItemViewPrivate::viewOptions();
- option.showDecorationSelected = true;
- return option;
-}
-
/*!
\reimp
*/
QStyleOptionViewItem QTableView::viewOptions() const
{
- Q_D(const QTableView);
- return d->viewOptions();
+ QStyleOptionViewItem option = QAbstractItemView::viewOptions();
+ option.showDecorationSelected = true;
+ return option;
}
/*!
@@ -1369,7 +1363,7 @@ void QTableView::paintEvent(QPaintEvent *event)
{
Q_D(QTableView);
// setup temp variables for the painting
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
const QPoint offset = d->scrollDelayOffset;
const bool showGrid = d->showGrid;
const int gridSize = showGrid ? 1 : 0;
@@ -2241,7 +2235,7 @@ int QTableView::sizeHintForRow(int row) const
if (right == -1) // the table don't have enough columns to fill the viewport
right = d->model->columnCount(d->root) - 1;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
int hint = 0;
QModelIndex index;
@@ -2329,7 +2323,7 @@ int QTableView::sizeHintForColumn(int column) const
if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport
bottom = d->model->rowCount(d->root) - 1;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
int hint = 0;
int rowsProcessed = 0;
diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h
index 74eb7b7728..555ae50daf 100644
--- a/src/widgets/itemviews/qtableview_p.h
+++ b/src/widgets/itemviews/qtableview_p.h
@@ -150,8 +150,6 @@ public:
void init();
void trimHiddenSelections(QItemSelectionRange *range) const;
- QStyleOptionViewItem viewOptions() const;
-
inline bool isHidden(int row, int col) const {
return verticalHeader->isSectionHidden(row)
|| horizontalHeader->isSectionHidden(col);
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 22cd9abc73..792b75ac69 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -1441,7 +1441,7 @@ void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
Q_D(const QTreeView);
const QVector<QTreeViewItem> viewItems = d->viewItems;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
const QStyle::State state = option.state;
d->current = 0;
@@ -2850,7 +2850,7 @@ int QTreeView::sizeHintForColumn(int column) const
return -1;
ensurePolished();
int w = 0;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
const QVector<QTreeViewItem> viewItems = d->viewItems;
const int maximumProcessRows = d->header->resizeContentsPrecision(); // To avoid this to take forever.
@@ -2947,7 +2947,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const
qSwap(end, start);
int height = -1;
- QStyleOptionViewItem option = d->viewOptions();
+ QStyleOptionViewItem option = d->viewOptionsV1();
// ### If we want word wrapping in the items,
// ### we need to go through all the columns
// ### and set the width of the column
@@ -3220,7 +3220,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
painter.end();
//and now let's render the editors the editors
- QStyleOptionViewItem option = viewOptions();
+ QStyleOptionViewItem option = viewOptionsV1();
for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) {
QWidget *editor = it.key();
const QModelIndex &index = it.value();
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri
index 533b696faa..444b9b687f 100644
--- a/src/widgets/kernel/kernel.pri
+++ b/src/widgets/kernel/kernel.pri
@@ -66,59 +66,9 @@ SOURCES += \
kernel/qwidgetwindow.cpp \
kernel/qwindowcontainer.cpp
-
-# TODO
-false:!x11:mac {
- SOURCES += \
- kernel/qclipboard_mac.cpp \
- kernel/qmime_mac.cpp \
- kernel/qt_mac.cpp \
- kernel/qkeymapper_mac.cpp
-
- OBJECTIVE_HEADERS += \
- qcocoawindow_mac_p.h \
- qcocoapanel_mac_p.h \
- qcocoawindowdelegate_mac_p.h \
- qcocoaview_mac_p.h \
- qcocoaapplication_mac_p.h \
- qcocoaapplicationdelegate_mac_p.h \
- qmacgesturerecognizer_mac_p.h \
- qmultitouch_mac_p.h \
- qcocoasharedwindowmethods_mac_p.h \
- qcocoaintrospection_p.h
-
- OBJECTIVE_SOURCES += \
- kernel/qcursor_mac.mm \
- kernel/qdnd_mac.mm \
- kernel/qapplication_mac.mm \
- kernel/qwidget_mac.mm \
- kernel/qcocoapanel_mac.mm \
- kernel/qcocoaview_mac.mm \
- kernel/qcocoawindow_mac.mm \
- kernel/qcocoawindowdelegate_mac.mm \
- kernel/qcocoaapplication_mac.mm \
- kernel/qcocoaapplicationdelegate_mac.mm \
- kernel/qt_cocoa_helpers_mac.mm \
- kernel/qdesktopwidget_mac.mm \
- kernel/qeventdispatcher_mac.mm \
- kernel/qcocoawindowcustomthemeframe_mac.mm \
- kernel/qmacgesturerecognizer_mac.mm \
- kernel/qmultitouch_mac.mm \
- kernel/qcocoaintrospection_mac.mm
-
- HEADERS += \
- kernel/qt_cocoa_helpers_mac_p.h \
- kernel/qcocoaapplication_mac_p.h \
- kernel/qcocoaapplicationdelegate_mac_p.h \
- kernel/qeventdispatcher_mac_p.h
-
- MENU_NIB.files = mac/qt_menu.nib
- MENU_NIB.path = Resources
- MENU_NIB.version = Versions
- QMAKE_BUNDLE_DATA += MENU_NIB
- RESOURCES += mac/macresources.qrc
-
- LIBS_PRIVATE += -framework AppKit
+macx: {
+ HEADERS += kernel/qmacgesturerecognizer_p.h
+ SOURCES += kernel/qmacgesturerecognizer.cpp
}
wince*: {
diff --git a/src/widgets/kernel/qgesture_p.h b/src/widgets/kernel/qgesture_p.h
index c041af7317..ae203d2819 100644
--- a/src/widgets/kernel/qgesture_p.h
+++ b/src/widgets/kernel/qgesture_p.h
@@ -190,41 +190,6 @@ public:
static int Timeout;
};
-#ifndef QT_NO_GESTURES
-class QNativeGestureEvent : public QEvent
-{
-public:
- enum Type {
- None,
- GestureBegin,
- GestureEnd,
- Pan,
- Zoom,
- Rotate,
- Swipe
- };
-
- QNativeGestureEvent()
- : QEvent(QEvent::NativeGesture), gestureType(None), percentage(0)
-#ifdef Q_WS_WIN
- , sequenceId(0), argument(0)
-#endif
- {
- }
-
- Type gestureType;
- float percentage;
- QPoint position;
- float angle;
-#ifdef Q_WS_WIN
- ulong sequenceId;
- quint64 argument;
-#endif
-};
-
-#endif // QT_NO_GESTURES
-
-
QT_END_NAMESPACE
#endif // QT_NO_GESTURES
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index d90b187bf0..18abad4b40 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -51,8 +51,8 @@
#include "qevent.h"
#include "qgraphicsitem.h"
-#ifdef Q_WS_MAC
-#include "qmacgesturerecognizer_mac_p.h"
+#ifdef Q_OS_OSX
+#include "qmacgesturerecognizer_p.h"
#endif
#if defined(Q_WS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
#include "qwinnativepangesturerecognizer_win_p.h"
@@ -76,7 +76,7 @@ QGestureManager::QGestureManager(QObject *parent)
{
qRegisterMetaType<Qt::GestureState>();
-#if defined(Q_WS_MAC)
+#if defined(Q_OS_OSX)
registerGestureRecognizer(new QMacSwipeGestureRecognizer);
registerGestureRecognizer(new QMacPinchGestureRecognizer);
registerGestureRecognizer(new QMacPanGestureRecognizer);
diff --git a/src/widgets/kernel/qmacgesturerecognizer.cpp b/src/widgets/kernel/qmacgesturerecognizer.cpp
new file mode 100644
index 0000000000..feb779e53f
--- /dev/null
+++ b/src/widgets/kernel/qmacgesturerecognizer.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmacgesturerecognizer_p.h"
+#include "qgesture.h"
+#include "qgesture_p.h"
+#include "qevent.h"
+#include "qwidget.h"
+#include "qdebug.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer()
+{
+}
+
+QGesture *QMacSwipeGestureRecognizer::create(QObject * /*target*/)
+{
+ return new QSwipeGesture;
+}
+
+QGestureRecognizer::Result
+QMacSwipeGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
+ QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+ switch (ev->gestureType()) {
+ case Qt::SwipeNativeGesture: {
+ QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
+ g->setSwipeAngle(ev->value());
+ g->setHotSpot(ev->screenPos());
+ return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
+ break; }
+ default:
+ break;
+ }
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacSwipeGestureRecognizer::reset(QGesture *gesture)
+{
+ QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
+ g->setSwipeAngle(0);
+ QGestureRecognizer::reset(gesture);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+QMacPinchGestureRecognizer::QMacPinchGestureRecognizer()
+{
+}
+
+QGesture *QMacPinchGestureRecognizer::create(QObject * /*target*/)
+{
+ return new QPinchGesture;
+}
+
+QGestureRecognizer::Result
+QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
+ QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
+ QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+ switch (ev->gestureType()) {
+ case Qt::BeginNativeGesture:
+ reset(gesture);
+ g->setStartCenterPoint(static_cast<QWidget*>(obj)->mapFromGlobal(ev->screenPos().toPoint()));
+ g->setCenterPoint(g->startCenterPoint());
+ g->setChangeFlags(QPinchGesture::CenterPointChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ g->setHotSpot(ev->screenPos());
+ return QGestureRecognizer::MayBeGesture | QGestureRecognizer::ConsumeEventHint;
+ case Qt::RotateNativeGesture:
+ g->setLastScaleFactor(g->scaleFactor());
+ g->setLastRotationAngle(g->rotationAngle());
+ g->setRotationAngle(g->rotationAngle() + ev->value());
+ g->setChangeFlags(QPinchGesture::RotationAngleChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ g->setHotSpot(ev->screenPos());
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
+ case Qt::ZoomNativeGesture:
+ g->setLastScaleFactor(g->scaleFactor());
+ g->setLastRotationAngle(g->rotationAngle());
+ g->setScaleFactor(g->scaleFactor() * (1 + ev->value()));
+ g->setChangeFlags(QPinchGesture::ScaleFactorChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ g->setHotSpot(ev->screenPos());
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
+ case Qt::SmartZoomNativeGesture:
+ g->setLastScaleFactor(g->scaleFactor());
+ g->setLastRotationAngle(g->rotationAngle());
+ g->setScaleFactor(ev->value() ? 1.7f : 1.0f);
+ g->setChangeFlags(QPinchGesture::ScaleFactorChanged);
+ g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
+ g->setHotSpot(ev->screenPos());
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
+ case Qt::EndNativeGesture:
+ return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint;
+ default:
+ break;
+ }
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacPinchGestureRecognizer::reset(QGesture *gesture)
+{
+ QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
+ g->setChangeFlags(0);
+ g->setTotalChangeFlags(0);
+ g->setScaleFactor(1.0f);
+ g->setTotalScaleFactor(1.0f);
+ g->setLastScaleFactor(1.0f);
+ g->setRotationAngle(0.0f);
+ g->setTotalRotationAngle(0.0f);
+ g->setLastRotationAngle(0.0f);
+ g->setCenterPoint(QPointF());
+ g->setStartCenterPoint(QPointF());
+ g->setLastCenterPoint(QPointF());
+ QGestureRecognizer::reset(gesture);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true)
+{
+}
+
+QGesture *QMacPanGestureRecognizer::create(QObject *target)
+{
+ if (!target)
+ return new QPanGesture;
+
+ if (QWidget *w = qobject_cast<QWidget *>(target)) {
+ w->setAttribute(Qt::WA_AcceptTouchEvents);
+ w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
+ return new QPanGesture;
+ }
+ return 0;
+}
+
+QGestureRecognizer::Result
+QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event)
+{
+ const int panBeginDelay = 300;
+ const int panBeginRadius = 3;
+
+ QPanGesture *g = static_cast<QPanGesture *>(gesture);
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (ev->touchPoints().size() == 1) {
+ reset(gesture);
+ _startPos = QCursor::pos();
+ _panTimer.start(panBeginDelay, target);
+ _panCanceled = false;
+ return QGestureRecognizer::MayBeGesture;
+ }
+ break;}
+ case QEvent::TouchEnd: {
+ if (_panCanceled)
+ break;
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (ev->touchPoints().size() == 1)
+ return QGestureRecognizer::FinishGesture;
+ break;}
+ case QEvent::TouchUpdate: {
+ if (_panCanceled)
+ break;
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (ev->touchPoints().size() == 1) {
+ if (_panTimer.isActive()) {
+ // INVARIANT: Still in maybeGesture. Check if the user
+ // moved his finger so much that it makes sense to cancel the pan:
+ const QPointF p = QCursor::pos();
+ if ((p - _startPos).manhattanLength() > panBeginRadius) {
+ _panCanceled = true;
+ _panTimer.stop();
+ return QGestureRecognizer::CancelGesture;
+ }
+ } else {
+ const QPointF p = QCursor::pos();
+ const QPointF posOffset = p - _startPos;
+ g->setLastOffset(g->offset());
+ g->setOffset(QPointF(posOffset.x(), posOffset.y()));
+ g->setHotSpot(_startPos);
+ return QGestureRecognizer::TriggerGesture;
+ }
+ } else if (_panTimer.isActive()) {
+ // I only want to cancel the pan if the user is pressing
+ // more than one finger, and the pan hasn't started yet:
+ _panCanceled = true;
+ _panTimer.stop();
+ return QGestureRecognizer::CancelGesture;
+ }
+ break;}
+ case QEvent::Timer: {
+ QTimerEvent *ev = static_cast<QTimerEvent *>(event);
+ if (ev->timerId() == _panTimer.timerId()) {
+ _panTimer.stop();
+ if (_panCanceled)
+ break;
+ // Begin new pan session!
+ _startPos = QCursor::pos();
+ g->setHotSpot(_startPos);
+ return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint;
+ }
+ break; }
+ default:
+ break;
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacPanGestureRecognizer::reset(QGesture *gesture)
+{
+ QPanGesture *g = static_cast<QPanGesture *>(gesture);
+ _startPos = QPointF();
+ _panCanceled = true;
+ g->setOffset(QPointF(0, 0));
+ g->setLastOffset(QPointF(0, 0));
+ g->setAcceleration(qreal(1));
+ QGestureRecognizer::reset(gesture);
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
diff --git a/src/widgets/kernel/qmacgesturerecognizer_p.h b/src/widgets/kernel/qmacgesturerecognizer_p.h
new file mode 100644
index 0000000000..02f836b3f7
--- /dev/null
+++ b/src/widgets/kernel/qmacgesturerecognizer_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMACSWIPEGESTURERECOGNIZER_MAC_P_H
+#define QMACSWIPEGESTURERECOGNIZER_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtimer.h"
+#include "qpoint.h"
+#include "qgesturerecognizer.h"
+
+#ifndef QT_NO_GESTURES
+
+QT_BEGIN_NAMESPACE
+
+class QMacSwipeGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QMacSwipeGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+};
+
+class QMacPinchGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QMacPinchGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+};
+
+class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
+{
+public:
+ QMacPanGestureRecognizer();
+
+ QGesture *create(QObject *target);
+ QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+private:
+ QPointF _startPos;
+ QBasicTimer _panTimer;
+ bool _panCanceled;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GESTURES
+
+#endif // QMACSWIPEGESTURERECOGNIZER_MAC_P_H
diff --git a/src/widgets/kernel/qsizepolicy.qdoc b/src/widgets/kernel/qsizepolicy.qdoc
index 1c99131bc4..d82f3837f2 100644
--- a/src/widgets/kernel/qsizepolicy.qdoc
+++ b/src/widgets/kernel/qsizepolicy.qdoc
@@ -342,6 +342,7 @@
/*!
\fn void QSizePolicy::retainSizeWhenHidden() const
+ \since 5.2
Returns if the layout should retain the widgets size when it is hidden. This is by default false.
@@ -350,6 +351,7 @@
/*!
\fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize)
+ \since 5.2
Set if a layout should retain the widgets size when it is hidden.
If \a retainSize is true the layout will not be changed by hiding the widget.
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 72e3a56702..55459ac1ac 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1594,6 +1594,7 @@ void QWidgetPrivate::createExtra()
extra->autoFillBackground = 0;
extra->nativeChildrenForced = 0;
extra->inRenderWithPainter = 0;
+ extra->hasWindowContainer = false;
extra->hasMask = 0;
createSysExtra();
#ifdef QWIDGET_EXTRA_DEBUG
@@ -6543,6 +6544,9 @@ void QWidget::move(const QPoint &p)
data->crect.moveTopLeft(p); // no frame yet
setAttribute(Qt::WA_PendingMoveEvent);
}
+
+ if (d->extra && d->extra->hasWindowContainer)
+ QWindowContainer::parentWasMoved(this);
}
/*! \fn void QWidget::resize(int w, int h)
@@ -6581,6 +6585,9 @@ void QWidget::setGeometry(const QRect &r)
setAttribute(Qt::WA_PendingMoveEvent);
setAttribute(Qt::WA_PendingResizeEvent);
}
+
+ if (d->extra && d->extra->hasWindowContainer)
+ QWindowContainer::parentWasMoved(this);
}
/*!
@@ -9715,6 +9722,9 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
ancestorProxy->d_func()->embedSubWindow(this);
}
#endif
+
+ if (d->extra && d->extra->hasWindowContainer)
+ QWindowContainer::parentWasChanged(this);
}
/*!
@@ -10747,6 +10757,9 @@ void QWidget::raise()
if (testAttribute(Qt::WA_WState_Created))
d->raise_sys();
+ if (d->extra && d->extra->hasWindowContainer)
+ QWindowContainer::parentWasRaised(this);
+
QEvent e(QEvent::ZOrderChange);
QApplication::sendEvent(this, &e);
}
@@ -10781,6 +10794,9 @@ void QWidget::lower()
if (testAttribute(Qt::WA_WState_Created))
d->lower_sys();
+ if (d->extra && d->extra->hasWindowContainer)
+ QWindowContainer::parentWasLowered(this);
+
QEvent e(QEvent::ZOrderChange);
QApplication::sendEvent(this, &e);
}
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index cc740034fc..df40908c00 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -254,6 +254,7 @@ struct QWExtra {
uint nativeChildrenForced : 1;
uint inRenderWithPainter : 1;
uint hasMask : 1;
+ uint hasWindowContainer : 1;
// *************************** Platform specific values (bit fields first) **********
#if defined(Q_WS_WIN) // <----------------------------------------------------------- WIN
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index f2bd389769..51a0eb7d72 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -49,6 +49,7 @@
#endif
#include <private/qwidgetbackingstore_p.h>
#include <qpa/qwindowsysteminterface_p.h>
+#include <private/qgesturemanager_p.h>
QT_BEGIN_NAMESPACE
@@ -85,6 +86,12 @@ QWidgetWindow::QWidgetWindow(QWidget *widget)
connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName);
}
+QWidgetWindow::~QWidgetWindow()
+{
+ if (m_widget == qt_tablet_target)
+ qt_tablet_target = 0;
+}
+
#ifndef QT_NO_ACCESSIBILITY
QAccessibleInterface *QWidgetWindow::accessibleRoot() const
{
@@ -220,6 +227,13 @@ bool QWidgetWindow::event(QEvent *event)
handleTabletEvent(static_cast<QTabletEvent *>(event));
return true;
#endif
+
+#ifndef QT_NO_GESTURES
+ case QEvent::NativeGesture:
+ handleGestureEvent(static_cast<QNativeGestureEvent *>(event));
+ return true;
+#endif
+
#ifndef QT_NO_CONTEXTMENU
case QEvent::ContextMenu:
handleContextMenuEvent(static_cast<QContextMenuEvent *>(event));
@@ -732,6 +746,25 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
}
#endif // QT_NO_TABLETEVENT
+#ifndef QT_NO_GESTURES
+void QWidgetWindow::handleGestureEvent(QNativeGestureEvent *e)
+{
+ // copy-pasted code to find correct widget follows:
+ QObject *receiver = 0;
+ if (QApplicationPrivate::inPopupMode()) {
+ QWidget *popup = QApplication::activePopupWidget();
+ QWidget *popupFocusWidget = popup->focusWidget();
+ receiver = popupFocusWidget ? popupFocusWidget : popup;
+ }
+ if (!receiver)
+ receiver = QApplication::widgetAt(e->globalPos());
+ if (!receiver)
+ receiver = m_widget; // last resort
+
+ QApplication::sendSpontaneousEvent(receiver, e);
+}
+#endif // QT_NO_GESTURES
+
#ifndef QT_NO_CONTEXTMENU
void QWidgetWindow::handleContextMenuEvent(QContextMenuEvent *e)
{
diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h
index cb7bef8f3e..ffde44dd27 100644
--- a/src/widgets/kernel/qwidgetwindow_qpa_p.h
+++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h
@@ -58,6 +58,7 @@ class QWidgetWindow : public QWindow
Q_OBJECT
public:
QWidgetWindow(QWidget *widget);
+ ~QWidgetWindow();
QWidget *widget() const { return m_widget; }
#ifndef QT_NO_ACCESSIBILITY
@@ -91,6 +92,9 @@ protected:
#ifndef QT_NO_TABLETEVENT
void handleTabletEvent(QTabletEvent *);
#endif
+#ifndef QT_NO_GESTURES
+ void handleGestureEvent(QNativeGestureEvent *);
+#endif
#ifndef QT_NO_CONTEXTMENU
void handleContextMenuEvent(QContextMenuEvent *);
#endif
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index b02b05552f..6914f64f8e 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -42,6 +42,10 @@
#include "qwindowcontainer_p.h"
#include "qwidget_p.h"
#include <QtGui/qwindow.h>
+#include <QDebug>
+
+#include <QMdiSubWindow>
+#include <QAbstractScrollArea>
QT_BEGIN_NAMESPACE
@@ -50,11 +54,67 @@ class QWindowContainerPrivate : public QWidgetPrivate
public:
Q_DECLARE_PUBLIC(QWindowContainer)
- QWindowContainerPrivate() : window(0), oldFocusWindow(0) { }
+ QWindowContainerPrivate()
+ : window(0)
+ , oldFocusWindow(0)
+ , usesNativeWidgets(false)
+ {
+ }
+
~QWindowContainerPrivate() { }
+ static QWindowContainerPrivate *get(QWidget *w) {
+ QWindowContainer *wc = qobject_cast<QWindowContainer *>(w);
+ if (wc)
+ return wc->d_func();
+ return 0;
+ }
+
+ void updateGeometry() {
+ Q_Q(QWindowContainer);
+ if (usesNativeWidgets)
+ window->setGeometry(q->rect());
+ else
+ window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size()));
+ }
+
+ void updateUsesNativeWidgets()
+ {
+ if (usesNativeWidgets || window->parent() == 0)
+ return;
+ Q_Q(QWindowContainer);
+ QWidget *p = q->parentWidget();
+ while (p) {
+ if (qobject_cast<QMdiSubWindow *>(p) != 0
+ || qobject_cast<QAbstractScrollArea *>(p) != 0) {
+ q->winId();
+ usesNativeWidgets = true;
+ break;
+ }
+ p = p->parentWidget();
+ }
+ }
+
+ void markParentChain() {
+ Q_Q(QWindowContainer);
+ QWidget *p = q;
+ while (p) {
+ QWidgetPrivate *d = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(p));
+ d->createExtra();
+ d->extra->hasWindowContainer = true;
+ p = p->parentWidget();
+ }
+ }
+
+ bool isStillAnOrphan() const {
+ return window->parent() == &fakeParent;
+ }
+
QPointer<QWindow> window;
QWindow *oldFocusWindow;
+ QWindow fakeParent;
+
+ uint usesNativeWidgets : 1;
};
@@ -78,6 +138,14 @@ public:
be removed from the window container with a call to
QWindow::setParent().
+ The window container is attached as a native child window to the
+ toplevel window it is a child of. When a window container is used
+ as a child of a QAbstractScrollArea or QMdiArea, it will
+ create a \l {Native Widgets vs Alien Widgets} {native window} for
+ every widget in its parent chain to allow for proper stacking and
+ clipping in this use case. Applications with many native child
+ windows may suffer from performance issues.
+
The window container has a number of known limitations:
\list
@@ -86,11 +154,6 @@ public:
widget hierarchy as an opaque box. The stacking order of multiple
overlapping window container instances is undefined.
- \li Window Handles; The window container will explicitly invoke
- winId() which will force the use of native window handles
- inside the application. See \l {Native Widgets vs Alien Widgets}
- {QWidget documentation} for more details.
-
\li Rendering Integration; The window container does not interoperate
with QGraphicsProxyWidget, QWidget::render() or similar functionality.
@@ -132,13 +195,7 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt:
}
d->window = embeddedWindow;
-
- // We force this window to become a native window and reparent the
- // window directly to it. This is done so that the order in which
- // the QWindowContainer is added to a QWidget tree and when it
- // gets a window does not matter.
- winId();
- d->window->setParent(windowHandle());
+ d->window->setParent(&d->fakeParent);
connect(QGuiApplication::instance(), SIGNAL(focusWindowChanged(QWindow *)), this, SLOT(focusWindowChanged(QWindow *)));
}
@@ -167,8 +224,6 @@ void QWindowContainer::focusWindowChanged(QWindow *focusWindow)
d->oldFocusWindow = focusWindow;
}
-
-
/*!
\internal
*/
@@ -190,22 +245,38 @@ bool QWindowContainer::event(QEvent *e)
// The only thing we are interested in is making sure our sizes stay
// in sync, so do a catch-all case.
case QEvent::Resize:
+ d->updateGeometry();
+ break;
case QEvent::Move:
+ d->updateGeometry();
+ break;
case QEvent::PolishRequest:
- d->window->setGeometry(0, 0, width(), height());
+ d->updateGeometry();
break;
case QEvent::Show:
- d->window->show();
+ d->updateUsesNativeWidgets();
+ if (d->isStillAnOrphan()) {
+ d->window->setParent(d->usesNativeWidgets
+ ? windowHandle()
+ : window()->windowHandle());
+ }
+ if (d->window->parent()) {
+ d->markParentChain();
+ d->window->show();
+ }
break;
case QEvent::Hide:
- d->window->hide();
+ if (d->window->parent())
+ d->window->hide();
break;
case QEvent::FocusIn:
- if (d->oldFocusWindow != d->window) {
- d->window->requestActivate();
- } else {
- QWidget *next = nextInFocusChain();
- next->setFocus();
+ if (d->window->parent()) {
+ if (d->oldFocusWindow != d->window) {
+ d->window->requestActivate();
+ } else {
+ QWidget *next = nextInFocusChain();
+ next->setFocus();
+ }
}
break;
default:
@@ -215,4 +286,60 @@ bool QWindowContainer::event(QEvent *e)
return QWidget::event(e);
}
+typedef void (*qwindowcontainer_traverse_callback)(QWidget *parent);
+static void qwindowcontainer_traverse(QWidget *parent, qwindowcontainer_traverse_callback callback)
+{
+ const QObjectList &children = parent->children();
+ for (int i=0; i<children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(children.at(i));
+ if (w) {
+ QWidgetPrivate *wd = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(w));
+ if (wd->extra && wd->extra->hasWindowContainer)
+ callback(w);
+ }
+ }
+}
+
+void QWindowContainer::parentWasChanged(QWidget *parent)
+{
+ if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
+ if (d->window->parent()) {
+ d->updateUsesNativeWidgets();
+ d->markParentChain();
+ d->window->setParent(d->usesNativeWidgets
+ ? parent->windowHandle()
+ : parent->window()->windowHandle());
+ d->updateGeometry();
+ }
+ }
+ qwindowcontainer_traverse(parent, parentWasChanged);
+}
+
+void QWindowContainer::parentWasMoved(QWidget *parent)
+{
+ if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
+ if (d->window->parent())
+ d->updateGeometry();
+ }
+ qwindowcontainer_traverse(parent, parentWasMoved);
+}
+
+void QWindowContainer::parentWasRaised(QWidget *parent)
+{
+ if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
+ if (d->window->parent())
+ d->window->raise();
+ }
+ qwindowcontainer_traverse(parent, parentWasRaised);
+}
+
+void QWindowContainer::parentWasLowered(QWidget *parent)
+{
+ if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) {
+ if (d->window->parent())
+ d->window->lower();
+ }
+ qwindowcontainer_traverse(parent, parentWasLowered);
+}
+
QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qwindowcontainer_p.h b/src/widgets/kernel/qwindowcontainer_p.h
index 37c023fc1d..e2446bef42 100644
--- a/src/widgets/kernel/qwindowcontainer_p.h
+++ b/src/widgets/kernel/qwindowcontainer_p.h
@@ -57,6 +57,11 @@ public:
explicit QWindowContainer(QWindow *embeddedWindow, QWidget *parent = 0, Qt::WindowFlags f = 0);
~QWindowContainer();
+ static void parentWasChanged(QWidget *parent);
+ static void parentWasMoved(QWidget *parent);
+ static void parentWasRaised(QWidget *parent);
+ static void parentWasLowered(QWidget *parent);
+
protected:
bool event(QEvent *ev);
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index 08b24a8200..79ca0a5bdb 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -380,6 +380,8 @@ bool QSystemTrayIcon::supportsMessages()
On Mac OS X, the Growl notification system must be installed for this function to
display messages.
+ Has been turned into a slot in Qt 5.2.
+
\sa show(), supportsMessages()
*/
void QSystemTrayIcon::showMessage(const QString& title, const QString& msg,
diff --git a/src/widgets/util/qsystemtrayicon.h b/src/widgets/util/qsystemtrayicon.h
index 278efae586..d6ba553a3a 100644
--- a/src/widgets/util/qsystemtrayicon.h
+++ b/src/widgets/util/qsystemtrayicon.h
@@ -94,8 +94,6 @@ public:
static bool supportsMessages();
enum MessageIcon { NoIcon, Information, Warning, Critical };
- void showMessage(const QString &title, const QString &msg,
- MessageIcon icon = Information, int msecs = 10000);
QRect geometry() const;
bool isVisible() const;
@@ -104,6 +102,8 @@ public Q_SLOTS:
void setVisible(bool visible);
inline void show() { setVisible(true); }
inline void hide() { setVisible(false); }
+ void showMessage(const QString &title, const QString &msg,
+ QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int msecs = 10000);
Q_SIGNALS:
void activated(QSystemTrayIcon::ActivationReason reason);
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
index 3771b97a31..e3222b49e8 100644
--- a/src/widgets/widgets.pro
+++ b/src/widgets/widgets.pro
@@ -44,7 +44,3 @@ QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtWidgets.dynlist
testcocoon {
load(testcocoon)
}
-
-win32:!contains(QT_CONFIG, directwrite) {
- DEFINES += QT_NO_DIRECTWRITE
-}
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index a9b21cbc81..8b151e65bd 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -674,12 +674,18 @@ void QDockWidgetPrivate::updateButtons()
= qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton));
button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
button->setVisible(canFloat && !hideButtons);
-
+#ifndef QT_NO_ACCESSIBILITY
+ button->setAccessibleName(QDockWidget::tr("Float"));
+ button->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget"));
+#endif
button
= qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton));
button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
button->setVisible(canClose && !hideButtons);
-
+#ifndef QT_NO_ACCESSIBILITY
+ button->setAccessibleName(QDockWidget::tr("Close"));
+ button->setAccessibleDescription(QDockWidget::tr("Closes the dock widget"));
+#endif
q->setAttribute(Qt::WA_ContentsPropagated,
(canFloat || canClose) && !hideButtons);
diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp
index 86fd10699c..7b1d66cf0d 100644
--- a/src/widgets/widgets/qstatusbar.cpp
+++ b/src/widgets/widgets/qstatusbar.cpp
@@ -551,8 +551,6 @@ void QStatusBar::showMessage(const QString &message, int timeout)
{
Q_D(QStatusBar);
- d->tempItem = message;
-
if (timeout > 0) {
if (!d->timer) {
d->timer = new QTimer(this);
@@ -563,6 +561,9 @@ void QStatusBar::showMessage(const QString &message, int timeout)
delete d->timer;
d->timer = 0;
}
+ if (d->tempItem == message)
+ return;
+ d->tempItem = message;
hideOrShow();
}
diff --git a/tests/auto/android/runtests.pl b/tests/auto/android/runtests.pl
index 55e1a224d8..365257aace 100755
--- a/tests/auto/android/runtests.pl
+++ b/tests/auto/android/runtests.pl
@@ -164,7 +164,7 @@ if ($output =~ m/.*\[ro.build.version.sdk\]: \[(\d+)\]/)
sub reinstallQuadruplor
{
pushd($quadruplor_dir);
- system("$android_sdk_dir/tools/android update project -p . -t android-4")==0 or die "Can't update project ...\n";
+ system("$android_sdk_dir/tools/android update project -p . -t android-10")==0 or die "Can't update project ...\n";
system("$ant_tool uninstall clean debug install")==0 or die "Can't install Quadruplor\n";
system("$adb_tool $device_serial shell am start -n $intentName"); # create application folders
waitForProcess($packageName,1,10);
diff --git a/tests/auto/android/runtests_androiddeployqt.pl b/tests/auto/android/runtests_androiddeployqt.pl
new file mode 100755
index 0000000000..d3c9a7bc11
--- /dev/null
+++ b/tests/auto/android/runtests_androiddeployqt.pl
@@ -0,0 +1,323 @@
+#!/usr/bin/perl -w
+#############################################################################
+##
+## Copyright (C) 2012-2013 BogDan Vatra <bogdan@kde.org>
+## Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+## Contact: http://www.qt-project.org/legal
+##
+## This file is part of the test suite 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 Digia. For licensing terms and
+## conditions see http://qt.digia.com/licensing. For further information
+## use the contact form at http://qt.digia.com/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Digia gives you certain additional
+## rights. These rights are described in the Digia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3.0 as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU General Public License version 3.0 requirements will be
+## met: http://www.gnu.org/copyleft/gpl.html.
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+use Cwd;
+use Cwd 'abs_path';
+use File::Basename;
+use File::Temp 'tempdir';
+use File::Path 'remove_tree';
+use Getopt::Long;
+use Pod::Usage;
+
+### default options
+my @stack = cwd;
+my $device_serial=""; # "-s device_serial";
+my $deployqt_device_serial=""; # "-device device_serial";
+my $className="org.qtproject.qt5.android.bindings.QtActivity";
+my $jobs = 4;
+my $testsubset = "";
+my $man = 0;
+my $help = 0;
+my $make_clean = 0;
+my $time_out=400;
+my $android_toolchain_version = "4.8";
+my $host_arch = "linux-x86";
+my $android_sdk_dir = "$ENV{'ANDROID_SDK_ROOT'}";
+my $android_ndk_dir = "$ENV{'ANDROID_NDK_ROOT'}";
+my $android_to_connect = "$ENV{'ANDROID_DEVICE'}";
+my $ant_tool = `which ant`;
+chomp $ant_tool;
+my $strip_tool="";
+my $readelf_tool="";
+GetOptions('h|help' => \$help
+ , man => \$man
+ , 's|serial=s' => \$device_serial
+ , 't|test=s' => \$testsubset
+ , 'c|clean' => \$make_clean
+ , 'j|jobs=i' => \$jobs
+ , 'sdk=s' => \$android_sdk_dir
+ , 'ndk=s' => \$android_ndk_dir
+ , 'toolchain=s' => \$android_toolchain_version
+ , 'host=s' => \$host_arch
+ , 'ant=s' => \$ant_tool
+ , 'strip=s' => \$strip_tool
+ , 'readelf=s' => \$readelf_tool
+ , 'testcase=s' => \$testcase
+ ) or pod2usage(2);
+pod2usage(1) if $help;
+pod2usage(-verbose => 2) if $man;
+
+my $adb_tool="$android_sdk_dir/platform-tools/adb";
+
+# For CI. Nodes are connecting to test devices over IP, which is stored to env variable
+if ($android_to_connect ne ""){
+ print " Found device to be connected from env: $android_to_connect \n";
+ system("$adb_tool disconnect $android_to_connect");
+ system("$adb_tool connect $android_to_connect");
+ sleep(2);# let it connect
+ system("$adb_tool -s $android_to_connect reboot &");# adb bug, it blocks forever
+ sleep(15); # wait for the device to come up again
+ system("$adb_tool disconnect $android_to_connect");# cleans up the left adb reboot process
+ system("$adb_tool connect $android_to_connect");
+ $device_serial =$android_to_connect;
+}
+
+
+system("$adb_tool devices") == 0 or die "No device found, please plug/start at least one device/emulator\n"; # make sure we have at least on device attached
+
+$deployqt_device_serial = "--device $device_serial" if ($device_serial);
+$device_serial = "-s $device_serial" if ($device_serial);
+$testsubset="/$testsubset" if ($testsubset);
+
+$strip_tool="$android_ndk_dir/toolchains/arm-linux-androideabi-$android_toolchain_version/prebuilt/$host_arch/bin/arm-linux-androideabi-strip" unless($strip_tool);
+$readelf_tool="$android_ndk_dir/toolchains/arm-linux-androideabi-$android_toolchain_version/prebuilt/$host_arch/bin/arm-linux-androideabi-readelf" unless($readelf_tool);
+$readelf_tool="$readelf_tool -d -w ";
+
+sub dir
+{
+# print "@stack\n";
+}
+
+sub pushd ($)
+{
+ unless ( chdir $_[0] )
+ {
+ warn "Error: $!\n";
+ return;
+ }
+ unshift @stack, cwd;
+ dir;
+}
+
+sub popd ()
+{
+ @stack > 1 and shift @stack;
+ chdir $stack[0];
+ dir;
+}
+
+
+sub waitForProcess
+{
+ my $process=shift;
+ my $action=shift;
+ my $timeout=shift;
+ my $sleepPeriod=shift;
+ $sleepPeriod=1 if !defined($sleepPeriod);
+ print "Waiting for $process ".$timeout*$sleepPeriod." seconds to";
+ print $action?" start...\n":" die...\n";
+ while ($timeout--)
+ {
+ my $output = `$adb_tool $device_serial shell ps 2>&1`; # get current processes
+ #FIXME check why $output is not matching m/.*S $process\n/ or m/.*S $process$/ (eol)
+ my $res=($output =~ m/.*S $process/)?1:0; # check the procress
+ if ($action == $res)
+ {
+ print "... succeed\n";
+ return 1;
+ }
+ sleep($sleepPeriod);
+ print "timeount in ".$timeout*$sleepPeriod." seconds\n"
+ }
+ print "... failed\n";
+ return 0;
+}
+
+my $src_dir_qt=abs_path(dirname($0)."/../../..");
+my $quadruplor_dir="$src_dir_qt/tests/auto/android";
+my $qmake_path="$src_dir_qt/bin/qmake";
+my $tests_dir="$src_dir_qt/tests$testsubset";
+my $temp_dir=tempdir(CLEANUP => 1);
+my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+my $output_dir=$stack[0]."/".(1900+$year)."-$mon-$mday-$hour:$min";
+mkdir($output_dir);
+my $sdk_api=0;
+my $output = `$adb_tool $device_serial shell getprop`; # get device properties
+if ($output =~ m/.*\[ro.build.version.sdk\]: \[(\d+)\]/)
+{
+ $sdk_api=int($1);
+ $sdk_api=5 if ($sdk_api>5 && $sdk_api<8);
+ $sdk_api=9 if ($sdk_api>9);
+}
+
+sub startTest
+{
+ my $testName = shift;
+ my $packageName = "org.qtproject.example.tst_$testName";
+ my $intentName = "$packageName/org.qtproject.qt5.android.bindings.QtActivity";
+ my $output_file = shift;
+
+ system("$adb_tool $device_serial shell am start -e applicationArguments \"-o /data/data/$packageName/output.xml\" -n $intentName"); # start intent
+ #wait to start (if it has not started and quit already)
+ waitForProcess($packageName,1,10);
+
+ #wait to stop
+ unless(waitForProcess($packageName,0,$time_out,5))
+ {
+ #killProcess($packageName);
+ print "Someone should kill $packageName\n";
+ return 1;
+ }
+ system("$adb_tool $device_serial pull /data/data/$packageName/output.xml $output_dir/$output_file");
+ return 1;
+}
+
+########### build qt tests and benchmarks ###########
+pushd($tests_dir);
+print "Building $tests_dir \n";
+system("make distclean") if ($make_clean);
+system("$qmake_path -r") == 0 or die "Can't run qmake\n"; #exec qmake
+system("make -j$jobs") == 0 or warn "Can't build all tests\n"; #exec make
+
+my $testsFiles = "";
+if ($testcase) {
+ $testsFiles=`find . -name libtst_$testcase.so`; # only tests
+} else {
+ $testsFiles=`find . -name libtst_*.so`; # only tests
+}
+
+foreach (split("\n",$testsFiles))
+{
+ chomp; #remove white spaces
+ pushd(abs_path(dirname($_))); # cd to application dir
+ system("make INSTALL_ROOT=$temp_dir install"); # install the application to temp dir
+ my $application=basename(cwd);
+ system("androiddeployqt --install $deployqt_device_serial --output $temp_dir --deployment debug --verbose --input android-libtst_$application.so-deployment-settings.json");
+ my $output_name=dirname($_);
+ $output_name =~ s/\.//; # remove first "." character
+ $output_name =~ s/\///; # remove first "/" character
+ $output_name =~ s/\//_/g; # replace all "/" with "_"
+ $output_name=$application unless($output_name);
+ $time_out=5*60/5; # 5 minutes time out for a normal test
+
+ $applicationLibrary = `find $temp_dir -name libtst_bench_$application.so`;
+
+ if ($applicationLibrary)
+ {
+ $time_out=5*60/5; # 10 minutes for a benchmark
+ $application = "bench_$application";
+ }
+ else
+ {
+ $applicationLibrary = `find $temp_dir -name libtst_$application.so`;
+ }
+
+ if (!$applicationLibrary)
+ {
+ print "Can't find application binary libtst_$application.so in $temp_dir!\n";
+ }
+ else
+ {
+ startTest($application, "$output_name.xml") or warn "Can't run $application ...\n";
+ }
+
+ popd();
+ remove_tree( $temp_dir, {keep_root => 1} );
+}
+popd();
+
+__END__
+
+=head1 NAME
+
+Script to run all qt tests/benchmarks to an android device/emulator
+
+=head1 SYNOPSIS
+
+runtests.pl [options]
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<-s --serial = serial>
+
+Device serial number. May be empty if only one device is attached.
+
+=item B<-t --test = test_subset>
+
+Tests subset (e.g. benchmarks, auto, auto/qbuffer, etc.).
+
+=item B<-c --clean>
+
+Clean tests before building them.
+
+=item B<-j --jobs = number>
+
+Make jobs when building tests.
+
+=item B<--sdk = sdk_path>
+
+Android SDK path.
+
+=item B<--ndk = ndk_path>
+
+Android NDK path.
+
+=item B<--ant = ant_tool_path>
+
+Ant tool path.
+
+=item B<--strip = strip_tool_path>
+
+Android strip tool path, used to deploy qt libs.
+
+=item B<--readelf = readelf_tool_path>
+
+Android readelf tool path, used to check if a test application uses qt OpenGL.
+
+=item B<-h --help>
+
+Print a brief help message and exits.
+
+=item B<--man>
+
+Prints the manual page and exits.
+
+=back
+
+=head1 DESCRIPTION
+
+B<This program> will run all qt tests/benchmarks to an android device/emulator.
+
+=cut
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index e16f229c4e..3ff78a955f 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -23,6 +23,7 @@ wince*: SUBDIRS -= printsupport
cross_compile: SUBDIRS -= tools
!qtHaveModule(opengl): SUBDIRS -= opengl
!unix|embedded|!qtHaveModule(dbus): SUBDIRS -= dbus
+!qtHaveModule(gui): SUBDIRS -= gui cmake
!qtHaveModule(widgets): SUBDIRS -= widgets
!qtHaveModule(printsupport): SUBDIRS -= printsupport
!qtHaveModule(concurrent): SUBDIRS -= concurrent
diff --git a/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro b/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro
index 4383c44259..23343f27f5 100644
--- a/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro
+++ b/tests/auto/corelib/animation/qparallelanimationgroup/qparallelanimationgroup.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qparallelanimationgroup
-QT = core gui testlib
+QT = core testlib
SOURCES = tst_qparallelanimationgroup.cpp
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro b/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro
index 812c98f8f0..4c2dd02951 100644
--- a/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro
+++ b/tests/auto/corelib/animation/qpauseanimation/qpauseanimation.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qpauseanimation
-QT = core-private gui-private testlib
+QT = core-private testlib
SOURCES = tst_qpauseanimation.cpp
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/codecs/qtextcodec/test/test.pro b/tests/auto/corelib/codecs/qtextcodec/test/test.pro
index ba16a75604..35b2b34690 100644
--- a/tests/auto/corelib/codecs/qtextcodec/test/test.pro
+++ b/tests/auto/corelib/codecs/qtextcodec/test/test.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
CONFIG += parallel_test
-QT += testlib
+QT = core testlib
SOURCES = ../tst_qtextcodec.cpp
TARGET = ../tst_qtextcodec
diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
index 6329160998..8e1b3cf3b2 100644
--- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
+++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
@@ -44,7 +44,6 @@
#include <qtextcodec.h>
#include <qfile.h>
-#include <qtextdocument.h>
#include <time.h>
#include <qprocess.h>
#include <QThreadPool>
@@ -67,9 +66,9 @@ private slots:
void codecForLocale();
void asciiToIscii() const;
- void flagCodepointFFFF() const;
+ void nonFlaggedCodepointFFFF() const;
void flagF7808080() const;
- void flagEFBFBF() const;
+ void nonFlaggedEFBFBF() const;
void decode0D() const;
void aliasForUTF16() const;
void mibForTSCII() const;
@@ -288,7 +287,7 @@ void tst_QTextCodec::toUnicode_codecForHtml()
QVERIFY(file.open(QFile::ReadOnly));
QByteArray data = file.readAll();
- QTextCodec *codec = Qt::codecForHtml(data);
+ QTextCodec *codec = QTextCodec::codecForHtml(data);
codec->toUnicode(data); // this line crashes
}
@@ -410,9 +409,9 @@ void tst_QTextCodec::asciiToIscii() const
}
}
-void tst_QTextCodec::flagCodepointFFFF() const
+void tst_QTextCodec::nonFlaggedCodepointFFFF() const
{
- // This is an invalid Unicode codepoint.
+ //Check that the code point 0xFFFF (=non-character code 0xEFBFBF) is not flagged
const QChar ch(0xFFFF);
QString input(ch);
@@ -420,12 +419,11 @@ void tst_QTextCodec::flagCodepointFFFF() const
QVERIFY(codec);
const QByteArray asDecoded(codec->fromUnicode(input));
- QCOMPARE(asDecoded, QByteArray("?"));
+ QCOMPARE(asDecoded, QByteArray("\357\277\277"));
QByteArray ffff("\357\277\277");
QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
- QVERIFY(codec->toUnicode(ffff.constData(), ffff.length(), &state) == QChar(0));
- QVERIFY(codec->toUnicode(ffff) == QChar(0xfffd));
+ QVERIFY(codec->toUnicode(ffff.constData(), ffff.length(), &state) == QByteArray::fromHex("EFBFBF"));
}
void tst_QTextCodec::flagF7808080() const
@@ -461,13 +459,16 @@ void tst_QTextCodec::flagF7808080() const
QVERIFY(codec->toUnicode(input.constData(), input.length(), &state) == QChar(0));
}
-void tst_QTextCodec::flagEFBFBF() const
+void tst_QTextCodec::nonFlaggedEFBFBF() const
{
- QByteArray invalidInput;
- invalidInput.resize(3);
- invalidInput[0] = char(0xEF);
- invalidInput[1] = char(0xBF);
- invalidInput[2] = char(0xBF);
+ /* Check that the codec does NOT flag EFBFBF.
+ * This is a regression test; see QTBUG-33229
+ */
+ QByteArray validInput;
+ validInput.resize(3);
+ validInput[0] = char(0xEF);
+ validInput[1] = char(0xBF);
+ validInput[2] = char(0xBF);
const QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8
QVERIFY(codec);
@@ -475,21 +476,20 @@ void tst_QTextCodec::flagEFBFBF() const
{
//QVERIFY(!codec->canEncode(QChar(0xFFFF)));
QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
- QVERIFY(codec->toUnicode(invalidInput.constData(), invalidInput.length(), &state) == QChar(0));
+ QVERIFY(codec->toUnicode(validInput.constData(), validInput.length(), &state) == QByteArray::fromHex("EFBFBF"));
QByteArray start("<?pi ");
- start.append(invalidInput);
+ start.append(validInput);
start.append("?>");
}
- /* When 0xEFBFBF is preceded by what seems to be an arbitrary character,
- * QTextCodec fails to flag it. */
+ // Check that 0xEFBFBF is correctly decoded when preceded by an arbitrary character
{
QByteArray start("B");
- start.append(invalidInput);
+ start.append(validInput);
QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
- QVERIFY(codec->toUnicode(start.constData(), start.length(), &state) == QString::fromLatin1("B\0", 2));
+ QVERIFY(codec->toUnicode(start.constData(), start.length(), &state) == QByteArray("B").append(QByteArray::fromHex("EFBFBF")));
}
}
@@ -675,13 +675,12 @@ void tst_QTextCodec::utf8Codec_data()
str = QChar(0x7ff);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.2") << utf8 << str << -1;
- // 2.2.3 U+000FFFF
+ // 2.2.3 U+000FFFF - non-character code
utf8.clear();
utf8 += char(0xef);
utf8 += char(0xbf);
utf8 += char(0xbf);
- str.clear();
- str += QChar::ReplacementCharacter;
+ str = QString::fromUtf8(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.3") << utf8 << str << -1;
// 2.2.4 U+001FFFFF
@@ -1536,20 +1535,22 @@ void tst_QTextCodec::utf8Codec_data()
str += QChar(QChar::ReplacementCharacter);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.8") << utf8 << str << -1;
- // 5.3.1
+ // 5.3.1 - non-character code
utf8.clear();
utf8 += char(0xef);
utf8 += char(0xbf);
utf8 += char(0xbe);
- str = QChar(QChar::ReplacementCharacter);
+ //str = QChar(QChar::ReplacementCharacter);
+ str = QString::fromUtf8(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.1") << utf8 << str << -1;
- // 5.3.2
+ // 5.3.2 - non-character code
utf8.clear();
utf8 += char(0xef);
utf8 += char(0xbf);
utf8 += char(0xbf);
- str = QChar(QChar::ReplacementCharacter);
+ //str = QChar(QChar::ReplacementCharacter);
+ str = QString::fromUtf8(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.2") << utf8 << str << -1;
}
diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
index 99147f3aff..e18f6f73b9 100644
--- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
+++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
@@ -233,8 +233,9 @@ void tst_Utf8::nonCharacters_data()
QTest::addColumn<QByteArray>("utf8");
QTest::addColumn<QString>("utf16");
- // Unicode has a couple of "non-characters" that one can use internally,
- // but are not allowed to be used for text interchange.
+ // Unicode has a couple of "non-characters" that one can use internally
+ // These characters may be used for interchange;
+ // see: http://www.unicode.org/versions/corrigendum9.html
//
// Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF,
// U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and
@@ -279,20 +280,17 @@ void tst_Utf8::nonCharacters()
decoder->toUnicode(utf8);
// Only enforce correctness on our UTF-8 decoder
- // The system's UTF-8 codec is sometimes buggy
- // GNU libc's iconv is known to accept U+FFFF and U+FFFE encoded as UTF-8
- // OS X's iconv is known to accept those, plus surrogates and codepoints above U+10FFFF
if (!useLocale)
- QVERIFY(decoder->hasFailure());
- else if (!decoder->hasFailure())
- qWarning("System codec does not report failure when it should. Should report bug upstream.");
+ QVERIFY(!decoder->hasFailure());
+ else if (decoder->hasFailure())
+ qWarning("System codec reports failure when it shouldn't. Should report bug upstream.");
QSharedPointer<QTextEncoder> encoder(codec->makeEncoder());
encoder->fromUnicode(utf16);
if (!useLocale)
- QVERIFY(encoder->hasFailure());
- else if (!encoder->hasFailure())
- qWarning("System codec does not report failure when it should. Should report bug upstream.");
+ QVERIFY(!encoder->hasFailure());
+ else if (encoder->hasFailure())
+ qWarning("System codec reports failure when it shouldn't. Should report bug upstream.");
}
QTEST_MAIN(tst_Utf8)
diff --git a/tests/auto/corelib/codecs/utf8/utf8data.cpp b/tests/auto/corelib/codecs/utf8/utf8data.cpp
index 2516cc9734..a41b0772e6 100644
--- a/tests/auto/corelib/codecs/utf8/utf8data.cpp
+++ b/tests/auto/corelib/codecs/utf8/utf8data.cpp
@@ -129,8 +129,8 @@ void loadInvalidUtf8Rows()
void loadNonCharactersRows()
{
- // Unicode has a couple of "non-characters" that one can use internally,
- // but are not allowed to be used for text interchange.
+ // Unicode has a couple of "non-characters" that one can use internally
+ // These characters are allowed for text-interchange (see http://www.unicode.org/versions/corrigendum9.html)
//
// Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF,
// U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and
diff --git a/tests/auto/corelib/global/qlogging/app/main.cpp b/tests/auto/corelib/global/qlogging/app/main.cpp
index 14416a914d..621059caad 100644
--- a/tests/auto/corelib/global/qlogging/app/main.cpp
+++ b/tests/auto/corelib/global/qlogging/app/main.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include <QCoreApplication>
+#include <QLoggingCategory>
struct T {
T() { qDebug("static constructor"); }
@@ -57,6 +58,9 @@ int main(int argc, char **argv)
qWarning("qWarning");
qCritical("qCritical");
+ QLoggingCategory cat("category");
+ qCWarning(cat) << "qDebug with category";
+
qSetMessagePattern(QString());
qDebug("qDebug2");
diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
index 94387704f6..31a4254344 100644
--- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
+++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
@@ -666,13 +666,14 @@ void tst_qmessagehandler::qMessagePattern()
// qDebug() << output;
QVERIFY(!output.isEmpty());
- QVERIFY(output.contains("debug 45 T::T static constructor"));
+ QVERIFY(output.contains("debug 46 T::T static constructor"));
// we can't be sure whether the QT_MESSAGE_PATTERN is already destructed
QVERIFY(output.contains("static destructor"));
- QVERIFY(output.contains("debug tst_qlogging 56 main qDebug"));
- QVERIFY(output.contains("warning tst_qlogging 57 main qWarning"));
- QVERIFY(output.contains("critical tst_qlogging 58 main qCritical"));
- QVERIFY(output.contains("debug tst_qlogging 62 main qDebug2"));
+ QVERIFY(output.contains("debug tst_qlogging 57 main qDebug"));
+ QVERIFY(output.contains("warning tst_qlogging 58 main qWarning"));
+ QVERIFY(output.contains("critical tst_qlogging 59 main qCritical"));
+ QVERIFY(output.contains("warning tst_qlogging 62 main qDebug with category "));
+ QVERIFY(output.contains("debug tst_qlogging 66 main qDebug2"));
environment = m_baseEnvironment;
environment.prepend("QT_MESSAGE_PATTERN=\"PREFIX: %{unknown} %{message}\"");
@@ -710,7 +711,8 @@ void tst_qmessagehandler::qMessagePattern()
QByteArray expected = "static constructor\n"
"[debug] qDebug\n"
"[warning] qWarning\n"
- "[critical] qCritical\n";
+ "[critical] qCritical\n"
+ "[warning] qDebug with category \n";
#ifdef Q_OS_WIN
output.replace("\r\n", "\n");
#endif
@@ -727,7 +729,7 @@ void tst_qmessagehandler::qMessagePatternIf()
const QString appExe = m_appDir + "/app";
QStringList environment = m_baseEnvironment;
- environment.prepend("QT_MESSAGE_PATTERN=\"[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{message}\"");
+ environment.prepend("QT_MESSAGE_PATTERN=\"[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{if-category}%{category}: %{endif}%{message}\"");
process.setEnvironment(environment);
process.start(appExe);
QVERIFY2(process.waitForStarted(), qPrintable(
@@ -745,6 +747,7 @@ void tst_qmessagehandler::qMessagePatternIf()
QVERIFY(output.contains("[D] qDebug"));
QVERIFY(output.contains("[W] qWarning"));
QVERIFY(output.contains("[C] qCritical"));
+ QVERIFY(output.contains("[W] category: qDebug with category"));
QVERIFY(output.contains("[D] qDebug2"));
//
diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro
index d70737a53f..11815c6160 100644
--- a/tests/auto/corelib/io/io.pro
+++ b/tests/auto/corelib/io/io.pro
@@ -38,6 +38,10 @@ SUBDIRS=\
qwinoverlappedionotifier
}
+!qtHaveModule(gui): SUBDIRS -= \
+ qdatastream \
+ qsettings
+
!qtHaveModule(network): SUBDIRS -= \
qfile \
qiodevice \
diff --git a/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp b/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp
index df93262d93..a49793c3d4 100644
--- a/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp
+++ b/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp
@@ -226,7 +226,7 @@ private slots:
void QLoggingCategory_categoryName()
{
logMessage.clear();
- QCOMPARE(QString::fromLatin1(QLoggingCategory::defaultCategory().categoryName()),
+ QCOMPARE(QString::fromLatin1(QLoggingCategory::defaultCategory()->categoryName()),
QStringLiteral("default"));
QLoggingCategory defaultCategory("default");
@@ -237,7 +237,7 @@ private slots:
QCOMPARE(QByteArray(nullCategory.categoryName()), QByteArray("default"));
// we rely on the same pointer for any "default" category
- QCOMPARE(QLoggingCategory::defaultCategory().categoryName(),
+ QCOMPARE(QLoggingCategory::defaultCategory()->categoryName(),
defaultCategory.categoryName());
QCOMPARE(defaultCategory.categoryName(),
nullCategory.categoryName());
@@ -256,12 +256,12 @@ private slots:
{
logMessage.clear();
- QCOMPARE(QLoggingCategory::defaultCategory().isDebugEnabled(), true);
- QCOMPARE(QLoggingCategory::defaultCategory().isEnabled(QtDebugMsg), true);
- QCOMPARE(QLoggingCategory::defaultCategory().isWarningEnabled(), true);
- QCOMPARE(QLoggingCategory::defaultCategory().isEnabled(QtWarningMsg), true);
- QCOMPARE(QLoggingCategory::defaultCategory().isCriticalEnabled(), true);
- QCOMPARE(QLoggingCategory::defaultCategory().isEnabled(QtCriticalMsg), true);
+ QCOMPARE(QLoggingCategory::defaultCategory()->isDebugEnabled(), true);
+ QCOMPARE(QLoggingCategory::defaultCategory()->isEnabled(QtDebugMsg), true);
+ QCOMPARE(QLoggingCategory::defaultCategory()->isWarningEnabled(), true);
+ QCOMPARE(QLoggingCategory::defaultCategory()->isEnabled(QtWarningMsg), true);
+ QCOMPARE(QLoggingCategory::defaultCategory()->isCriticalEnabled(), true);
+ QCOMPARE(QLoggingCategory::defaultCategory()->isEnabled(QtCriticalMsg), true);
QLoggingCategory defaultCategory("default");
QCOMPARE(defaultCategory.isDebugEnabled(), true);
@@ -287,11 +287,11 @@ private slots:
{
logMessage.clear();
- QCOMPARE(QLoggingCategory::defaultCategory().isDebugEnabled(), true);
+ QCOMPARE(QLoggingCategory::defaultCategory()->isDebugEnabled(), true);
- QLoggingCategory::defaultCategory().setEnabled(QtDebugMsg, false);
- QCOMPARE(QLoggingCategory::defaultCategory().isDebugEnabled(), false);
- QLoggingCategory::defaultCategory().setEnabled(QtDebugMsg, true);
+ QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, false);
+ QCOMPARE(QLoggingCategory::defaultCategory()->isDebugEnabled(), false);
+ QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true);
// make sure nothing has printed warnings
QVERIFY(logMessage.isEmpty());
@@ -300,13 +300,13 @@ private slots:
void QLoggingCategory_installFilter()
{
- QVERIFY(QLoggingCategory::defaultCategory().isDebugEnabled());
+ QVERIFY(QLoggingCategory::defaultCategory()->isDebugEnabled());
QLoggingCategory::CategoryFilter defaultFilter =
QLoggingCategory::installFilter(customCategoryFilter);
QVERIFY(defaultFilter);
customCategoryFilterArgs.clear();
- QVERIFY(!QLoggingCategory::defaultCategory().isDebugEnabled());
+ QVERIFY(!QLoggingCategory::defaultCategory()->isDebugEnabled());
QLoggingCategory cat("custom");
QCOMPARE(customCategoryFilterArgs, QStringList() << "custom");
@@ -319,7 +319,7 @@ private slots:
QCOMPARE((void*)currentFilter, (void*)customCategoryFilter);
QCOMPARE(customCategoryFilterArgs.size(), 0);
- QVERIFY(QLoggingCategory::defaultCategory().isDebugEnabled());
+ QVERIFY(QLoggingCategory::defaultCategory()->isDebugEnabled());
QVERIFY(!cat.isDebugEnabled());
// install default filter
@@ -328,7 +328,7 @@ private slots:
QCOMPARE((void*)defaultFilter, (void*)currentFilter);
QCOMPARE(customCategoryFilterArgs.size(), 0);
- QVERIFY(QLoggingCategory::defaultCategory().isDebugEnabled());
+ QVERIFY(QLoggingCategory::defaultCategory()->isDebugEnabled());
QVERIFY(!cat.isDebugEnabled());
}
diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
index d9a0f51f3e..b020a50346 100644
--- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
+++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
@@ -514,20 +514,20 @@ void tst_QSettings::ctor()
QSettings settings5(format, QSettings::UserScope, "SoftWare.ORG", "killerApp");
if (format == QSettings::NativeFormat) {
#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN)
-# ifdef Q_OS_MACX
+# ifdef Q_OS_OSX
if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_8)
QEXPECT_FAIL("native", "See QTBUG-32655", Continue);
-# endif // Q_OS_MACX
+# endif // Q_OS_OSX
QCOMPARE(settings5.value("key 1").toString(), QString("gurgle"));
#else
QVERIFY(!settings5.contains("key 1"));
#endif
} else {
#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN)
-# ifdef Q_OS_MACX
+# ifdef Q_OS_OSX
if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_8)
QEXPECT_FAIL("", "See QTBUG-32655", Continue);
-# endif // Q_OS_MACX
+# endif // Q_OS_OSX
QCOMPARE(settings5.value("key 1").toString(), QString("gurgle"));
#else
QVERIFY(!settings5.contains("key 1"));
@@ -3183,7 +3183,7 @@ void tst_QSettings::rainersSyncBugOnMac()
{
QSettings s3(format, QSettings::UserScope, "software.org", "KillerAPP");
-#ifdef Q_OS_MACX
+#ifdef Q_OS_OSX
if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_8)
QEXPECT_FAIL("native", "See QTBUG-32655", Continue);
#endif
diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
index 75b17df759..d3a8bcfd13 100644
--- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
+++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
@@ -964,8 +964,10 @@ void tst_QUrlInternal::encodingRecode_data()
addUtf8Data("utf8-string-2", "\xDF\xBF\xE0\xA0\x80""A");
addUtf8Data("utf8-string-3", "\xE0\xA0\x80\xDF\xBF...");
+ QTest::newRow("encode-unicode-noncharacter") << QString(QChar(0xffff)) << F(QUrl::FullyEncoded) << "%EF%BF%BF";
+ QTest::newRow("decode-unicode-noncharacter") << QString(QChar(0xffff)) << F(QUrl::PrettyDecoded) << QString::fromUtf8("\xEF\xBF\xBF");
+
// special cases: stuff we can encode, but not decode
- QTest::newRow("unicode-noncharacter") << QString(QChar(0xffff)) << F(QUrl::FullyEncoded) << "%EF%BF%BF";
QTest::newRow("unicode-lo-surrogate") << QString(QChar(0xD800)) << F(QUrl::FullyEncoded) << "%ED%A0%80";
QTest::newRow("unicode-hi-surrogate") << QString(QChar(0xDC00)) << F(QUrl::FullyEncoded) << "%ED%B0%80";
@@ -1011,9 +1013,6 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8_data()
extern void loadInvalidUtf8Rows();
loadInvalidUtf8Rows();
- extern void loadNonCharactersRows();
- loadNonCharactersRows();
-
QTest::newRow("utf8-mix-4") << QByteArray("\xE0.A2\x80");
QTest::newRow("utf8-mix-5") << QByteArray("\xE0\xA2.80");
QTest::newRow("utf8-mix-6") << QByteArray("\xE0\xA2\x33");
diff --git a/tests/auto/corelib/itemmodels/itemmodels.pro b/tests/auto/corelib/itemmodels/itemmodels.pro
index 3f726692ff..7e0e3a0944 100644
--- a/tests/auto/corelib/itemmodels/itemmodels.pro
+++ b/tests/auto/corelib/itemmodels/itemmodels.pro
@@ -1,10 +1,12 @@
TEMPLATE=subdirs
SUBDIRS = qabstractitemmodel \
+ qstringlistmodel \
+
+qtHaveModule(gui): SUBDIRS += \
qabstractproxymodel \
qidentityproxymodel \
qitemselectionmodel \
- qstringlistmodel \
qtHaveModule(widgets): SUBDIRS += \
qitemmodel \
diff --git a/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro b/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro
index ef36f8d7fc..ef571de192 100644
--- a/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro
+++ b/tests/auto/corelib/itemmodels/qabstractitemmodel/qabstractitemmodel.pro
@@ -1,7 +1,7 @@
CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qabstractitemmodel
-QT += testlib
+QT = core testlib
mtdir = ../../../other/modeltest
INCLUDEPATH += $$PWD/$${mtdir}
diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp
index 9dbd6414ad..c79e7273c0 100644
--- a/tests/auto/corelib/json/tst_qtjson.cpp
+++ b/tests/auto/corelib/json/tst_qtjson.cpp
@@ -47,7 +47,8 @@
#include "qjsondocument.h"
#include <limits>
-#define INVALID_UNICODE "\357\277\277" // "\uffff"
+#define INVALID_UNICODE "\xCE\xBA\xE1"
+#define UNICODE_NON_CHARACTER "\xEF\xBF\xBF"
#define UNICODE_DJE "\320\202" // Character from the Serbian Cyrillic alphabet
class tst_QtJson: public QObject
@@ -1306,6 +1307,19 @@ void tst_QtJson::fromJson()
QCOMPARE(doc.toJson(), json);
}
{
+ //regression test: test if unicode_control_characters are correctly decoded
+ QByteArray json = "[\n \"" UNICODE_NON_CHARACTER "\"\n]\n";
+ QJsonDocument doc = QJsonDocument::fromJson(json);
+ QVERIFY(!doc.isEmpty());
+ QCOMPARE(doc.isArray(), true);
+ QCOMPARE(doc.isObject(), false);
+ QJsonArray array = doc.array();
+ QCOMPARE(array.size(), 1);
+ QCOMPARE(array.at(0).type(), QJsonValue::String);
+ QCOMPARE(array.at(0).toString(), QString::fromUtf8(UNICODE_NON_CHARACTER));
+ QCOMPARE(doc.toJson(), json);
+ }
+ {
QByteArray json = "[]";
QJsonDocument doc = QJsonDocument::fromJson(json);
QVERIFY(!doc.isEmpty());
@@ -1532,7 +1546,7 @@ void tst_QtJson::fromJsonErrors()
QJsonDocument doc = QJsonDocument::fromJson(json, &error);
QVERIFY(doc.isEmpty());
QCOMPARE(error.error, QJsonParseError::IllegalUTF8String);
- QCOMPARE(error.offset, 13);
+ QCOMPARE(error.offset, 14);
}
{
QJsonParseError error;
@@ -1556,7 +1570,7 @@ void tst_QtJson::fromJsonErrors()
QJsonDocument doc = QJsonDocument::fromJson(json, &error);
QVERIFY(doc.isEmpty());
QCOMPARE(error.error, QJsonParseError::IllegalUTF8String);
- QCOMPARE(error.offset, 14);
+ QCOMPARE(error.offset, 15);
}
{
QJsonParseError error;
@@ -1702,6 +1716,7 @@ void tst_QtJson::parseStrings()
"abc\\tabc",
"abc\\u0019abc",
"abc" UNICODE_DJE "abc",
+ UNICODE_NON_CHARACTER
};
int size = sizeof(strings)/sizeof(const char *);
@@ -1728,7 +1743,8 @@ void tst_QtJson::parseStrings()
Pairs pairs [] = {
{ "abc\\/abc", "abc/abc" },
{ "abc\\u0402abc", "abc" UNICODE_DJE "abc" },
- { "abc\\u0065abc", "abceabc" }
+ { "abc\\u0065abc", "abceabc" },
+ { "abc\\uFFFFabc", "abc" UNICODE_NON_CHARACTER "abc" }
};
size = sizeof(pairs)/sizeof(Pairs);
diff --git a/tests/auto/corelib/kernel/kernel.pro b/tests/auto/corelib/kernel/kernel.pro
index 2f3c02332d..c1b867e6eb 100644
--- a/tests/auto/corelib/kernel/kernel.pro
+++ b/tests/auto/corelib/kernel/kernel.pro
@@ -21,6 +21,9 @@ SUBDIRS=\
qvariant \
qwineventnotifier
+!qtHaveModule(gui): SUBDIRS -= \
+ qmimedata
+
!qtHaveModule(network): SUBDIRS -= \
qeventloop \
qobject \
diff --git a/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro b/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro
index 0800b71c22..509ade6e2a 100644
--- a/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro
+++ b/tests/auto/corelib/kernel/qmetaobject/qmetaobject.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qmetaobject
-QT = core-private gui testlib
+QT = core-private testlib
SOURCES = tst_qmetaobject.cpp
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
index 4f1320e375..870e65f0cc 100644
--- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
+++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp
@@ -43,7 +43,7 @@
#include <qobject.h>
#include <qmetaobject.h>
-#include <qwindow.h>
+#include <qabstractproxymodel.h>
#include <private/qmetaobject_p.h>
Q_DECLARE_METATYPE(const QMetaObject *)
@@ -746,13 +746,13 @@ void tst_QMetaObject::invokeBlockingQueuedMetaMember()
void tst_QMetaObject::qtMetaObjectInheritance()
{
QVERIFY(QObject::staticMetaObject.superClass() == 0);
- QCOMPARE(QWindow::staticMetaObject.indexOfEnumerator("Qt::ScreenOrientation"), -1);
- QCOMPARE(QWindow::staticMetaObject.indexOfEnumerator("ScreenOrientation"), -1);
- int indexOfContentOrientation = QWindow::staticMetaObject.indexOfProperty("contentOrientation");
- QVERIFY(indexOfContentOrientation != -1);
- QMetaProperty contentOrientation = QWindow::staticMetaObject.property(indexOfContentOrientation);
- QVERIFY(contentOrientation.isValid());
- QCOMPARE(contentOrientation.enumerator().name(), "ScreenOrientation");
+ QCOMPARE(QSortFilterProxyModel::staticMetaObject.indexOfEnumerator("Qt::CaseSensitivity"), -1);
+ QCOMPARE(QSortFilterProxyModel::staticMetaObject.indexOfEnumerator("CaseSensitivity"), -1);
+ int indexOfSortCaseSensitivity = QSortFilterProxyModel::staticMetaObject.indexOfProperty("sortCaseSensitivity");
+ QVERIFY(indexOfSortCaseSensitivity != -1);
+ QMetaProperty sortCaseSensitivity = QSortFilterProxyModel::staticMetaObject.property(indexOfSortCaseSensitivity);
+ QVERIFY(sortCaseSensitivity.isValid());
+ QCOMPARE(sortCaseSensitivity.enumerator().name(), "CaseSensitivity");
}
struct MyType
diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro b/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro
index 9e2d3519e6..68d3b48086 100644
--- a/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro
+++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/qmetaobjectbuilder.pro
@@ -1,6 +1,6 @@
CONFIG += testcase parallel_test
TARGET = tst_qmetaobjectbuilder
-QT = core-private gui-private testlib
+QT = core-private testlib
SOURCES = tst_qmetaobjectbuilder.cpp
mac:CONFIG -= app_bundle
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/kernel/qpointer/qpointer.pro b/tests/auto/corelib/kernel/qpointer/qpointer.pro
index 8786d07292..4b573cb6a5 100644
--- a/tests/auto/corelib/kernel/qpointer/qpointer.pro
+++ b/tests/auto/corelib/kernel/qpointer/qpointer.pro
@@ -1,7 +1,7 @@
CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qpointer
-QT += testlib
+QT = core testlib
qtHaveModule(widgets): QT += widgets
SOURCES = tst_qpointer.cpp
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro b/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro
index 59660d4b07..526db5eef3 100644
--- a/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro
+++ b/tests/auto/corelib/kernel/qsignalmapper/qsignalmapper.pro
@@ -1,6 +1,6 @@
CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qsignalmapper
-QT += testlib
+QT = core testlib
SOURCES = tst_qsignalmapper.cpp
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro
index 66fe844b21..2496cd2f1e 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.pro
@@ -1,4 +1,5 @@
TEMPLATE = lib
+QT = core
CONFIG += plugin
HEADERS = plugin1.h
SOURCES = plugin1.cpp
diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro
index aec057e80c..e70ed4fb25 100644
--- a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro
+++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.pro
@@ -1,4 +1,5 @@
TEMPLATE = lib
+QT = core
CONFIG += plugin
HEADERS = plugin2.h
SOURCES = plugin2.cpp
diff --git a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro
index 9ce1ef3dcf..b2f7aaf2d3 100644
--- a/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro
+++ b/tests/auto/corelib/plugin/quuid/testProcessUniqueness/testProcessUniqueness.pro
@@ -1,4 +1,5 @@
SOURCES = main.cpp
+QT = core
CONFIG += console
DESTDIR = ./
diff --git a/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro b/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro
index b830efe3a5..f6fbbc83c6 100644
--- a/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro
+++ b/tests/auto/corelib/statemachine/qstatemachine/qstatemachine.pro
@@ -1,7 +1,7 @@
CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qstatemachine
-QT = core-private testlib gui
+QT = core-private testlib
qtHaveModule(widgets): QT += widgets
SOURCES = tst_qstatemachine.cpp
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro b/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro
index 135b1ff8c4..e23018f96a 100644
--- a/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro
+++ b/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro
@@ -1,4 +1,4 @@
TARGET = tst_qbytedatabuffer
CONFIG += testcase
-QT += core-private testlib
+QT = core-private testlib
SOURCES += tst_qbytedatabuffer.cpp
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index ffc4baa55d..8c0f32bb74 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -150,6 +150,8 @@ private slots:
void daylightTransitions() const;
void timeZones() const;
+ void invalid() const;
+
private:
bool europeanTimeZone;
QDate defDate() const { return QDate(1900, 1, 1); }
@@ -779,7 +781,11 @@ void tst_QDateTime::toString_rfcDate()
QFETCH(QDateTime, dt);
QFETCH(QString, formatted);
+ // Set to non-English locale to confirm still uses English
+ QLocale oldLocale;
+ QLocale::setDefault(QLocale("de_DE"));
QCOMPARE(dt.toString(Qt::RFC2822Date), formatted);
+ QLocale::setDefault(oldLocale);
}
void tst_QDateTime::toString_enumformat()
@@ -2902,5 +2908,24 @@ void tst_QDateTime::timeZones() const
QCOMPARE(hourAfterStd.toMSecsSinceEpoch(), dstToStdMSecs + 3600000);
}
+void tst_QDateTime::invalid() const
+{
+ QDateTime invalidDate = QDateTime(QDate(0, 0, 0), QTime(-1, -1, -1));
+ QCOMPARE(invalidDate.isValid(), false);
+ QCOMPARE(invalidDate.timeSpec(), Qt::LocalTime);
+
+ QDateTime utcDate = invalidDate.toUTC();
+ QCOMPARE(utcDate.isValid(), false);
+ QCOMPARE(utcDate.timeSpec(), Qt::UTC);
+
+ QDateTime offsetDate = invalidDate.toOffsetFromUtc(3600);
+ QCOMPARE(offsetDate.isValid(), false);
+ QCOMPARE(offsetDate.timeSpec(), Qt::OffsetFromUTC);
+
+ QDateTime tzDate = invalidDate.toTimeZone(QTimeZone("Europe/Oslo"));
+ QCOMPARE(tzDate.isValid(), false);
+ QCOMPARE(tzDate.timeSpec(), Qt::TimeZone);
+}
+
QTEST_APPLESS_MAIN(tst_QDateTime)
#include "tst_qdatetime.moc"
diff --git a/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp b/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp
index d22e771b79..ec83740196 100644
--- a/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp
+++ b/tests/auto/corelib/tools/qmargins/tst_qmargins.cpp
@@ -93,6 +93,12 @@ void tst_QMargins::operators()
a -= m2;
QCOMPARE(a, subtracted);
+ QMargins h = m1;
+ h += 2;
+ QCOMPARE(h, QMargins(14, 16, 18, 20));
+ h -= 2;
+ QCOMPARE(h, m1);
+
const QMargins doubled = m1 * 2;
QCOMPARE(doubled, QMargins(24, 28, 32, 36));
QCOMPARE(2 * m1, doubled);
diff --git a/tests/auto/corelib/tools/qtimezone/qtimezone.pro b/tests/auto/corelib/tools/qtimezone/qtimezone.pro
index 2c53100857..fa2397a6bb 100644
--- a/tests/auto/corelib/tools/qtimezone/qtimezone.pro
+++ b/tests/auto/corelib/tools/qtimezone/qtimezone.pro
@@ -1,6 +1,6 @@
CONFIG += testcase parallel_test
TARGET = tst_qtimezone
-QT += core-private testlib
+QT = core-private testlib
SOURCES = tst_qtimezone.cpp
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
contains(QT_CONFIG,icu) {
diff --git a/tests/auto/dbus/qdbusmarshall/qdbusmarshall.pro b/tests/auto/dbus/qdbusmarshall/qdbusmarshall.pro
index 0578433d58..dfbb206324 100644
--- a/tests/auto/dbus/qdbusmarshall/qdbusmarshall.pro
+++ b/tests/auto/dbus/qdbusmarshall/qdbusmarshall.pro
@@ -4,6 +4,6 @@ TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = qpong test
-QT += core-private testlib
+QT = core-private testlib
requires(contains(QT_CONFIG,private_tests))
diff --git a/tests/auto/gui/kernel/qguivariant/test/data/qpolygonf.bin b/tests/auto/gui/kernel/qguivariant/test/data/qpolygonf.bin
new file mode 100644
index 0000000000..02e749b83f
--- /dev/null
+++ b/tests/auto/gui/kernel/qguivariant/test/data/qpolygonf.bin
Binary files differ
diff --git a/tests/auto/gui/kernel/qguivariant/test/qguivariant.qrc b/tests/auto/gui/kernel/qguivariant/test/qguivariant.qrc
new file mode 100644
index 0000000000..576d9cda1c
--- /dev/null
+++ b/tests/auto/gui/kernel/qguivariant/test/qguivariant.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>data</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/gui/kernel/qguivariant/test/test.pro b/tests/auto/gui/kernel/qguivariant/test/test.pro
index 86ab17d9cd..c4123797d2 100644
--- a/tests/auto/gui/kernel/qguivariant/test/test.pro
+++ b/tests/auto/gui/kernel/qguivariant/test/test.pro
@@ -5,3 +5,4 @@ SOURCES += tst_qguivariant.cpp
RESOURCES = tst_qguivariant.qrc
INCLUDEPATH += $$PWD/../../../../other/qvariant_common
QT += testlib
+RESOURCES += qguivariant.qrc
diff --git a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp
index d5ec9fcfaa..1220ce3b23 100644
--- a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp
+++ b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp
@@ -114,6 +114,7 @@ private slots:
void writeToReadFromDataStream_data();
void writeToReadFromDataStream();
+ void writeToReadFromOldDataStream();
void colorInteger();
void invalidQColor();
@@ -527,6 +528,8 @@ void tst_QGuiVariant::writeToReadFromDataStream_data()
QTest::newRow( "pointarray_valid" ) << QVariant::fromValue( QPolygon( QRect( 10, 10, 20, 20 ) ) ) << false;
QTest::newRow( "region_invalid" ) << QVariant::fromValue( QRegion() ) << true;
QTest::newRow( "region_valid" ) << QVariant::fromValue( QRegion( 10, 10, 20, 20 ) ) << false;
+ QTest::newRow("polygonf_invalid") << QVariant::fromValue(QPolygonF()) << true;
+ QTest::newRow("polygonf_valid") << QVariant::fromValue(QPolygonF(QRectF(10, 10, 20, 20))) << false;
}
void tst_QGuiVariant::invalidQColor()
@@ -611,6 +614,46 @@ void tst_QGuiVariant::writeToReadFromDataStream()
}
}
+void tst_QGuiVariant::writeToReadFromOldDataStream()
+{
+ QPolygonF polyF(QRectF(10, 10, 50, 50));
+ QVariant testVariant(polyF);
+ {
+ // Read into a variant and compare
+ QFile file(":/data/qpolygonf.bin");
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QDataStream dataFileStream(&file);
+ dataFileStream.setVersion(QDataStream::Qt_4_9);
+ QVariant readVariant;
+ dataFileStream >> readVariant;
+ QVERIFY(readVariant.type() == QMetaType::QPolygonF);
+ QCOMPARE(testVariant, readVariant);
+ file.close();
+ }
+ {
+ QByteArray variantData;
+ {
+ QDataStream varDataStream(&variantData, QIODevice::WriteOnly);
+ varDataStream << testVariant;
+ }
+ // Read into a bytearray and compare
+ QFile file(":/data/qpolygonf.bin");
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QDataStream dataFileStream(&file);
+ dataFileStream.setVersion(QDataStream::Qt_4_9);
+ int dummy;
+ dataFileStream >> dummy;
+ QByteArray polyData49;
+ dataFileStream >> polyData49;
+ file.close();
+ QByteArray polyData50;
+ QDataStream readVarData(variantData);
+ readVarData >> dummy;
+ readVarData >> polyData50;
+ QVERIFY(polyData49 == polyData50);
+ }
+}
+
void tst_QGuiVariant::debugStream_data()
{
QTest::addColumn<QVariant>("variant");
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index 7ad7880330..c4983f4462 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -223,7 +223,7 @@ void tst_QWindow::positioning()
window.setWindowState(Qt::WindowFullScreen);
QCoreApplication::processEvents();
-#ifdef Q_OS_MACX
+#ifdef Q_OS_OSX
QEXPECT_FAIL("", "Multiple failures in this test on Mac OS X, see QTBUG-23059", Abort);
#endif
QTRY_COMPARE(window.received(QEvent::Resize), 2);
diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
index 3f6eaae89b..3d2cde5fd3 100644
--- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
+++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp
@@ -502,10 +502,10 @@ void tst_QGlyphRun::drawMultiScriptText2()
drawGlyphs.save("drawMultiScriptText2_drawGlyphIndexes.png");
#endif
-#ifdef Q_OS_MACX
+#ifdef Q_OS_OSX
if (drawGlyphs.toImage() != textLayoutDraw.toImage())
QEXPECT_FAIL("", "See QTBUG-32690", Continue);
-#endif // Q_OS_MACX
+#endif // Q_OS_OSX
QCOMPARE(drawGlyphs, textLayoutDraw);
}
diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
index 10e79065ee..b065f537f7 100644
--- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
+++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
@@ -54,6 +54,7 @@
#include <qabstracttextdocumentlayout.h>
#include <qtextlist.h>
#include <qtextcodec.h>
+#include <qguiapplication.h>
#include <qurl.h>
#include <qpainter.h>
#include <qfontmetrics.h>
@@ -113,6 +114,7 @@ private slots:
void toHtmlBodyBgColorRgba();
void toHtmlBodyBgColorTransparent();
void toHtmlRootFrameProperties();
+ void toHtmlLineHeightProperties();
void capitalizationHtmlInExport();
void wordspacingHtmlExport();
@@ -186,6 +188,9 @@ private slots:
void QTBUG27354_spaceAndSoftSpace();
void cssInheritance();
+
+ void QTBUG28998_linkColor();
+
private:
void backgroundImage_checkExpectedHtml(const QTextDocument &doc);
@@ -1856,6 +1861,25 @@ void tst_QTextDocument::toHtmlRootFrameProperties()
QCOMPARE(doc.toHtml(), expectedOutput);
}
+void tst_QTextDocument::toHtmlLineHeightProperties()
+{
+ CREATE_DOC_AND_CURSOR();
+
+ QTextBlock block = doc.firstBlock();
+ QTextBlockFormat blockFormat = block.blockFormat();
+ blockFormat.setLineHeight(200, QTextBlockFormat::ProportionalHeight);
+ cursor.setBlockFormat(blockFormat);
+
+ cursor.insertText("Blah");
+ QString expectedOutput("<p DEFAULTBLOCKSTYLE line-height:200%;\">Blah</p>");
+
+ expectedOutput.prepend(htmlHead);
+ 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);
+
+ QCOMPARE(doc.toHtml(), expectedOutput);
+}
+
void tst_QTextDocument::capitalizationHtmlInExport()
{
doc->setPlainText("Test");
@@ -2954,5 +2978,29 @@ void tst_QTextDocument::cssInheritance()
}
}
+void tst_QTextDocument::QTBUG28998_linkColor()
+{
+ QPalette pal;
+ pal.setColor(QPalette::Link, QColor("tomato"));
+ QGuiApplication::setPalette(pal);
+
+ QTextDocument doc;
+ doc.setHtml("<a href=\"http://www.qt-project.org\">Qt</a>");
+
+ QCOMPARE(doc.blockCount(), 1);
+ QTextBlock block = doc.firstBlock();
+ QVERIFY(block.isValid());
+
+ QTextFragment fragment = block.begin().fragment();
+ QVERIFY(fragment.isValid());
+
+ QTextCharFormat format = fragment.charFormat();
+ QVERIFY(format.isValid());
+ QVERIFY(format.isAnchor());
+ QCOMPARE(format.anchorHref(), QStringLiteral("http://www.qt-project.org"));
+
+ QCOMPARE(format.foreground(), pal.link());
+}
+
QTEST_MAIN(tst_QTextDocument)
#include "tst_qtextdocument.moc"
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 0e8d9fa2a3..2826c497df 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -7588,7 +7588,7 @@ void tst_QNetworkReply::backgroundRequestInterruption()
QNetworkSessionPrivate::setUsagePolicies(*const_cast<QNetworkSession *>(session.data()), original);
QVERIFY(reply->isFinished());
-#ifdef Q_OS_MACX
+#ifdef Q_OS_OSX
if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_8)
QEXPECT_FAIL("ftp, bg, nobg", "See QTBUG-32435", Abort);
#endif
diff --git a/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp b/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp
index 9e03884e4e..1271bf38ca 100644
--- a/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp
+++ b/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp
@@ -380,7 +380,7 @@ void tst_QNetworkProxyFactory::genericSystemProxy()
QFETCH(int, port);
// The generic system proxy is only available on the following platforms
-#if (!defined Q_OS_BLACKBERRY) && (!defined Q_OS_WIN) && (!defined Q_OS_MACX)
+#if (!defined Q_OS_BLACKBERRY) && (!defined Q_OS_WIN) && (!defined Q_OS_OSX)
qputenv(envVar, url);
const QList<QNetworkProxy> systemProxy = QNetworkProxyFactory::systemProxyForQuery();
QCOMPARE(systemProxy.size(), 1);
diff --git a/tests/auto/other/modeltest/modeltest.cpp b/tests/auto/other/modeltest/modeltest.cpp
index d356b26c54..a5233c4c3a 100644
--- a/tests/auto/other/modeltest/modeltest.cpp
+++ b/tests/auto/other/modeltest/modeltest.cpp
@@ -39,11 +39,9 @@
**
****************************************************************************/
-
-#include <QtGui/QtGui>
-
#include "modeltest.h"
+#include <QtCore/QtCore>
#include <QtTest/QtTest>
/*!
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 092995c0aa..73bf4aab6a 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -3056,60 +3056,127 @@ void tst_QAccessibility::dockWidgetTest()
mw->setMenuBar(mb);
QDockWidget *dock1 = new QDockWidget(mw);
+ dock1->setWindowTitle("Dock 1");
mw->addDockWidget(Qt::LeftDockWidgetArea, dock1);
QPushButton *pb1 = new QPushButton(tr("Push me"), dock1);
dock1->setWidget(pb1);
QDockWidget *dock2 = new QDockWidget(mw);
+ dock2->setWindowTitle("Dock 2");
mw->addDockWidget(Qt::BottomDockWidgetArea, dock2);
QPushButton *pb2 = new QPushButton(tr("Push me"), dock2);
dock2->setWidget(pb2);
+ dock2->setFeatures(QDockWidget::DockWidgetClosable);
mw->resize(600,400);
mw->show();
-#if defined(Q_OS_UNIX)
- QCoreApplication::processEvents();
- QTest::qWait(100);
-#endif
+ QTest::qWaitForWindowExposed(mw);
QAccessibleInterface *accMainWindow = QAccessible::queryAccessibleInterface(mw);
// 4 children: menu bar, dock1, dock2, and central widget
QCOMPARE(accMainWindow->childCount(), 4);
QAccessibleInterface *accDock1 = 0;
+ QAccessibleInterface *accDock2 = 0;
for (int i = 0; i < 4; ++i) {
- accDock1 = accMainWindow->child(i);
- if (accMainWindow->role() == QAccessible::Window) {
- if (accDock1 && qobject_cast<QDockWidget*>(accDock1->object()) == dock1) {
- break;
- }
- }
+ QAccessibleInterface *child = accMainWindow->child(i);
+ if (child && child->object() == dock1)
+ accDock1 = child;
+ if (child && child->object() == dock2)
+ accDock2 = child;
}
+
+ // Dock widgets consist of
+ // 0 contents
+ // 1 close button
+ // 2 float button
QVERIFY(accDock1);
QCOMPARE(accDock1->role(), QAccessible::Window);
+ QCOMPARE(accDock1->text(QAccessible::Name), dock1->windowTitle());
+ QCOMPARE(accDock1->childCount(), 3);
+
+ QAccessibleInterface *dock1Widget = accDock1->child(0);
+ QCOMPARE(dock1Widget->role(), QAccessible::Button);
+ QCOMPARE(dock1Widget->text(QAccessible::Name), pb1->text());
+
+#ifdef Q_OS_MAC
+ QEXPECT_FAIL("", "Dock Widget geometry on Mac seems broken.", Continue);
+#endif
+ QVERIFY(accDock1->rect().contains(dock1Widget->rect()));
+ QCOMPARE(accDock1->indexOfChild(dock1Widget), 0);
+ QCOMPARE(dock1Widget->parent()->object(), dock1);
+
+ QAccessibleInterface *dock1Close = accDock1->child(1);
+ QCOMPARE(dock1Close->role(), QAccessible::Button);
+ QCOMPARE(dock1Close->text(QAccessible::Name), QDockWidget::tr("Close"));
+ QVERIFY(accDock1->rect().contains(dock1Close->rect()));
+ QCOMPARE(accDock1->indexOfChild(dock1Close), 1);
+ QCOMPARE(dock1Close->parent()->object(), dock1);
+
+ QAccessibleInterface *dock1Float = accDock1->child(2);
+ QCOMPARE(dock1Float->role(), QAccessible::Button);
+ QCOMPARE(dock1Float->text(QAccessible::Name), QDockWidget::tr("Float"));
+ QVERIFY(accDock1->rect().contains(dock1Float->rect()));
+ QCOMPARE(accDock1->indexOfChild(dock1Float), 2);
+ QVERIFY(!dock1Float->state().invisible);
+
+ QVERIFY(accDock2);
+ QCOMPARE(accDock2->role(), QAccessible::Window);
+ QCOMPARE(accDock2->text(QAccessible::Name), dock2->windowTitle());
+ QCOMPARE(accDock2->childCount(), 3);
+
+ QAccessibleInterface *dock2Widget = accDock2->child(0);
+ QCOMPARE(dock2Widget->role(), QAccessible::Button);
+ QCOMPARE(dock2Widget->text(QAccessible::Name), pb1->text());
+#ifdef Q_OS_MAC
+ QEXPECT_FAIL("", "Dock Widget geometry on Mac seems broken.", Continue);
+#endif
+ QVERIFY(accDock2->rect().contains(dock2Widget->rect()));
+ QCOMPARE(accDock2->indexOfChild(dock2Widget), 0);
+
+ QAccessibleInterface *dock2Close = accDock2->child(1);
+ QCOMPARE(dock2Close->role(), QAccessible::Button);
+ QCOMPARE(dock2Close->text(QAccessible::Name), QDockWidget::tr("Close"));
+ QVERIFY(accDock2->rect().contains(dock2Close->rect()));
+ QCOMPARE(accDock2->indexOfChild(dock2Close), 1);
+ QVERIFY(!dock2Close->state().invisible);
+
+ QAccessibleInterface *dock2Float = accDock2->child(2);
+ QCOMPARE(dock2Float->role(), QAccessible::Button);
+ QCOMPARE(dock2Float->text(QAccessible::Name), QDockWidget::tr("Float"));
+ QCOMPARE(accDock2->indexOfChild(dock2Float), 2);
+ QVERIFY(dock2Float->state().invisible);
+
+ QPoint buttonPoint = pb2->mapToGlobal(QPoint(pb2->width()/2, pb2->height()/2));
+ QAccessibleInterface *childAt = accDock2->childAt(buttonPoint.x(), buttonPoint.y());
+ QVERIFY(childAt);
+ QVERIFY(childAt->object() == pb2);
+
+ QWidget *close1 = qobject_cast<QWidget*>(dock1Close->object());
+ QPoint close1ButtonPoint = close1->mapToGlobal(QPoint(close1->width()/2, close1->height()/2));
+ QAccessibleInterface *childAt2 = accDock1->childAt(close1ButtonPoint.x(), close1ButtonPoint.y());
+ QVERIFY(childAt2);
+ QVERIFY(childAt2->object() == close1);
+
+ // custom title bar widget
+ QDockWidget *dock3 = new QDockWidget(mw);
+ dock3->setWindowTitle("Dock 3");
+ mw->addDockWidget(Qt::LeftDockWidgetArea, dock3);
+ QPushButton *pb3 = new QPushButton(tr("Push me"), dock3);
+ dock3->setWidget(pb3);
+ QLabel *titleLabel = new QLabel("I am a title widget");
+ dock3->setTitleBarWidget(titleLabel);
+
+ QAccessibleInterface *accDock3 = accMainWindow->child(4);
+ QVERIFY(accDock3);
+ QCOMPARE(accDock3->role(), QAccessible::Window);
+ QCOMPARE(accDock3->text(QAccessible::Name), dock3->windowTitle());
+ QCOMPARE(accDock3->childCount(), 2);
+ QAccessibleInterface *titleWidget = accDock3->child(1);
+ QVERIFY(titleWidget);
+ QCOMPARE(titleWidget->text(QAccessible::Name), titleLabel->text());
+ QAccessibleInterface *dock3Widget = accDock3->child(0);
+ QCOMPARE(dock3Widget->text(QAccessible::Name), pb3->text());
- QAccessibleInterface *dock1TitleBar = accDock1->child(0);
- QCOMPARE(dock1TitleBar->role(), QAccessible::TitleBar);
- QVERIFY(accDock1->rect().contains(dock1TitleBar->rect()));
-
- QPoint globalPos = dock1->mapToGlobal(QPoint(0,0));
- globalPos.rx()+=5; //### query style
- globalPos.ry()+=5;
- QAccessibleInterface *childAt = accDock1->childAt(globalPos.x(), globalPos.y()); //###
- QCOMPARE(childAt->role(), QAccessible::TitleBar);
- int index = accDock1->indexOfChild(childAt);
- QAccessibleInterface *accTitleBar = accDock1->child(index);
-
- QCOMPARE(accTitleBar->role(), QAccessible::TitleBar);
- QCOMPARE(accDock1->indexOfChild(accTitleBar), 0);
- QAccessibleInterface *acc;
- acc = accTitleBar->parent();
- QVERIFY(acc);
- QCOMPARE(acc->role(), QAccessible::Window);
-
- delete pb1;
- delete pb2;
- delete dock1;
- delete dock2;
delete mw;
QTestAccessibility::clearEvents();
#endif // QT_NO_DOCKWIDGET
@@ -3228,7 +3295,7 @@ void tst_QAccessibility::labelTest()
QCOMPARE(imageInterface->imageSize(), testPixmap.size());
QCOMPARE(imageInterface->imageDescription(), QString::fromLatin1("Test Description"));
const QPoint labelPos = imageLabel.mapToGlobal(QPoint(0,0));
- QCOMPARE(imageInterface->imagePosition().topLeft(), labelPos);
+ QCOMPARE(imageInterface->imagePosition(), labelPos);
QTestAccessibility::clearEvents();
}
diff --git a/tests/auto/testlib/selftests/cmptest/cmptest.pro b/tests/auto/testlib/selftests/cmptest/cmptest.pro
index a793c203dd..2d5dd071a9 100644
--- a/tests/auto/testlib/selftests/cmptest/cmptest.pro
+++ b/tests/auto/testlib/selftests/cmptest/cmptest.pro
@@ -1,5 +1,6 @@
SOURCES += tst_cmptest.cpp
-QT = core gui testlib
+QT = core testlib
+qtHaveModule(gui): QT += gui
mac:CONFIG -= app_bundle
CONFIG -= debug_and_release_target
diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
index e9ad1778fa..9f8343b57a 100644
--- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
+++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp
@@ -42,8 +42,10 @@
#include <QtCore/QCoreApplication>
#include <QtTest/QtTest>
+#ifdef QT_GUI_LIB
#include <QtGui/QImage>
#include <QtGui/QPixmap>
+#endif
/* XPM test data for QPixmap, QImage tests (use drag cursors as example) */
@@ -138,10 +140,12 @@ private slots:
void compareQStringLists_data();
void compareQListInt();
void compareQListDouble();
+#ifdef QT_GUI_LIB
void compareQPixmaps();
void compareQPixmaps_data();
void compareQImages();
void compareQImages_data();
+#endif
};
static bool boolfunc() { return true; }
@@ -323,6 +327,7 @@ void tst_Cmptest::compareQListDouble()
QCOMPARE(double1, double2);
}
+#ifdef QT_GUI_LIB
void tst_Cmptest::compareQPixmaps_data()
{
QTest::addColumn<QPixmap>("opA");
@@ -374,6 +379,7 @@ void tst_Cmptest::compareQImages()
QCOMPARE(opA, opB);
}
+#endif
QTEST_MAIN(tst_Cmptest)
#include "tst_cmptest.moc"
diff --git a/tests/auto/tools/qmake/testdata/json/json.pro b/tests/auto/tools/qmake/testdata/json/json.pro
new file mode 100644
index 0000000000..33440b3209
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/json/json.pro
@@ -0,0 +1,26 @@
+jsontext = $$cat($$PWD/test.json)
+parseJson(jsontext, json)
+
+# print all keys
+message(json._KEYS_ $${json._KEYS_})
+
+# print array
+message(json.array._KEYS_ $${json.array._KEYS_})
+for(key, json.array._KEYS_): \
+ message(json.array.$${key} $$eval(json.array.$${key}))
+
+# print object
+message(json.object._KEYS_ $${json.object._KEYS_})
+for(key, json.object._KEYS_): \
+ message(json.object.$${key} $$eval(json.object.$${key}))
+
+# print value tyes
+message(json.string: $${json.string})
+message(json.number: $${json.number})
+message(json.true: $${json.true})
+message(json.false: $${json.false})
+message(json.null: $${json.null})
+
+# check that booleans work
+$${json.true}: message(json.true is true)
+!$${json.false}: message(json.false is false)
diff --git a/tests/auto/tools/qmake/testdata/json/test.json b/tests/auto/tools/qmake/testdata/json/test.json
new file mode 100644
index 0000000000..cc82908eba
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/json/test.json
@@ -0,0 +1,9 @@
+{
+ "array" : ["arrayItem1", "arrayItem2", "arrayItem3"],
+ "object" : { "key1" : "objectValue1", "key2" : "objectValue2" },
+ "string" : "test string",
+ "number" : 999,
+ "true" : true,
+ "false" :false,
+ "null" : null
+}
diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp
index cf5c75a66b..87e86406b8 100644
--- a/tests/auto/tools/qmake/tst_qmake.cpp
+++ b/tests/auto/tools/qmake/tst_qmake.cpp
@@ -92,6 +92,7 @@ private slots:
void substitutes();
void project();
void proFileCache();
+ void json();
private:
TestCompiler test_compiler;
@@ -556,5 +557,33 @@ void tst_qmake::proFileCache()
QVERIFY( test_compiler.qmake( workDir, "pro_file_cache" ));
}
+void tst_qmake::json()
+{
+ QString workDir = base_path + "/testdata/json";
+ QVERIFY( test_compiler.qmake( workDir, "json.pro" ));
+ QString output = test_compiler.commandOutput();
+
+ // all keys
+ QVERIFY(output.contains("json._KEYS_ array false null number object string true"));
+ // array
+ QVERIFY(output.contains("json.array._KEYS_ 0 1 2"));
+ QVERIFY(output.contains("json.array.0 arrayItem1"));
+ QVERIFY(output.contains("json.array.1 arrayItem2"));
+ QVERIFY(output.contains("json.array.2 arrayItem3"));
+ // object
+ QVERIFY(output.contains("json.object._KEYS_ key1 key2"));
+ QVERIFY(output.contains("json.object.key1 objectValue1"));
+ QVERIFY(output.contains("json.object.key1 objectValue1"));
+ // value types
+ QVERIFY(output.contains("json.string: test string"));
+ QVERIFY(output.contains("json.number: 999"));
+ QVERIFY(output.contains("json.true: true"));
+ QVERIFY(output.contains("json.false: false"));
+ QVERIFY(output.contains("json.null:"));
+ // functional booleans
+ QVERIFY(output.contains("json.true is true"));
+ QVERIFY(output.contains("json.false is false"));
+}
+
QTEST_MAIN(tst_qmake)
#include "tst_qmake.moc"
diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
index 81b69f6b89..8bad4bb176 100644
--- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
@@ -66,6 +66,8 @@
#include <private/qfilesystemmodel_p.h>
#include <private/qfiledialog_p.h>
#endif
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformtheme.h>
#include <QFileDialog>
#include <QFileSystemModel>
@@ -145,6 +147,7 @@ private slots:
void clearLineEdit();
void enableChooseButton();
void hooks();
+ void widgetlessNativeDialog();
#ifdef Q_OS_UNIX
#ifdef QT_BUILD_INTERNAL
void tildeExpansion_data();
@@ -1396,6 +1399,20 @@ void tst_QFiledialog::hooks()
QCOMPARE(QFileDialog::getSaveFileUrl(), QUrl("http://saveUrl"));
}
+void tst_QFiledialog::widgetlessNativeDialog()
+{
+ if (!QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(QPlatformTheme::FileDialog))
+ QSKIP("This platform always uses widgets to realize its QFileDialog, instead of the native file dialog.");
+ QFileDialog fd;
+ fd.setWindowModality(Qt::ApplicationModal);
+ fd.show();
+ QTRY_VERIFY(fd.isVisible());
+ QFileSystemModel *model = fd.findChild<QFileSystemModel*>("qt_filesystem_model");
+ QVERIFY(!model);
+ QPushButton *button = fd.findChild<QPushButton*>();
+ QVERIFY(!button);
+}
+
#ifdef Q_OS_UNIX
#ifdef QT_BUILD_INTERNAL
void tst_QFiledialog::tildeExpansion_data()
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
index e24a1dfc96..816d375b97 100644
--- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -115,6 +115,7 @@ private slots:
void sort();
void mkdir();
+ void deleteFile();
void caseSensitivity();
@@ -934,6 +935,25 @@ void tst_QFileSystemModel::mkdir()
QCOMPARE(oldRow, idx.row());
}
+void tst_QFileSystemModel::deleteFile()
+{
+ QString newFilePath = QDir::temp().filePath("NewFileDeleteTest");
+ QFile newFile(newFilePath);
+ if (newFile.exists()) {
+ if (!newFile.remove())
+ qWarning() << "unable to remove" << newFilePath;
+ QTest::qWait(WAITTIME);
+ }
+ if (!newFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ qWarning() << "unable to create" << newFilePath;
+ }
+ newFile.close();
+ QModelIndex idx = model->index(newFilePath);
+ QVERIFY(idx.isValid());
+ QVERIFY(model->remove(idx));
+ QVERIFY(!newFile.exists());
+}
+
void tst_QFileSystemModel::caseSensitivity()
{
QString tmp = flatDirTestPath;
diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
index c240b5eb35..4506d0af14 100644
--- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
+++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
@@ -439,7 +439,7 @@ void tst_QWizard::setPixmap()
QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull());
QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull());
QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull());
-#ifdef Q_OS_MACX
+#ifdef Q_OS_OSX
QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false);
#else
QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull());
@@ -448,7 +448,7 @@ void tst_QWizard::setPixmap()
QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull());
QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull());
QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull());
-#ifdef Q_OS_MACX
+#ifdef Q_OS_OSX
QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false);
#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 70cfbc8856..4f25aab32a 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -5089,6 +5089,10 @@ public:
void tst_QGraphicsItem::paint()
{
+#ifdef Q_OS_MACX
+ if (QSysInfo::MacintoshVersion == QSysInfo::MV_10_7)
+ QSKIP("QTBUG-31454 - Unstable auto-test");
+#endif
QGraphicsScene scene;
PaintTester paintTester;
diff --git a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp
index 2d9cb98e27..c17a03e058 100644
--- a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp
+++ b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp
@@ -68,8 +68,6 @@ public:
int numberOfObscures;
};
-
-
class tst_QWindowContainer: public QObject
{
Q_OBJECT
@@ -81,6 +79,7 @@ private slots:
void testBehindTheScenesDeletion();
void testUnparenting();
void testActivation();
+ void testAncestorChange();
};
@@ -188,6 +187,7 @@ void tst_QWindowContainer::testActivation()
root.show();
root.activateWindow();
+ QVERIFY(QTest::qWaitForWindowExposed(&root));
QVERIFY(QTest::qWaitForWindowActive(root.windowHandle()));
QVERIFY(QGuiApplication::focusWindow() == root.windowHandle());
@@ -204,8 +204,7 @@ void tst_QWindowContainer::testActivation()
QTest::qWait(100);
window->requestActivate();
- QVERIFY(QTest::qWaitForWindowActive(window));
- QVERIFY(QGuiApplication::focusWindow() == window);
+ QTRY_VERIFY(QGuiApplication::focusWindow() == window);
// Verify that all states in the root widget still indicate it is active
QVERIFY(root.windowHandle()->isActive());
@@ -231,6 +230,61 @@ void tst_QWindowContainer::testUnparenting()
QVERIFY(!window->isVisible());
}
+void tst_QWindowContainer::testAncestorChange()
+{
+ QWidget root;
+ QWidget *left = new QWidget(&root);
+ QWidget *right = new QWidget(&root);
+
+ root.setGeometry(0, 0, 200, 100);
+ left->setGeometry(0, 0, 100, 100);
+ right->setGeometry(100, 0, 100, 100);
+
+ QWindow *window = new QWindow();
+ QWidget *container = QWidget::createWindowContainer(window, left);
+ container->setGeometry(0, 0, 100, 100);
+
+ // Root
+ // + left
+ // | + container
+ // | + window
+ // + right
+ root.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&root));
+ QCOMPARE(window->geometry(), QRect(0, 0, 100, 100));
+
+ container->setParent(right);
+ // Root
+ // + left
+ // + right
+ // + container
+ // + window
+ QCOMPARE(window->geometry(), QRect(100, 0, 100, 100));
+
+ QWidget *newRoot = new QWidget(&root);
+ newRoot->setGeometry(50, 50, 200, 200);
+ right->setParent(newRoot);
+ // Root
+ // + left
+ // + newRoot
+ // + right
+ // + container
+ // + window
+ QCOMPARE(window->geometry(), QRect(150, 50, 100, 100));
+ newRoot->move(0, 0);
+ QCOMPARE(window->geometry(), QRect(100, 0, 100, 100));
+
+ newRoot->setParent(0);
+ newRoot->setGeometry(100, 100, 200, 200);
+ newRoot->show();
+ QVERIFY(QTest::qWaitForWindowExposed(newRoot));
+ // newRoot
+ // + right
+ // + container
+ // + window
+ QCOMPARE(window->geometry(), QRect(100, 0, 100, 100));
+}
+
QTEST_MAIN(tst_QWindowContainer)
#include "tst_qwindowcontainer.moc"
diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
index 4631154230..eabb7aaa17 100644
--- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
@@ -2587,6 +2587,18 @@ void tst_QComboBox::resetModel()
}
+static inline void centerCursor(const QWidget *w)
+{
+#ifndef QT_NO_CURSOR
+ // Force cursor movement to prevent QCursor::setPos() from returning prematurely on QPA:
+ const QPoint target(w->mapToGlobal(w->rect().center()));
+ QCursor::setPos(QPoint(target.x() + 1, target.y()));
+ QCursor::setPos(target);
+#else // !QT_NO_CURSOR
+ Q_UNUSED(w)
+#endif
+}
+
void tst_QComboBox::keyBoardNavigationWithMouse()
{
QComboBox combo;
@@ -2597,6 +2609,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse()
combo.addItem( QString::number(i));
combo.show();
+ centerCursor(&combo); // QTBUG-33973, cursor needs to be within view from start on Mac.
QApplication::setActiveWindow(&combo);
QVERIFY(QTest::qWaitForWindowActive(&combo));
QCOMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&combo));
@@ -2617,10 +2630,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse()
// When calling cursor function, Windows CE responds with: This function is not supported on this system.
#ifndef Q_OS_WINCE
// Force cursor movement to prevent QCursor::setPos() from returning prematurely on QPA:
- const QPoint target(combo.view()->mapToGlobal(combo.view()->rect().center()));
- QCursor::setPos(QPoint(target.x() + 1, target.y()));
- QCursor::setPos(target);
-
+ centerCursor(combo.view());
QTest::qWait(200);
#define GET_SELECTION(SEL) \
@@ -2632,7 +2642,7 @@ void tst_QComboBox::keyBoardNavigationWithMouse()
GET_SELECTION(selection);
//since we moved the mouse is in the middle it should even be around 5;
- QVERIFY(selection > 3);
+ QVERIFY2(selection > 3, (QByteArrayLiteral("selection=") + QByteArray::number(selection)).constData());
static const int final = 40;
for (int i = selection + 1; i <= final; i++)
diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
index 3c32b8a476..7c1bb957d6 100644
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -764,14 +764,20 @@ void tst_QMenu::task258920_mouseBorder()
menu.setMouseTracking(true);
QAction *action = menu.addAction("test");
- menu.popup(QApplication::desktop()->availableGeometry().center());
+ const QPoint center = QApplication::desktop()->availableGeometry().center();
+#ifndef QT_NO_CURSOR
+ QCursor::setPos(center - QPoint(100, 100)); // Mac: Ensure cursor is outside
+#endif
+ menu.popup(center);
QVERIFY(QTest::qWaitForWindowExposed(&menu));
QTest::qWait(100);
QRect actionRect = menu.actionGeometry(action);
- QTest::mouseMove(&menu, actionRect.center());
+ const QPoint actionCenter = actionRect.center();
+ QTest::mouseMove(&menu, actionCenter - QPoint(-10, 0));
QTest::qWait(30);
- QTest::mouseMove(&menu, actionRect.center() + QPoint(10, 0));
+ QTest::mouseMove(&menu, actionCenter);
QTest::qWait(30);
+ QTest::mouseMove(&menu, actionCenter + QPoint(10, 0));
QTRY_COMPARE(action, menu.activeAction());
menu.painted = false;
QTest::mouseMove(&menu, QPoint(actionRect.center().x(), actionRect.bottom() + 1));
diff --git a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp
index 3bdf583153..a301d51c4c 100644
--- a/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp
+++ b/tests/auto/widgets/widgets/qstatusbar/tst_qstatusbar.cpp
@@ -74,6 +74,7 @@ private slots:
void task194017_hiddenWidget();
void QTBUG4334_hiddenOnMaximizedWindow();
void QTBUG25492_msgtimeout();
+ void messageChangedSignal();
private:
QStatusBar *testWidget;
@@ -95,6 +96,8 @@ void tst_QStatusBar::init()
QWidget *item1 = new QWidget(testWidget);
testWidget->addWidget(item1);
+ // currentMessage needs to be null as the code relies on this
+ currentMessage = QString();
}
void tst_QStatusBar::cleanup()
@@ -316,6 +319,30 @@ void tst_QStatusBar::QTBUG25492_msgtimeout()
QCOMPARE(testWidget->currentMessage(), currentMessage);
}
+void tst_QStatusBar::messageChangedSignal()
+{
+ QVERIFY(testWidget->currentMessage().isNull());
+ QVERIFY(currentMessage.isNull());
+ testWidget->show();
+
+ QSignalSpy spy(testWidget, SIGNAL(messageChanged(QString)));
+ testWidget->showMessage("Ready", 0);
+ QCOMPARE(testWidget->currentMessage(), QString("Ready"));
+ QCOMPARE(testWidget->currentMessage(), currentMessage);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().at(0).toString(), currentMessage);
+ testWidget->clearMessage();
+ QCOMPARE(testWidget->currentMessage(), QString());
+ QCOMPARE(testWidget->currentMessage(), currentMessage);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().at(0).toString(), currentMessage);
+ testWidget->showMessage("Ready", 0);
+ testWidget->showMessage("Ready", 0);
+ QCOMPARE(testWidget->currentMessage(), QString("Ready"));
+ QCOMPARE(testWidget->currentMessage(), currentMessage);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().at(0).toString(), currentMessage);
+}
QTEST_MAIN(tst_QStatusBar)
#include "tst_qstatusbar.moc"
diff --git a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
index d4c0ff44ca..f09fbff6c4 100644
--- a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
+++ b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
@@ -315,9 +315,7 @@ void tst_QXmlSimpleReader::testGoodXmlFile()
QVERIFY(file.open(QIODevice::ReadOnly));
Parser parser;
-// static int i = 0;
-// qWarning("Test nr: " + QString::number(i)); ++i;
- QEXPECT_FAIL("xmldocs/valid/sa/089.xml", "", Continue);
+ QEXPECT_FAIL("xmldocs/valid/sa/089.xml", "a form feed character is not accepted in XML", Continue);
QVERIFY(parser.parseFile(&file));
QFile ref_file(file_name + ".ref");
@@ -326,7 +324,6 @@ void tst_QXmlSimpleReader::testGoodXmlFile()
ref_stream.setCodec("UTF-8");
QString ref_file_contents = ref_stream.readAll();
- QEXPECT_FAIL("xmldocs/valid/sa/089.xml", "", Continue);
QCOMPARE(parser.result(), ref_file_contents);
}
@@ -355,53 +352,46 @@ void tst_QXmlSimpleReader::testBadXmlFile()
QVERIFY(file.open(QIODevice::ReadOnly));
Parser parser;
-// static int i = 0;
-// qWarning("Test nr: " + QString::number(++i));
- QEXPECT_FAIL("xmldocs/not-wf/sa/030.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/031.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/032.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/033.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/038.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/072.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/073.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/074.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/076.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/077.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/078.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/085.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/086.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/087.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/101.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/102.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/104.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/116.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/117.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/119.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/122.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/132.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/142.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/143.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/144.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/145.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/146.xml", "", Abort);
- QEXPECT_FAIL("xmldocs/not-wf/sa/160.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/162.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/166.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/167.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/168.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/169.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/170.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/171.xml", "", Abort);
- QEXPECT_FAIL("xmldocs/not-wf/sa/172.xml", "", Abort);
- QEXPECT_FAIL("xmldocs/not-wf/sa/173.xml", "", Abort);
- QEXPECT_FAIL("xmldocs/not-wf/sa/174.xml", "", Abort);
- QEXPECT_FAIL("xmldocs/not-wf/sa/175.xml", "", Abort);
- QEXPECT_FAIL("xmldocs/not-wf/sa/177.xml", "", Abort);
- QEXPECT_FAIL("xmldocs/not-wf/sa/180.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/181.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/182.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/185.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/186.xml", "", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/030.xml", "a form feed character is not accepted in XML", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/031.xml", "a form feed character is not accepted in a processing instruction", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/032.xml", "a form feed character is not accepted in a comment", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/033.xml", "overlong sequence - small latin letter d should be rejected", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/038.xml", "attribute x redefined; should be rejected", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/072.xml", "entity foo not defined", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/073.xml", "entity f not defined", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/074.xml", "entity e is not well-formed (</foo><foo>)", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/076.xml", "entity foo is not defined", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/077.xml", "entity bar is not defined within the definition of entity foo", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/078.xml", "entity foo not defined", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/085.xml", "Unfinished Public or System Id", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/086.xml", "Unfinished Public or System Id", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/087.xml", "Unfinished Public or System Id", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/101.xml", "Invalid XML encoding name (space before utf-8)", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/102.xml", "Invalid version specification (1.0 followed by space)", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/104.xml", "Premature end of data in tag foo", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/116.xml", "Invalid decimal value", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/117.xml", "No name", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/119.xml", "No name", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/122.xml", "; expected in declaration of element", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/132.xml", "; expected in declaration of element", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/142.xml", "Invalid value '0'", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/143.xml", "Invalid value '31'", Continue);
+
+ QEXPECT_FAIL("xmldocs/not-wf/sa/144.xml", "noncharacter code 0xFFFF should be rejected", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/145.xml", "surrogate code point 0xD800 should be rejected", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/146.xml", "code point out-of-range 0x110000 (must be < 0x10FFFE)", Abort);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/160.xml", "Parameter references forbidden in internal subset", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/162.xml", "Parameter references forbidden in internal subset", Continue);
+
+ QEXPECT_FAIL("xmldocs/not-wf/sa/168.xml", "Surrogate code point 0xEDA080 should be rejected", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/169.xml", "Surrogate code point 0xEDB080 should be rejected", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/170.xml", "Code point 0xF7808080 should be rejected", Continue);
+
+ QEXPECT_FAIL("xmldocs/not-wf/sa/180.xml", "Entity e is not defined", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/181.xml", "Unregistered error message", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/182.xml", "Comment not terminated", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/185.xml", "Entity e not defined", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/186.xml", "Attributes constructs error", Continue);
QVERIFY(!parser.parseFile(&file));
@@ -411,12 +401,7 @@ void tst_QXmlSimpleReader::testBadXmlFile()
ref_stream.setCodec("UTF-8");
QString ref_file_contents = ref_stream.readAll();
- QEXPECT_FAIL("xmldocs/not-wf/sa/144.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/145.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/146.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/167.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/166.xml", "", Continue);
- QEXPECT_FAIL("xmldocs/not-wf/sa/170.xml", "", Continue);
+ QEXPECT_FAIL("xmldocs/not-wf/sa/145.xml", "Surrogate code point 0xD800 should be rejected", Continue);
QCOMPARE(parser.result(), ref_file_contents);
}
diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref
index 0508ee88c7..eca786f688 100644
--- a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref
+++ b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref
@@ -1,6 +1,6 @@
setDocumentLocator(locator={columnNumber=1, lineNumber=1})
startDocument()
startElement(namespaceURI="", localName="doc", qName="doc", atts=[])
- characters(ch="í»€í°€")
+ characters(ch="�")
endElement(namespaceURI="", localName="doc", qName="doc")
endDocument()
diff --git a/tests/benchmarks/corelib/tools/qstring/main.cpp b/tests/benchmarks/corelib/tools/qstring/main.cpp
index 67ed4c32b9..6101cfe8fb 100644
--- a/tests/benchmarks/corelib/tools/qstring/main.cpp
+++ b/tests/benchmarks/corelib/tools/qstring/main.cpp
@@ -1980,16 +1980,15 @@ int fromUtf8_qt47(ushort *dst, const char *chars, int len)
--need;
if (!need) {
// utf-8 bom composes into 0xfeff code point
- bool nonCharacter;
if (!headerdone && uc == 0xfeff) {
// don't do anything, just skip the BOM
- } else if (!(nonCharacter = QChar::isNonCharacter(uc)) && QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
+ } else if (QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
// surrogate pair
//Q_ASSERT((qch - (ushort*)result.unicode()) + 2 < result.length());
*qch++ = QChar::highSurrogate(uc);
*qch++ = QChar::lowSurrogate(uc);
- } else if ((uc < min_uc) || QChar::isSurrogate(uc) || nonCharacter || uc > QChar::LastValidCodePoint) {
- // error: overlong sequence, UTF16 surrogate or non-character
+ } else if ((uc < min_uc) || QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) {
+ // error: overlong sequence or UTF16 surrogate
*qch++ = replacement;
++invalid;
} else {
@@ -2086,16 +2085,15 @@ int fromUtf8_qt47_stateless(ushort *dst, const char *chars, int len)
--need;
if (!need) {
// utf-8 bom composes into 0xfeff code point
- bool nonCharacter;
if (!headerdone && uc == 0xfeff) {
// don't do anything, just skip the BOM
- } else if (!(nonCharacter = QChar::isNonCharacter(uc)) && QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
+ } else if (QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
// surrogate pair
//Q_ASSERT((qch - (ushort*)result.unicode()) + 2 < result.length());
*qch++ = QChar::highSurrogate(uc);
*qch++ = QChar::lowSurrogate(uc);
- } else if ((uc < min_uc) || QChar::isSurrogate(uc) || nonCharacter || uc > QChar::LastValidCodePoint) {
- // error: overlong sequence, UTF16 surrogate or non-character
+ } else if ((uc < min_uc) || QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) {
+ // error: overlong sequence or UTF16 surrogate
*qch++ = replacement;
++invalid;
} else {
@@ -2214,7 +2212,7 @@ static inline void extract_utf8_multibyte(ushort *&dst, const char *&chars, qptr
chars += 2;
len -= 2;
if (!trusted &&
- (ucs < 0x800 || QChar::isNonCharacter(ucs) || QChar::isSurrogate(ucs)))
+ (ucs < 0x800 || QChar::isSurrogate(ucs)))
dst[counter] = QChar::ReplacementCharacter;
else
dst[counter] = ucs;
@@ -2245,7 +2243,7 @@ static inline void extract_utf8_multibyte(ushort *&dst, const char *&chars, qptr
// dst[counter] will correspond to chars[counter..counter+2], so adjust
chars += 3;
len -= 3;
- if (trusted || (QChar::requiresSurrogates(ucs) && ucs <= QChar::LastValidCodePoint && !QChar::isNonCharacter(ucs))) {
+ if (trusted || (QChar::requiresSurrogates(ucs) && ucs <= QChar::LastValidCodePoint)) {
dst[counter + 0] = QChar::highSurrogate(ucs);
dst[counter + 1] = QChar::lowSurrogate(ucs);
counter += 2;
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index f9d3377540..b4162b3f0f 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -2353,6 +2353,11 @@ void Configure::autoDetection()
if (i.value() == "auto")
i.value() = defaultTo(i.key());
}
+
+ if (tryCompileProject("unix/ptrsize"))
+ dictionary["QT_POINTER_SIZE"] = "8";
+ else
+ dictionary["QT_POINTER_SIZE"] = "4";
}
bool Configure::verifyConfiguration()
@@ -3411,6 +3416,8 @@ void Configure::generateConfigfiles()
if (dictionary["REDUCE_RELOCATIONS"] == "yes") qconfigList += "QT_REDUCE_RELOCATIONS";
if (dictionary["QT_GETIFADDRS"] == "no") qconfigList += "QT_NO_GETIFADDRS";
+ qconfigList += QString("QT_POINTER_SIZE=%1").arg(dictionary["QT_POINTER_SIZE"]);
+
qconfigList.sort();
for (int i = 0; i < qconfigList.count(); ++i)
tmpStream << addDefine(qconfigList.at(i));