summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/double-conversion/LICENSE26
-rw-r--r--src/3rdparty/double-conversion/README8
-rw-r--r--src/3rdparty/double-conversion/bignum-dtoa.cc641
-rw-r--r--src/3rdparty/double-conversion/bignum-dtoa.h84
-rw-r--r--src/3rdparty/double-conversion/bignum.cc766
-rw-r--r--src/3rdparty/double-conversion/bignum.h145
-rw-r--r--src/3rdparty/double-conversion/cached-powers.cc178
-rw-r--r--src/3rdparty/double-conversion/cached-powers.h64
-rw-r--r--src/3rdparty/double-conversion/diy-fp.cc57
-rw-r--r--src/3rdparty/double-conversion/diy-fp.h118
-rw-r--r--src/3rdparty/double-conversion/double-conversion.cc975
-rw-r--r--src/3rdparty/double-conversion/double-conversion.pri24
-rw-r--r--src/3rdparty/double-conversion/fast-dtoa.cc665
-rw-r--r--src/3rdparty/double-conversion/fast-dtoa.h88
-rw-r--r--src/3rdparty/double-conversion/fixed-dtoa.cc404
-rw-r--r--src/3rdparty/double-conversion/fixed-dtoa.h56
-rw-r--r--src/3rdparty/double-conversion/ieee.h402
-rw-r--r--src/3rdparty/double-conversion/include/double-conversion/double-conversion.h543
-rw-r--r--src/3rdparty/double-conversion/include/double-conversion/utils.h330
-rw-r--r--src/3rdparty/double-conversion/strtod.cc555
-rw-r--r--src/3rdparty/double-conversion/strtod.h45
-rw-r--r--src/3rdparty/sqlite/0001-Fixing-the-SQLite3-build-for-WEC2013-again.patch33
-rw-r--r--src/3rdparty/sqlite/sqlite3.c4
-rw-r--r--src/android/accessibility/accessibility.pro2
-rw-r--r--src/android/accessibility/jar/AndroidManifest.xml7
-rw-r--r--src/android/accessibility/jar/bundledjar.pro3
-rw-r--r--src/android/accessibility/jar/distributedjar.pro2
-rw-r--r--src/android/accessibility/jar/jar.pri15
-rw-r--r--src/android/accessibility/jar/jar.pro2
-rw-r--r--src/android/android.pro2
-rw-r--r--src/android/jar/jar.pri6
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java26
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java168
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtMessageDialogHelper.java81
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java18
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtPopupMenu.java66
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtPopupMenu14.java69
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtSurface.java3
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java (renamed from src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java)0
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java (renamed from src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java)0
-rw-r--r--src/android/java/res/values-ro/strings.xml1
-rw-r--r--src/android/java/res/values/strings.xml1
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java37
-rw-r--r--src/android/templates/AndroidManifest.xml2
-rw-r--r--src/corelib/Qt5CoreConfigExtras.cmake.in2
-rw-r--r--src/corelib/Qt5CoreMacros.cmake8
-rw-r--r--src/corelib/codecs/qutfcodec.cpp29
-rw-r--r--src/corelib/codecs/qutfcodec_p.h1
-rw-r--r--src/corelib/corelib.pro6
-rw-r--r--src/corelib/doc/snippets/code/doc_src_qpair.cpp9
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp5
-rw-r--r--src/corelib/doc/snippets/qprocess/qprocess-createprocessargumentsmodifier.cpp63
-rw-r--r--src/corelib/doc/snippets/qstring/main.cpp2
-rw-r--r--src/corelib/global/qcompilerdetection.h31
-rw-r--r--src/corelib/global/qendian.h8
-rw-r--r--src/corelib/global/qglobal.cpp135
-rw-r--r--src/corelib/global/qglobal.h86
-rw-r--r--src/corelib/global/qhooks.cpp11
-rw-r--r--src/corelib/global/qhooks_p.h1
-rw-r--r--src/corelib/global/qlogging.cpp8
-rw-r--r--src/corelib/global/qnamespace.h4
-rw-r--r--src/corelib/global/qnamespace.qdoc27
-rw-r--r--src/corelib/global/qnumeric_p.h280
-rw-r--r--src/corelib/global/qprocessordetection.h6
-rw-r--r--src/corelib/global/qsystemdetection.h67
-rw-r--r--src/corelib/global/qtypeinfo.h14
-rw-r--r--src/corelib/io/io.pri14
-rw-r--r--src/corelib/io/qdatastream.cpp1
-rw-r--r--src/corelib/io/qdatastream.h5
-rw-r--r--src/corelib/io/qdebug.cpp49
-rw-r--r--src/corelib/io/qdebug.h113
-rw-r--r--src/corelib/io/qfile.cpp2
-rw-r--r--src/corelib/io/qfileselector.cpp18
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp18
-rw-r--r--src/corelib/io/qfilesystementry.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp5
-rw-r--r--src/corelib/io/qfilesystemwatcher_kqueue.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_win.cpp12
-rw-r--r--src/corelib/io/qiodevice.cpp2
-rw-r--r--src/corelib/io/qlockfile_unix.cpp10
-rw-r--r--src/corelib/io/qloggingregistry.cpp12
-rw-r--r--src/corelib/io/qprocess.cpp75
-rw-r--r--src/corelib/io/qprocess.h22
-rw-r--r--src/corelib/io/qprocess_p.h6
-rw-r--r--src/corelib/io/qprocess_unix.cpp65
-rw-r--r--src/corelib/io/qprocess_win.cpp21
-rw-r--r--src/corelib/io/qsettings.cpp49
-rw-r--r--src/corelib/io/qsettings.h5
-rw-r--r--src/corelib/io/qsettings_p.h5
-rw-r--r--src/corelib/io/qsettings_win.cpp120
-rw-r--r--src/corelib/io/qsettings_winrt.cpp6
-rw-r--r--src/corelib/io/qstandardpaths.cpp46
-rw-r--r--src/corelib/io/qstandardpaths_blackberry.cpp115
-rw-r--r--src/corelib/io/qstandardpaths_ios.mm133
-rw-r--r--src/corelib/io/qstandardpaths_mac.mm204
-rw-r--r--src/corelib/io/qtemporarydir.cpp4
-rw-r--r--src/corelib/io/qtextstream.cpp44
-rw-r--r--src/corelib/io/qtextstream_p.h4
-rw-r--r--src/corelib/io/qurl.cpp5
-rw-r--r--src/corelib/io/qurlquery.cpp3
-rw-r--r--src/corelib/io/qurlquery.h4
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp53
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel_p.h37
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.cpp2
-rw-r--r--src/corelib/itemmodels/qidentityproxymodel.cpp7
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.cpp2
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp6
-rw-r--r--src/corelib/json/qjsonwriter.cpp3
-rw-r--r--src/corelib/kernel/kernel.pri13
-rw-r--r--src/corelib/kernel/qabstractnativeeventfilter.cpp3
-rw-r--r--src/corelib/kernel/qcore_unix.cpp98
-rw-r--r--src/corelib/kernel/qcore_unix_p.h22
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp106
-rw-r--r--src/corelib/kernel/qcoreevent.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry.cpp502
-rw-r--r--src/corelib/kernel/qeventdispatcher_blackberry_p.h97
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp19
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h20
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp2
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp402
-rw-r--r--src/corelib/kernel/qmetatype.cpp4
-rw-r--r--src/corelib/kernel/qobject.cpp2
-rw-r--r--src/corelib/kernel/qobject.h10
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h2
-rw-r--r--src/corelib/kernel/qpoll.cpp220
-rw-r--r--src/corelib/kernel/qpoll_p.h79
-rw-r--r--src/corelib/kernel/qsharedmemory_p.h2
-rw-r--r--src/corelib/kernel/qtranslator.cpp55
-rw-r--r--src/corelib/kernel/qvariant.cpp21
-rw-r--r--src/corelib/kernel/qvariant.h2
-rw-r--r--src/corelib/kernel/qvariant_p.h39
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp25
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern.cpp6
-rw-r--r--src/corelib/mimetypes/qmimemagicrulematcher.cpp2
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp24
-rw-r--r--src/corelib/mimetypes/qmimetype.cpp11
-rw-r--r--src/corelib/plugin/plugin.pri4
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp107
-rw-r--r--src/corelib/plugin/qfactoryloader_p.h82
-rw-r--r--src/corelib/plugin/qlibrary.cpp6
-rw-r--r--src/corelib/plugin/qlibrary_p.h25
-rw-r--r--src/corelib/plugin/qlibrary_win.cpp2
-rw-r--r--src/corelib/plugin/qpluginloader.cpp21
-rw-r--r--src/corelib/plugin/qpluginloader.h15
-rw-r--r--src/corelib/plugin/quuid.cpp33
-rw-r--r--src/corelib/plugin/quuid.h15
-rw-r--r--src/corelib/plugin/quuid_darwin.mm (renamed from src/widgets/styles/qgtkpainter.cpp)47
-rw-r--r--src/corelib/statemachine/qsignaltransition.cpp13
-rw-r--r--src/corelib/statemachine/qsignaltransition.h13
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp87
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h14
-rw-r--r--src/corelib/thread/qmutex_p.h11
-rw-r--r--src/corelib/thread/qmutex_unix.cpp48
-rw-r--r--src/corelib/thread/qthread_unix.cpp14
-rw-r--r--src/corelib/thread/qthreadpool.cpp2
-rw-r--r--src/corelib/tools/qalgorithms.h8
-rw-r--r--src/corelib/tools/qbytearray.cpp59
-rw-r--r--src/corelib/tools/qbytearray.h23
-rw-r--r--src/corelib/tools/qchar.h8
-rw-r--r--src/corelib/tools/qcommandlineparser.cpp58
-rw-r--r--src/corelib/tools/qdatetime.cpp4
-rw-r--r--src/corelib/tools/qdoublescanprint_p.h150
-rw-r--r--src/corelib/tools/qeasingcurve.h6
-rw-r--r--src/corelib/tools/qhash.cpp30
-rw-r--r--src/corelib/tools/qhash.h27
-rw-r--r--src/corelib/tools/qhashfunctions.h9
-rw-r--r--src/corelib/tools/qlocale.cpp265
-rw-r--r--src/corelib/tools/qlocale.h9
-rw-r--r--src/corelib/tools/qlocale.qdoc27
-rw-r--r--src/corelib/tools/qlocale_blackberry.cpp333
-rw-r--r--src/corelib/tools/qlocale_blackberry.h91
-rw-r--r--src/corelib/tools/qlocale_p.h43
-rw-r--r--src/corelib/tools/qlocale_tools.cpp2734
-rw-r--r--src/corelib/tools/qlocale_tools_p.h20
-rw-r--r--src/corelib/tools/qlocale_win.cpp2
-rw-r--r--src/corelib/tools/qpair.h18
-rw-r--r--src/corelib/tools/qpair.qdoc12
-rw-r--r--src/corelib/tools/qregexp.h5
-rw-r--r--src/corelib/tools/qringbuffer.cpp89
-rw-r--r--src/corelib/tools/qringbuffer_p.h11
-rw-r--r--src/corelib/tools/qset.h13
-rw-r--r--src/corelib/tools/qset.qdoc10
-rw-r--r--src/corelib/tools/qsharedpointer.cpp25
-rw-r--r--src/corelib/tools/qsharedpointer.h2
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h42
-rw-r--r--src/corelib/tools/qsimd.cpp29
-rw-r--r--src/corelib/tools/qsimd_p.h19
-rw-r--r--src/corelib/tools/qsize.cpp8
-rw-r--r--src/corelib/tools/qstring.cpp224
-rw-r--r--src/corelib/tools/qstring.h123
-rw-r--r--src/corelib/tools/qtimezone.cpp6
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp14
-rw-r--r--src/corelib/tools/qtimezoneprivate_win.cpp12
-rw-r--r--src/corelib/tools/qversionnumber.h2
-rw-r--r--src/corelib/tools/tools.pri13
-rw-r--r--src/corelib/xml/qxmlstream.h5
-rw-r--r--src/dbus/qdbus_symbols.cpp4
-rw-r--r--src/dbus/qdbusabstractinterface.cpp2
-rw-r--r--src/dbus/qdbusargument.h31
-rw-r--r--src/dbus/qdbusconnection.cpp4
-rw-r--r--src/dbus/qdbusconnectioninterface.cpp8
-rw-r--r--src/dbus/qdbusintegrator.cpp29
-rw-r--r--src/dbus/qdbuspendingcall.cpp2
-rw-r--r--src/gui/accessible/accessible.pri6
-rw-r--r--src/gui/gui.pro2
-rw-r--r--src/gui/image/qicon.cpp50
-rw-r--r--src/gui/image/qicon.h3
-rw-r--r--src/gui/image/qiconengine.cpp17
-rw-r--r--src/gui/image/qiconengine.h3
-rw-r--r--src/gui/image/qiconloader.cpp168
-rw-r--r--src/gui/image/qiconloader_p.h5
-rw-r--r--src/gui/image/qimage.h4
-rw-r--r--src/gui/image/qmovie.cpp14
-rw-r--r--src/gui/image/qpixmap.cpp2
-rw-r--r--src/gui/image/qpixmapcache.cpp10
-rw-r--r--src/gui/image/qpixmapcache.h1
-rw-r--r--src/gui/kernel/qdrag.cpp19
-rw-r--r--src/gui/kernel/qdrag.h2
-rw-r--r--src/gui/kernel/qevent.cpp3
-rw-r--r--src/gui/kernel/qevent.h12
-rw-r--r--src/gui/kernel/qgenericplugin.cpp4
-rw-r--r--src/gui/kernel/qgenericplugin.h5
-rw-r--r--src/gui/kernel/qgenericpluginfactory.cpp2
-rw-r--r--src/gui/kernel/qguiapplication.cpp88
-rw-r--r--src/gui/kernel/qguiapplication.h4
-rw-r--r--src/gui/kernel/qguiapplication_p.h12
-rw-r--r--src/gui/kernel/qinputdevicemanager_p.h3
-rw-r--r--src/gui/kernel/qopenglcontext.cpp2
-rw-r--r--src/gui/kernel/qplatformdrag.cpp14
-rw-r--r--src/gui/kernel/qplatformdrag.h1
-rw-r--r--src/gui/kernel/qplatforminputcontextfactory.cpp2
-rw-r--r--src/gui/kernel/qplatformintegration.cpp21
-rw-r--r--src/gui/kernel/qplatformintegration.h2
-rw-r--r--src/gui/kernel/qplatformintegrationfactory.cpp25
-rw-r--r--src/gui/kernel/qplatformnativeinterface.cpp9
-rw-r--r--src/gui/kernel/qplatformnativeinterface.h3
-rw-r--r--src/gui/kernel/qplatformtheme.cpp35
-rw-r--r--src/gui/kernel/qplatformtheme.h2
-rw-r--r--src/gui/kernel/qplatformthemefactory.cpp9
-rw-r--r--src/gui/kernel/qsimpledrag.cpp8
-rw-r--r--src/gui/kernel/qsimpledrag_p.h1
-rw-r--r--src/gui/kernel/qstylehints.cpp22
-rw-r--r--src/gui/kernel/qstylehints.h4
-rw-r--r--src/gui/kernel/qwindow.cpp72
-rw-r--r--src/gui/opengl/qopenglengineshadermanager.cpp14
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp6
-rw-r--r--src/gui/opengl/qtriangulator_p.h11
-rw-r--r--src/gui/painting/painting.pri3
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp4
-rw-r--r--src/gui/painting/qdrawhelper.cpp24
-rw-r--r--src/gui/painting/qdrawhelper_p.h95
-rw-r--r--src/gui/painting/qimagescale.cpp38
-rw-r--r--src/gui/painting/qimagescale_neon.cpp209
-rw-r--r--src/gui/painting/qpaintengine_blitter.cpp4
-rw-r--r--src/gui/painting/qpaintengine_blitter_p.h66
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp6
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h87
-rw-r--r--src/gui/painting/qpainterpath.cpp3
-rw-r--r--src/gui/painting/qrgba64.h2
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.cpp4
-rw-r--r--src/gui/text/qfont.cpp16
-rw-r--r--src/gui/text/qfontdatabase.cpp2
-rw-r--r--src/gui/text/qfontmetrics.cpp20
-rw-r--r--src/gui/text/qplatformfontdatabase.cpp2
-rw-r--r--src/gui/text/qrawfont.cpp3
-rw-r--r--src/gui/text/qsyntaxhighlighter.cpp20
-rw-r--r--src/gui/text/qtextengine.cpp2
-rw-r--r--src/gui/text/qtexthtmlparser.cpp3
-rw-r--r--src/gui/text/qtextimagehandler.cpp1
-rw-r--r--src/gui/text/qtextobject.cpp4
-rw-r--r--src/gui/text/qtextobject.h4
-rw-r--r--src/gui/util/qvalidator.cpp18
-rw-r--r--src/network/access/access.pri2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp4
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h2
-rw-r--r--src/network/access/qhttpthreaddelegate_p.h10
-rw-r--r--src/network/access/qnetworkdiskcache.cpp4
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp15
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h6
-rw-r--r--src/network/access/qnetworkreplyimpl.cpp8
-rw-r--r--src/network/access/qspdyprotocolhandler.cpp2
-rw-r--r--src/network/access/qspdyprotocolhandler_p.h2
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.cpp4
-rw-r--r--src/network/bearer/qnetworkconfiguration.cpp103
-rw-r--r--src/network/bearer/qnetworkconfiguration_p.h11
-rw-r--r--src/network/bearer/qnetworksession_p.h2
-rw-r--r--src/network/bearer/qsharednetworksession.cpp4
-rw-r--r--src/network/bearer/qsharednetworksession_p.h4
-rw-r--r--src/network/kernel/kernel.pri4
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp2
-rw-r--r--src/network/kernel/qnetworkinterface.cpp46
-rw-r--r--src/network/kernel/qnetworkinterface.h2
-rw-r--r--src/network/kernel/qnetworkinterface_p.h3
-rw-r--r--src/network/kernel/qnetworkinterface_unix.cpp62
-rw-r--r--src/network/kernel/qnetworkinterface_win.cpp43
-rw-r--r--src/network/kernel/qnetworkinterface_winrt.cpp13
-rw-r--r--src/network/kernel/qnetworkproxy.cpp10
-rw-r--r--src/network/kernel/qnetworkproxy_blackberry.cpp165
-rw-r--r--src/network/socket/qabstractsocket.cpp99
-rw-r--r--src/network/socket/qabstractsocket.h2
-rw-r--r--src/network/socket/qabstractsocket_p.h3
-rw-r--r--src/network/socket/qhttpsocketengine.cpp4
-rw-r--r--src/network/socket/qhttpsocketengine_p.h2
-rw-r--r--src/network/socket/qnativesocketengine_p.h16
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp74
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp13
-rw-r--r--src/network/ssl/qsslconfiguration.cpp17
-rw-r--r--src/network/ssl/qsslconfiguration.h2
-rw-r--r--src/network/ssl/qsslconfiguration_p.h2
-rw-r--r--src/network/ssl/qsslsocket.cpp4
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp30
-rw-r--r--src/network/ssl/qsslsocket_mac_shared.cpp149
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp73
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h3
-rw-r--r--src/network/ssl/qsslsocket_p.h6
-rw-r--r--src/network/ssl/ssl.pri5
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp14
-rw-r--r--src/opengl/qglshaderprogram.cpp21
-rw-r--r--src/platformsupport/cglconvenience/cglconvenience.mm2
-rw-r--r--src/platformsupport/cglconvenience/cglconvenience.pri4
-rw-r--r--src/platformsupport/clipboard/qmacmime.mm7
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_static.cpp102
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp6
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp1
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm4
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm15
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h2
-rw-r--r--src/platformsupport/graphics/graphics.pri2
-rw-r--r--src/platformsupport/graphics/qrasterbackingstore.cpp104
-rw-r--r--src/platformsupport/graphics/qrasterbackingstore_p.h71
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp1
-rw-r--r--src/platformsupport/input/evdevtablet/evdevtablet.pri6
-rw-r--r--src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp (renamed from src/platformsupport/input/evdevtablet/qevdevtablet.cpp)203
-rw-r--r--src/platformsupport/input/evdevtablet/qevdevtablethandler_p.h (renamed from src/platformsupport/input/evdevtablet/qevdevtablet_p.h)19
-rw-r--r--src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp122
-rw-r--r--src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h (renamed from src/widgets/styles/qgtkglobal_p.h)54
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp1
-rw-r--r--src/platformsupport/input/libinput/qlibinputhandler.cpp6
-rw-r--r--src/platformsupport/platformsupport.pro1
-rw-r--r--src/platformsupport/services/genericunix/qgenericunixservices.cpp22
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp8
-rw-r--r--src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp4
-rw-r--r--src/plugins/bearer/bearer.pro1
-rw-r--r--src/plugins/bearer/blackberry/blackberry.json3
-rw-r--r--src/plugins/bearer/blackberry/blackberry.pro20
-rw-r--r--src/plugins/bearer/blackberry/qbbengine.cpp413
-rw-r--r--src/plugins/bearer/blackberry/qbbengine.h101
-rw-r--r--src/plugins/generic/evdevtablet/main.cpp12
-rw-r--r--src/plugins/generic/tuiotouch/qtuiohandler.cpp1
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp2
-rw-r--r--src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h2
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp4
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp7
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp4
-rw-r--r--src/plugins/platforms/android/androidjnimenu.cpp9
-rw-r--r--src/plugins/platforms/android/qandroideventdispatcher.cpp18
-rw-r--r--src/plugins/platforms/android/qandroideventdispatcher.h3
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp20
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp6
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.cpp2
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp6
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro2
-rw-r--r--src/plugins/platforms/cocoa/main.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h5
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm257
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoakeymapper.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm7
-rw-r--r--src/plugins/platforms/cocoa/qcocoaservices.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm29
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h5
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm59
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm17
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.h2
-rw-r--r--src/plugins/platforms/cocoa/qmacdefines_mac.h2
-rw-r--r--src/plugins/platforms/cocoa/qmultitouch_mac_p.h2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm1
-rw-r--r--src/plugins/platforms/cocoa/qnsviewaccessibility.mm2
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.h2
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm2
-rw-r--r--src/plugins/platforms/cocoa/qt_mac_p.h32
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp2
-rw-r--r--src/plugins/platforms/directfb/qdirectfbblitter.cpp4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp10
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp24
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp2
-rw-r--r--src/plugins/platforms/eglfs/qeglfscursor.cpp1
-rw-r--r--src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp19
-rw-r--r--src/plugins/platforms/eglfs/qeglfsdeviceintegration.h4
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp4
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp20
-rw-r--r--src/plugins/platforms/haiku/qhaikuwindow.cpp2
-rw-r--r--src/plugins/platforms/ios/ios.pro8
-rw-r--r--src/plugins/platforms/ios/qiosbackingstore.h21
-rw-r--r--src/plugins/platforms/ios/qiosbackingstore.mm111
-rw-r--r--src/plugins/platforms/ios/qioseventdispatcher.mm4
-rw-r--r--src/plugins/platforms/ios/qiosintegration.h2
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm11
-rw-r--r--src/plugins/platforms/ios/qiosmenu.h3
-rw-r--r--src/plugins/platforms/ios/qiosmenu.mm38
-rw-r--r--src/plugins/platforms/ios/qiosmessagedialog.h (renamed from src/plugins/bearer/blackberry/main.cpp)40
-rw-r--r--src/plugins/platforms/ios/qiosmessagedialog.mm135
-rw-r--r--src/plugins/platforms/ios/qiostheme.mm5
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp5
-rw-r--r--src/plugins/platforms/minimalegl/qminimaleglscreen.cpp12
-rw-r--r--src/plugins/platforms/mirclient/qmirclientclipboard.cpp7
-rw-r--r--src/plugins/platforms/mirclient/qmirclientglcontext.cpp10
-rw-r--r--src/plugins/platforms/mirclient/qmirclientintegration.cpp2
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp4
-rw-r--r--src/plugins/platforms/openwfd/qopenwfdport.cpp7
-rw-r--r--src/plugins/platforms/qnx/qblackberrytheme.cpp119
-rw-r--r--src/plugins/platforms/qnx/qblackberrytheme.h73
-rw-r--r--src/plugins/platforms/qnx/qnx.pro51
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.cpp229
-rw-r--r--src/plugins/platforms/qnx/qqnxbpseventfilter.h82
-rw-r--r--src/plugins/platforms/qnx/qqnxbuffer.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.cpp14
-rw-r--r--src/plugins/platforms/qnx/qqnxeventdispatcher_blackberry.cpp68
-rw-r--r--src/plugins/platforms/qnx/qqnxeventdispatcher_blackberry.h58
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper.h87
-rw-r--r--src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp212
-rw-r--r--src/plugins/platforms/qnx/qqnxfilepicker.cpp322
-rw-r--r--src/plugins/platforms/qnx/qqnxfilepicker.h107
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp18
-rw-r--r--src/plugins/platforms/qnx/qqnxglobal.cpp4
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp27
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp89
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h10
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.cpp5
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatorbps.cpp66
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatorbps.h54
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatorcover.cpp57
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatorcover.h52
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatorpps.cpp8
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterwindow.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp4
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp13
-rw-r--r--src/plugins/platforms/qnx/qqnxsystemsettings.cpp74
-rw-r--r--src/plugins/platforms/qnx/qqnxsystemsettings.h48
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp217
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h68
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp10
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp42
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp15
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp11
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp16
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp1
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeimage.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp21
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.h6
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp53
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp4
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp17
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationplugin.h3
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp26
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h16
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp13
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp41
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h1
-rw-r--r--src/plugins/platformthemes/gtk2/gtk2.json3
-rw-r--r--src/plugins/platformthemes/gtk2/gtk2.pro21
-rw-r--r--src/plugins/platformthemes/gtk3/gtk3.json3
-rw-r--r--src/plugins/platformthemes/gtk3/gtk3.pro21
-rw-r--r--src/plugins/platformthemes/gtk3/main.cpp (renamed from src/plugins/platformthemes/gtk2/main.cpp)12
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp (renamed from src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp)182
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h (renamed from src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h)38
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3theme.cpp (renamed from src/plugins/platformthemes/gtk2/qgtk2theme.cpp)45
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3theme.h (renamed from src/plugins/platformthemes/gtk2/qgtk2theme.h)10
-rw-r--r--src/plugins/platformthemes/platformthemes.pro2
-rw-r--r--src/plugins/plugins.pro1
-rw-r--r--src/plugins/printsupport/cocoa/cocoa.pro2
-rw-r--r--src/plugins/styles/bb10style/bb10lightstyle.qrc54
-rw-r--r--src/plugins/styles/bb10style/bb10style.pro28
-rw-r--r--src/plugins/styles/bb10style/bright/button/core_button_disabled.pngbin1510 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/button/core_button_disabled_selected.pngbin1782 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/button/core_button_enabled_selected.pngbin1830 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/button/core_button_inactive.pngbin2428 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/button/core_button_pressed.pngbin3221 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/checkbox/core_checkbox_checked.pngbin2048 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/checkbox/core_checkbox_disabled.pngbin935 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/checkbox/core_checkbox_disabled_checked.pngbin1702 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/checkbox/core_checkbox_enabled.pngbin1082 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.pngbin2776 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed_checked.pngbin2652 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_dropdown_button.pngbin1605 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowdown.pngbin1419 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowdown_pressed.pngbin1404 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowup.pngbin1398 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_disabled.pngbin1587 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_pressed.pngbin1801 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_dropdown_checkmark.pngbin1769 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_dropdown_divider.pngbin134 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_dropdown_menu.pngbin874 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_dropdown_menuup.pngbin996 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/combobox/core_listitem_active.pngbin182 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.pngbin1315 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_disabled.pngbin454 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.pngbin394 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/listitem/core_listitem_active.pngbin164 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.pngbin135 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.pngbin1802 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_complete.pngbin635 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_fill.pngbin629 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vbg.pngbin903 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vcomplete.pngbin614 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vfill.pngbin594 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_checked.pngbin4471 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_disabled.pngbin3652 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_disabled_checked.pngbin4094 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.pngbin4245 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.pngbin5460 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.pngbin1242 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar_v.pngbin385 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_active.pngbin1167 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_cache.pngbin1154 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_disabled.pngbin1134 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_enabled.pngbin1049 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_handle.pngbin2843 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_handle_disabled.pngbin2708 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.pngbin6577 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_inactive.pngbin1162 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_vactive.pngbin1077 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_vcache.pngbin1063 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_vdisabled.pngbin1064 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_venabled.pngbin996 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/bright/slider/core_slider_vinactive.pngbin1071 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/button/core_button_disabled.pngbin1291 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/button/core_button_disabled_selected.pngbin1655 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/button/core_button_enabled_selected.pngbin1665 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/button/core_button_inactive.pngbin2262 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/button/core_button_pressed.pngbin2853 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/checkbox/core_checkbox_checked.pngbin1947 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/checkbox/core_checkbox_disabled.pngbin787 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/checkbox/core_checkbox_disabled_checked.pngbin1578 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/checkbox/core_checkbox_enabled.pngbin925 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.pngbin2478 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed_checked.pngbin2256 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_dropdown_button.pngbin1425 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowdown.pngbin1404 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowdown_pressed.pngbin1465 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowup.pngbin1383 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_disabled.pngbin1291 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_pressed.pngbin1583 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_dropdown_checkmark.pngbin1588 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_dropdown_divider.pngbin134 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_dropdown_menu.pngbin662 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_dropdown_menuup.pngbin688 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/combobox/core_listitem_active.pngbin149 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.pngbin1315 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_disabled.pngbin454 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.pngbin394 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/listitem/core_listitem_active.pngbin164 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.pngbin136 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.pngbin1724 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_complete.pngbin635 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_fill.pngbin658 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vbg.pngbin815 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vcomplete.pngbin614 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vfill.pngbin602 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_checked.pngbin4298 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_disabled.pngbin3125 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_disabled_checked.pngbin3539 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.pngbin3968 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.pngbin4777 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.pngbin1245 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar_v.pngbin369 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_active.pngbin1160 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_cache.pngbin1154 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_disabled.pngbin1105 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_enabled.pngbin983 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_handle.pngbin3019 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_handle_disabled.pngbin1715 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.pngbin6593 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_inactive.pngbin1158 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_vactive.pngbin1066 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_vcache.pngbin1058 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_vdisabled.pngbin1009 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_venabled.pngbin929 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/dark/slider/core_slider_vinactive.pngbin1067 -> 0 bytes
-rw-r--r--src/plugins/styles/bb10style/qbb10brightstyle.cpp344
-rw-r--r--src/plugins/styles/bb10style/qbb10brightstyle.h62
-rw-r--r--src/plugins/styles/bb10style/qbb10brightstyle.qrc57
-rw-r--r--src/plugins/styles/bb10style/qbb10darkstyle.cpp349
-rw-r--r--src/plugins/styles/bb10style/qbb10darkstyle.h62
-rw-r--r--src/plugins/styles/bb10style/qbb10darkstyle.qrc57
-rw-r--r--src/plugins/styles/bb10style/qbb10styleplugin.cpp66
-rw-r--r--src/plugins/styles/bb10style/qbb10styleplugin.h56
-rw-r--r--src/plugins/styles/bb10style/qbb10styleplugin.json3
-rw-r--r--src/plugins/styles/styles.pro3
-rw-r--r--src/printsupport/dialogs/dialogs.pri4
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_mac.mm2
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix.cpp4
-rw-r--r--src/printsupport/dialogs/qprintdialog_mac.mm2
-rw-r--r--src/printsupport/dialogs/qprintdialog_unix.cpp25
-rw-r--r--src/printsupport/kernel/qplatformprintdevice.cpp10
-rw-r--r--src/printsupport/kernel/qprintengine_win.cpp8
-rw-r--r--src/printsupport/kernel/qprinter.cpp5
-rw-r--r--src/printsupport/kernel/qprinterinfo.cpp8
-rw-r--r--src/printsupport/widgets/qprintpreviewwidget.cpp4
-rw-r--r--src/sql/drivers/db2/qsql_db2.cpp85
-rw-r--r--src/sql/drivers/db2/qsql_db2_p.h68
-rw-r--r--src/sql/drivers/ibase/qsql_ibase.cpp72
-rw-r--r--src/sql/drivers/ibase/qsql_ibase_p.h61
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.cpp159
-rw-r--r--src/sql/drivers/mysql/qsql_mysql_p.h39
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp148
-rw-r--r--src/sql/drivers/oci/qsql_oci_p.h41
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp141
-rw-r--r--src/sql/drivers/odbc/qsql_odbc_p.h76
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp61
-rw-r--r--src/sql/drivers/psql/qsql_psql_p.h33
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.cpp70
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite_p.h5
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2.cpp68
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2_p.h57
-rw-r--r--src/sql/drivers/tds/qsql_tds.cpp45
-rw-r--r--src/sql/drivers/tds/qsql_tds_p.h39
-rw-r--r--src/sql/kernel/qsqlcachedresult.cpp48
-rw-r--r--src/sql/kernel/qsqlcachedresult_p.h47
-rw-r--r--src/sql/kernel/qsqldriver.cpp29
-rw-r--r--src/sql/kernel/qsqlnulldriver_p.h53
-rw-r--r--src/sql/kernel/qsqlresult.cpp14
-rw-r--r--src/sql/kernel/qsqlresult.h2
-rw-r--r--src/sql/kernel/qsqlresult_p.h13
-rw-r--r--src/testlib/qbenchmarkvalgrind.cpp2
-rw-r--r--src/testlib/qplaintestlogger.cpp9
-rw-r--r--src/testlib/qtestblacklist.cpp7
-rw-r--r--src/testlib/qtestcase.cpp1496
-rw-r--r--src/testlib/qtestcase.qdoc1278
-rw-r--r--src/testlib/qxctestlogger.mm2
-rw-r--r--src/tools/moc/parser.h5
-rw-r--r--src/tools/moc/preprocessor.cpp9
-rw-r--r--src/tools/rcc/main.cpp2
-rw-r--r--src/widgets/accessible/itemviews.cpp10
-rw-r--r--src/widgets/accessible/qaccessiblewidget.cpp16
-rw-r--r--src/widgets/accessible/qaccessiblewidgets.cpp80
-rw-r--r--src/widgets/accessible/simplewidgets.cpp4
-rw-r--r--src/widgets/dialogs/qdialog.cpp7
-rw-r--r--src/widgets/dialogs/qdialog_p.h2
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp129
-rw-r--r--src/widgets/dialogs/qfileinfogatherer.cpp4
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp43
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.h1
-rw-r--r--src/widgets/dialogs/qfontdialog.cpp3
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp44
-rw-r--r--src/widgets/dialogs/qprogressdialog.cpp10
-rw-r--r--src/widgets/dialogs/qsidebar.cpp10
-rw-r--r--src/widgets/dialogs/qwizard.cpp45
-rw-r--r--src/widgets/doc/images/gtk-calendarwidget.pngbin16761 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-checkbox.pngbin2323 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-combobox.pngbin2730 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-dateedit.pngbin2163 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-datetimeedit.pngbin2923 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-dial.pngbin7221 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-doublespinbox.pngbin2325 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-fontcombobox.pngbin3022 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-frame.pngbin2340 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-groupbox.pngbin6650 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-horizontalscrollbar.pngbin1701 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-label.pngbin1582 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-lcdnumber.pngbin1193 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-lineedit.pngbin2528 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-listview.pngbin8493 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-progressbar.pngbin2228 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-pushbutton.pngbin2153 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-radiobutton.pngbin3142 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-slider.pngbin1359 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-spinbox.pngbin2078 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-tableview.pngbin8364 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-tabwidget.pngbin8179 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-textedit.pngbin12641 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-timeedit.pngbin2621 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-toolbox.pngbin4240 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-toolbutton.pngbin2260 -> 0 bytes
-rw-r--r--src/widgets/doc/images/gtk-treeview.pngbin9722 -> 0 bytes
-rw-r--r--src/widgets/doc/snippets/code/doc_src_stylesheet.cpp4
-rw-r--r--src/widgets/doc/snippets/macmainwindow.mm2
-rw-r--r--src/widgets/doc/snippets/qmacnativewidget/main.mm2
-rw-r--r--src/widgets/doc/snippets/styles/qcustompixmapstyle.cpp85
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/gallery-gtk.qdoc142
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/gallery.qdoc4
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/styles.qdoc2
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc22
-rw-r--r--src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc13
-rw-r--r--src/widgets/effects/qgraphicseffect.cpp4
-rw-r--r--src/widgets/effects/qpixmapfilter.cpp9
-rw-r--r--src/widgets/effects/qpixmapfilter_p.h1
-rw-r--r--src/widgets/graphicsview/qgraph_p.h5
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp53
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout_p.h2
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp110
-rw-r--r--src/widgets/graphicsview/qgraphicsitem_p.h75
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp28
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget_p.h14
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp159
-rw-r--r--src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp29
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp15
-rw-r--r--src/widgets/graphicsview/qgraphicswidget.cpp7
-rw-r--r--src/widgets/graphicsview/qgraphicswidget.h3
-rw-r--r--src/widgets/graphicsview/qgraphicswidget_p.cpp19
-rw-r--r--src/widgets/graphicsview/qgraphicswidget_p.h18
-rw-r--r--src/widgets/graphicsview/qsimplex_p.cpp8
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp39
-rw-r--r--src/widgets/itemviews/qabstractitemview.h1
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h22
-rw-r--r--src/widgets/itemviews/qdirmodel.cpp19
-rw-r--r--src/widgets/itemviews/qfileiconprovider.cpp13
-rw-r--r--src/widgets/itemviews/qheaderview.cpp134
-rw-r--r--src/widgets/itemviews/qheaderview_p.h11
-rw-r--r--src/widgets/itemviews/qitemeditorfactory.cpp7
-rw-r--r--src/widgets/itemviews/qlistview.cpp45
-rw-r--r--src/widgets/itemviews/qlistview_p.h13
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp4
-rw-r--r--src/widgets/itemviews/qtableview.cpp30
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp33
-rw-r--r--src/widgets/itemviews/qtreeview.cpp8
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp63
-rw-r--r--src/widgets/itemviews/qtreewidget.h3
-rw-r--r--src/widgets/itemviews/qwidgetitemdata_p.h2
-rw-r--r--src/widgets/kernel/mac.pri4
-rw-r--r--src/widgets/kernel/qaction.cpp2
-rw-r--r--src/widgets/kernel/qapplication.cpp95
-rw-r--r--src/widgets/kernel/qdesktopwidget.cpp4
-rw-r--r--src/widgets/kernel/qformlayout.cpp8
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp16
-rw-r--r--src/widgets/kernel/qgridlayout.cpp6
-rw-r--r--src/widgets/kernel/qlayout.cpp66
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp14
-rw-r--r--src/widgets/kernel/qshortcut.cpp4
-rw-r--r--src/widgets/kernel/qstackedlayout.cpp12
-rw-r--r--src/widgets/kernel/qtooltip.cpp8
-rw-r--r--src/widgets/kernel/qwidget.cpp85
-rw-r--r--src/widgets/kernel/qwidget.h3
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp2
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp10
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp2
-rw-r--r--src/widgets/styles/qandroidstyle.cpp2
-rw-r--r--src/widgets/styles/qcommonstyle.cpp62
-rw-r--r--src/widgets/styles/qdrawutil.cpp8
-rw-r--r--src/widgets/styles/qgtk2painter.cpp699
-rw-r--r--src/widgets/styles/qgtk2painter_p.h100
-rw-r--r--src/widgets/styles/qgtkpainter_p.h119
-rw-r--r--src/widgets/styles/qgtkstyle.cpp4257
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp891
-rw-r--r--src/widgets/styles/qgtkstyle_p.h123
-rw-r--r--src/widgets/styles/qgtkstyle_p_p.h449
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm82
-rw-r--r--src/widgets/styles/qmacstyle_mac_p_p.h3
-rw-r--r--src/widgets/styles/qpixmapstyle.cpp (renamed from src/plugins/styles/bb10style/qpixmapstyle.cpp)300
-rw-r--r--src/widgets/styles/qpixmapstyle_p.h (renamed from src/plugins/styles/bb10style/qpixmapstyle.h)92
-rw-r--r--src/widgets/styles/qpixmapstyle_p_p.h86
-rw-r--r--src/widgets/styles/qstyle.cpp11
-rw-r--r--src/widgets/styles/qstyle.h26
-rw-r--r--src/widgets/styles/qstylefactory.cpp14
-rw-r--r--src/widgets/styles/qstyleoption.h24
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp129
-rw-r--r--src/widgets/styles/qstylesheetstyle_default.cpp3
-rw-r--r--src/widgets/styles/qstylesheetstyle_p.h7
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp4
-rw-r--r--src/widgets/styles/qwindowsxpstyle.cpp8
-rw-r--r--src/widgets/styles/styles.pri30
-rw-r--r--src/widgets/util/qcolormap.cpp2
-rw-r--r--src/widgets/util/qcompleter.cpp8
-rw-r--r--src/widgets/util/qflickgesture.cpp6
-rw-r--r--src/widgets/util/qscroller.cpp12
-rw-r--r--src/widgets/util/qscroller_mac.mm4
-rw-r--r--src/widgets/util/qscroller_p.h6
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp2
-rw-r--r--src/widgets/util/qsystemtrayicon_x11.cpp4
-rw-r--r--src/widgets/util/qundostack.cpp12
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp6
-rw-r--r--src/widgets/widgets/qabstractslider.cpp19
-rw-r--r--src/widgets/widgets/qabstractslider_p.h3
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp4
-rw-r--r--src/widgets/widgets/qcalendarwidget.cpp128
-rw-r--r--src/widgets/widgets/qcombobox.cpp39
-rw-r--r--src/widgets/widgets/qcombobox.h2
-rw-r--r--src/widgets/widgets/qdatetimeedit.cpp8
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp11
-rw-r--r--src/widgets/widgets/qdockarealayout.cpp24
-rw-r--r--src/widgets/widgets/qdockarealayout_p.h8
-rw-r--r--src/widgets/widgets/qgroupbox.cpp8
-rw-r--r--src/widgets/widgets/qlabel.cpp6
-rw-r--r--src/widgets/widgets/qlabel.h2
-rw-r--r--src/widgets/widgets/qlcdnumber.cpp4
-rw-r--r--src/widgets/widgets/qlineedit.cpp5
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp45
-rw-r--r--src/widgets/widgets/qlineedit_p.h25
-rw-r--r--src/widgets/widgets/qmaccocoaviewcontainer_mac.mm4
-rw-r--r--src/widgets/widgets/qmacnativewidget_mac.mm4
-rw-r--r--src/widgets/widgets/qmainwindow.cpp2
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp2
-rw-r--r--src/widgets/widgets/qmainwindowlayout_p.h14
-rw-r--r--src/widgets/widgets/qmdiarea.cpp63
-rw-r--r--src/widgets/widgets/qmdiarea_p.h2
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp14
-rw-r--r--src/widgets/widgets/qmenu_mac.mm4
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp4
-rw-r--r--src/widgets/widgets/qscrollbar.h7
-rw-r--r--src/widgets/widgets/qspinbox.cpp2
-rw-r--r--src/widgets/widgets/qsplitter.cpp6
-rw-r--r--src/widgets/widgets/qstackedwidget.cpp2
-rw-r--r--src/widgets/widgets/qstatusbar.cpp4
-rw-r--r--src/widgets/widgets/qtabbar.cpp257
-rw-r--r--src/widgets/widgets/qtabbar_p.h4
-rw-r--r--src/widgets/widgets/qtextbrowser.cpp6
-rw-r--r--src/widgets/widgets/qtextedit.cpp2
-rw-r--r--src/widgets/widgets/qtoolbararealayout.cpp4
-rw-r--r--src/widgets/widgets/qtoolbox.cpp6
-rw-r--r--src/widgets/widgets/qwidgetanimator.cpp4
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp37
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h1
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp4
-rw-r--r--src/xml/sax/qxml.cpp45
-rw-r--r--src/xml/sax/qxml_p.h4
855 files changed, 17584 insertions, 22033 deletions
diff --git a/src/3rdparty/double-conversion/LICENSE b/src/3rdparty/double-conversion/LICENSE
new file mode 100644
index 0000000000..933718a9ef
--- /dev/null
+++ b/src/3rdparty/double-conversion/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2006-2011, the V8 project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Google Inc. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/3rdparty/double-conversion/README b/src/3rdparty/double-conversion/README
new file mode 100644
index 0000000000..75d08df5fe
--- /dev/null
+++ b/src/3rdparty/double-conversion/README
@@ -0,0 +1,8 @@
+This is a copy of the library for binary-decimal and decimal-binary
+conversion routines for IEEE doubles, available from
+
+ https://github.com/google/double-conversion
+
+commit 2fb03de56faa32bbba5e02222528e7b760f71d77
+
+See the LICENSE file for license information.
diff --git a/src/3rdparty/double-conversion/bignum-dtoa.cc b/src/3rdparty/double-conversion/bignum-dtoa.cc
new file mode 100644
index 0000000000..f1ad7a5ae8
--- /dev/null
+++ b/src/3rdparty/double-conversion/bignum-dtoa.cc
@@ -0,0 +1,641 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <math.h>
+
+#include "bignum-dtoa.h"
+
+#include "bignum.h"
+#include "ieee.h"
+
+namespace double_conversion {
+
+static int NormalizedExponent(uint64_t significand, int exponent) {
+ ASSERT(significand != 0);
+ while ((significand & Double::kHiddenBit) == 0) {
+ significand = significand << 1;
+ exponent = exponent - 1;
+ }
+ return exponent;
+}
+
+
+// Forward declarations:
+// Returns an estimation of k such that 10^(k-1) <= v < 10^k.
+static int EstimatePower(int exponent);
+// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
+// and denominator.
+static void InitialScaledStartValues(uint64_t significand,
+ int exponent,
+ bool lower_boundary_is_closer,
+ int estimated_power,
+ bool need_boundary_deltas,
+ Bignum* numerator,
+ Bignum* denominator,
+ Bignum* delta_minus,
+ Bignum* delta_plus);
+// Multiplies numerator/denominator so that its values lies in the range 1-10.
+// Returns decimal_point s.t.
+// v = numerator'/denominator' * 10^(decimal_point-1)
+// where numerator' and denominator' are the values of numerator and
+// denominator after the call to this function.
+static void FixupMultiply10(int estimated_power, bool is_even,
+ int* decimal_point,
+ Bignum* numerator, Bignum* denominator,
+ Bignum* delta_minus, Bignum* delta_plus);
+// Generates digits from the left to the right and stops when the generated
+// digits yield the shortest decimal representation of v.
+static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
+ Bignum* delta_minus, Bignum* delta_plus,
+ bool is_even,
+ Vector<char> buffer, int* length);
+// Generates 'requested_digits' after the decimal point.
+static void BignumToFixed(int requested_digits, int* decimal_point,
+ Bignum* numerator, Bignum* denominator,
+ Vector<char>(buffer), int* length);
+// Generates 'count' digits of numerator/denominator.
+// Once 'count' digits have been produced rounds the result depending on the
+// remainder (remainders of exactly .5 round upwards). Might update the
+// decimal_point when rounding up (for example for 0.9999).
+static void GenerateCountedDigits(int count, int* decimal_point,
+ Bignum* numerator, Bignum* denominator,
+ Vector<char>(buffer), int* length);
+
+
+void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
+ Vector<char> buffer, int* length, int* decimal_point) {
+ ASSERT(v > 0);
+ ASSERT(!Double(v).IsSpecial());
+ uint64_t significand;
+ int exponent;
+ bool lower_boundary_is_closer;
+ if (mode == BIGNUM_DTOA_SHORTEST_SINGLE) {
+ float f = static_cast<float>(v);
+ ASSERT(f == v);
+ significand = Single(f).Significand();
+ exponent = Single(f).Exponent();
+ lower_boundary_is_closer = Single(f).LowerBoundaryIsCloser();
+ } else {
+ significand = Double(v).Significand();
+ exponent = Double(v).Exponent();
+ lower_boundary_is_closer = Double(v).LowerBoundaryIsCloser();
+ }
+ bool need_boundary_deltas =
+ (mode == BIGNUM_DTOA_SHORTEST || mode == BIGNUM_DTOA_SHORTEST_SINGLE);
+
+ bool is_even = (significand & 1) == 0;
+ int normalized_exponent = NormalizedExponent(significand, exponent);
+ // estimated_power might be too low by 1.
+ int estimated_power = EstimatePower(normalized_exponent);
+
+ // Shortcut for Fixed.
+ // The requested digits correspond to the digits after the point. If the
+ // number is much too small, then there is no need in trying to get any
+ // digits.
+ if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) {
+ buffer[0] = '\0';
+ *length = 0;
+ // Set decimal-point to -requested_digits. This is what Gay does.
+ // Note that it should not have any effect anyways since the string is
+ // empty.
+ *decimal_point = -requested_digits;
+ return;
+ }
+
+ Bignum numerator;
+ Bignum denominator;
+ Bignum delta_minus;
+ Bignum delta_plus;
+ // Make sure the bignum can grow large enough. The smallest double equals
+ // 4e-324. In this case the denominator needs fewer than 324*4 binary digits.
+ // The maximum double is 1.7976931348623157e308 which needs fewer than
+ // 308*4 binary digits.
+ ASSERT(Bignum::kMaxSignificantBits >= 324*4);
+ InitialScaledStartValues(significand, exponent, lower_boundary_is_closer,
+ estimated_power, need_boundary_deltas,
+ &numerator, &denominator,
+ &delta_minus, &delta_plus);
+ // We now have v = (numerator / denominator) * 10^estimated_power.
+ FixupMultiply10(estimated_power, is_even, decimal_point,
+ &numerator, &denominator,
+ &delta_minus, &delta_plus);
+ // We now have v = (numerator / denominator) * 10^(decimal_point-1), and
+ // 1 <= (numerator + delta_plus) / denominator < 10
+ switch (mode) {
+ case BIGNUM_DTOA_SHORTEST:
+ case BIGNUM_DTOA_SHORTEST_SINGLE:
+ GenerateShortestDigits(&numerator, &denominator,
+ &delta_minus, &delta_plus,
+ is_even, buffer, length);
+ break;
+ case BIGNUM_DTOA_FIXED:
+ BignumToFixed(requested_digits, decimal_point,
+ &numerator, &denominator,
+ buffer, length);
+ break;
+ case BIGNUM_DTOA_PRECISION:
+ GenerateCountedDigits(requested_digits, decimal_point,
+ &numerator, &denominator,
+ buffer, length);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ buffer[*length] = '\0';
+}
+
+
+// The procedure starts generating digits from the left to the right and stops
+// when the generated digits yield the shortest decimal representation of v. A
+// decimal representation of v is a number lying closer to v than to any other
+// double, so it converts to v when read.
+//
+// This is true if d, the decimal representation, is between m- and m+, the
+// upper and lower boundaries. d must be strictly between them if !is_even.
+// m- := (numerator - delta_minus) / denominator
+// m+ := (numerator + delta_plus) / denominator
+//
+// Precondition: 0 <= (numerator+delta_plus) / denominator < 10.
+// If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit
+// will be produced. This should be the standard precondition.
+static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
+ Bignum* delta_minus, Bignum* delta_plus,
+ bool is_even,
+ Vector<char> buffer, int* length) {
+ // Small optimization: if delta_minus and delta_plus are the same just reuse
+ // one of the two bignums.
+ if (Bignum::Equal(*delta_minus, *delta_plus)) {
+ delta_plus = delta_minus;
+ }
+ *length = 0;
+ for (;;) {
+ uint16_t digit;
+ digit = numerator->DivideModuloIntBignum(*denominator);
+ ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
+ // digit = numerator / denominator (integer division).
+ // numerator = numerator % denominator.
+ buffer[(*length)++] = static_cast<char>(digit + '0');
+
+ // Can we stop already?
+ // If the remainder of the division is less than the distance to the lower
+ // boundary we can stop. In this case we simply round down (discarding the
+ // remainder).
+ // Similarly we test if we can round up (using the upper boundary).
+ bool in_delta_room_minus;
+ bool in_delta_room_plus;
+ if (is_even) {
+ in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus);
+ } else {
+ in_delta_room_minus = Bignum::Less(*numerator, *delta_minus);
+ }
+ if (is_even) {
+ in_delta_room_plus =
+ Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
+ } else {
+ in_delta_room_plus =
+ Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
+ }
+ if (!in_delta_room_minus && !in_delta_room_plus) {
+ // Prepare for next iteration.
+ numerator->Times10();
+ delta_minus->Times10();
+ // We optimized delta_plus to be equal to delta_minus (if they share the
+ // same value). So don't multiply delta_plus if they point to the same
+ // object.
+ if (delta_minus != delta_plus) {
+ delta_plus->Times10();
+ }
+ } else if (in_delta_room_minus && in_delta_room_plus) {
+ // Let's see if 2*numerator < denominator.
+ // If yes, then the next digit would be < 5 and we can round down.
+ int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator);
+ if (compare < 0) {
+ // Remaining digits are less than .5. -> Round down (== do nothing).
+ } else if (compare > 0) {
+ // Remaining digits are more than .5 of denominator. -> Round up.
+ // Note that the last digit could not be a '9' as otherwise the whole
+ // loop would have stopped earlier.
+ // We still have an assert here in case the preconditions were not
+ // satisfied.
+ ASSERT(buffer[(*length) - 1] != '9');
+ buffer[(*length) - 1]++;
+ } else {
+ // Halfway case.
+ // TODO(floitsch): need a way to solve half-way cases.
+ // For now let's round towards even (since this is what Gay seems to
+ // do).
+
+ if ((buffer[(*length) - 1] - '0') % 2 == 0) {
+ // Round down => Do nothing.
+ } else {
+ ASSERT(buffer[(*length) - 1] != '9');
+ buffer[(*length) - 1]++;
+ }
+ }
+ return;
+ } else if (in_delta_room_minus) {
+ // Round down (== do nothing).
+ return;
+ } else { // in_delta_room_plus
+ // Round up.
+ // Note again that the last digit could not be '9' since this would have
+ // stopped the loop earlier.
+ // We still have an ASSERT here, in case the preconditions were not
+ // satisfied.
+ ASSERT(buffer[(*length) -1] != '9');
+ buffer[(*length) - 1]++;
+ return;
+ }
+ }
+}
+
+
+// Let v = numerator / denominator < 10.
+// Then we generate 'count' digits of d = x.xxxxx... (without the decimal point)
+// from left to right. Once 'count' digits have been produced we decide wether
+// to round up or down. Remainders of exactly .5 round upwards. Numbers such
+// as 9.999999 propagate a carry all the way, and change the
+// exponent (decimal_point), when rounding upwards.
+static void GenerateCountedDigits(int count, int* decimal_point,
+ Bignum* numerator, Bignum* denominator,
+ Vector<char> buffer, int* length) {
+ ASSERT(count >= 0);
+ for (int i = 0; i < count - 1; ++i) {
+ uint16_t digit;
+ digit = numerator->DivideModuloIntBignum(*denominator);
+ ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
+ // digit = numerator / denominator (integer division).
+ // numerator = numerator % denominator.
+ buffer[i] = static_cast<char>(digit + '0');
+ // Prepare for next iteration.
+ numerator->Times10();
+ }
+ // Generate the last digit.
+ uint16_t digit;
+ digit = numerator->DivideModuloIntBignum(*denominator);
+ if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
+ digit++;
+ }
+ ASSERT(digit <= 10);
+ buffer[count - 1] = static_cast<char>(digit + '0');
+ // Correct bad digits (in case we had a sequence of '9's). Propagate the
+ // carry until we hat a non-'9' or til we reach the first digit.
+ for (int i = count - 1; i > 0; --i) {
+ if (buffer[i] != '0' + 10) break;
+ buffer[i] = '0';
+ buffer[i - 1]++;
+ }
+ if (buffer[0] == '0' + 10) {
+ // Propagate a carry past the top place.
+ buffer[0] = '1';
+ (*decimal_point)++;
+ }
+ *length = count;
+}
+
+
+// Generates 'requested_digits' after the decimal point. It might omit
+// trailing '0's. If the input number is too small then no digits at all are
+// generated (ex.: 2 fixed digits for 0.00001).
+//
+// Input verifies: 1 <= (numerator + delta) / denominator < 10.
+static void BignumToFixed(int requested_digits, int* decimal_point,
+ Bignum* numerator, Bignum* denominator,
+ Vector<char>(buffer), int* length) {
+ // Note that we have to look at more than just the requested_digits, since
+ // a number could be rounded up. Example: v=0.5 with requested_digits=0.
+ // Even though the power of v equals 0 we can't just stop here.
+ if (-(*decimal_point) > requested_digits) {
+ // The number is definitively too small.
+ // Ex: 0.001 with requested_digits == 1.
+ // Set decimal-point to -requested_digits. This is what Gay does.
+ // Note that it should not have any effect anyways since the string is
+ // empty.
+ *decimal_point = -requested_digits;
+ *length = 0;
+ return;
+ } else if (-(*decimal_point) == requested_digits) {
+ // We only need to verify if the number rounds down or up.
+ // Ex: 0.04 and 0.06 with requested_digits == 1.
+ ASSERT(*decimal_point == -requested_digits);
+ // Initially the fraction lies in range (1, 10]. Multiply the denominator
+ // by 10 so that we can compare more easily.
+ denominator->Times10();
+ if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
+ // If the fraction is >= 0.5 then we have to include the rounded
+ // digit.
+ buffer[0] = '1';
+ *length = 1;
+ (*decimal_point)++;
+ } else {
+ // Note that we caught most of similar cases earlier.
+ *length = 0;
+ }
+ return;
+ } else {
+ // The requested digits correspond to the digits after the point.
+ // The variable 'needed_digits' includes the digits before the point.
+ int needed_digits = (*decimal_point) + requested_digits;
+ GenerateCountedDigits(needed_digits, decimal_point,
+ numerator, denominator,
+ buffer, length);
+ }
+}
+
+
+// Returns an estimation of k such that 10^(k-1) <= v < 10^k where
+// v = f * 2^exponent and 2^52 <= f < 2^53.
+// v is hence a normalized double with the given exponent. The output is an
+// approximation for the exponent of the decimal approimation .digits * 10^k.
+//
+// The result might undershoot by 1 in which case 10^k <= v < 10^k+1.
+// Note: this property holds for v's upper boundary m+ too.
+// 10^k <= m+ < 10^k+1.
+// (see explanation below).
+//
+// Examples:
+// EstimatePower(0) => 16
+// EstimatePower(-52) => 0
+//
+// Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0.
+static int EstimatePower(int exponent) {
+ // This function estimates log10 of v where v = f*2^e (with e == exponent).
+ // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)).
+ // Note that f is bounded by its container size. Let p = 53 (the double's
+ // significand size). Then 2^(p-1) <= f < 2^p.
+ //
+ // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close
+ // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)).
+ // The computed number undershoots by less than 0.631 (when we compute log3
+ // and not log10).
+ //
+ // Optimization: since we only need an approximated result this computation
+ // can be performed on 64 bit integers. On x86/x64 architecture the speedup is
+ // not really measurable, though.
+ //
+ // Since we want to avoid overshooting we decrement by 1e10 so that
+ // floating-point imprecisions don't affect us.
+ //
+ // Explanation for v's boundary m+: the computation takes advantage of
+ // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement
+ // (even for denormals where the delta can be much more important).
+
+ const double k1Log10 = 0.30102999566398114; // 1/lg(10)
+
+ // For doubles len(f) == 53 (don't forget the hidden bit).
+ const int kSignificandSize = Double::kSignificandSize;
+ double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10);
+ return static_cast<int>(estimate);
+}
+
+
+// See comments for InitialScaledStartValues.
+static void InitialScaledStartValuesPositiveExponent(
+ uint64_t significand, int exponent,
+ int estimated_power, bool need_boundary_deltas,
+ Bignum* numerator, Bignum* denominator,
+ Bignum* delta_minus, Bignum* delta_plus) {
+ // A positive exponent implies a positive power.
+ ASSERT(estimated_power >= 0);
+ // Since the estimated_power is positive we simply multiply the denominator
+ // by 10^estimated_power.
+
+ // numerator = v.
+ numerator->AssignUInt64(significand);
+ numerator->ShiftLeft(exponent);
+ // denominator = 10^estimated_power.
+ denominator->AssignPowerUInt16(10, estimated_power);
+
+ if (need_boundary_deltas) {
+ // Introduce a common denominator so that the deltas to the boundaries are
+ // integers.
+ denominator->ShiftLeft(1);
+ numerator->ShiftLeft(1);
+ // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
+ // denominator (of 2) delta_plus equals 2^e.
+ delta_plus->AssignUInt16(1);
+ delta_plus->ShiftLeft(exponent);
+ // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
+ delta_minus->AssignUInt16(1);
+ delta_minus->ShiftLeft(exponent);
+ }
+}
+
+
+// See comments for InitialScaledStartValues
+static void InitialScaledStartValuesNegativeExponentPositivePower(
+ uint64_t significand, int exponent,
+ int estimated_power, bool need_boundary_deltas,
+ Bignum* numerator, Bignum* denominator,
+ Bignum* delta_minus, Bignum* delta_plus) {
+ // v = f * 2^e with e < 0, and with estimated_power >= 0.
+ // This means that e is close to 0 (have a look at how estimated_power is
+ // computed).
+
+ // numerator = significand
+ // since v = significand * 2^exponent this is equivalent to
+ // numerator = v * / 2^-exponent
+ numerator->AssignUInt64(significand);
+ // denominator = 10^estimated_power * 2^-exponent (with exponent < 0)
+ denominator->AssignPowerUInt16(10, estimated_power);
+ denominator->ShiftLeft(-exponent);
+
+ if (need_boundary_deltas) {
+ // Introduce a common denominator so that the deltas to the boundaries are
+ // integers.
+ denominator->ShiftLeft(1);
+ numerator->ShiftLeft(1);
+ // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common
+ // denominator (of 2) delta_plus equals 2^e.
+ // Given that the denominator already includes v's exponent the distance
+ // to the boundaries is simply 1.
+ delta_plus->AssignUInt16(1);
+ // Same for delta_minus. The adjustments if f == 2^p-1 are done later.
+ delta_minus->AssignUInt16(1);
+ }
+}
+
+
+// See comments for InitialScaledStartValues
+static void InitialScaledStartValuesNegativeExponentNegativePower(
+ uint64_t significand, int exponent,
+ int estimated_power, bool need_boundary_deltas,
+ Bignum* numerator, Bignum* denominator,
+ Bignum* delta_minus, Bignum* delta_plus) {
+ // Instead of multiplying the denominator with 10^estimated_power we
+ // multiply all values (numerator and deltas) by 10^-estimated_power.
+
+ // Use numerator as temporary container for power_ten.
+ Bignum* power_ten = numerator;
+ power_ten->AssignPowerUInt16(10, -estimated_power);
+
+ if (need_boundary_deltas) {
+ // Since power_ten == numerator we must make a copy of 10^estimated_power
+ // before we complete the computation of the numerator.
+ // delta_plus = delta_minus = 10^estimated_power
+ delta_plus->AssignBignum(*power_ten);
+ delta_minus->AssignBignum(*power_ten);
+ }
+
+ // numerator = significand * 2 * 10^-estimated_power
+ // since v = significand * 2^exponent this is equivalent to
+ // numerator = v * 10^-estimated_power * 2 * 2^-exponent.
+ // Remember: numerator has been abused as power_ten. So no need to assign it
+ // to itself.
+ ASSERT(numerator == power_ten);
+ numerator->MultiplyByUInt64(significand);
+
+ // denominator = 2 * 2^-exponent with exponent < 0.
+ denominator->AssignUInt16(1);
+ denominator->ShiftLeft(-exponent);
+
+ if (need_boundary_deltas) {
+ // Introduce a common denominator so that the deltas to the boundaries are
+ // integers.
+ numerator->ShiftLeft(1);
+ denominator->ShiftLeft(1);
+ // With this shift the boundaries have their correct value, since
+ // delta_plus = 10^-estimated_power, and
+ // delta_minus = 10^-estimated_power.
+ // These assignments have been done earlier.
+ // The adjustments if f == 2^p-1 (lower boundary is closer) are done later.
+ }
+}
+
+
+// Let v = significand * 2^exponent.
+// Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator
+// and denominator. The functions GenerateShortestDigits and
+// GenerateCountedDigits will then convert this ratio to its decimal
+// representation d, with the required accuracy.
+// Then d * 10^estimated_power is the representation of v.
+// (Note: the fraction and the estimated_power might get adjusted before
+// generating the decimal representation.)
+//
+// The initial start values consist of:
+// - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power.
+// - a scaled (common) denominator.
+// optionally (used by GenerateShortestDigits to decide if it has the shortest
+// decimal converting back to v):
+// - v - m-: the distance to the lower boundary.
+// - m+ - v: the distance to the upper boundary.
+//
+// v, m+, m-, and therefore v - m- and m+ - v all share the same denominator.
+//
+// Let ep == estimated_power, then the returned values will satisfy:
+// v / 10^ep = numerator / denominator.
+// v's boundarys m- and m+:
+// m- / 10^ep == v / 10^ep - delta_minus / denominator
+// m+ / 10^ep == v / 10^ep + delta_plus / denominator
+// Or in other words:
+// m- == v - delta_minus * 10^ep / denominator;
+// m+ == v + delta_plus * 10^ep / denominator;
+//
+// Since 10^(k-1) <= v < 10^k (with k == estimated_power)
+// or 10^k <= v < 10^(k+1)
+// we then have 0.1 <= numerator/denominator < 1
+// or 1 <= numerator/denominator < 10
+//
+// It is then easy to kickstart the digit-generation routine.
+//
+// The boundary-deltas are only filled if the mode equals BIGNUM_DTOA_SHORTEST
+// or BIGNUM_DTOA_SHORTEST_SINGLE.
+
+static void InitialScaledStartValues(uint64_t significand,
+ int exponent,
+ bool lower_boundary_is_closer,
+ int estimated_power,
+ bool need_boundary_deltas,
+ Bignum* numerator,
+ Bignum* denominator,
+ Bignum* delta_minus,
+ Bignum* delta_plus) {
+ if (exponent >= 0) {
+ InitialScaledStartValuesPositiveExponent(
+ significand, exponent, estimated_power, need_boundary_deltas,
+ numerator, denominator, delta_minus, delta_plus);
+ } else if (estimated_power >= 0) {
+ InitialScaledStartValuesNegativeExponentPositivePower(
+ significand, exponent, estimated_power, need_boundary_deltas,
+ numerator, denominator, delta_minus, delta_plus);
+ } else {
+ InitialScaledStartValuesNegativeExponentNegativePower(
+ significand, exponent, estimated_power, need_boundary_deltas,
+ numerator, denominator, delta_minus, delta_plus);
+ }
+
+ if (need_boundary_deltas && lower_boundary_is_closer) {
+ // The lower boundary is closer at half the distance of "normal" numbers.
+ // Increase the common denominator and adapt all but the delta_minus.
+ denominator->ShiftLeft(1); // *2
+ numerator->ShiftLeft(1); // *2
+ delta_plus->ShiftLeft(1); // *2
+ }
+}
+
+
+// This routine multiplies numerator/denominator so that its values lies in the
+// range 1-10. That is after a call to this function we have:
+// 1 <= (numerator + delta_plus) /denominator < 10.
+// Let numerator the input before modification and numerator' the argument
+// after modification, then the output-parameter decimal_point is such that
+// numerator / denominator * 10^estimated_power ==
+// numerator' / denominator' * 10^(decimal_point - 1)
+// In some cases estimated_power was too low, and this is already the case. We
+// then simply adjust the power so that 10^(k-1) <= v < 10^k (with k ==
+// estimated_power) but do not touch the numerator or denominator.
+// Otherwise the routine multiplies the numerator and the deltas by 10.
+static void FixupMultiply10(int estimated_power, bool is_even,
+ int* decimal_point,
+ Bignum* numerator, Bignum* denominator,
+ Bignum* delta_minus, Bignum* delta_plus) {
+ bool in_range;
+ if (is_even) {
+ // For IEEE doubles half-way cases (in decimal system numbers ending with 5)
+ // are rounded to the closest floating-point number with even significand.
+ in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0;
+ } else {
+ in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0;
+ }
+ if (in_range) {
+ // Since numerator + delta_plus >= denominator we already have
+ // 1 <= numerator/denominator < 10. Simply update the estimated_power.
+ *decimal_point = estimated_power + 1;
+ } else {
+ *decimal_point = estimated_power;
+ numerator->Times10();
+ if (Bignum::Equal(*delta_minus, *delta_plus)) {
+ delta_minus->Times10();
+ delta_plus->AssignBignum(*delta_minus);
+ } else {
+ delta_minus->Times10();
+ delta_plus->Times10();
+ }
+ }
+}
+
+} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/bignum-dtoa.h b/src/3rdparty/double-conversion/bignum-dtoa.h
new file mode 100644
index 0000000000..34b961992d
--- /dev/null
+++ b/src/3rdparty/double-conversion/bignum-dtoa.h
@@ -0,0 +1,84 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_BIGNUM_DTOA_H_
+#define DOUBLE_CONVERSION_BIGNUM_DTOA_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+enum BignumDtoaMode {
+ // Return the shortest correct representation.
+ // For example the output of 0.299999999999999988897 is (the less accurate but
+ // correct) 0.3.
+ BIGNUM_DTOA_SHORTEST,
+ // Same as BIGNUM_DTOA_SHORTEST but for single-precision floats.
+ BIGNUM_DTOA_SHORTEST_SINGLE,
+ // Return a fixed number of digits after the decimal point.
+ // For instance fixed(0.1, 4) becomes 0.1000
+ // If the input number is big, the output will be big.
+ BIGNUM_DTOA_FIXED,
+ // Return a fixed number of digits, no matter what the exponent is.
+ BIGNUM_DTOA_PRECISION
+};
+
+// Converts the given double 'v' to ascii.
+// The result should be interpreted as buffer * 10^(point-length).
+// The buffer will be null-terminated.
+//
+// The input v must be > 0 and different from NaN, and Infinity.
+//
+// The output depends on the given mode:
+// - SHORTEST: produce the least amount of digits for which the internal
+// identity requirement is still satisfied. If the digits are printed
+// (together with the correct exponent) then reading this number will give
+// 'v' again. The buffer will choose the representation that is closest to
+// 'v'. If there are two at the same distance, than the number is round up.
+// In this mode the 'requested_digits' parameter is ignored.
+// - FIXED: produces digits necessary to print a given number with
+// 'requested_digits' digits after the decimal point. The produced digits
+// might be too short in which case the caller has to fill the gaps with '0's.
+// Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
+// Halfway cases are rounded up. The call toFixed(0.15, 2) thus returns
+// buffer="2", point=0.
+// Note: the length of the returned buffer has no meaning wrt the significance
+// of its digits. That is, just because it contains '0's does not mean that
+// any other digit would not satisfy the internal identity requirement.
+// - PRECISION: produces 'requested_digits' where the first digit is not '0'.
+// Even though the length of produced digits usually equals
+// 'requested_digits', the function is allowed to return fewer digits, in
+// which case the caller has to fill the missing digits with '0's.
+// Halfway cases are again rounded up.
+// 'BignumDtoa' expects the given buffer to be big enough to hold all digits
+// and a terminating null-character.
+void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits,
+ Vector<char> buffer, int* length, int* point);
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_BIGNUM_DTOA_H_
diff --git a/src/3rdparty/double-conversion/bignum.cc b/src/3rdparty/double-conversion/bignum.cc
new file mode 100644
index 0000000000..2743d67e8d
--- /dev/null
+++ b/src/3rdparty/double-conversion/bignum.cc
@@ -0,0 +1,766 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "bignum.h"
+#include "utils.h"
+
+namespace double_conversion {
+
+Bignum::Bignum()
+ : bigits_(bigits_buffer_, kBigitCapacity), used_digits_(0), exponent_(0) {
+ for (int i = 0; i < kBigitCapacity; ++i) {
+ bigits_[i] = 0;
+ }
+}
+
+
+template<typename S>
+static int BitSize(S value) {
+ (void) value; // Mark variable as used.
+ return 8 * sizeof(value);
+}
+
+// Guaranteed to lie in one Bigit.
+void Bignum::AssignUInt16(uint16_t value) {
+ ASSERT(kBigitSize >= BitSize(value));
+ Zero();
+ if (value == 0) return;
+
+ EnsureCapacity(1);
+ bigits_[0] = value;
+ used_digits_ = 1;
+}
+
+
+void Bignum::AssignUInt64(uint64_t value) {
+ const int kUInt64Size = 64;
+
+ Zero();
+ if (value == 0) return;
+
+ int needed_bigits = kUInt64Size / kBigitSize + 1;
+ EnsureCapacity(needed_bigits);
+ for (int i = 0; i < needed_bigits; ++i) {
+ bigits_[i] = value & kBigitMask;
+ value = value >> kBigitSize;
+ }
+ used_digits_ = needed_bigits;
+ Clamp();
+}
+
+
+void Bignum::AssignBignum(const Bignum& other) {
+ exponent_ = other.exponent_;
+ for (int i = 0; i < other.used_digits_; ++i) {
+ bigits_[i] = other.bigits_[i];
+ }
+ // Clear the excess digits (if there were any).
+ for (int i = other.used_digits_; i < used_digits_; ++i) {
+ bigits_[i] = 0;
+ }
+ used_digits_ = other.used_digits_;
+}
+
+
+static uint64_t ReadUInt64(Vector<const char> buffer,
+ int from,
+ int digits_to_read) {
+ uint64_t result = 0;
+ for (int i = from; i < from + digits_to_read; ++i) {
+ int digit = buffer[i] - '0';
+ ASSERT(0 <= digit && digit <= 9);
+ result = result * 10 + digit;
+ }
+ return result;
+}
+
+
+void Bignum::AssignDecimalString(Vector<const char> value) {
+ // 2^64 = 18446744073709551616 > 10^19
+ const int kMaxUint64DecimalDigits = 19;
+ Zero();
+ int length = value.length();
+ int pos = 0;
+ // Let's just say that each digit needs 4 bits.
+ while (length >= kMaxUint64DecimalDigits) {
+ uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits);
+ pos += kMaxUint64DecimalDigits;
+ length -= kMaxUint64DecimalDigits;
+ MultiplyByPowerOfTen(kMaxUint64DecimalDigits);
+ AddUInt64(digits);
+ }
+ uint64_t digits = ReadUInt64(value, pos, length);
+ MultiplyByPowerOfTen(length);
+ AddUInt64(digits);
+ Clamp();
+}
+
+
+static int HexCharValue(char c) {
+ if ('0' <= c && c <= '9') return c - '0';
+ if ('a' <= c && c <= 'f') return 10 + c - 'a';
+ ASSERT('A' <= c && c <= 'F');
+ return 10 + c - 'A';
+}
+
+
+void Bignum::AssignHexString(Vector<const char> value) {
+ Zero();
+ int length = value.length();
+
+ int needed_bigits = length * 4 / kBigitSize + 1;
+ EnsureCapacity(needed_bigits);
+ int string_index = length - 1;
+ for (int i = 0; i < needed_bigits - 1; ++i) {
+ // These bigits are guaranteed to be "full".
+ Chunk current_bigit = 0;
+ for (int j = 0; j < kBigitSize / 4; j++) {
+ current_bigit += HexCharValue(value[string_index--]) << (j * 4);
+ }
+ bigits_[i] = current_bigit;
+ }
+ used_digits_ = needed_bigits - 1;
+
+ Chunk most_significant_bigit = 0; // Could be = 0;
+ for (int j = 0; j <= string_index; ++j) {
+ most_significant_bigit <<= 4;
+ most_significant_bigit += HexCharValue(value[j]);
+ }
+ if (most_significant_bigit != 0) {
+ bigits_[used_digits_] = most_significant_bigit;
+ used_digits_++;
+ }
+ Clamp();
+}
+
+
+void Bignum::AddUInt64(uint64_t operand) {
+ if (operand == 0) return;
+ Bignum other;
+ other.AssignUInt64(operand);
+ AddBignum(other);
+}
+
+
+void Bignum::AddBignum(const Bignum& other) {
+ ASSERT(IsClamped());
+ ASSERT(other.IsClamped());
+
+ // If this has a greater exponent than other append zero-bigits to this.
+ // After this call exponent_ <= other.exponent_.
+ Align(other);
+
+ // There are two possibilities:
+ // aaaaaaaaaaa 0000 (where the 0s represent a's exponent)
+ // bbbbb 00000000
+ // ----------------
+ // ccccccccccc 0000
+ // or
+ // aaaaaaaaaa 0000
+ // bbbbbbbbb 0000000
+ // -----------------
+ // cccccccccccc 0000
+ // In both cases we might need a carry bigit.
+
+ EnsureCapacity(1 + Max(BigitLength(), other.BigitLength()) - exponent_);
+ Chunk carry = 0;
+ int bigit_pos = other.exponent_ - exponent_;
+ ASSERT(bigit_pos >= 0);
+ for (int i = 0; i < other.used_digits_; ++i) {
+ Chunk sum = bigits_[bigit_pos] + other.bigits_[i] + carry;
+ bigits_[bigit_pos] = sum & kBigitMask;
+ carry = sum >> kBigitSize;
+ bigit_pos++;
+ }
+
+ while (carry != 0) {
+ Chunk sum = bigits_[bigit_pos] + carry;
+ bigits_[bigit_pos] = sum & kBigitMask;
+ carry = sum >> kBigitSize;
+ bigit_pos++;
+ }
+ used_digits_ = Max(bigit_pos, used_digits_);
+ ASSERT(IsClamped());
+}
+
+
+void Bignum::SubtractBignum(const Bignum& other) {
+ ASSERT(IsClamped());
+ ASSERT(other.IsClamped());
+ // We require this to be bigger than other.
+ ASSERT(LessEqual(other, *this));
+
+ Align(other);
+
+ int offset = other.exponent_ - exponent_;
+ Chunk borrow = 0;
+ int i;
+ for (i = 0; i < other.used_digits_; ++i) {
+ ASSERT((borrow == 0) || (borrow == 1));
+ Chunk difference = bigits_[i + offset] - other.bigits_[i] - borrow;
+ bigits_[i + offset] = difference & kBigitMask;
+ borrow = difference >> (kChunkSize - 1);
+ }
+ while (borrow != 0) {
+ Chunk difference = bigits_[i + offset] - borrow;
+ bigits_[i + offset] = difference & kBigitMask;
+ borrow = difference >> (kChunkSize - 1);
+ ++i;
+ }
+ Clamp();
+}
+
+
+void Bignum::ShiftLeft(int shift_amount) {
+ if (used_digits_ == 0) return;
+ exponent_ += shift_amount / kBigitSize;
+ int local_shift = shift_amount % kBigitSize;
+ EnsureCapacity(used_digits_ + 1);
+ BigitsShiftLeft(local_shift);
+}
+
+
+void Bignum::MultiplyByUInt32(uint32_t factor) {
+ if (factor == 1) return;
+ if (factor == 0) {
+ Zero();
+ return;
+ }
+ if (used_digits_ == 0) return;
+
+ // The product of a bigit with the factor is of size kBigitSize + 32.
+ // Assert that this number + 1 (for the carry) fits into double chunk.
+ ASSERT(kDoubleChunkSize >= kBigitSize + 32 + 1);
+ DoubleChunk carry = 0;
+ for (int i = 0; i < used_digits_; ++i) {
+ DoubleChunk product = static_cast<DoubleChunk>(factor) * bigits_[i] + carry;
+ bigits_[i] = static_cast<Chunk>(product & kBigitMask);
+ carry = (product >> kBigitSize);
+ }
+ while (carry != 0) {
+ EnsureCapacity(used_digits_ + 1);
+ bigits_[used_digits_] = carry & kBigitMask;
+ used_digits_++;
+ carry >>= kBigitSize;
+ }
+}
+
+
+void Bignum::MultiplyByUInt64(uint64_t factor) {
+ if (factor == 1) return;
+ if (factor == 0) {
+ Zero();
+ return;
+ }
+ ASSERT(kBigitSize < 32);
+ uint64_t carry = 0;
+ uint64_t low = factor & 0xFFFFFFFF;
+ uint64_t high = factor >> 32;
+ for (int i = 0; i < used_digits_; ++i) {
+ uint64_t product_low = low * bigits_[i];
+ uint64_t product_high = high * bigits_[i];
+ uint64_t tmp = (carry & kBigitMask) + product_low;
+ bigits_[i] = tmp & kBigitMask;
+ carry = (carry >> kBigitSize) + (tmp >> kBigitSize) +
+ (product_high << (32 - kBigitSize));
+ }
+ while (carry != 0) {
+ EnsureCapacity(used_digits_ + 1);
+ bigits_[used_digits_] = carry & kBigitMask;
+ used_digits_++;
+ carry >>= kBigitSize;
+ }
+}
+
+
+void Bignum::MultiplyByPowerOfTen(int exponent) {
+ const uint64_t kFive27 = UINT64_2PART_C(0x6765c793, fa10079d);
+ const uint16_t kFive1 = 5;
+ const uint16_t kFive2 = kFive1 * 5;
+ const uint16_t kFive3 = kFive2 * 5;
+ const uint16_t kFive4 = kFive3 * 5;
+ const uint16_t kFive5 = kFive4 * 5;
+ const uint16_t kFive6 = kFive5 * 5;
+ const uint32_t kFive7 = kFive6 * 5;
+ const uint32_t kFive8 = kFive7 * 5;
+ const uint32_t kFive9 = kFive8 * 5;
+ const uint32_t kFive10 = kFive9 * 5;
+ const uint32_t kFive11 = kFive10 * 5;
+ const uint32_t kFive12 = kFive11 * 5;
+ const uint32_t kFive13 = kFive12 * 5;
+ const uint32_t kFive1_to_12[] =
+ { kFive1, kFive2, kFive3, kFive4, kFive5, kFive6,
+ kFive7, kFive8, kFive9, kFive10, kFive11, kFive12 };
+
+ ASSERT(exponent >= 0);
+ if (exponent == 0) return;
+ if (used_digits_ == 0) return;
+
+ // We shift by exponent at the end just before returning.
+ int remaining_exponent = exponent;
+ while (remaining_exponent >= 27) {
+ MultiplyByUInt64(kFive27);
+ remaining_exponent -= 27;
+ }
+ while (remaining_exponent >= 13) {
+ MultiplyByUInt32(kFive13);
+ remaining_exponent -= 13;
+ }
+ if (remaining_exponent > 0) {
+ MultiplyByUInt32(kFive1_to_12[remaining_exponent - 1]);
+ }
+ ShiftLeft(exponent);
+}
+
+
+void Bignum::Square() {
+ ASSERT(IsClamped());
+ int product_length = 2 * used_digits_;
+ EnsureCapacity(product_length);
+
+ // Comba multiplication: compute each column separately.
+ // Example: r = a2a1a0 * b2b1b0.
+ // r = 1 * a0b0 +
+ // 10 * (a1b0 + a0b1) +
+ // 100 * (a2b0 + a1b1 + a0b2) +
+ // 1000 * (a2b1 + a1b2) +
+ // 10000 * a2b2
+ //
+ // In the worst case we have to accumulate nb-digits products of digit*digit.
+ //
+ // Assert that the additional number of bits in a DoubleChunk are enough to
+ // sum up used_digits of Bigit*Bigit.
+ if ((1 << (2 * (kChunkSize - kBigitSize))) <= used_digits_) {
+ UNIMPLEMENTED();
+ }
+ DoubleChunk accumulator = 0;
+ // First shift the digits so we don't overwrite them.
+ int copy_offset = used_digits_;
+ for (int i = 0; i < used_digits_; ++i) {
+ bigits_[copy_offset + i] = bigits_[i];
+ }
+ // We have two loops to avoid some 'if's in the loop.
+ for (int i = 0; i < used_digits_; ++i) {
+ // Process temporary digit i with power i.
+ // The sum of the two indices must be equal to i.
+ int bigit_index1 = i;
+ int bigit_index2 = 0;
+ // Sum all of the sub-products.
+ while (bigit_index1 >= 0) {
+ Chunk chunk1 = bigits_[copy_offset + bigit_index1];
+ Chunk chunk2 = bigits_[copy_offset + bigit_index2];
+ accumulator += static_cast<DoubleChunk>(chunk1) * chunk2;
+ bigit_index1--;
+ bigit_index2++;
+ }
+ bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask;
+ accumulator >>= kBigitSize;
+ }
+ for (int i = used_digits_; i < product_length; ++i) {
+ int bigit_index1 = used_digits_ - 1;
+ int bigit_index2 = i - bigit_index1;
+ // Invariant: sum of both indices is again equal to i.
+ // Inner loop runs 0 times on last iteration, emptying accumulator.
+ while (bigit_index2 < used_digits_) {
+ Chunk chunk1 = bigits_[copy_offset + bigit_index1];
+ Chunk chunk2 = bigits_[copy_offset + bigit_index2];
+ accumulator += static_cast<DoubleChunk>(chunk1) * chunk2;
+ bigit_index1--;
+ bigit_index2++;
+ }
+ // The overwritten bigits_[i] will never be read in further loop iterations,
+ // because bigit_index1 and bigit_index2 are always greater
+ // than i - used_digits_.
+ bigits_[i] = static_cast<Chunk>(accumulator) & kBigitMask;
+ accumulator >>= kBigitSize;
+ }
+ // Since the result was guaranteed to lie inside the number the
+ // accumulator must be 0 now.
+ ASSERT(accumulator == 0);
+
+ // Don't forget to update the used_digits and the exponent.
+ used_digits_ = product_length;
+ exponent_ *= 2;
+ Clamp();
+}
+
+
+void Bignum::AssignPowerUInt16(uint16_t base, int power_exponent) {
+ ASSERT(base != 0);
+ ASSERT(power_exponent >= 0);
+ if (power_exponent == 0) {
+ AssignUInt16(1);
+ return;
+ }
+ Zero();
+ int shifts = 0;
+ // We expect base to be in range 2-32, and most often to be 10.
+ // It does not make much sense to implement different algorithms for counting
+ // the bits.
+ while ((base & 1) == 0) {
+ base >>= 1;
+ shifts++;
+ }
+ int bit_size = 0;
+ int tmp_base = base;
+ while (tmp_base != 0) {
+ tmp_base >>= 1;
+ bit_size++;
+ }
+ int final_size = bit_size * power_exponent;
+ // 1 extra bigit for the shifting, and one for rounded final_size.
+ EnsureCapacity(final_size / kBigitSize + 2);
+
+ // Left to Right exponentiation.
+ int mask = 1;
+ while (power_exponent >= mask) mask <<= 1;
+
+ // The mask is now pointing to the bit above the most significant 1-bit of
+ // power_exponent.
+ // Get rid of first 1-bit;
+ mask >>= 2;
+ uint64_t this_value = base;
+
+ bool delayed_multipliciation = false;
+ const uint64_t max_32bits = 0xFFFFFFFF;
+ while (mask != 0 && this_value <= max_32bits) {
+ this_value = this_value * this_value;
+ // Verify that there is enough space in this_value to perform the
+ // multiplication. The first bit_size bits must be 0.
+ if ((power_exponent & mask) != 0) {
+ uint64_t base_bits_mask =
+ ~((static_cast<uint64_t>(1) << (64 - bit_size)) - 1);
+ bool high_bits_zero = (this_value & base_bits_mask) == 0;
+ if (high_bits_zero) {
+ this_value *= base;
+ } else {
+ delayed_multipliciation = true;
+ }
+ }
+ mask >>= 1;
+ }
+ AssignUInt64(this_value);
+ if (delayed_multipliciation) {
+ MultiplyByUInt32(base);
+ }
+
+ // Now do the same thing as a bignum.
+ while (mask != 0) {
+ Square();
+ if ((power_exponent & mask) != 0) {
+ MultiplyByUInt32(base);
+ }
+ mask >>= 1;
+ }
+
+ // And finally add the saved shifts.
+ ShiftLeft(shifts * power_exponent);
+}
+
+
+// Precondition: this/other < 16bit.
+uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
+ ASSERT(IsClamped());
+ ASSERT(other.IsClamped());
+ ASSERT(other.used_digits_ > 0);
+
+ // Easy case: if we have less digits than the divisor than the result is 0.
+ // Note: this handles the case where this == 0, too.
+ if (BigitLength() < other.BigitLength()) {
+ return 0;
+ }
+
+ Align(other);
+
+ uint16_t result = 0;
+
+ // Start by removing multiples of 'other' until both numbers have the same
+ // number of digits.
+ while (BigitLength() > other.BigitLength()) {
+ // This naive approach is extremely inefficient if `this` divided by other
+ // is big. This function is implemented for doubleToString where
+ // the result should be small (less than 10).
+ ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16));
+ ASSERT(bigits_[used_digits_ - 1] < 0x10000);
+ // Remove the multiples of the first digit.
+ // Example this = 23 and other equals 9. -> Remove 2 multiples.
+ result += static_cast<uint16_t>(bigits_[used_digits_ - 1]);
+ SubtractTimes(other, bigits_[used_digits_ - 1]);
+ }
+
+ ASSERT(BigitLength() == other.BigitLength());
+
+ // Both bignums are at the same length now.
+ // Since other has more than 0 digits we know that the access to
+ // bigits_[used_digits_ - 1] is safe.
+ Chunk this_bigit = bigits_[used_digits_ - 1];
+ Chunk other_bigit = other.bigits_[other.used_digits_ - 1];
+
+ if (other.used_digits_ == 1) {
+ // Shortcut for easy (and common) case.
+ int quotient = this_bigit / other_bigit;
+ bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient;
+ ASSERT(quotient < 0x10000);
+ result += static_cast<uint16_t>(quotient);
+ Clamp();
+ return result;
+ }
+
+ int division_estimate = this_bigit / (other_bigit + 1);
+ ASSERT(division_estimate < 0x10000);
+ result += static_cast<uint16_t>(division_estimate);
+ SubtractTimes(other, division_estimate);
+
+ if (other_bigit * (division_estimate + 1) > this_bigit) {
+ // No need to even try to subtract. Even if other's remaining digits were 0
+ // another subtraction would be too much.
+ return result;
+ }
+
+ while (LessEqual(other, *this)) {
+ SubtractBignum(other);
+ result++;
+ }
+ return result;
+}
+
+
+template<typename S>
+static int SizeInHexChars(S number) {
+ ASSERT(number > 0);
+ int result = 0;
+ while (number != 0) {
+ number >>= 4;
+ result++;
+ }
+ return result;
+}
+
+
+static char HexCharOfValue(int value) {
+ ASSERT(0 <= value && value <= 16);
+ if (value < 10) return static_cast<char>(value + '0');
+ return static_cast<char>(value - 10 + 'A');
+}
+
+
+bool Bignum::ToHexString(char* buffer, int buffer_size) const {
+ ASSERT(IsClamped());
+ // Each bigit must be printable as separate hex-character.
+ ASSERT(kBigitSize % 4 == 0);
+ const int kHexCharsPerBigit = kBigitSize / 4;
+
+ if (used_digits_ == 0) {
+ if (buffer_size < 2) return false;
+ buffer[0] = '0';
+ buffer[1] = '\0';
+ return true;
+ }
+ // We add 1 for the terminating '\0' character.
+ int needed_chars = (BigitLength() - 1) * kHexCharsPerBigit +
+ SizeInHexChars(bigits_[used_digits_ - 1]) + 1;
+ if (needed_chars > buffer_size) return false;
+ int string_index = needed_chars - 1;
+ buffer[string_index--] = '\0';
+ for (int i = 0; i < exponent_; ++i) {
+ for (int j = 0; j < kHexCharsPerBigit; ++j) {
+ buffer[string_index--] = '0';
+ }
+ }
+ for (int i = 0; i < used_digits_ - 1; ++i) {
+ Chunk current_bigit = bigits_[i];
+ for (int j = 0; j < kHexCharsPerBigit; ++j) {
+ buffer[string_index--] = HexCharOfValue(current_bigit & 0xF);
+ current_bigit >>= 4;
+ }
+ }
+ // And finally the last bigit.
+ Chunk most_significant_bigit = bigits_[used_digits_ - 1];
+ while (most_significant_bigit != 0) {
+ buffer[string_index--] = HexCharOfValue(most_significant_bigit & 0xF);
+ most_significant_bigit >>= 4;
+ }
+ return true;
+}
+
+
+Bignum::Chunk Bignum::BigitAt(int index) const {
+ if (index >= BigitLength()) return 0;
+ if (index < exponent_) return 0;
+ return bigits_[index - exponent_];
+}
+
+
+int Bignum::Compare(const Bignum& a, const Bignum& b) {
+ ASSERT(a.IsClamped());
+ ASSERT(b.IsClamped());
+ int bigit_length_a = a.BigitLength();
+ int bigit_length_b = b.BigitLength();
+ if (bigit_length_a < bigit_length_b) return -1;
+ if (bigit_length_a > bigit_length_b) return +1;
+ for (int i = bigit_length_a - 1; i >= Min(a.exponent_, b.exponent_); --i) {
+ Chunk bigit_a = a.BigitAt(i);
+ Chunk bigit_b = b.BigitAt(i);
+ if (bigit_a < bigit_b) return -1;
+ if (bigit_a > bigit_b) return +1;
+ // Otherwise they are equal up to this digit. Try the next digit.
+ }
+ return 0;
+}
+
+
+int Bignum::PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c) {
+ ASSERT(a.IsClamped());
+ ASSERT(b.IsClamped());
+ ASSERT(c.IsClamped());
+ if (a.BigitLength() < b.BigitLength()) {
+ return PlusCompare(b, a, c);
+ }
+ if (a.BigitLength() + 1 < c.BigitLength()) return -1;
+ if (a.BigitLength() > c.BigitLength()) return +1;
+ // The exponent encodes 0-bigits. So if there are more 0-digits in 'a' than
+ // 'b' has digits, then the bigit-length of 'a'+'b' must be equal to the one
+ // of 'a'.
+ if (a.exponent_ >= b.BigitLength() && a.BigitLength() < c.BigitLength()) {
+ return -1;
+ }
+
+ Chunk borrow = 0;
+ // Starting at min_exponent all digits are == 0. So no need to compare them.
+ int min_exponent = Min(Min(a.exponent_, b.exponent_), c.exponent_);
+ for (int i = c.BigitLength() - 1; i >= min_exponent; --i) {
+ Chunk chunk_a = a.BigitAt(i);
+ Chunk chunk_b = b.BigitAt(i);
+ Chunk chunk_c = c.BigitAt(i);
+ Chunk sum = chunk_a + chunk_b;
+ if (sum > chunk_c + borrow) {
+ return +1;
+ } else {
+ borrow = chunk_c + borrow - sum;
+ if (borrow > 1) return -1;
+ borrow <<= kBigitSize;
+ }
+ }
+ if (borrow == 0) return 0;
+ return -1;
+}
+
+
+void Bignum::Clamp() {
+ while (used_digits_ > 0 && bigits_[used_digits_ - 1] == 0) {
+ used_digits_--;
+ }
+ if (used_digits_ == 0) {
+ // Zero.
+ exponent_ = 0;
+ }
+}
+
+
+bool Bignum::IsClamped() const {
+ return used_digits_ == 0 || bigits_[used_digits_ - 1] != 0;
+}
+
+
+void Bignum::Zero() {
+ for (int i = 0; i < used_digits_; ++i) {
+ bigits_[i] = 0;
+ }
+ used_digits_ = 0;
+ exponent_ = 0;
+}
+
+
+void Bignum::Align(const Bignum& other) {
+ if (exponent_ > other.exponent_) {
+ // If "X" represents a "hidden" digit (by the exponent) then we are in the
+ // following case (a == this, b == other):
+ // a: aaaaaaXXXX or a: aaaaaXXX
+ // b: bbbbbbX b: bbbbbbbbXX
+ // We replace some of the hidden digits (X) of a with 0 digits.
+ // a: aaaaaa000X or a: aaaaa0XX
+ int zero_digits = exponent_ - other.exponent_;
+ EnsureCapacity(used_digits_ + zero_digits);
+ for (int i = used_digits_ - 1; i >= 0; --i) {
+ bigits_[i + zero_digits] = bigits_[i];
+ }
+ for (int i = 0; i < zero_digits; ++i) {
+ bigits_[i] = 0;
+ }
+ used_digits_ += zero_digits;
+ exponent_ -= zero_digits;
+ ASSERT(used_digits_ >= 0);
+ ASSERT(exponent_ >= 0);
+ }
+}
+
+
+void Bignum::BigitsShiftLeft(int shift_amount) {
+ ASSERT(shift_amount < kBigitSize);
+ ASSERT(shift_amount >= 0);
+ Chunk carry = 0;
+ for (int i = 0; i < used_digits_; ++i) {
+ Chunk new_carry = bigits_[i] >> (kBigitSize - shift_amount);
+ bigits_[i] = ((bigits_[i] << shift_amount) + carry) & kBigitMask;
+ carry = new_carry;
+ }
+ if (carry != 0) {
+ bigits_[used_digits_] = carry;
+ used_digits_++;
+ }
+}
+
+
+void Bignum::SubtractTimes(const Bignum& other, int factor) {
+ ASSERT(exponent_ <= other.exponent_);
+ if (factor < 3) {
+ for (int i = 0; i < factor; ++i) {
+ SubtractBignum(other);
+ }
+ return;
+ }
+ Chunk borrow = 0;
+ int exponent_diff = other.exponent_ - exponent_;
+ for (int i = 0; i < other.used_digits_; ++i) {
+ DoubleChunk product = static_cast<DoubleChunk>(factor) * other.bigits_[i];
+ DoubleChunk remove = borrow + product;
+ Chunk difference = bigits_[i + exponent_diff] - (remove & kBigitMask);
+ bigits_[i + exponent_diff] = difference & kBigitMask;
+ borrow = static_cast<Chunk>((difference >> (kChunkSize - 1)) +
+ (remove >> kBigitSize));
+ }
+ for (int i = other.used_digits_ + exponent_diff; i < used_digits_; ++i) {
+ if (borrow == 0) return;
+ Chunk difference = bigits_[i] - borrow;
+ bigits_[i] = difference & kBigitMask;
+ borrow = difference >> (kChunkSize - 1);
+ }
+ Clamp();
+}
+
+
+} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/bignum.h b/src/3rdparty/double-conversion/bignum.h
new file mode 100644
index 0000000000..5ec3544f57
--- /dev/null
+++ b/src/3rdparty/double-conversion/bignum.h
@@ -0,0 +1,145 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_BIGNUM_H_
+#define DOUBLE_CONVERSION_BIGNUM_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+class Bignum {
+ public:
+ // 3584 = 128 * 28. We can represent 2^3584 > 10^1000 accurately.
+ // This bignum can encode much bigger numbers, since it contains an
+ // exponent.
+ static const int kMaxSignificantBits = 3584;
+
+ Bignum();
+ void AssignUInt16(uint16_t value);
+ void AssignUInt64(uint64_t value);
+ void AssignBignum(const Bignum& other);
+
+ void AssignDecimalString(Vector<const char> value);
+ void AssignHexString(Vector<const char> value);
+
+ void AssignPowerUInt16(uint16_t base, int exponent);
+
+ void AddUInt16(uint16_t operand);
+ void AddUInt64(uint64_t operand);
+ void AddBignum(const Bignum& other);
+ // Precondition: this >= other.
+ void SubtractBignum(const Bignum& other);
+
+ void Square();
+ void ShiftLeft(int shift_amount);
+ void MultiplyByUInt32(uint32_t factor);
+ void MultiplyByUInt64(uint64_t factor);
+ void MultiplyByPowerOfTen(int exponent);
+ void Times10() { return MultiplyByUInt32(10); }
+ // Pseudocode:
+ // int result = this / other;
+ // this = this % other;
+ // In the worst case this function is in O(this/other).
+ uint16_t DivideModuloIntBignum(const Bignum& other);
+
+ bool ToHexString(char* buffer, int buffer_size) const;
+
+ // Returns
+ // -1 if a < b,
+ // 0 if a == b, and
+ // +1 if a > b.
+ static int Compare(const Bignum& a, const Bignum& b);
+ static bool Equal(const Bignum& a, const Bignum& b) {
+ return Compare(a, b) == 0;
+ }
+ static bool LessEqual(const Bignum& a, const Bignum& b) {
+ return Compare(a, b) <= 0;
+ }
+ static bool Less(const Bignum& a, const Bignum& b) {
+ return Compare(a, b) < 0;
+ }
+ // Returns Compare(a + b, c);
+ static int PlusCompare(const Bignum& a, const Bignum& b, const Bignum& c);
+ // Returns a + b == c
+ static bool PlusEqual(const Bignum& a, const Bignum& b, const Bignum& c) {
+ return PlusCompare(a, b, c) == 0;
+ }
+ // Returns a + b <= c
+ static bool PlusLessEqual(const Bignum& a, const Bignum& b, const Bignum& c) {
+ return PlusCompare(a, b, c) <= 0;
+ }
+ // Returns a + b < c
+ static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) {
+ return PlusCompare(a, b, c) < 0;
+ }
+ private:
+ typedef uint32_t Chunk;
+ typedef uint64_t DoubleChunk;
+
+ static const int kChunkSize = sizeof(Chunk) * 8;
+ static const int kDoubleChunkSize = sizeof(DoubleChunk) * 8;
+ // With bigit size of 28 we loose some bits, but a double still fits easily
+ // into two chunks, and more importantly we can use the Comba multiplication.
+ static const int kBigitSize = 28;
+ static const Chunk kBigitMask = (1 << kBigitSize) - 1;
+ // Every instance allocates kBigitLength chunks on the stack. Bignums cannot
+ // grow. There are no checks if the stack-allocated space is sufficient.
+ static const int kBigitCapacity = kMaxSignificantBits / kBigitSize;
+
+ void EnsureCapacity(int size) {
+ if (size > kBigitCapacity) {
+ UNREACHABLE();
+ }
+ }
+ void Align(const Bignum& other);
+ void Clamp();
+ bool IsClamped() const;
+ void Zero();
+ // Requires this to have enough capacity (no tests done).
+ // Updates used_digits_ if necessary.
+ // shift_amount must be < kBigitSize.
+ void BigitsShiftLeft(int shift_amount);
+ // BigitLength includes the "hidden" digits encoded in the exponent.
+ int BigitLength() const { return used_digits_ + exponent_; }
+ Chunk BigitAt(int index) const;
+ void SubtractTimes(const Bignum& other, int factor);
+
+ Chunk bigits_buffer_[kBigitCapacity];
+ // A vector backed by bigits_buffer_. This way accesses to the array are
+ // checked for out-of-bounds errors.
+ Vector<Chunk> bigits_;
+ int used_digits_;
+ // The Bignum's value equals value(bigits_) * 2^(exponent_ * kBigitSize).
+ int exponent_;
+
+ DISALLOW_COPY_AND_ASSIGN(Bignum);
+};
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_BIGNUM_H_
diff --git a/src/3rdparty/double-conversion/cached-powers.cc b/src/3rdparty/double-conversion/cached-powers.cc
new file mode 100644
index 0000000000..9536f26927
--- /dev/null
+++ b/src/3rdparty/double-conversion/cached-powers.cc
@@ -0,0 +1,178 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdarg.h>
+#include <limits.h>
+#include <math.h>
+
+#include "utils.h"
+
+#include "cached-powers.h"
+
+namespace double_conversion {
+
+struct CachedPower {
+ uint64_t significand;
+ int16_t binary_exponent;
+ int16_t decimal_exponent;
+};
+
+static const CachedPower kCachedPowers[] = {
+ {UINT64_2PART_C(0xfa8fd5a0, 081c0288), -1220, -348},
+ {UINT64_2PART_C(0xbaaee17f, a23ebf76), -1193, -340},
+ {UINT64_2PART_C(0x8b16fb20, 3055ac76), -1166, -332},
+ {UINT64_2PART_C(0xcf42894a, 5dce35ea), -1140, -324},
+ {UINT64_2PART_C(0x9a6bb0aa, 55653b2d), -1113, -316},
+ {UINT64_2PART_C(0xe61acf03, 3d1a45df), -1087, -308},
+ {UINT64_2PART_C(0xab70fe17, c79ac6ca), -1060, -300},
+ {UINT64_2PART_C(0xff77b1fc, bebcdc4f), -1034, -292},
+ {UINT64_2PART_C(0xbe5691ef, 416bd60c), -1007, -284},
+ {UINT64_2PART_C(0x8dd01fad, 907ffc3c), -980, -276},
+ {UINT64_2PART_C(0xd3515c28, 31559a83), -954, -268},
+ {UINT64_2PART_C(0x9d71ac8f, ada6c9b5), -927, -260},
+ {UINT64_2PART_C(0xea9c2277, 23ee8bcb), -901, -252},
+ {UINT64_2PART_C(0xaecc4991, 4078536d), -874, -244},
+ {UINT64_2PART_C(0x823c1279, 5db6ce57), -847, -236},
+ {UINT64_2PART_C(0xc2109436, 4dfb5637), -821, -228},
+ {UINT64_2PART_C(0x9096ea6f, 3848984f), -794, -220},
+ {UINT64_2PART_C(0xd77485cb, 25823ac7), -768, -212},
+ {UINT64_2PART_C(0xa086cfcd, 97bf97f4), -741, -204},
+ {UINT64_2PART_C(0xef340a98, 172aace5), -715, -196},
+ {UINT64_2PART_C(0xb23867fb, 2a35b28e), -688, -188},
+ {UINT64_2PART_C(0x84c8d4df, d2c63f3b), -661, -180},
+ {UINT64_2PART_C(0xc5dd4427, 1ad3cdba), -635, -172},
+ {UINT64_2PART_C(0x936b9fce, bb25c996), -608, -164},
+ {UINT64_2PART_C(0xdbac6c24, 7d62a584), -582, -156},
+ {UINT64_2PART_C(0xa3ab6658, 0d5fdaf6), -555, -148},
+ {UINT64_2PART_C(0xf3e2f893, dec3f126), -529, -140},
+ {UINT64_2PART_C(0xb5b5ada8, aaff80b8), -502, -132},
+ {UINT64_2PART_C(0x87625f05, 6c7c4a8b), -475, -124},
+ {UINT64_2PART_C(0xc9bcff60, 34c13053), -449, -116},
+ {UINT64_2PART_C(0x964e858c, 91ba2655), -422, -108},
+ {UINT64_2PART_C(0xdff97724, 70297ebd), -396, -100},
+ {UINT64_2PART_C(0xa6dfbd9f, b8e5b88f), -369, -92},
+ {UINT64_2PART_C(0xf8a95fcf, 88747d94), -343, -84},
+ {UINT64_2PART_C(0xb9447093, 8fa89bcf), -316, -76},
+ {UINT64_2PART_C(0x8a08f0f8, bf0f156b), -289, -68},
+ {UINT64_2PART_C(0xcdb02555, 653131b6), -263, -60},
+ {UINT64_2PART_C(0x993fe2c6, d07b7fac), -236, -52},
+ {UINT64_2PART_C(0xe45c10c4, 2a2b3b06), -210, -44},
+ {UINT64_2PART_C(0xaa242499, 697392d3), -183, -36},
+ {UINT64_2PART_C(0xfd87b5f2, 8300ca0e), -157, -28},
+ {UINT64_2PART_C(0xbce50864, 92111aeb), -130, -20},
+ {UINT64_2PART_C(0x8cbccc09, 6f5088cc), -103, -12},
+ {UINT64_2PART_C(0xd1b71758, e219652c), -77, -4},
+ {UINT64_2PART_C(0x9c400000, 00000000), -50, 4},
+ {UINT64_2PART_C(0xe8d4a510, 00000000), -24, 12},
+ {UINT64_2PART_C(0xad78ebc5, ac620000), 3, 20},
+ {UINT64_2PART_C(0x813f3978, f8940984), 30, 28},
+ {UINT64_2PART_C(0xc097ce7b, c90715b3), 56, 36},
+ {UINT64_2PART_C(0x8f7e32ce, 7bea5c70), 83, 44},
+ {UINT64_2PART_C(0xd5d238a4, abe98068), 109, 52},
+ {UINT64_2PART_C(0x9f4f2726, 179a2245), 136, 60},
+ {UINT64_2PART_C(0xed63a231, d4c4fb27), 162, 68},
+ {UINT64_2PART_C(0xb0de6538, 8cc8ada8), 189, 76},
+ {UINT64_2PART_C(0x83c7088e, 1aab65db), 216, 84},
+ {UINT64_2PART_C(0xc45d1df9, 42711d9a), 242, 92},
+ {UINT64_2PART_C(0x924d692c, a61be758), 269, 100},
+ {UINT64_2PART_C(0xda01ee64, 1a708dea), 295, 108},
+ {UINT64_2PART_C(0xa26da399, 9aef774a), 322, 116},
+ {UINT64_2PART_C(0xf209787b, b47d6b85), 348, 124},
+ {UINT64_2PART_C(0xb454e4a1, 79dd1877), 375, 132},
+ {UINT64_2PART_C(0x865b8692, 5b9bc5c2), 402, 140},
+ {UINT64_2PART_C(0xc83553c5, c8965d3d), 428, 148},
+ {UINT64_2PART_C(0x952ab45c, fa97a0b3), 455, 156},
+ {UINT64_2PART_C(0xde469fbd, 99a05fe3), 481, 164},
+ {UINT64_2PART_C(0xa59bc234, db398c25), 508, 172},
+ {UINT64_2PART_C(0xf6c69a72, a3989f5c), 534, 180},
+ {UINT64_2PART_C(0xb7dcbf53, 54e9bece), 561, 188},
+ {UINT64_2PART_C(0x88fcf317, f22241e2), 588, 196},
+ {UINT64_2PART_C(0xcc20ce9b, d35c78a5), 614, 204},
+ {UINT64_2PART_C(0x98165af3, 7b2153df), 641, 212},
+ {UINT64_2PART_C(0xe2a0b5dc, 971f303a), 667, 220},
+ {UINT64_2PART_C(0xa8d9d153, 5ce3b396), 694, 228},
+ {UINT64_2PART_C(0xfb9b7cd9, a4a7443c), 720, 236},
+ {UINT64_2PART_C(0xbb764c4c, a7a44410), 747, 244},
+ {UINT64_2PART_C(0x8bab8eef, b6409c1a), 774, 252},
+ {UINT64_2PART_C(0xd01fef10, a657842c), 800, 260},
+ {UINT64_2PART_C(0x9b10a4e5, e9913129), 827, 268},
+ {UINT64_2PART_C(0xe7109bfb, a19c0c9d), 853, 276},
+ {UINT64_2PART_C(0xac2820d9, 623bf429), 880, 284},
+ {UINT64_2PART_C(0x80444b5e, 7aa7cf85), 907, 292},
+ {UINT64_2PART_C(0xbf21e440, 03acdd2d), 933, 300},
+ {UINT64_2PART_C(0x8e679c2f, 5e44ff8f), 960, 308},
+ {UINT64_2PART_C(0xd433179d, 9c8cb841), 986, 316},
+ {UINT64_2PART_C(0x9e19db92, b4e31ba9), 1013, 324},
+ {UINT64_2PART_C(0xeb96bf6e, badf77d9), 1039, 332},
+ {UINT64_2PART_C(0xaf87023b, 9bf0ee6b), 1066, 340},
+};
+
+static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers);
+static const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent.
+static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10)
+// Difference between the decimal exponents in the table above.
+const int PowersOfTenCache::kDecimalExponentDistance = 8;
+const int PowersOfTenCache::kMinDecimalExponent = -348;
+const int PowersOfTenCache::kMaxDecimalExponent = 340;
+
+void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
+ int min_exponent,
+ int max_exponent,
+ DiyFp* power,
+ int* decimal_exponent) {
+ (void)max_exponent; // Silence unused parameter warning in release builds
+ (void)kCachedPowersLength; // Silence unused parameter warning in release builds
+ int kQ = DiyFp::kSignificandSize;
+ double k = ceil((min_exponent + kQ - 1) * kD_1_LOG2_10);
+ int foo = kCachedPowersOffset;
+ int index =
+ (foo + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1;
+ ASSERT(0 <= index && index < kCachedPowersLength);
+ CachedPower cached_power = kCachedPowers[index];
+ ASSERT(min_exponent <= cached_power.binary_exponent);
+ (void) max_exponent; // Mark variable as used.
+ ASSERT(cached_power.binary_exponent <= max_exponent);
+ *decimal_exponent = cached_power.decimal_exponent;
+ *power = DiyFp(cached_power.significand, cached_power.binary_exponent);
+}
+
+
+void PowersOfTenCache::GetCachedPowerForDecimalExponent(int requested_exponent,
+ DiyFp* power,
+ int* found_exponent) {
+ ASSERT(kMinDecimalExponent <= requested_exponent);
+ ASSERT(requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance);
+ int index =
+ (requested_exponent + kCachedPowersOffset) / kDecimalExponentDistance;
+ CachedPower cached_power = kCachedPowers[index];
+ *power = DiyFp(cached_power.significand, cached_power.binary_exponent);
+ *found_exponent = cached_power.decimal_exponent;
+ ASSERT(*found_exponent <= requested_exponent);
+ ASSERT(requested_exponent < *found_exponent + kDecimalExponentDistance);
+}
+
+} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/cached-powers.h b/src/3rdparty/double-conversion/cached-powers.h
new file mode 100644
index 0000000000..61a50614cf
--- /dev/null
+++ b/src/3rdparty/double-conversion/cached-powers.h
@@ -0,0 +1,64 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_CACHED_POWERS_H_
+#define DOUBLE_CONVERSION_CACHED_POWERS_H_
+
+#include "diy-fp.h"
+
+namespace double_conversion {
+
+class PowersOfTenCache {
+ public:
+
+ // Not all powers of ten are cached. The decimal exponent of two neighboring
+ // cached numbers will differ by kDecimalExponentDistance.
+ static const int kDecimalExponentDistance;
+
+ static const int kMinDecimalExponent;
+ static const int kMaxDecimalExponent;
+
+ // Returns a cached power-of-ten with a binary exponent in the range
+ // [min_exponent; max_exponent] (boundaries included).
+ static void GetCachedPowerForBinaryExponentRange(int min_exponent,
+ int max_exponent,
+ DiyFp* power,
+ int* decimal_exponent);
+
+ // Returns a cached power of ten x ~= 10^k such that
+ // k <= decimal_exponent < k + kCachedPowersDecimalDistance.
+ // The given decimal_exponent must satisfy
+ // kMinDecimalExponent <= requested_exponent, and
+ // requested_exponent < kMaxDecimalExponent + kDecimalExponentDistance.
+ static void GetCachedPowerForDecimalExponent(int requested_exponent,
+ DiyFp* power,
+ int* found_exponent);
+};
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_CACHED_POWERS_H_
diff --git a/src/3rdparty/double-conversion/diy-fp.cc b/src/3rdparty/double-conversion/diy-fp.cc
new file mode 100644
index 0000000000..ddd1891b16
--- /dev/null
+++ b/src/3rdparty/double-conversion/diy-fp.cc
@@ -0,0 +1,57 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+#include "diy-fp.h"
+#include "utils.h"
+
+namespace double_conversion {
+
+void DiyFp::Multiply(const DiyFp& other) {
+ // Simply "emulates" a 128 bit multiplication.
+ // However: the resulting number only contains 64 bits. The least
+ // significant 64 bits are only used for rounding the most significant 64
+ // bits.
+ const uint64_t kM32 = 0xFFFFFFFFU;
+ uint64_t a = f_ >> 32;
+ uint64_t b = f_ & kM32;
+ uint64_t c = other.f_ >> 32;
+ uint64_t d = other.f_ & kM32;
+ uint64_t ac = a * c;
+ uint64_t bc = b * c;
+ uint64_t ad = a * d;
+ uint64_t bd = b * d;
+ uint64_t tmp = (bd >> 32) + (ad & kM32) + (bc & kM32);
+ // By adding 1U << 31 to tmp we round the final result.
+ // Halfway cases will be round up.
+ tmp += 1U << 31;
+ uint64_t result_f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32);
+ e_ += other.e_ + 64;
+ f_ = result_f;
+}
+
+} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/diy-fp.h b/src/3rdparty/double-conversion/diy-fp.h
new file mode 100644
index 0000000000..9dcf8fbdba
--- /dev/null
+++ b/src/3rdparty/double-conversion/diy-fp.h
@@ -0,0 +1,118 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_DIY_FP_H_
+#define DOUBLE_CONVERSION_DIY_FP_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+// This "Do It Yourself Floating Point" class implements a floating-point number
+// with a uint64 significand and an int exponent. Normalized DiyFp numbers will
+// have the most significant bit of the significand set.
+// Multiplication and Subtraction do not normalize their results.
+// DiyFp are not designed to contain special doubles (NaN and Infinity).
+class DiyFp {
+ public:
+ static const int kSignificandSize = 64;
+
+ DiyFp() : f_(0), e_(0) {}
+ DiyFp(uint64_t f, int e) : f_(f), e_(e) {}
+
+ // this = this - other.
+ // The exponents of both numbers must be the same and the significand of this
+ // must be bigger than the significand of other.
+ // The result will not be normalized.
+ void Subtract(const DiyFp& other) {
+ ASSERT(e_ == other.e_);
+ ASSERT(f_ >= other.f_);
+ f_ -= other.f_;
+ }
+
+ // Returns a - b.
+ // The exponents of both numbers must be the same and this must be bigger
+ // than other. The result will not be normalized.
+ static DiyFp Minus(const DiyFp& a, const DiyFp& b) {
+ DiyFp result = a;
+ result.Subtract(b);
+ return result;
+ }
+
+
+ // this = this * other.
+ void Multiply(const DiyFp& other);
+
+ // returns a * b;
+ static DiyFp Times(const DiyFp& a, const DiyFp& b) {
+ DiyFp result = a;
+ result.Multiply(b);
+ return result;
+ }
+
+ void Normalize() {
+ ASSERT(f_ != 0);
+ uint64_t f = f_;
+ int e = e_;
+
+ // This method is mainly called for normalizing boundaries. In general
+ // boundaries need to be shifted by 10 bits. We thus optimize for this case.
+ const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000);
+ while ((f & k10MSBits) == 0) {
+ f <<= 10;
+ e -= 10;
+ }
+ while ((f & kUint64MSB) == 0) {
+ f <<= 1;
+ e--;
+ }
+ f_ = f;
+ e_ = e;
+ }
+
+ static DiyFp Normalize(const DiyFp& a) {
+ DiyFp result = a;
+ result.Normalize();
+ return result;
+ }
+
+ uint64_t f() const { return f_; }
+ int e() const { return e_; }
+
+ void set_f(uint64_t new_value) { f_ = new_value; }
+ void set_e(int new_value) { e_ = new_value; }
+
+ private:
+ static const uint64_t kUint64MSB = UINT64_2PART_C(0x80000000, 00000000);
+
+ uint64_t f_;
+ int e_;
+};
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_DIY_FP_H_
diff --git a/src/3rdparty/double-conversion/double-conversion.cc b/src/3rdparty/double-conversion/double-conversion.cc
new file mode 100644
index 0000000000..909985be82
--- /dev/null
+++ b/src/3rdparty/double-conversion/double-conversion.cc
@@ -0,0 +1,975 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <limits.h>
+#include <math.h>
+
+#include "double-conversion.h"
+
+#include "bignum-dtoa.h"
+#include "fast-dtoa.h"
+#include "fixed-dtoa.h"
+#include "ieee.h"
+#include "strtod.h"
+#include "utils.h"
+
+namespace double_conversion {
+
+const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
+ int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
+ static DoubleToStringConverter converter(flags,
+ "Infinity",
+ "NaN",
+ 'e',
+ -6, 21,
+ 6, 0);
+ return converter;
+}
+
+
+bool DoubleToStringConverter::HandleSpecialValues(
+ double value,
+ StringBuilder* result_builder) const {
+ Double double_inspect(value);
+ if (double_inspect.IsInfinite()) {
+ if (infinity_symbol_ == NULL) return false;
+ if (value < 0) {
+ result_builder->AddCharacter('-');
+ }
+ result_builder->AddString(infinity_symbol_);
+ return true;
+ }
+ if (double_inspect.IsNan()) {
+ if (nan_symbol_ == NULL) return false;
+ result_builder->AddString(nan_symbol_);
+ return true;
+ }
+ return false;
+}
+
+
+void DoubleToStringConverter::CreateExponentialRepresentation(
+ const char* decimal_digits,
+ int length,
+ int exponent,
+ StringBuilder* result_builder) const {
+ ASSERT(length != 0);
+ result_builder->AddCharacter(decimal_digits[0]);
+ if (length != 1) {
+ result_builder->AddCharacter('.');
+ result_builder->AddSubstring(&decimal_digits[1], length-1);
+ }
+ result_builder->AddCharacter(exponent_character_);
+ if (exponent < 0) {
+ result_builder->AddCharacter('-');
+ exponent = -exponent;
+ } else {
+ if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
+ result_builder->AddCharacter('+');
+ }
+ }
+ if (exponent == 0) {
+ result_builder->AddCharacter('0');
+ return;
+ }
+ ASSERT(exponent < 1e4);
+ const int kMaxExponentLength = 5;
+ char buffer[kMaxExponentLength + 1];
+ buffer[kMaxExponentLength] = '\0';
+ int first_char_pos = kMaxExponentLength;
+ while (exponent > 0) {
+ buffer[--first_char_pos] = '0' + (exponent % 10);
+ exponent /= 10;
+ }
+ result_builder->AddSubstring(&buffer[first_char_pos],
+ kMaxExponentLength - first_char_pos);
+}
+
+
+void DoubleToStringConverter::CreateDecimalRepresentation(
+ const char* decimal_digits,
+ int length,
+ int decimal_point,
+ int digits_after_point,
+ StringBuilder* result_builder) const {
+ // Create a representation that is padded with zeros if needed.
+ if (decimal_point <= 0) {
+ // "0.00000decimal_rep".
+ result_builder->AddCharacter('0');
+ if (digits_after_point > 0) {
+ result_builder->AddCharacter('.');
+ result_builder->AddPadding('0', -decimal_point);
+ ASSERT(length <= digits_after_point - (-decimal_point));
+ result_builder->AddSubstring(decimal_digits, length);
+ int remaining_digits = digits_after_point - (-decimal_point) - length;
+ result_builder->AddPadding('0', remaining_digits);
+ }
+ } else if (decimal_point >= length) {
+ // "decimal_rep0000.00000" or "decimal_rep.0000"
+ result_builder->AddSubstring(decimal_digits, length);
+ result_builder->AddPadding('0', decimal_point - length);
+ if (digits_after_point > 0) {
+ result_builder->AddCharacter('.');
+ result_builder->AddPadding('0', digits_after_point);
+ }
+ } else {
+ // "decima.l_rep000"
+ ASSERT(digits_after_point > 0);
+ result_builder->AddSubstring(decimal_digits, decimal_point);
+ result_builder->AddCharacter('.');
+ ASSERT(length - decimal_point <= digits_after_point);
+ result_builder->AddSubstring(&decimal_digits[decimal_point],
+ length - decimal_point);
+ int remaining_digits = digits_after_point - (length - decimal_point);
+ result_builder->AddPadding('0', remaining_digits);
+ }
+ if (digits_after_point == 0) {
+ if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
+ result_builder->AddCharacter('.');
+ }
+ if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
+ result_builder->AddCharacter('0');
+ }
+ }
+}
+
+
+bool DoubleToStringConverter::ToShortestIeeeNumber(
+ double value,
+ StringBuilder* result_builder,
+ DoubleToStringConverter::DtoaMode mode) const {
+ ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE);
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
+ }
+
+ int decimal_point;
+ bool sign;
+ const int kDecimalRepCapacity = kBase10MaximalLength + 1;
+ char decimal_rep[kDecimalRepCapacity];
+ int decimal_rep_length;
+
+ DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
+
+ bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
+
+ int exponent = decimal_point - 1;
+ if ((decimal_in_shortest_low_ <= exponent) &&
+ (exponent < decimal_in_shortest_high_)) {
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
+ decimal_point,
+ Max(0, decimal_rep_length - decimal_point),
+ result_builder);
+ } else {
+ CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
+ result_builder);
+ }
+ return true;
+}
+
+
+bool DoubleToStringConverter::ToFixed(double value,
+ int requested_digits,
+ StringBuilder* result_builder) const {
+ ASSERT(kMaxFixedDigitsBeforePoint == 60);
+ const double kFirstNonFixed = 1e60;
+
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
+ }
+
+ if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
+ if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
+
+ // Find a sufficiently precise decimal representation of n.
+ int decimal_point;
+ bool sign;
+ // Add space for the '\0' byte.
+ const int kDecimalRepCapacity =
+ kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
+ char decimal_rep[kDecimalRepCapacity];
+ int decimal_rep_length;
+ DoubleToAscii(value, FIXED, requested_digits,
+ decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
+
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
+
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
+ requested_digits, result_builder);
+ return true;
+}
+
+
+bool DoubleToStringConverter::ToExponential(
+ double value,
+ int requested_digits,
+ StringBuilder* result_builder) const {
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
+ }
+
+ if (requested_digits < -1) return false;
+ if (requested_digits > kMaxExponentialDigits) return false;
+
+ int decimal_point;
+ bool sign;
+ // Add space for digit before the decimal point and the '\0' character.
+ const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
+ ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
+ char decimal_rep[kDecimalRepCapacity];
+ int decimal_rep_length;
+
+ if (requested_digits == -1) {
+ DoubleToAscii(value, SHORTEST, 0,
+ decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
+ } else {
+ DoubleToAscii(value, PRECISION, requested_digits + 1,
+ decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
+ ASSERT(decimal_rep_length <= requested_digits + 1);
+
+ for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
+ decimal_rep[i] = '0';
+ }
+ decimal_rep_length = requested_digits + 1;
+ }
+
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
+
+ int exponent = decimal_point - 1;
+ CreateExponentialRepresentation(decimal_rep,
+ decimal_rep_length,
+ exponent,
+ result_builder);
+ return true;
+}
+
+
+bool DoubleToStringConverter::ToPrecision(double value,
+ int precision,
+ StringBuilder* result_builder) const {
+ if (Double(value).IsSpecial()) {
+ return HandleSpecialValues(value, result_builder);
+ }
+
+ if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
+ return false;
+ }
+
+ // Find a sufficiently precise decimal representation of n.
+ int decimal_point;
+ bool sign;
+ // Add one for the terminating null character.
+ const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
+ char decimal_rep[kDecimalRepCapacity];
+ int decimal_rep_length;
+
+ DoubleToAscii(value, PRECISION, precision,
+ decimal_rep, kDecimalRepCapacity,
+ &sign, &decimal_rep_length, &decimal_point);
+ ASSERT(decimal_rep_length <= precision);
+
+ bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
+ if (sign && (value != 0.0 || !unique_zero)) {
+ result_builder->AddCharacter('-');
+ }
+
+ // The exponent if we print the number as x.xxeyyy. That is with the
+ // decimal point after the first digit.
+ int exponent = decimal_point - 1;
+
+ int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
+ if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
+ (decimal_point - precision + extra_zero >
+ max_trailing_padding_zeroes_in_precision_mode_)) {
+ // Fill buffer to contain 'precision' digits.
+ // Usually the buffer is already at the correct length, but 'DoubleToAscii'
+ // is allowed to return less characters.
+ for (int i = decimal_rep_length; i < precision; ++i) {
+ decimal_rep[i] = '0';
+ }
+
+ CreateExponentialRepresentation(decimal_rep,
+ precision,
+ exponent,
+ result_builder);
+ } else {
+ CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
+ Max(0, precision - decimal_point),
+ result_builder);
+ }
+ return true;
+}
+
+
+static BignumDtoaMode DtoaToBignumDtoaMode(
+ DoubleToStringConverter::DtoaMode dtoa_mode) {
+ switch (dtoa_mode) {
+ case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST;
+ case DoubleToStringConverter::SHORTEST_SINGLE:
+ return BIGNUM_DTOA_SHORTEST_SINGLE;
+ case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED;
+ case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
+ default:
+ UNREACHABLE();
+ }
+}
+
+
+void DoubleToStringConverter::DoubleToAscii(double v,
+ DtoaMode mode,
+ int requested_digits,
+ char* buffer,
+ int buffer_length,
+ bool* sign,
+ int* length,
+ int* point) {
+ Vector<char> vector(buffer, buffer_length);
+ ASSERT(!Double(v).IsSpecial());
+ ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
+
+ if (Double(v).Sign() < 0) {
+ *sign = true;
+ v = -v;
+ } else {
+ *sign = false;
+ }
+
+ if (mode == PRECISION && requested_digits == 0) {
+ vector[0] = '\0';
+ *length = 0;
+ return;
+ }
+
+ if (v == 0) {
+ vector[0] = '0';
+ vector[1] = '\0';
+ *length = 1;
+ *point = 1;
+ return;
+ }
+
+ bool fast_worked;
+ switch (mode) {
+ case SHORTEST:
+ fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
+ break;
+ case SHORTEST_SINGLE:
+ fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
+ vector, length, point);
+ break;
+ case FIXED:
+ fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
+ break;
+ case PRECISION:
+ fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
+ vector, length, point);
+ break;
+ default:
+ fast_worked = false;
+ UNREACHABLE();
+ }
+ if (fast_worked) return;
+
+ // If the fast dtoa didn't succeed use the slower bignum version.
+ BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
+ BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
+ vector[*length] = '\0';
+}
+
+
+// Consumes the given substring from the iterator.
+// Returns false, if the substring does not match.
+template <class Iterator>
+static bool ConsumeSubString(Iterator* current,
+ Iterator end,
+ const char* substring) {
+ ASSERT(**current == *substring);
+ for (substring++; *substring != '\0'; substring++) {
+ ++*current;
+ if (*current == end || **current != *substring) return false;
+ }
+ ++*current;
+ return true;
+}
+
+
+// Maximum number of significant digits in decimal representation.
+// The longest possible double in decimal representation is
+// (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
+// (768 digits). If we parse a number whose first digits are equal to a
+// mean of 2 adjacent doubles (that could have up to 769 digits) the result
+// must be rounded to the bigger one unless the tail consists of zeros, so
+// we don't need to preserve all the digits.
+const int kMaxSignificantDigits = 772;
+
+
+static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
+static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
+
+
+static const uc16 kWhitespaceTable16[] = {
+ 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
+ 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
+};
+static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
+
+
+static bool isWhitespace(int x) {
+ if (x < 128) {
+ for (int i = 0; i < kWhitespaceTable7Length; i++) {
+ if (kWhitespaceTable7[i] == x) return true;
+ }
+ } else {
+ for (int i = 0; i < kWhitespaceTable16Length; i++) {
+ if (kWhitespaceTable16[i] == x) return true;
+ }
+ }
+ return false;
+}
+
+
+// Returns true if a nonspace found and false if the end has reached.
+template <class Iterator>
+static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
+ while (*current != end) {
+ if (!isWhitespace(**current)) return true;
+ ++*current;
+ }
+ return false;
+}
+
+
+static bool isDigit(int x, int radix) {
+ return (x >= '0' && x <= '9' && x < '0' + radix)
+ || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
+ || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
+}
+
+
+static double SignedZero(bool sign) {
+ return sign ? -0.0 : 0.0;
+}
+
+
+// Returns true if 'c' is a decimal digit that is valid for the given radix.
+//
+// The function is small and could be inlined, but VS2012 emitted a warning
+// because it constant-propagated the radix and concluded that the last
+// condition was always true. By moving it into a separate function the
+// compiler wouldn't warn anymore.
+static bool IsDecimalDigitForRadix(int c, int radix) {
+ return '0' <= c && c <= '9' && (c - '0') < radix;
+}
+
+// Returns true if 'c' is a character digit that is valid for the given radix.
+// The 'a_character' should be 'a' or 'A'.
+//
+// The function is small and could be inlined, but VS2012 emitted a warning
+// because it constant-propagated the radix and concluded that the first
+// condition was always false. By moving it into a separate function the
+// compiler wouldn't warn anymore.
+static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
+ return radix > 10 && c >= a_character && c < a_character + radix - 10;
+}
+
+
+// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
+template <int radix_log_2, class Iterator>
+static double RadixStringToIeee(Iterator* current,
+ Iterator end,
+ bool sign,
+ bool allow_trailing_junk,
+ double junk_string_value,
+ bool read_as_double,
+ bool* result_is_junk) {
+ ASSERT(*current != end);
+
+ const int kDoubleSize = Double::kSignificandSize;
+ const int kSingleSize = Single::kSignificandSize;
+ const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
+
+ *result_is_junk = true;
+
+ // Skip leading 0s.
+ while (**current == '0') {
+ ++(*current);
+ if (*current == end) {
+ *result_is_junk = false;
+ return SignedZero(sign);
+ }
+ }
+
+ int64_t number = 0;
+ int exponent = 0;
+ const int radix = (1 << radix_log_2);
+
+ do {
+ int digit;
+ if (IsDecimalDigitForRadix(**current, radix)) {
+ digit = static_cast<char>(**current) - '0';
+ } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
+ digit = static_cast<char>(**current) - 'a' + 10;
+ } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
+ digit = static_cast<char>(**current) - 'A' + 10;
+ } else {
+ if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
+ break;
+ } else {
+ return junk_string_value;
+ }
+ }
+
+ number = number * radix + digit;
+ int overflow = static_cast<int>(number >> kSignificandSize);
+ if (overflow != 0) {
+ // Overflow occurred. Need to determine which direction to round the
+ // result.
+ int overflow_bits_count = 1;
+ while (overflow > 1) {
+ overflow_bits_count++;
+ overflow >>= 1;
+ }
+
+ int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
+ int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
+ number >>= overflow_bits_count;
+ exponent = overflow_bits_count;
+
+ bool zero_tail = true;
+ for (;;) {
+ ++(*current);
+ if (*current == end || !isDigit(**current, radix)) break;
+ zero_tail = zero_tail && **current == '0';
+ exponent += radix_log_2;
+ }
+
+ if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
+ return junk_string_value;
+ }
+
+ int middle_value = (1 << (overflow_bits_count - 1));
+ if (dropped_bits > middle_value) {
+ number++; // Rounding up.
+ } else if (dropped_bits == middle_value) {
+ // Rounding to even to consistency with decimals: half-way case rounds
+ // up if significant part is odd and down otherwise.
+ if ((number & 1) != 0 || !zero_tail) {
+ number++; // Rounding up.
+ }
+ }
+
+ // Rounding up may cause overflow.
+ if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
+ exponent++;
+ number >>= 1;
+ }
+ break;
+ }
+ ++(*current);
+ } while (*current != end);
+
+ ASSERT(number < ((int64_t)1 << kSignificandSize));
+ ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
+
+ *result_is_junk = false;
+
+ if (exponent == 0) {
+ if (sign) {
+ if (number == 0) return -0.0;
+ number = -number;
+ }
+ return static_cast<double>(number);
+ }
+
+ ASSERT(number != 0);
+ return Double(DiyFp(number, exponent)).value();
+}
+
+
+template <class Iterator>
+double StringToDoubleConverter::StringToIeee(
+ Iterator input,
+ int length,
+ bool read_as_double,
+ int* processed_characters_count) const {
+ Iterator current = input;
+ Iterator end = input + length;
+
+ *processed_characters_count = 0;
+
+ const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
+ const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
+ const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
+ const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
+
+ // To make sure that iterator dereferencing is valid the following
+ // convention is used:
+ // 1. Each '++current' statement is followed by check for equality to 'end'.
+ // 2. If AdvanceToNonspace returned false then current == end.
+ // 3. If 'current' becomes equal to 'end' the function returns or goes to
+ // 'parsing_done'.
+ // 4. 'current' is not dereferenced after the 'parsing_done' label.
+ // 5. Code before 'parsing_done' may rely on 'current != end'.
+ if (current == end) return empty_string_value_;
+
+ if (allow_leading_spaces || allow_trailing_spaces) {
+ if (!AdvanceToNonspace(&current, end)) {
+ *processed_characters_count = static_cast<int>(current - input);
+ return empty_string_value_;
+ }
+ if (!allow_leading_spaces && (input != current)) {
+ // No leading spaces allowed, but AdvanceToNonspace moved forward.
+ return junk_string_value_;
+ }
+ }
+
+ // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
+ const int kBufferSize = kMaxSignificantDigits + 10;
+ char buffer[kBufferSize]; // NOLINT: size is known at compile time.
+ int buffer_pos = 0;
+
+ // Exponent will be adjusted if insignificant digits of the integer part
+ // or insignificant leading zeros of the fractional part are dropped.
+ int exponent = 0;
+ int significant_digits = 0;
+ int insignificant_digits = 0;
+ bool nonzero_digit_dropped = false;
+
+ bool sign = false;
+
+ if (*current == '+' || *current == '-') {
+ sign = (*current == '-');
+ ++current;
+ Iterator next_non_space = current;
+ // Skip following spaces (if allowed).
+ if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
+ if (!allow_spaces_after_sign && (current != next_non_space)) {
+ return junk_string_value_;
+ }
+ current = next_non_space;
+ }
+
+ if (infinity_symbol_ != NULL) {
+ if (*current == infinity_symbol_[0]) {
+ if (!ConsumeSubString(&current, end, infinity_symbol_)) {
+ return junk_string_value_;
+ }
+
+ if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
+ return junk_string_value_;
+ }
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+ return junk_string_value_;
+ }
+
+ ASSERT(buffer_pos == 0);
+ *processed_characters_count = static_cast<int>(current - input);
+ return sign ? -Double::Infinity() : Double::Infinity();
+ }
+ }
+
+ if (nan_symbol_ != NULL) {
+ if (*current == nan_symbol_[0]) {
+ if (!ConsumeSubString(&current, end, nan_symbol_)) {
+ return junk_string_value_;
+ }
+
+ if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
+ return junk_string_value_;
+ }
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+ return junk_string_value_;
+ }
+
+ ASSERT(buffer_pos == 0);
+ *processed_characters_count = static_cast<int>(current - input);
+ return sign ? -Double::NaN() : Double::NaN();
+ }
+ }
+
+ bool leading_zero = false;
+ if (*current == '0') {
+ ++current;
+ if (current == end) {
+ *processed_characters_count = static_cast<int>(current - input);
+ return SignedZero(sign);
+ }
+
+ leading_zero = true;
+
+ // It could be hexadecimal value.
+ if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
+ ++current;
+ if (current == end || !isDigit(*current, 16)) {
+ return junk_string_value_; // "0x".
+ }
+
+ bool result_is_junk;
+ double result = RadixStringToIeee<4>(&current,
+ end,
+ sign,
+ allow_trailing_junk,
+ junk_string_value_,
+ read_as_double,
+ &result_is_junk);
+ if (!result_is_junk) {
+ if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
+ *processed_characters_count = static_cast<int>(current - input);
+ }
+ return result;
+ }
+
+ // Ignore leading zeros in the integer part.
+ while (*current == '0') {
+ ++current;
+ if (current == end) {
+ *processed_characters_count = static_cast<int>(current - input);
+ return SignedZero(sign);
+ }
+ }
+ }
+
+ bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
+
+ // Copy significant digits of the integer part (if any) to the buffer.
+ while (*current >= '0' && *current <= '9') {
+ if (significant_digits < kMaxSignificantDigits) {
+ ASSERT(buffer_pos < kBufferSize);
+ buffer[buffer_pos++] = static_cast<char>(*current);
+ significant_digits++;
+ // Will later check if it's an octal in the buffer.
+ } else {
+ insignificant_digits++; // Move the digit into the exponential part.
+ nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
+ }
+ octal = octal && *current < '8';
+ ++current;
+ if (current == end) goto parsing_done;
+ }
+
+ if (significant_digits == 0) {
+ octal = false;
+ }
+
+ if (*current == '.') {
+ if (octal && !allow_trailing_junk) return junk_string_value_;
+ if (octal) goto parsing_done;
+
+ ++current;
+ if (current == end) {
+ if (significant_digits == 0 && !leading_zero) {
+ return junk_string_value_;
+ } else {
+ goto parsing_done;
+ }
+ }
+
+ if (significant_digits == 0) {
+ // octal = false;
+ // Integer part consists of 0 or is absent. Significant digits start after
+ // leading zeros (if any).
+ while (*current == '0') {
+ ++current;
+ if (current == end) {
+ *processed_characters_count = static_cast<int>(current - input);
+ return SignedZero(sign);
+ }
+ exponent--; // Move this 0 into the exponent.
+ }
+ }
+
+ // There is a fractional part.
+ // We don't emit a '.', but adjust the exponent instead.
+ while (*current >= '0' && *current <= '9') {
+ if (significant_digits < kMaxSignificantDigits) {
+ ASSERT(buffer_pos < kBufferSize);
+ buffer[buffer_pos++] = static_cast<char>(*current);
+ significant_digits++;
+ exponent--;
+ } else {
+ // Ignore insignificant digits in the fractional part.
+ nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
+ }
+ ++current;
+ if (current == end) goto parsing_done;
+ }
+ }
+
+ if (!leading_zero && exponent == 0 && significant_digits == 0) {
+ // If leading_zeros is true then the string contains zeros.
+ // If exponent < 0 then string was [+-]\.0*...
+ // If significant_digits != 0 the string is not equal to 0.
+ // Otherwise there are no digits in the string.
+ return junk_string_value_;
+ }
+
+ // Parse exponential part.
+ if (*current == 'e' || *current == 'E') {
+ if (octal && !allow_trailing_junk) return junk_string_value_;
+ if (octal) goto parsing_done;
+ ++current;
+ if (current == end) {
+ if (allow_trailing_junk) {
+ goto parsing_done;
+ } else {
+ return junk_string_value_;
+ }
+ }
+ char sign = '+';
+ if (*current == '+' || *current == '-') {
+ sign = static_cast<char>(*current);
+ ++current;
+ if (current == end) {
+ if (allow_trailing_junk) {
+ goto parsing_done;
+ } else {
+ return junk_string_value_;
+ }
+ }
+ }
+
+ if (current == end || *current < '0' || *current > '9') {
+ if (allow_trailing_junk) {
+ goto parsing_done;
+ } else {
+ return junk_string_value_;
+ }
+ }
+
+ const int max_exponent = INT_MAX / 2;
+ ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
+ int num = 0;
+ do {
+ // Check overflow.
+ int digit = *current - '0';
+ if (num >= max_exponent / 10
+ && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
+ num = max_exponent;
+ } else {
+ num = num * 10 + digit;
+ }
+ ++current;
+ } while (current != end && *current >= '0' && *current <= '9');
+
+ exponent += (sign == '-' ? -num : num);
+ }
+
+ if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
+ return junk_string_value_;
+ }
+ if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+ return junk_string_value_;
+ }
+ if (allow_trailing_spaces) {
+ AdvanceToNonspace(&current, end);
+ }
+
+ parsing_done:
+ exponent += insignificant_digits;
+
+ if (octal) {
+ double result;
+ bool result_is_junk;
+ char* start = buffer;
+ result = RadixStringToIeee<3>(&start,
+ buffer + buffer_pos,
+ sign,
+ allow_trailing_junk,
+ junk_string_value_,
+ read_as_double,
+ &result_is_junk);
+ ASSERT(!result_is_junk);
+ *processed_characters_count = static_cast<int>(current - input);
+ return result;
+ }
+
+ if (nonzero_digit_dropped) {
+ buffer[buffer_pos++] = '1';
+ exponent--;
+ }
+
+ ASSERT(buffer_pos < kBufferSize);
+ buffer[buffer_pos] = '\0';
+
+ double converted;
+ if (read_as_double) {
+ converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
+ } else {
+ converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
+ }
+ *processed_characters_count = static_cast<int>(current - input);
+ return sign? -converted: converted;
+}
+
+
+double StringToDoubleConverter::StringToDouble(
+ const char* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return StringToIeee(buffer, length, true, processed_characters_count);
+}
+
+
+double StringToDoubleConverter::StringToDouble(
+ const uc16* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return StringToIeee(buffer, length, true, processed_characters_count);
+}
+
+
+float StringToDoubleConverter::StringToFloat(
+ const char* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return static_cast<float>(StringToIeee(buffer, length, false,
+ processed_characters_count));
+}
+
+
+float StringToDoubleConverter::StringToFloat(
+ const uc16* buffer,
+ int length,
+ int* processed_characters_count) const {
+ return static_cast<float>(StringToIeee(buffer, length, false,
+ processed_characters_count));
+}
+
+} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/double-conversion.pri b/src/3rdparty/double-conversion/double-conversion.pri
new file mode 100644
index 0000000000..3207169689
--- /dev/null
+++ b/src/3rdparty/double-conversion/double-conversion.pri
@@ -0,0 +1,24 @@
+INCLUDEPATH += $$PWD/include $$PWD/include/double-conversion
+SOURCES += \
+ $$PWD/bignum.cc \
+ $$PWD/bignum-dtoa.cc \
+ $$PWD/cached-powers.cc \
+ $$PWD/diy-fp.cc \
+ $$PWD/double-conversion.cc \
+ $$PWD/fast-dtoa.cc \
+ $$PWD/fixed-dtoa.cc \
+ $$PWD/strtod.cc
+
+HEADERS += \
+ $$PWD/bignum-dtoa.h \
+ $$PWD/bignum.h \
+ $$PWD/cached-powers.h \
+ $$PWD/diy-fp.h \
+ $$PWD/include/double-conversion/double-conversion.h \
+ $$PWD/fast-dtoa.h \
+ $$PWD/fixed-dtoa.h \
+ $$PWD/ieee.h \
+ $$PWD/strtod.h \
+ $$PWD/include/double-conversion/utils.h
+
+OTHER_FILES += README
diff --git a/src/3rdparty/double-conversion/fast-dtoa.cc b/src/3rdparty/double-conversion/fast-dtoa.cc
new file mode 100644
index 0000000000..61350383a9
--- /dev/null
+++ b/src/3rdparty/double-conversion/fast-dtoa.cc
@@ -0,0 +1,665 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "fast-dtoa.h"
+
+#include "cached-powers.h"
+#include "diy-fp.h"
+#include "ieee.h"
+
+namespace double_conversion {
+
+// The minimal and maximal target exponent define the range of w's binary
+// exponent, where 'w' is the result of multiplying the input by a cached power
+// of ten.
+//
+// A different range might be chosen on a different platform, to optimize digit
+// generation, but a smaller range requires more powers of ten to be cached.
+static const int kMinimalTargetExponent = -60;
+static const int kMaximalTargetExponent = -32;
+
+
+// Adjusts the last digit of the generated number, and screens out generated
+// solutions that may be inaccurate. A solution may be inaccurate if it is
+// outside the safe interval, or if we cannot prove that it is closer to the
+// input than a neighboring representation of the same length.
+//
+// Input: * buffer containing the digits of too_high / 10^kappa
+// * the buffer's length
+// * distance_too_high_w == (too_high - w).f() * unit
+// * unsafe_interval == (too_high - too_low).f() * unit
+// * rest = (too_high - buffer * 10^kappa).f() * unit
+// * ten_kappa = 10^kappa * unit
+// * unit = the common multiplier
+// Output: returns true if the buffer is guaranteed to contain the closest
+// representable number to the input.
+// Modifies the generated digits in the buffer to approach (round towards) w.
+static bool RoundWeed(Vector<char> buffer,
+ int length,
+ uint64_t distance_too_high_w,
+ uint64_t unsafe_interval,
+ uint64_t rest,
+ uint64_t ten_kappa,
+ uint64_t unit) {
+ uint64_t small_distance = distance_too_high_w - unit;
+ uint64_t big_distance = distance_too_high_w + unit;
+ // Let w_low = too_high - big_distance, and
+ // w_high = too_high - small_distance.
+ // Note: w_low < w < w_high
+ //
+ // The real w (* unit) must lie somewhere inside the interval
+ // ]w_low; w_high[ (often written as "(w_low; w_high)")
+
+ // Basically the buffer currently contains a number in the unsafe interval
+ // ]too_low; too_high[ with too_low < w < too_high
+ //
+ // too_high - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ // ^v 1 unit ^ ^ ^ ^
+ // boundary_high --------------------- . . . .
+ // ^v 1 unit . . . .
+ // - - - - - - - - - - - - - - - - - - - + - - + - - - - - - . .
+ // . . ^ . .
+ // . big_distance . . .
+ // . . . . rest
+ // small_distance . . . .
+ // v . . . .
+ // w_high - - - - - - - - - - - - - - - - - - . . . .
+ // ^v 1 unit . . . .
+ // w ---------------------------------------- . . . .
+ // ^v 1 unit v . . .
+ // w_low - - - - - - - - - - - - - - - - - - - - - . . .
+ // . . v
+ // buffer --------------------------------------------------+-------+--------
+ // . .
+ // safe_interval .
+ // v .
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .
+ // ^v 1 unit .
+ // boundary_low ------------------------- unsafe_interval
+ // ^v 1 unit v
+ // too_low - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ //
+ //
+ // Note that the value of buffer could lie anywhere inside the range too_low
+ // to too_high.
+ //
+ // boundary_low, boundary_high and w are approximations of the real boundaries
+ // and v (the input number). They are guaranteed to be precise up to one unit.
+ // In fact the error is guaranteed to be strictly less than one unit.
+ //
+ // Anything that lies outside the unsafe interval is guaranteed not to round
+ // to v when read again.
+ // Anything that lies inside the safe interval is guaranteed to round to v
+ // when read again.
+ // If the number inside the buffer lies inside the unsafe interval but not
+ // inside the safe interval then we simply do not know and bail out (returning
+ // false).
+ //
+ // Similarly we have to take into account the imprecision of 'w' when finding
+ // the closest representation of 'w'. If we have two potential
+ // representations, and one is closer to both w_low and w_high, then we know
+ // it is closer to the actual value v.
+ //
+ // By generating the digits of too_high we got the largest (closest to
+ // too_high) buffer that is still in the unsafe interval. In the case where
+ // w_high < buffer < too_high we try to decrement the buffer.
+ // This way the buffer approaches (rounds towards) w.
+ // There are 3 conditions that stop the decrementation process:
+ // 1) the buffer is already below w_high
+ // 2) decrementing the buffer would make it leave the unsafe interval
+ // 3) decrementing the buffer would yield a number below w_high and farther
+ // away than the current number. In other words:
+ // (buffer{-1} < w_high) && w_high - buffer{-1} > buffer - w_high
+ // Instead of using the buffer directly we use its distance to too_high.
+ // Conceptually rest ~= too_high - buffer
+ // We need to do the following tests in this order to avoid over- and
+ // underflows.
+ ASSERT(rest <= unsafe_interval);
+ while (rest < small_distance && // Negated condition 1
+ unsafe_interval - rest >= ten_kappa && // Negated condition 2
+ (rest + ten_kappa < small_distance || // buffer{-1} > w_high
+ small_distance - rest >= rest + ten_kappa - small_distance)) {
+ buffer[length - 1]--;
+ rest += ten_kappa;
+ }
+
+ // We have approached w+ as much as possible. We now test if approaching w-
+ // would require changing the buffer. If yes, then we have two possible
+ // representations close to w, but we cannot decide which one is closer.
+ if (rest < big_distance &&
+ unsafe_interval - rest >= ten_kappa &&
+ (rest + ten_kappa < big_distance ||
+ big_distance - rest > rest + ten_kappa - big_distance)) {
+ return false;
+ }
+
+ // Weeding test.
+ // The safe interval is [too_low + 2 ulp; too_high - 2 ulp]
+ // Since too_low = too_high - unsafe_interval this is equivalent to
+ // [too_high - unsafe_interval + 4 ulp; too_high - 2 ulp]
+ // Conceptually we have: rest ~= too_high - buffer
+ return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit);
+}
+
+
+// Rounds the buffer upwards if the result is closer to v by possibly adding
+// 1 to the buffer. If the precision of the calculation is not sufficient to
+// round correctly, return false.
+// The rounding might shift the whole buffer in which case the kappa is
+// adjusted. For example "99", kappa = 3 might become "10", kappa = 4.
+//
+// If 2*rest > ten_kappa then the buffer needs to be round up.
+// rest can have an error of +/- 1 unit. This function accounts for the
+// imprecision and returns false, if the rounding direction cannot be
+// unambiguously determined.
+//
+// Precondition: rest < ten_kappa.
+static bool RoundWeedCounted(Vector<char> buffer,
+ int length,
+ uint64_t rest,
+ uint64_t ten_kappa,
+ uint64_t unit,
+ int* kappa) {
+ ASSERT(rest < ten_kappa);
+ // The following tests are done in a specific order to avoid overflows. They
+ // will work correctly with any uint64 values of rest < ten_kappa and unit.
+ //
+ // If the unit is too big, then we don't know which way to round. For example
+ // a unit of 50 means that the real number lies within rest +/- 50. If
+ // 10^kappa == 40 then there is no way to tell which way to round.
+ if (unit >= ten_kappa) return false;
+ // Even if unit is just half the size of 10^kappa we are already completely
+ // lost. (And after the previous test we know that the expression will not
+ // over/underflow.)
+ if (ten_kappa - unit <= unit) return false;
+ // If 2 * (rest + unit) <= 10^kappa we can safely round down.
+ if ((ten_kappa - rest > rest) && (ten_kappa - 2 * rest >= 2 * unit)) {
+ return true;
+ }
+ // If 2 * (rest - unit) >= 10^kappa, then we can safely round up.
+ if ((rest > unit) && (ten_kappa - (rest - unit) <= (rest - unit))) {
+ // Increment the last digit recursively until we find a non '9' digit.
+ buffer[length - 1]++;
+ for (int i = length - 1; i > 0; --i) {
+ if (buffer[i] != '0' + 10) break;
+ buffer[i] = '0';
+ buffer[i - 1]++;
+ }
+ // If the first digit is now '0'+ 10 we had a buffer with all '9's. With the
+ // exception of the first digit all digits are now '0'. Simply switch the
+ // first digit to '1' and adjust the kappa. Example: "99" becomes "10" and
+ // the power (the kappa) is increased.
+ if (buffer[0] == '0' + 10) {
+ buffer[0] = '1';
+ (*kappa) += 1;
+ }
+ return true;
+ }
+ return false;
+}
+
+// Returns the biggest power of ten that is less than or equal to the given
+// number. We furthermore receive the maximum number of bits 'number' has.
+//
+// Returns power == 10^(exponent_plus_one-1) such that
+// power <= number < power * 10.
+// If number_bits == 0 then 0^(0-1) is returned.
+// The number of bits must be <= 32.
+// Precondition: number < (1 << (number_bits + 1)).
+
+// Inspired by the method for finding an integer log base 10 from here:
+// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+static unsigned int const kSmallPowersOfTen[] =
+ {0, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
+ 1000000000};
+
+static void BiggestPowerTen(uint32_t number,
+ int number_bits,
+ uint32_t* power,
+ int* exponent_plus_one) {
+ ASSERT(number < (1u << (number_bits + 1)));
+ // 1233/4096 is approximately 1/lg(10).
+ int exponent_plus_one_guess = ((number_bits + 1) * 1233 >> 12);
+ // We increment to skip over the first entry in the kPowersOf10 table.
+ // Note: kPowersOf10[i] == 10^(i-1).
+ exponent_plus_one_guess++;
+ // We don't have any guarantees that 2^number_bits <= number.
+ if (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
+ exponent_plus_one_guess--;
+ }
+ *power = kSmallPowersOfTen[exponent_plus_one_guess];
+ *exponent_plus_one = exponent_plus_one_guess;
+}
+
+// Generates the digits of input number w.
+// w is a floating-point number (DiyFp), consisting of a significand and an
+// exponent. Its exponent is bounded by kMinimalTargetExponent and
+// kMaximalTargetExponent.
+// Hence -60 <= w.e() <= -32.
+//
+// Returns false if it fails, in which case the generated digits in the buffer
+// should not be used.
+// Preconditions:
+// * low, w and high are correct up to 1 ulp (unit in the last place). That
+// is, their error must be less than a unit of their last digits.
+// * low.e() == w.e() == high.e()
+// * low < w < high, and taking into account their error: low~ <= high~
+// * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent
+// Postconditions: returns false if procedure fails.
+// otherwise:
+// * buffer is not null-terminated, but len contains the number of digits.
+// * buffer contains the shortest possible decimal digit-sequence
+// such that LOW < buffer * 10^kappa < HIGH, where LOW and HIGH are the
+// correct values of low and high (without their error).
+// * if more than one decimal representation gives the minimal number of
+// decimal digits then the one closest to W (where W is the correct value
+// of w) is chosen.
+// Remark: this procedure takes into account the imprecision of its input
+// numbers. If the precision is not enough to guarantee all the postconditions
+// then false is returned. This usually happens rarely (~0.5%).
+//
+// Say, for the sake of example, that
+// w.e() == -48, and w.f() == 0x1234567890abcdef
+// w's value can be computed by w.f() * 2^w.e()
+// We can obtain w's integral digits by simply shifting w.f() by -w.e().
+// -> w's integral part is 0x1234
+// w's fractional part is therefore 0x567890abcdef.
+// Printing w's integral part is easy (simply print 0x1234 in decimal).
+// In order to print its fraction we repeatedly multiply the fraction by 10 and
+// get each digit. Example the first digit after the point would be computed by
+// (0x567890abcdef * 10) >> 48. -> 3
+// The whole thing becomes slightly more complicated because we want to stop
+// once we have enough digits. That is, once the digits inside the buffer
+// represent 'w' we can stop. Everything inside the interval low - high
+// represents w. However we have to pay attention to low, high and w's
+// imprecision.
+static bool DigitGen(DiyFp low,
+ DiyFp w,
+ DiyFp high,
+ Vector<char> buffer,
+ int* length,
+ int* kappa) {
+ ASSERT(low.e() == w.e() && w.e() == high.e());
+ ASSERT(low.f() + 1 <= high.f() - 1);
+ ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
+ // low, w and high are imprecise, but by less than one ulp (unit in the last
+ // place).
+ // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that
+ // the new numbers are outside of the interval we want the final
+ // representation to lie in.
+ // Inversely adding (resp. removing) 1 ulp from low (resp. high) would yield
+ // numbers that are certain to lie in the interval. We will use this fact
+ // later on.
+ // We will now start by generating the digits within the uncertain
+ // interval. Later we will weed out representations that lie outside the safe
+ // interval and thus _might_ lie outside the correct interval.
+ uint64_t unit = 1;
+ DiyFp too_low = DiyFp(low.f() - unit, low.e());
+ DiyFp too_high = DiyFp(high.f() + unit, high.e());
+ // too_low and too_high are guaranteed to lie outside the interval we want the
+ // generated number in.
+ DiyFp unsafe_interval = DiyFp::Minus(too_high, too_low);
+ // We now cut the input number into two parts: the integral digits and the
+ // fractionals. We will not write any decimal separator though, but adapt
+ // kappa instead.
+ // Reminder: we are currently computing the digits (stored inside the buffer)
+ // such that: too_low < buffer * 10^kappa < too_high
+ // We use too_high for the digit_generation and stop as soon as possible.
+ // If we stop early we effectively round down.
+ DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
+ // Division by one is a shift.
+ uint32_t integrals = static_cast<uint32_t>(too_high.f() >> -one.e());
+ // Modulo by one is an and.
+ uint64_t fractionals = too_high.f() & (one.f() - 1);
+ uint32_t divisor;
+ int divisor_exponent_plus_one;
+ BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
+ &divisor, &divisor_exponent_plus_one);
+ *kappa = divisor_exponent_plus_one;
+ *length = 0;
+ // Loop invariant: buffer = too_high / 10^kappa (integer division)
+ // The invariant holds for the first iteration: kappa has been initialized
+ // with the divisor exponent + 1. And the divisor is the biggest power of ten
+ // that is smaller than integrals.
+ while (*kappa > 0) {
+ int digit = integrals / divisor;
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
+ (*length)++;
+ integrals %= divisor;
+ (*kappa)--;
+ // Note that kappa now equals the exponent of the divisor and that the
+ // invariant thus holds again.
+ uint64_t rest =
+ (static_cast<uint64_t>(integrals) << -one.e()) + fractionals;
+ // Invariant: too_high = buffer * 10^kappa + DiyFp(rest, one.e())
+ // Reminder: unsafe_interval.e() == one.e()
+ if (rest < unsafe_interval.f()) {
+ // Rounding down (by not emitting the remaining digits) yields a number
+ // that lies within the unsafe interval.
+ return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).f(),
+ unsafe_interval.f(), rest,
+ static_cast<uint64_t>(divisor) << -one.e(), unit);
+ }
+ divisor /= 10;
+ }
+
+ // The integrals have been generated. We are at the point of the decimal
+ // separator. In the following loop we simply multiply the remaining digits by
+ // 10 and divide by one. We just need to pay attention to multiply associated
+ // data (like the interval or 'unit'), too.
+ // Note that the multiplication by 10 does not overflow, because w.e >= -60
+ // and thus one.e >= -60.
+ ASSERT(one.e() >= -60);
+ ASSERT(fractionals < one.f());
+ ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
+ for (;;) {
+ fractionals *= 10;
+ unit *= 10;
+ unsafe_interval.set_f(unsafe_interval.f() * 10);
+ // Integer division by one.
+ int digit = static_cast<int>(fractionals >> -one.e());
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
+ (*length)++;
+ fractionals &= one.f() - 1; // Modulo by one.
+ (*kappa)--;
+ if (fractionals < unsafe_interval.f()) {
+ return RoundWeed(buffer, *length, DiyFp::Minus(too_high, w).f() * unit,
+ unsafe_interval.f(), fractionals, one.f(), unit);
+ }
+ }
+}
+
+
+
+// Generates (at most) requested_digits digits of input number w.
+// w is a floating-point number (DiyFp), consisting of a significand and an
+// exponent. Its exponent is bounded by kMinimalTargetExponent and
+// kMaximalTargetExponent.
+// Hence -60 <= w.e() <= -32.
+//
+// Returns false if it fails, in which case the generated digits in the buffer
+// should not be used.
+// Preconditions:
+// * w is correct up to 1 ulp (unit in the last place). That
+// is, its error must be strictly less than a unit of its last digit.
+// * kMinimalTargetExponent <= w.e() <= kMaximalTargetExponent
+//
+// Postconditions: returns false if procedure fails.
+// otherwise:
+// * buffer is not null-terminated, but length contains the number of
+// digits.
+// * the representation in buffer is the most precise representation of
+// requested_digits digits.
+// * buffer contains at most requested_digits digits of w. If there are less
+// than requested_digits digits then some trailing '0's have been removed.
+// * kappa is such that
+// w = buffer * 10^kappa + eps with |eps| < 10^kappa / 2.
+//
+// Remark: This procedure takes into account the imprecision of its input
+// numbers. If the precision is not enough to guarantee all the postconditions
+// then false is returned. This usually happens rarely, but the failure-rate
+// increases with higher requested_digits.
+static bool DigitGenCounted(DiyFp w,
+ int requested_digits,
+ Vector<char> buffer,
+ int* length,
+ int* kappa) {
+ ASSERT(kMinimalTargetExponent <= w.e() && w.e() <= kMaximalTargetExponent);
+ ASSERT(kMinimalTargetExponent >= -60);
+ ASSERT(kMaximalTargetExponent <= -32);
+ // w is assumed to have an error less than 1 unit. Whenever w is scaled we
+ // also scale its error.
+ uint64_t w_error = 1;
+ // We cut the input number into two parts: the integral digits and the
+ // fractional digits. We don't emit any decimal separator, but adapt kappa
+ // instead. Example: instead of writing "1.2" we put "12" into the buffer and
+ // increase kappa by 1.
+ DiyFp one = DiyFp(static_cast<uint64_t>(1) << -w.e(), w.e());
+ // Division by one is a shift.
+ uint32_t integrals = static_cast<uint32_t>(w.f() >> -one.e());
+ // Modulo by one is an and.
+ uint64_t fractionals = w.f() & (one.f() - 1);
+ uint32_t divisor;
+ int divisor_exponent_plus_one;
+ BiggestPowerTen(integrals, DiyFp::kSignificandSize - (-one.e()),
+ &divisor, &divisor_exponent_plus_one);
+ *kappa = divisor_exponent_plus_one;
+ *length = 0;
+
+ // Loop invariant: buffer = w / 10^kappa (integer division)
+ // The invariant holds for the first iteration: kappa has been initialized
+ // with the divisor exponent + 1. And the divisor is the biggest power of ten
+ // that is smaller than 'integrals'.
+ while (*kappa > 0) {
+ int digit = integrals / divisor;
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
+ (*length)++;
+ requested_digits--;
+ integrals %= divisor;
+ (*kappa)--;
+ // Note that kappa now equals the exponent of the divisor and that the
+ // invariant thus holds again.
+ if (requested_digits == 0) break;
+ divisor /= 10;
+ }
+
+ if (requested_digits == 0) {
+ uint64_t rest =
+ (static_cast<uint64_t>(integrals) << -one.e()) + fractionals;
+ return RoundWeedCounted(buffer, *length, rest,
+ static_cast<uint64_t>(divisor) << -one.e(), w_error,
+ kappa);
+ }
+
+ // The integrals have been generated. We are at the point of the decimal
+ // separator. In the following loop we simply multiply the remaining digits by
+ // 10 and divide by one. We just need to pay attention to multiply associated
+ // data (the 'unit'), too.
+ // Note that the multiplication by 10 does not overflow, because w.e >= -60
+ // and thus one.e >= -60.
+ ASSERT(one.e() >= -60);
+ ASSERT(fractionals < one.f());
+ ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
+ while (requested_digits > 0 && fractionals > w_error) {
+ fractionals *= 10;
+ w_error *= 10;
+ // Integer division by one.
+ int digit = static_cast<int>(fractionals >> -one.e());
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
+ (*length)++;
+ requested_digits--;
+ fractionals &= one.f() - 1; // Modulo by one.
+ (*kappa)--;
+ }
+ if (requested_digits != 0) return false;
+ return RoundWeedCounted(buffer, *length, fractionals, one.f(), w_error,
+ kappa);
+}
+
+
+// Provides a decimal representation of v.
+// Returns true if it succeeds, otherwise the result cannot be trusted.
+// There will be *length digits inside the buffer (not null-terminated).
+// If the function returns true then
+// v == (double) (buffer * 10^decimal_exponent).
+// The digits in the buffer are the shortest representation possible: no
+// 0.09999999999999999 instead of 0.1. The shorter representation will even be
+// chosen even if the longer one would be closer to v.
+// The last digit will be closest to the actual v. That is, even if several
+// digits might correctly yield 'v' when read again, the closest will be
+// computed.
+static bool Grisu3(double v,
+ FastDtoaMode mode,
+ Vector<char> buffer,
+ int* length,
+ int* decimal_exponent) {
+ DiyFp w = Double(v).AsNormalizedDiyFp();
+ // boundary_minus and boundary_plus are the boundaries between v and its
+ // closest floating-point neighbors. Any number strictly between
+ // boundary_minus and boundary_plus will round to v when convert to a double.
+ // Grisu3 will never output representations that lie exactly on a boundary.
+ DiyFp boundary_minus, boundary_plus;
+ if (mode == FAST_DTOA_SHORTEST) {
+ Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+ } else {
+ ASSERT(mode == FAST_DTOA_SHORTEST_SINGLE);
+ float single_v = static_cast<float>(v);
+ Single(single_v).NormalizedBoundaries(&boundary_minus, &boundary_plus);
+ }
+ ASSERT(boundary_plus.e() == w.e());
+ DiyFp ten_mk; // Cached power of ten: 10^-k
+ int mk; // -k
+ int ten_mk_minimal_binary_exponent =
+ kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+ int ten_mk_maximal_binary_exponent =
+ kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+ PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
+ ten_mk_minimal_binary_exponent,
+ ten_mk_maximal_binary_exponent,
+ &ten_mk, &mk);
+ ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
+ DiyFp::kSignificandSize) &&
+ (kMaximalTargetExponent >= w.e() + ten_mk.e() +
+ DiyFp::kSignificandSize));
+ // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a
+ // 64 bit significand and ten_mk is thus only precise up to 64 bits.
+
+ // The DiyFp::Times procedure rounds its result, and ten_mk is approximated
+ // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now
+ // off by a small amount.
+ // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
+ // In other words: let f = scaled_w.f() and e = scaled_w.e(), then
+ // (f-1) * 2^e < w*10^k < (f+1) * 2^e
+ DiyFp scaled_w = DiyFp::Times(w, ten_mk);
+ ASSERT(scaled_w.e() ==
+ boundary_plus.e() + ten_mk.e() + DiyFp::kSignificandSize);
+ // In theory it would be possible to avoid some recomputations by computing
+ // the difference between w and boundary_minus/plus (a power of 2) and to
+ // compute scaled_boundary_minus/plus by subtracting/adding from
+ // scaled_w. However the code becomes much less readable and the speed
+ // enhancements are not terriffic.
+ DiyFp scaled_boundary_minus = DiyFp::Times(boundary_minus, ten_mk);
+ DiyFp scaled_boundary_plus = DiyFp::Times(boundary_plus, ten_mk);
+
+ // DigitGen will generate the digits of scaled_w. Therefore we have
+ // v == (double) (scaled_w * 10^-mk).
+ // Set decimal_exponent == -mk and pass it to DigitGen. If scaled_w is not an
+ // integer than it will be updated. For instance if scaled_w == 1.23 then
+ // the buffer will be filled with "123" und the decimal_exponent will be
+ // decreased by 2.
+ int kappa;
+ bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus,
+ buffer, length, &kappa);
+ *decimal_exponent = -mk + kappa;
+ return result;
+}
+
+
+// The "counted" version of grisu3 (see above) only generates requested_digits
+// number of digits. This version does not generate the shortest representation,
+// and with enough requested digits 0.1 will at some point print as 0.9999999...
+// Grisu3 is too imprecise for real halfway cases (1.5 will not work) and
+// therefore the rounding strategy for halfway cases is irrelevant.
+static bool Grisu3Counted(double v,
+ int requested_digits,
+ Vector<char> buffer,
+ int* length,
+ int* decimal_exponent) {
+ DiyFp w = Double(v).AsNormalizedDiyFp();
+ DiyFp ten_mk; // Cached power of ten: 10^-k
+ int mk; // -k
+ int ten_mk_minimal_binary_exponent =
+ kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+ int ten_mk_maximal_binary_exponent =
+ kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+ PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
+ ten_mk_minimal_binary_exponent,
+ ten_mk_maximal_binary_exponent,
+ &ten_mk, &mk);
+ ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
+ DiyFp::kSignificandSize) &&
+ (kMaximalTargetExponent >= w.e() + ten_mk.e() +
+ DiyFp::kSignificandSize));
+ // Note that ten_mk is only an approximation of 10^-k. A DiyFp only contains a
+ // 64 bit significand and ten_mk is thus only precise up to 64 bits.
+
+ // The DiyFp::Times procedure rounds its result, and ten_mk is approximated
+ // too. The variable scaled_w (as well as scaled_boundary_minus/plus) are now
+ // off by a small amount.
+ // In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
+ // In other words: let f = scaled_w.f() and e = scaled_w.e(), then
+ // (f-1) * 2^e < w*10^k < (f+1) * 2^e
+ DiyFp scaled_w = DiyFp::Times(w, ten_mk);
+
+ // We now have (double) (scaled_w * 10^-mk).
+ // DigitGen will generate the first requested_digits digits of scaled_w and
+ // return together with a kappa such that scaled_w ~= buffer * 10^kappa. (It
+ // will not always be exactly the same since DigitGenCounted only produces a
+ // limited number of digits.)
+ int kappa;
+ bool result = DigitGenCounted(scaled_w, requested_digits,
+ buffer, length, &kappa);
+ *decimal_exponent = -mk + kappa;
+ return result;
+}
+
+
+bool FastDtoa(double v,
+ FastDtoaMode mode,
+ int requested_digits,
+ Vector<char> buffer,
+ int* length,
+ int* decimal_point) {
+ ASSERT(v > 0);
+ ASSERT(!Double(v).IsSpecial());
+
+ bool result = false;
+ int decimal_exponent = 0;
+ switch (mode) {
+ case FAST_DTOA_SHORTEST:
+ case FAST_DTOA_SHORTEST_SINGLE:
+ result = Grisu3(v, mode, buffer, length, &decimal_exponent);
+ break;
+ case FAST_DTOA_PRECISION:
+ result = Grisu3Counted(v, requested_digits,
+ buffer, length, &decimal_exponent);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ if (result) {
+ *decimal_point = *length + decimal_exponent;
+ buffer[*length] = '\0';
+ }
+ return result;
+}
+
+} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/fast-dtoa.h b/src/3rdparty/double-conversion/fast-dtoa.h
new file mode 100644
index 0000000000..5f1e8eee5e
--- /dev/null
+++ b/src/3rdparty/double-conversion/fast-dtoa.h
@@ -0,0 +1,88 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_FAST_DTOA_H_
+#define DOUBLE_CONVERSION_FAST_DTOA_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+enum FastDtoaMode {
+ // Computes the shortest representation of the given input. The returned
+ // result will be the most accurate number of this length. Longer
+ // representations might be more accurate.
+ FAST_DTOA_SHORTEST,
+ // Same as FAST_DTOA_SHORTEST but for single-precision floats.
+ FAST_DTOA_SHORTEST_SINGLE,
+ // Computes a representation where the precision (number of digits) is
+ // given as input. The precision is independent of the decimal point.
+ FAST_DTOA_PRECISION
+};
+
+// FastDtoa will produce at most kFastDtoaMaximalLength digits. This does not
+// include the terminating '\0' character.
+static const int kFastDtoaMaximalLength = 17;
+// Same for single-precision numbers.
+static const int kFastDtoaMaximalSingleLength = 9;
+
+// Provides a decimal representation of v.
+// The result should be interpreted as buffer * 10^(point - length).
+//
+// Precondition:
+// * v must be a strictly positive finite double.
+//
+// Returns true if it succeeds, otherwise the result can not be trusted.
+// There will be *length digits inside the buffer followed by a null terminator.
+// If the function returns true and mode equals
+// - FAST_DTOA_SHORTEST, then
+// the parameter requested_digits is ignored.
+// The result satisfies
+// v == (double) (buffer * 10^(point - length)).
+// The digits in the buffer are the shortest representation possible. E.g.
+// if 0.099999999999 and 0.1 represent the same double then "1" is returned
+// with point = 0.
+// The last digit will be closest to the actual v. That is, even if several
+// digits might correctly yield 'v' when read again, the buffer will contain
+// the one closest to v.
+// - FAST_DTOA_PRECISION, then
+// the buffer contains requested_digits digits.
+// the difference v - (buffer * 10^(point-length)) is closest to zero for
+// all possible representations of requested_digits digits.
+// If there are two values that are equally close, then FastDtoa returns
+// false.
+// For both modes the buffer must be large enough to hold the result.
+bool FastDtoa(double d,
+ FastDtoaMode mode,
+ int requested_digits,
+ Vector<char> buffer,
+ int* length,
+ int* decimal_point);
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_FAST_DTOA_H_
diff --git a/src/3rdparty/double-conversion/fixed-dtoa.cc b/src/3rdparty/double-conversion/fixed-dtoa.cc
new file mode 100644
index 0000000000..aef65fdc21
--- /dev/null
+++ b/src/3rdparty/double-conversion/fixed-dtoa.cc
@@ -0,0 +1,404 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <math.h>
+
+#include "fixed-dtoa.h"
+#include "ieee.h"
+
+namespace double_conversion {
+
+// Represents a 128bit type. This class should be replaced by a native type on
+// platforms that support 128bit integers.
+class UInt128 {
+ public:
+ UInt128() : high_bits_(0), low_bits_(0) { }
+ UInt128(uint64_t high, uint64_t low) : high_bits_(high), low_bits_(low) { }
+
+ void Multiply(uint32_t multiplicand) {
+ uint64_t accumulator;
+
+ accumulator = (low_bits_ & kMask32) * multiplicand;
+ uint32_t part = static_cast<uint32_t>(accumulator & kMask32);
+ accumulator >>= 32;
+ accumulator = accumulator + (low_bits_ >> 32) * multiplicand;
+ low_bits_ = (accumulator << 32) + part;
+ accumulator >>= 32;
+ accumulator = accumulator + (high_bits_ & kMask32) * multiplicand;
+ part = static_cast<uint32_t>(accumulator & kMask32);
+ accumulator >>= 32;
+ accumulator = accumulator + (high_bits_ >> 32) * multiplicand;
+ high_bits_ = (accumulator << 32) + part;
+ ASSERT((accumulator >> 32) == 0);
+ }
+
+ void Shift(int shift_amount) {
+ ASSERT(-64 <= shift_amount && shift_amount <= 64);
+ if (shift_amount == 0) {
+ return;
+ } else if (shift_amount == -64) {
+ high_bits_ = low_bits_;
+ low_bits_ = 0;
+ } else if (shift_amount == 64) {
+ low_bits_ = high_bits_;
+ high_bits_ = 0;
+ } else if (shift_amount <= 0) {
+ high_bits_ <<= -shift_amount;
+ high_bits_ += low_bits_ >> (64 + shift_amount);
+ low_bits_ <<= -shift_amount;
+ } else {
+ low_bits_ >>= shift_amount;
+ low_bits_ += high_bits_ << (64 - shift_amount);
+ high_bits_ >>= shift_amount;
+ }
+ }
+
+ // Modifies *this to *this MOD (2^power).
+ // Returns *this DIV (2^power).
+ int DivModPowerOf2(int power) {
+ if (power >= 64) {
+ int result = static_cast<int>(high_bits_ >> (power - 64));
+ high_bits_ -= static_cast<uint64_t>(result) << (power - 64);
+ return result;
+ } else {
+ uint64_t part_low = low_bits_ >> power;
+ uint64_t part_high = high_bits_ << (64 - power);
+ int result = static_cast<int>(part_low + part_high);
+ high_bits_ = 0;
+ low_bits_ -= part_low << power;
+ return result;
+ }
+ }
+
+ bool IsZero() const {
+ return high_bits_ == 0 && low_bits_ == 0;
+ }
+
+ int BitAt(int position) {
+ if (position >= 64) {
+ return static_cast<int>(high_bits_ >> (position - 64)) & 1;
+ } else {
+ return static_cast<int>(low_bits_ >> position) & 1;
+ }
+ }
+
+ private:
+ static const uint64_t kMask32 = 0xFFFFFFFF;
+ // Value == (high_bits_ << 64) + low_bits_
+ uint64_t high_bits_;
+ uint64_t low_bits_;
+};
+
+
+static const int kDoubleSignificandSize = 53; // Includes the hidden bit.
+
+
+static void FillDigits32FixedLength(uint32_t number, int requested_length,
+ Vector<char> buffer, int* length) {
+ for (int i = requested_length - 1; i >= 0; --i) {
+ buffer[(*length) + i] = '0' + number % 10;
+ number /= 10;
+ }
+ *length += requested_length;
+}
+
+
+static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) {
+ int number_length = 0;
+ // We fill the digits in reverse order and exchange them afterwards.
+ while (number != 0) {
+ int digit = number % 10;
+ number /= 10;
+ buffer[(*length) + number_length] = static_cast<char>('0' + digit);
+ number_length++;
+ }
+ // Exchange the digits.
+ int i = *length;
+ int j = *length + number_length - 1;
+ while (i < j) {
+ char tmp = buffer[i];
+ buffer[i] = buffer[j];
+ buffer[j] = tmp;
+ i++;
+ j--;
+ }
+ *length += number_length;
+}
+
+
+static void FillDigits64FixedLength(uint64_t number,
+ Vector<char> buffer, int* length) {
+ const uint32_t kTen7 = 10000000;
+ // For efficiency cut the number into 3 uint32_t parts, and print those.
+ uint32_t part2 = static_cast<uint32_t>(number % kTen7);
+ number /= kTen7;
+ uint32_t part1 = static_cast<uint32_t>(number % kTen7);
+ uint32_t part0 = static_cast<uint32_t>(number / kTen7);
+
+ FillDigits32FixedLength(part0, 3, buffer, length);
+ FillDigits32FixedLength(part1, 7, buffer, length);
+ FillDigits32FixedLength(part2, 7, buffer, length);
+}
+
+
+static void FillDigits64(uint64_t number, Vector<char> buffer, int* length) {
+ const uint32_t kTen7 = 10000000;
+ // For efficiency cut the number into 3 uint32_t parts, and print those.
+ uint32_t part2 = static_cast<uint32_t>(number % kTen7);
+ number /= kTen7;
+ uint32_t part1 = static_cast<uint32_t>(number % kTen7);
+ uint32_t part0 = static_cast<uint32_t>(number / kTen7);
+
+ if (part0 != 0) {
+ FillDigits32(part0, buffer, length);
+ FillDigits32FixedLength(part1, 7, buffer, length);
+ FillDigits32FixedLength(part2, 7, buffer, length);
+ } else if (part1 != 0) {
+ FillDigits32(part1, buffer, length);
+ FillDigits32FixedLength(part2, 7, buffer, length);
+ } else {
+ FillDigits32(part2, buffer, length);
+ }
+}
+
+
+static void RoundUp(Vector<char> buffer, int* length, int* decimal_point) {
+ // An empty buffer represents 0.
+ if (*length == 0) {
+ buffer[0] = '1';
+ *decimal_point = 1;
+ *length = 1;
+ return;
+ }
+ // Round the last digit until we either have a digit that was not '9' or until
+ // we reached the first digit.
+ buffer[(*length) - 1]++;
+ for (int i = (*length) - 1; i > 0; --i) {
+ if (buffer[i] != '0' + 10) {
+ return;
+ }
+ buffer[i] = '0';
+ buffer[i - 1]++;
+ }
+ // If the first digit is now '0' + 10, we would need to set it to '0' and add
+ // a '1' in front. However we reach the first digit only if all following
+ // digits had been '9' before rounding up. Now all trailing digits are '0' and
+ // we simply switch the first digit to '1' and update the decimal-point
+ // (indicating that the point is now one digit to the right).
+ if (buffer[0] == '0' + 10) {
+ buffer[0] = '1';
+ (*decimal_point)++;
+ }
+}
+
+
+// The given fractionals number represents a fixed-point number with binary
+// point at bit (-exponent).
+// Preconditions:
+// -128 <= exponent <= 0.
+// 0 <= fractionals * 2^exponent < 1
+// The buffer holds the result.
+// The function will round its result. During the rounding-process digits not
+// generated by this function might be updated, and the decimal-point variable
+// might be updated. If this function generates the digits 99 and the buffer
+// already contained "199" (thus yielding a buffer of "19999") then a
+// rounding-up will change the contents of the buffer to "20000".
+static void FillFractionals(uint64_t fractionals, int exponent,
+ int fractional_count, Vector<char> buffer,
+ int* length, int* decimal_point) {
+ ASSERT(-128 <= exponent && exponent <= 0);
+ // 'fractionals' is a fixed-point number, with binary point at bit
+ // (-exponent). Inside the function the non-converted remainder of fractionals
+ // is a fixed-point number, with binary point at bit 'point'.
+ if (-exponent <= 64) {
+ // One 64 bit number is sufficient.
+ ASSERT(fractionals >> 56 == 0);
+ int point = -exponent;
+ for (int i = 0; i < fractional_count; ++i) {
+ if (fractionals == 0) break;
+ // Instead of multiplying by 10 we multiply by 5 and adjust the point
+ // location. This way the fractionals variable will not overflow.
+ // Invariant at the beginning of the loop: fractionals < 2^point.
+ // Initially we have: point <= 64 and fractionals < 2^56
+ // After each iteration the point is decremented by one.
+ // Note that 5^3 = 125 < 128 = 2^7.
+ // Therefore three iterations of this loop will not overflow fractionals
+ // (even without the subtraction at the end of the loop body). At this
+ // time point will satisfy point <= 61 and therefore fractionals < 2^point
+ // and any further multiplication of fractionals by 5 will not overflow.
+ fractionals *= 5;
+ point--;
+ int digit = static_cast<int>(fractionals >> point);
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
+ (*length)++;
+ fractionals -= static_cast<uint64_t>(digit) << point;
+ }
+ // If the first bit after the point is set we have to round up.
+ if (((fractionals >> (point - 1)) & 1) == 1) {
+ RoundUp(buffer, length, decimal_point);
+ }
+ } else { // We need 128 bits.
+ ASSERT(64 < -exponent && -exponent <= 128);
+ UInt128 fractionals128 = UInt128(fractionals, 0);
+ fractionals128.Shift(-exponent - 64);
+ int point = 128;
+ for (int i = 0; i < fractional_count; ++i) {
+ if (fractionals128.IsZero()) break;
+ // As before: instead of multiplying by 10 we multiply by 5 and adjust the
+ // point location.
+ // This multiplication will not overflow for the same reasons as before.
+ fractionals128.Multiply(5);
+ point--;
+ int digit = fractionals128.DivModPowerOf2(point);
+ ASSERT(digit <= 9);
+ buffer[*length] = static_cast<char>('0' + digit);
+ (*length)++;
+ }
+ if (fractionals128.BitAt(point - 1) == 1) {
+ RoundUp(buffer, length, decimal_point);
+ }
+ }
+}
+
+
+// Removes leading and trailing zeros.
+// If leading zeros are removed then the decimal point position is adjusted.
+static void TrimZeros(Vector<char> buffer, int* length, int* decimal_point) {
+ while (*length > 0 && buffer[(*length) - 1] == '0') {
+ (*length)--;
+ }
+ int first_non_zero = 0;
+ while (first_non_zero < *length && buffer[first_non_zero] == '0') {
+ first_non_zero++;
+ }
+ if (first_non_zero != 0) {
+ for (int i = first_non_zero; i < *length; ++i) {
+ buffer[i - first_non_zero] = buffer[i];
+ }
+ *length -= first_non_zero;
+ *decimal_point -= first_non_zero;
+ }
+}
+
+
+bool FastFixedDtoa(double v,
+ int fractional_count,
+ Vector<char> buffer,
+ int* length,
+ int* decimal_point) {
+ const uint32_t kMaxUInt32 = 0xFFFFFFFF;
+ uint64_t significand = Double(v).Significand();
+ int exponent = Double(v).Exponent();
+ // v = significand * 2^exponent (with significand a 53bit integer).
+ // If the exponent is larger than 20 (i.e. we may have a 73bit number) then we
+ // don't know how to compute the representation. 2^73 ~= 9.5*10^21.
+ // If necessary this limit could probably be increased, but we don't need
+ // more.
+ if (exponent > 20) return false;
+ if (fractional_count > 20) return false;
+ *length = 0;
+ // At most kDoubleSignificandSize bits of the significand are non-zero.
+ // Given a 64 bit integer we have 11 0s followed by 53 potentially non-zero
+ // bits: 0..11*..0xxx..53*..xx
+ if (exponent + kDoubleSignificandSize > 64) {
+ // The exponent must be > 11.
+ //
+ // We know that v = significand * 2^exponent.
+ // And the exponent > 11.
+ // We simplify the task by dividing v by 10^17.
+ // The quotient delivers the first digits, and the remainder fits into a 64
+ // bit number.
+ // Dividing by 10^17 is equivalent to dividing by 5^17*2^17.
+ const uint64_t kFive17 = UINT64_2PART_C(0xB1, A2BC2EC5); // 5^17
+ uint64_t divisor = kFive17;
+ int divisor_power = 17;
+ uint64_t dividend = significand;
+ uint32_t quotient;
+ uint64_t remainder;
+ // Let v = f * 2^e with f == significand and e == exponent.
+ // Then need q (quotient) and r (remainder) as follows:
+ // v = q * 10^17 + r
+ // f * 2^e = q * 10^17 + r
+ // f * 2^e = q * 5^17 * 2^17 + r
+ // If e > 17 then
+ // f * 2^(e-17) = q * 5^17 + r/2^17
+ // else
+ // f = q * 5^17 * 2^(17-e) + r/2^e
+ if (exponent > divisor_power) {
+ // We only allow exponents of up to 20 and therefore (17 - e) <= 3
+ dividend <<= exponent - divisor_power;
+ quotient = static_cast<uint32_t>(dividend / divisor);
+ remainder = (dividend % divisor) << divisor_power;
+ } else {
+ divisor <<= divisor_power - exponent;
+ quotient = static_cast<uint32_t>(dividend / divisor);
+ remainder = (dividend % divisor) << exponent;
+ }
+ FillDigits32(quotient, buffer, length);
+ FillDigits64FixedLength(remainder, buffer, length);
+ *decimal_point = *length;
+ } else if (exponent >= 0) {
+ // 0 <= exponent <= 11
+ significand <<= exponent;
+ FillDigits64(significand, buffer, length);
+ *decimal_point = *length;
+ } else if (exponent > -kDoubleSignificandSize) {
+ // We have to cut the number.
+ uint64_t integrals = significand >> -exponent;
+ uint64_t fractionals = significand - (integrals << -exponent);
+ if (integrals > kMaxUInt32) {
+ FillDigits64(integrals, buffer, length);
+ } else {
+ FillDigits32(static_cast<uint32_t>(integrals), buffer, length);
+ }
+ *decimal_point = *length;
+ FillFractionals(fractionals, exponent, fractional_count,
+ buffer, length, decimal_point);
+ } else if (exponent < -128) {
+ // This configuration (with at most 20 digits) means that all digits must be
+ // 0.
+ ASSERT(fractional_count <= 20);
+ buffer[0] = '\0';
+ *length = 0;
+ *decimal_point = -fractional_count;
+ } else {
+ *decimal_point = 0;
+ FillFractionals(significand, exponent, fractional_count,
+ buffer, length, decimal_point);
+ }
+ TrimZeros(buffer, length, decimal_point);
+ buffer[*length] = '\0';
+ if ((*length) == 0) {
+ // The string is empty and the decimal_point thus has no importance. Mimick
+ // Gay's dtoa and and set it to -fractional_count.
+ *decimal_point = -fractional_count;
+ }
+ return true;
+}
+
+} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/fixed-dtoa.h b/src/3rdparty/double-conversion/fixed-dtoa.h
new file mode 100644
index 0000000000..3bdd08e21f
--- /dev/null
+++ b/src/3rdparty/double-conversion/fixed-dtoa.h
@@ -0,0 +1,56 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_FIXED_DTOA_H_
+#define DOUBLE_CONVERSION_FIXED_DTOA_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+// Produces digits necessary to print a given number with
+// 'fractional_count' digits after the decimal point.
+// The buffer must be big enough to hold the result plus one terminating null
+// character.
+//
+// The produced digits might be too short in which case the caller has to fill
+// the gaps with '0's.
+// Example: FastFixedDtoa(0.001, 5, ...) is allowed to return buffer = "1", and
+// decimal_point = -2.
+// Halfway cases are rounded towards +/-Infinity (away from 0). The call
+// FastFixedDtoa(0.15, 2, ...) thus returns buffer = "2", decimal_point = 0.
+// The returned buffer may contain digits that would be truncated from the
+// shortest representation of the input.
+//
+// This method only works for some parameters. If it can't handle the input it
+// returns false. The output is null-terminated when the function succeeds.
+bool FastFixedDtoa(double v, int fractional_count,
+ Vector<char> buffer, int* length, int* decimal_point);
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_FIXED_DTOA_H_
diff --git a/src/3rdparty/double-conversion/ieee.h b/src/3rdparty/double-conversion/ieee.h
new file mode 100644
index 0000000000..661141d1a8
--- /dev/null
+++ b/src/3rdparty/double-conversion/ieee.h
@@ -0,0 +1,402 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_DOUBLE_H_
+#define DOUBLE_CONVERSION_DOUBLE_H_
+
+#include "diy-fp.h"
+
+namespace double_conversion {
+
+// We assume that doubles and uint64_t have the same endianness.
+static uint64_t double_to_uint64(double d) { return BitCast<uint64_t>(d); }
+static double uint64_to_double(uint64_t d64) { return BitCast<double>(d64); }
+static uint32_t float_to_uint32(float f) { return BitCast<uint32_t>(f); }
+static float uint32_to_float(uint32_t d32) { return BitCast<float>(d32); }
+
+// Helper functions for doubles.
+class Double {
+ public:
+ static const uint64_t kSignMask = UINT64_2PART_C(0x80000000, 00000000);
+ static const uint64_t kExponentMask = UINT64_2PART_C(0x7FF00000, 00000000);
+ static const uint64_t kSignificandMask = UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
+ static const uint64_t kHiddenBit = UINT64_2PART_C(0x00100000, 00000000);
+ static const int kPhysicalSignificandSize = 52; // Excludes the hidden bit.
+ static const int kSignificandSize = 53;
+
+ Double() : d64_(0) {}
+ explicit Double(double d) : d64_(double_to_uint64(d)) {}
+ explicit Double(uint64_t d64) : d64_(d64) {}
+ explicit Double(DiyFp diy_fp)
+ : d64_(DiyFpToUint64(diy_fp)) {}
+
+ // The value encoded by this Double must be greater or equal to +0.0.
+ // It must not be special (infinity, or NaN).
+ DiyFp AsDiyFp() const {
+ ASSERT(Sign() > 0);
+ ASSERT(!IsSpecial());
+ return DiyFp(Significand(), Exponent());
+ }
+
+ // The value encoded by this Double must be strictly greater than 0.
+ DiyFp AsNormalizedDiyFp() const {
+ ASSERT(value() > 0.0);
+ uint64_t f = Significand();
+ int e = Exponent();
+
+ // The current double could be a denormal.
+ while ((f & kHiddenBit) == 0) {
+ f <<= 1;
+ e--;
+ }
+ // Do the final shifts in one go.
+ f <<= DiyFp::kSignificandSize - kSignificandSize;
+ e -= DiyFp::kSignificandSize - kSignificandSize;
+ return DiyFp(f, e);
+ }
+
+ // Returns the double's bit as uint64.
+ uint64_t AsUint64() const {
+ return d64_;
+ }
+
+ // Returns the next greater double. Returns +infinity on input +infinity.
+ double NextDouble() const {
+ if (d64_ == kInfinity) return Double(kInfinity).value();
+ if (Sign() < 0 && Significand() == 0) {
+ // -0.0
+ return 0.0;
+ }
+ if (Sign() < 0) {
+ return Double(d64_ - 1).value();
+ } else {
+ return Double(d64_ + 1).value();
+ }
+ }
+
+ double PreviousDouble() const {
+ if (d64_ == (kInfinity | kSignMask)) return -Double::Infinity();
+ if (Sign() < 0) {
+ return Double(d64_ + 1).value();
+ } else {
+ if (Significand() == 0) return -0.0;
+ return Double(d64_ - 1).value();
+ }
+ }
+
+ int Exponent() const {
+ if (IsDenormal()) return kDenormalExponent;
+
+ uint64_t d64 = AsUint64();
+ int biased_e =
+ static_cast<int>((d64 & kExponentMask) >> kPhysicalSignificandSize);
+ return biased_e - kExponentBias;
+ }
+
+ uint64_t Significand() const {
+ uint64_t d64 = AsUint64();
+ uint64_t significand = d64 & kSignificandMask;
+ if (!IsDenormal()) {
+ return significand + kHiddenBit;
+ } else {
+ return significand;
+ }
+ }
+
+ // Returns true if the double is a denormal.
+ bool IsDenormal() const {
+ uint64_t d64 = AsUint64();
+ return (d64 & kExponentMask) == 0;
+ }
+
+ // We consider denormals not to be special.
+ // Hence only Infinity and NaN are special.
+ bool IsSpecial() const {
+ uint64_t d64 = AsUint64();
+ return (d64 & kExponentMask) == kExponentMask;
+ }
+
+ bool IsNan() const {
+ uint64_t d64 = AsUint64();
+ return ((d64 & kExponentMask) == kExponentMask) &&
+ ((d64 & kSignificandMask) != 0);
+ }
+
+ bool IsInfinite() const {
+ uint64_t d64 = AsUint64();
+ return ((d64 & kExponentMask) == kExponentMask) &&
+ ((d64 & kSignificandMask) == 0);
+ }
+
+ int Sign() const {
+ uint64_t d64 = AsUint64();
+ return (d64 & kSignMask) == 0? 1: -1;
+ }
+
+ // Precondition: the value encoded by this Double must be greater or equal
+ // than +0.0.
+ DiyFp UpperBoundary() const {
+ ASSERT(Sign() > 0);
+ return DiyFp(Significand() * 2 + 1, Exponent() - 1);
+ }
+
+ // Computes the two boundaries of this.
+ // The bigger boundary (m_plus) is normalized. The lower boundary has the same
+ // exponent as m_plus.
+ // Precondition: the value encoded by this Double must be greater than 0.
+ void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
+ ASSERT(value() > 0.0);
+ DiyFp v = this->AsDiyFp();
+ DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
+ DiyFp m_minus;
+ if (LowerBoundaryIsCloser()) {
+ m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
+ } else {
+ m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
+ }
+ m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
+ m_minus.set_e(m_plus.e());
+ *out_m_plus = m_plus;
+ *out_m_minus = m_minus;
+ }
+
+ bool LowerBoundaryIsCloser() const {
+ // The boundary is closer if the significand is of the form f == 2^p-1 then
+ // the lower boundary is closer.
+ // Think of v = 1000e10 and v- = 9999e9.
+ // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
+ // at a distance of 1e8.
+ // The only exception is for the smallest normal: the largest denormal is
+ // at the same distance as its successor.
+ // Note: denormals have the same exponent as the smallest normals.
+ bool physical_significand_is_zero = ((AsUint64() & kSignificandMask) == 0);
+ return physical_significand_is_zero && (Exponent() != kDenormalExponent);
+ }
+
+ double value() const { return uint64_to_double(d64_); }
+
+ // Returns the significand size for a given order of magnitude.
+ // If v = f*2^e with 2^p-1 <= f <= 2^p then p+e is v's order of magnitude.
+ // This function returns the number of significant binary digits v will have
+ // once it's encoded into a double. In almost all cases this is equal to
+ // kSignificandSize. The only exceptions are denormals. They start with
+ // leading zeroes and their effective significand-size is hence smaller.
+ static int SignificandSizeForOrderOfMagnitude(int order) {
+ if (order >= (kDenormalExponent + kSignificandSize)) {
+ return kSignificandSize;
+ }
+ if (order <= kDenormalExponent) return 0;
+ return order - kDenormalExponent;
+ }
+
+ static double Infinity() {
+ return Double(kInfinity).value();
+ }
+
+ static double NaN() {
+ return Double(kNaN).value();
+ }
+
+ private:
+ static const int kExponentBias = 0x3FF + kPhysicalSignificandSize;
+ static const int kDenormalExponent = -kExponentBias + 1;
+ static const int kMaxExponent = 0x7FF - kExponentBias;
+ static const uint64_t kInfinity = UINT64_2PART_C(0x7FF00000, 00000000);
+ static const uint64_t kNaN = UINT64_2PART_C(0x7FF80000, 00000000);
+
+ const uint64_t d64_;
+
+ static uint64_t DiyFpToUint64(DiyFp diy_fp) {
+ uint64_t significand = diy_fp.f();
+ int exponent = diy_fp.e();
+ while (significand > kHiddenBit + kSignificandMask) {
+ significand >>= 1;
+ exponent++;
+ }
+ if (exponent >= kMaxExponent) {
+ return kInfinity;
+ }
+ if (exponent < kDenormalExponent) {
+ return 0;
+ }
+ while (exponent > kDenormalExponent && (significand & kHiddenBit) == 0) {
+ significand <<= 1;
+ exponent--;
+ }
+ uint64_t biased_exponent;
+ if (exponent == kDenormalExponent && (significand & kHiddenBit) == 0) {
+ biased_exponent = 0;
+ } else {
+ biased_exponent = static_cast<uint64_t>(exponent + kExponentBias);
+ }
+ return (significand & kSignificandMask) |
+ (biased_exponent << kPhysicalSignificandSize);
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(Double);
+};
+
+class Single {
+ public:
+ static const uint32_t kSignMask = 0x80000000;
+ static const uint32_t kExponentMask = 0x7F800000;
+ static const uint32_t kSignificandMask = 0x007FFFFF;
+ static const uint32_t kHiddenBit = 0x00800000;
+ static const int kPhysicalSignificandSize = 23; // Excludes the hidden bit.
+ static const int kSignificandSize = 24;
+
+ Single() : d32_(0) {}
+ explicit Single(float f) : d32_(float_to_uint32(f)) {}
+ explicit Single(uint32_t d32) : d32_(d32) {}
+
+ // The value encoded by this Single must be greater or equal to +0.0.
+ // It must not be special (infinity, or NaN).
+ DiyFp AsDiyFp() const {
+ ASSERT(Sign() > 0);
+ ASSERT(!IsSpecial());
+ return DiyFp(Significand(), Exponent());
+ }
+
+ // Returns the single's bit as uint64.
+ uint32_t AsUint32() const {
+ return d32_;
+ }
+
+ int Exponent() const {
+ if (IsDenormal()) return kDenormalExponent;
+
+ uint32_t d32 = AsUint32();
+ int biased_e =
+ static_cast<int>((d32 & kExponentMask) >> kPhysicalSignificandSize);
+ return biased_e - kExponentBias;
+ }
+
+ uint32_t Significand() const {
+ uint32_t d32 = AsUint32();
+ uint32_t significand = d32 & kSignificandMask;
+ if (!IsDenormal()) {
+ return significand + kHiddenBit;
+ } else {
+ return significand;
+ }
+ }
+
+ // Returns true if the single is a denormal.
+ bool IsDenormal() const {
+ uint32_t d32 = AsUint32();
+ return (d32 & kExponentMask) == 0;
+ }
+
+ // We consider denormals not to be special.
+ // Hence only Infinity and NaN are special.
+ bool IsSpecial() const {
+ uint32_t d32 = AsUint32();
+ return (d32 & kExponentMask) == kExponentMask;
+ }
+
+ bool IsNan() const {
+ uint32_t d32 = AsUint32();
+ return ((d32 & kExponentMask) == kExponentMask) &&
+ ((d32 & kSignificandMask) != 0);
+ }
+
+ bool IsInfinite() const {
+ uint32_t d32 = AsUint32();
+ return ((d32 & kExponentMask) == kExponentMask) &&
+ ((d32 & kSignificandMask) == 0);
+ }
+
+ int Sign() const {
+ uint32_t d32 = AsUint32();
+ return (d32 & kSignMask) == 0? 1: -1;
+ }
+
+ // Computes the two boundaries of this.
+ // The bigger boundary (m_plus) is normalized. The lower boundary has the same
+ // exponent as m_plus.
+ // Precondition: the value encoded by this Single must be greater than 0.
+ void NormalizedBoundaries(DiyFp* out_m_minus, DiyFp* out_m_plus) const {
+ ASSERT(value() > 0.0);
+ DiyFp v = this->AsDiyFp();
+ DiyFp m_plus = DiyFp::Normalize(DiyFp((v.f() << 1) + 1, v.e() - 1));
+ DiyFp m_minus;
+ if (LowerBoundaryIsCloser()) {
+ m_minus = DiyFp((v.f() << 2) - 1, v.e() - 2);
+ } else {
+ m_minus = DiyFp((v.f() << 1) - 1, v.e() - 1);
+ }
+ m_minus.set_f(m_minus.f() << (m_minus.e() - m_plus.e()));
+ m_minus.set_e(m_plus.e());
+ *out_m_plus = m_plus;
+ *out_m_minus = m_minus;
+ }
+
+ // Precondition: the value encoded by this Single must be greater or equal
+ // than +0.0.
+ DiyFp UpperBoundary() const {
+ ASSERT(Sign() > 0);
+ return DiyFp(Significand() * 2 + 1, Exponent() - 1);
+ }
+
+ bool LowerBoundaryIsCloser() const {
+ // The boundary is closer if the significand is of the form f == 2^p-1 then
+ // the lower boundary is closer.
+ // Think of v = 1000e10 and v- = 9999e9.
+ // Then the boundary (== (v - v-)/2) is not just at a distance of 1e9 but
+ // at a distance of 1e8.
+ // The only exception is for the smallest normal: the largest denormal is
+ // at the same distance as its successor.
+ // Note: denormals have the same exponent as the smallest normals.
+ bool physical_significand_is_zero = ((AsUint32() & kSignificandMask) == 0);
+ return physical_significand_is_zero && (Exponent() != kDenormalExponent);
+ }
+
+ float value() const { return uint32_to_float(d32_); }
+
+ static float Infinity() {
+ return Single(kInfinity).value();
+ }
+
+ static float NaN() {
+ return Single(kNaN).value();
+ }
+
+ private:
+ static const int kExponentBias = 0x7F + kPhysicalSignificandSize;
+ static const int kDenormalExponent = -kExponentBias + 1;
+ static const int kMaxExponent = 0xFF - kExponentBias;
+ static const uint32_t kInfinity = 0x7F800000;
+ static const uint32_t kNaN = 0x7FC00000;
+
+ const uint32_t d32_;
+
+ DISALLOW_COPY_AND_ASSIGN(Single);
+};
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_DOUBLE_H_
diff --git a/src/3rdparty/double-conversion/include/double-conversion/double-conversion.h b/src/3rdparty/double-conversion/include/double-conversion/double-conversion.h
new file mode 100644
index 0000000000..6bdfa8d25d
--- /dev/null
+++ b/src/3rdparty/double-conversion/include/double-conversion/double-conversion.h
@@ -0,0 +1,543 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
+#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+class DoubleToStringConverter {
+ public:
+ // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint
+ // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the
+ // function returns false.
+ static const int kMaxFixedDigitsBeforePoint = 60;
+ static const int kMaxFixedDigitsAfterPoint = 60;
+
+ // When calling ToExponential with a requested_digits
+ // parameter > kMaxExponentialDigits then the function returns false.
+ static const int kMaxExponentialDigits = 120;
+
+ // When calling ToPrecision with a requested_digits
+ // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits
+ // then the function returns false.
+ static const int kMinPrecisionDigits = 1;
+ static const int kMaxPrecisionDigits = 120;
+
+ enum Flags {
+ NO_FLAGS = 0,
+ EMIT_POSITIVE_EXPONENT_SIGN = 1,
+ EMIT_TRAILING_DECIMAL_POINT = 2,
+ EMIT_TRAILING_ZERO_AFTER_POINT = 4,
+ UNIQUE_ZERO = 8
+ };
+
+ // Flags should be a bit-or combination of the possible Flags-enum.
+ // - NO_FLAGS: no special flags.
+ // - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent
+ // form, emits a '+' for positive exponents. Example: 1.2e+2.
+ // - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is
+ // converted into decimal format then a trailing decimal point is appended.
+ // Example: 2345.0 is converted to "2345.".
+ // - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point
+ // emits a trailing '0'-character. This flag requires the
+ // EXMIT_TRAILING_DECIMAL_POINT flag.
+ // Example: 2345.0 is converted to "2345.0".
+ // - UNIQUE_ZERO: "-0.0" is converted to "0.0".
+ //
+ // Infinity symbol and nan_symbol provide the string representation for these
+ // special values. If the string is NULL and the special value is encountered
+ // then the conversion functions return false.
+ //
+ // The exponent_character is used in exponential representations. It is
+ // usually 'e' or 'E'.
+ //
+ // When converting to the shortest representation the converter will
+ // represent input numbers in decimal format if they are in the interval
+ // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[
+ // (lower boundary included, greater boundary excluded).
+ // Example: with decimal_in_shortest_low = -6 and
+ // decimal_in_shortest_high = 21:
+ // ToShortest(0.000001) -> "0.000001"
+ // ToShortest(0.0000001) -> "1e-7"
+ // ToShortest(111111111111111111111.0) -> "111111111111111110000"
+ // ToShortest(100000000000000000000.0) -> "100000000000000000000"
+ // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
+ //
+ // When converting to precision mode the converter may add
+ // max_leading_padding_zeroes before returning the number in exponential
+ // format.
+ // Example with max_leading_padding_zeroes_in_precision_mode = 6.
+ // ToPrecision(0.0000012345, 2) -> "0.0000012"
+ // ToPrecision(0.00000012345, 2) -> "1.2e-7"
+ // Similarily the converter may add up to
+ // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
+ // returning an exponential representation. A zero added by the
+ // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
+ // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
+ // ToPrecision(230.0, 2) -> "230"
+ // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT.
+ // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
+ DoubleToStringConverter(int flags,
+ const char* infinity_symbol,
+ const char* nan_symbol,
+ char exponent_character,
+ int decimal_in_shortest_low,
+ int decimal_in_shortest_high,
+ int max_leading_padding_zeroes_in_precision_mode,
+ int max_trailing_padding_zeroes_in_precision_mode)
+ : flags_(flags),
+ infinity_symbol_(infinity_symbol),
+ nan_symbol_(nan_symbol),
+ exponent_character_(exponent_character),
+ decimal_in_shortest_low_(decimal_in_shortest_low),
+ decimal_in_shortest_high_(decimal_in_shortest_high),
+ max_leading_padding_zeroes_in_precision_mode_(
+ max_leading_padding_zeroes_in_precision_mode),
+ max_trailing_padding_zeroes_in_precision_mode_(
+ max_trailing_padding_zeroes_in_precision_mode) {
+ // When 'trailing zero after the point' is set, then 'trailing point'
+ // must be set too.
+ ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) ||
+ !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0));
+ }
+
+ // Returns a converter following the EcmaScript specification.
+ static const DoubleToStringConverter& EcmaScriptConverter();
+
+ // Computes the shortest string of digits that correctly represent the input
+ // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high
+ // (see constructor) it then either returns a decimal representation, or an
+ // exponential representation.
+ // Example with decimal_in_shortest_low = -6,
+ // decimal_in_shortest_high = 21,
+ // EMIT_POSITIVE_EXPONENT_SIGN activated, and
+ // EMIT_TRAILING_DECIMAL_POINT deactived:
+ // ToShortest(0.000001) -> "0.000001"
+ // ToShortest(0.0000001) -> "1e-7"
+ // ToShortest(111111111111111111111.0) -> "111111111111111110000"
+ // ToShortest(100000000000000000000.0) -> "100000000000000000000"
+ // ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
+ //
+ // Note: the conversion may round the output if the returned string
+ // is accurate enough to uniquely identify the input-number.
+ // For example the most precise representation of the double 9e59 equals
+ // "899999999999999918767229449717619953810131273674690656206848", but
+ // the converter will return the shorter (but still correct) "9e59".
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except when the input value is special and no infinity_symbol or
+ // nan_symbol has been given to the constructor.
+ bool ToShortest(double value, StringBuilder* result_builder) const {
+ return ToShortestIeeeNumber(value, result_builder, SHORTEST);
+ }
+
+ // Same as ToShortest, but for single-precision floats.
+ bool ToShortestSingle(float value, StringBuilder* result_builder) const {
+ return ToShortestIeeeNumber(value, result_builder, SHORTEST_SINGLE);
+ }
+
+
+ // Computes a decimal representation with a fixed number of digits after the
+ // decimal point. The last emitted digit is rounded.
+ //
+ // Examples:
+ // ToFixed(3.12, 1) -> "3.1"
+ // ToFixed(3.1415, 3) -> "3.142"
+ // ToFixed(1234.56789, 4) -> "1234.5679"
+ // ToFixed(1.23, 5) -> "1.23000"
+ // ToFixed(0.1, 4) -> "0.1000"
+ // ToFixed(1e30, 2) -> "1000000000000000019884624838656.00"
+ // ToFixed(0.1, 30) -> "0.100000000000000005551115123126"
+ // ToFixed(0.1, 17) -> "0.10000000000000001"
+ //
+ // If requested_digits equals 0, then the tail of the result depends on
+ // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT.
+ // Examples, for requested_digits == 0,
+ // let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be
+ // - false and false: then 123.45 -> 123
+ // 0.678 -> 1
+ // - true and false: then 123.45 -> 123.
+ // 0.678 -> 1.
+ // - true and true: then 123.45 -> 123.0
+ // 0.678 -> 1.0
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except for the following cases:
+ // - the input value is special and no infinity_symbol or nan_symbol has
+ // been provided to the constructor,
+ // - 'value' > 10^kMaxFixedDigitsBeforePoint, or
+ // - 'requested_digits' > kMaxFixedDigitsAfterPoint.
+ // The last two conditions imply that the result will never contain more than
+ // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters
+ // (one additional character for the sign, and one for the decimal point).
+ bool ToFixed(double value,
+ int requested_digits,
+ StringBuilder* result_builder) const;
+
+ // Computes a representation in exponential format with requested_digits
+ // after the decimal point. The last emitted digit is rounded.
+ // If requested_digits equals -1, then the shortest exponential representation
+ // is computed.
+ //
+ // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and
+ // exponent_character set to 'e'.
+ // ToExponential(3.12, 1) -> "3.1e0"
+ // ToExponential(5.0, 3) -> "5.000e0"
+ // ToExponential(0.001, 2) -> "1.00e-3"
+ // ToExponential(3.1415, -1) -> "3.1415e0"
+ // ToExponential(3.1415, 4) -> "3.1415e0"
+ // ToExponential(3.1415, 3) -> "3.142e0"
+ // ToExponential(123456789000000, 3) -> "1.235e14"
+ // ToExponential(1000000000000000019884624838656.0, -1) -> "1e30"
+ // ToExponential(1000000000000000019884624838656.0, 32) ->
+ // "1.00000000000000001988462483865600e30"
+ // ToExponential(1234, 0) -> "1e3"
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except for the following cases:
+ // - the input value is special and no infinity_symbol or nan_symbol has
+ // been provided to the constructor,
+ // - 'requested_digits' > kMaxExponentialDigits.
+ // The last condition implies that the result will never contain more than
+ // kMaxExponentialDigits + 8 characters (the sign, the digit before the
+ // decimal point, the decimal point, the exponent character, the
+ // exponent's sign, and at most 3 exponent digits).
+ bool ToExponential(double value,
+ int requested_digits,
+ StringBuilder* result_builder) const;
+
+ // Computes 'precision' leading digits of the given 'value' and returns them
+ // either in exponential or decimal format, depending on
+ // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the
+ // constructor).
+ // The last computed digit is rounded.
+ //
+ // Example with max_leading_padding_zeroes_in_precision_mode = 6.
+ // ToPrecision(0.0000012345, 2) -> "0.0000012"
+ // ToPrecision(0.00000012345, 2) -> "1.2e-7"
+ // Similarily the converter may add up to
+ // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
+ // returning an exponential representation. A zero added by the
+ // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
+ // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
+ // ToPrecision(230.0, 2) -> "230"
+ // ToPrecision(230.0, 2) -> "230." with EMIT_TRAILING_DECIMAL_POINT.
+ // ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
+ // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no
+ // EMIT_TRAILING_ZERO_AFTER_POINT:
+ // ToPrecision(123450.0, 6) -> "123450"
+ // ToPrecision(123450.0, 5) -> "123450"
+ // ToPrecision(123450.0, 4) -> "123500"
+ // ToPrecision(123450.0, 3) -> "123000"
+ // ToPrecision(123450.0, 2) -> "1.2e5"
+ //
+ // Returns true if the conversion succeeds. The conversion always succeeds
+ // except for the following cases:
+ // - the input value is special and no infinity_symbol or nan_symbol has
+ // been provided to the constructor,
+ // - precision < kMinPericisionDigits
+ // - precision > kMaxPrecisionDigits
+ // The last condition implies that the result will never contain more than
+ // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the
+ // exponent character, the exponent's sign, and at most 3 exponent digits).
+ bool ToPrecision(double value,
+ int precision,
+ StringBuilder* result_builder) const;
+
+ enum DtoaMode {
+ // Produce the shortest correct representation.
+ // For example the output of 0.299999999999999988897 is (the less accurate
+ // but correct) 0.3.
+ SHORTEST,
+ // Same as SHORTEST, but for single-precision floats.
+ SHORTEST_SINGLE,
+ // Produce a fixed number of digits after the decimal point.
+ // For instance fixed(0.1, 4) becomes 0.1000
+ // If the input number is big, the output will be big.
+ FIXED,
+ // Fixed number of digits (independent of the decimal point).
+ PRECISION
+ };
+
+ // The maximal number of digits that are needed to emit a double in base 10.
+ // A higher precision can be achieved by using more digits, but the shortest
+ // accurate representation of any double will never use more digits than
+ // kBase10MaximalLength.
+ // Note that DoubleToAscii null-terminates its input. So the given buffer
+ // should be at least kBase10MaximalLength + 1 characters long.
+ static const int kBase10MaximalLength = 17;
+
+ // Converts the given double 'v' to ascii. 'v' must not be NaN, +Infinity, or
+ // -Infinity. In SHORTEST_SINGLE-mode this restriction also applies to 'v'
+ // after it has been casted to a single-precision float. That is, in this
+ // mode static_cast<float>(v) must not be NaN, +Infinity or -Infinity.
+ //
+ // The result should be interpreted as buffer * 10^(point-length).
+ //
+ // The output depends on the given mode:
+ // - SHORTEST: produce the least amount of digits for which the internal
+ // identity requirement is still satisfied. If the digits are printed
+ // (together with the correct exponent) then reading this number will give
+ // 'v' again. The buffer will choose the representation that is closest to
+ // 'v'. If there are two at the same distance, than the one farther away
+ // from 0 is chosen (halfway cases - ending with 5 - are rounded up).
+ // In this mode the 'requested_digits' parameter is ignored.
+ // - SHORTEST_SINGLE: same as SHORTEST but with single-precision.
+ // - FIXED: produces digits necessary to print a given number with
+ // 'requested_digits' digits after the decimal point. The produced digits
+ // might be too short in which case the caller has to fill the remainder
+ // with '0's.
+ // Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
+ // Halfway cases are rounded towards +/-Infinity (away from 0). The call
+ // toFixed(0.15, 2) thus returns buffer="2", point=0.
+ // The returned buffer may contain digits that would be truncated from the
+ // shortest representation of the input.
+ // - PRECISION: produces 'requested_digits' where the first digit is not '0'.
+ // Even though the length of produced digits usually equals
+ // 'requested_digits', the function is allowed to return fewer digits, in
+ // which case the caller has to fill the missing digits with '0's.
+ // Halfway cases are again rounded away from 0.
+ // DoubleToAscii expects the given buffer to be big enough to hold all
+ // digits and a terminating null-character. In SHORTEST-mode it expects a
+ // buffer of at least kBase10MaximalLength + 1. In all other modes the
+ // requested_digits parameter and the padding-zeroes limit the size of the
+ // output. Don't forget the decimal point, the exponent character and the
+ // terminating null-character when computing the maximal output size.
+ // The given length is only used in debug mode to ensure the buffer is big
+ // enough.
+ static void DoubleToAscii(double v,
+ DtoaMode mode,
+ int requested_digits,
+ char* buffer,
+ int buffer_length,
+ bool* sign,
+ int* length,
+ int* point);
+
+ private:
+ // Implementation for ToShortest and ToShortestSingle.
+ bool ToShortestIeeeNumber(double value,
+ StringBuilder* result_builder,
+ DtoaMode mode) const;
+
+ // If the value is a special value (NaN or Infinity) constructs the
+ // corresponding string using the configured infinity/nan-symbol.
+ // If either of them is NULL or the value is not special then the
+ // function returns false.
+ bool HandleSpecialValues(double value, StringBuilder* result_builder) const;
+ // Constructs an exponential representation (i.e. 1.234e56).
+ // The given exponent assumes a decimal point after the first decimal digit.
+ void CreateExponentialRepresentation(const char* decimal_digits,
+ int length,
+ int exponent,
+ StringBuilder* result_builder) const;
+ // Creates a decimal representation (i.e 1234.5678).
+ void CreateDecimalRepresentation(const char* decimal_digits,
+ int length,
+ int decimal_point,
+ int digits_after_point,
+ StringBuilder* result_builder) const;
+
+ const int flags_;
+ const char* const infinity_symbol_;
+ const char* const nan_symbol_;
+ const char exponent_character_;
+ const int decimal_in_shortest_low_;
+ const int decimal_in_shortest_high_;
+ const int max_leading_padding_zeroes_in_precision_mode_;
+ const int max_trailing_padding_zeroes_in_precision_mode_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter);
+};
+
+
+class StringToDoubleConverter {
+ public:
+ // Enumeration for allowing octals and ignoring junk when converting
+ // strings to numbers.
+ enum Flags {
+ NO_FLAGS = 0,
+ ALLOW_HEX = 1,
+ ALLOW_OCTALS = 2,
+ ALLOW_TRAILING_JUNK = 4,
+ ALLOW_LEADING_SPACES = 8,
+ ALLOW_TRAILING_SPACES = 16,
+ ALLOW_SPACES_AFTER_SIGN = 32
+ };
+
+ // Flags should be a bit-or combination of the possible Flags-enum.
+ // - NO_FLAGS: no special flags.
+ // - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers.
+ // Ex: StringToDouble("0x1234") -> 4660.0
+ // In StringToDouble("0x1234.56") the characters ".56" are trailing
+ // junk. The result of the call is hence dependent on
+ // the ALLOW_TRAILING_JUNK flag and/or the junk value.
+ // With this flag "0x" is a junk-string. Even with ALLOW_TRAILING_JUNK,
+ // the string will not be parsed as "0" followed by junk.
+ //
+ // - ALLOW_OCTALS: recognizes the prefix "0" for octals:
+ // If a sequence of octal digits starts with '0', then the number is
+ // read as octal integer. Octal numbers may only be integers.
+ // Ex: StringToDouble("01234") -> 668.0
+ // StringToDouble("012349") -> 12349.0 // Not a sequence of octal
+ // // digits.
+ // In StringToDouble("01234.56") the characters ".56" are trailing
+ // junk. The result of the call is hence dependent on
+ // the ALLOW_TRAILING_JUNK flag and/or the junk value.
+ // In StringToDouble("01234e56") the characters "e56" are trailing
+ // junk, too.
+ // - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of
+ // a double literal.
+ // - ALLOW_LEADING_SPACES: skip over leading whitespace, including spaces,
+ // new-lines, and tabs.
+ // - ALLOW_TRAILING_SPACES: ignore trailing whitespace.
+ // - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign.
+ // Ex: StringToDouble("- 123.2") -> -123.2.
+ // StringToDouble("+ 123.2") -> 123.2
+ //
+ // empty_string_value is returned when an empty string is given as input.
+ // If ALLOW_LEADING_SPACES or ALLOW_TRAILING_SPACES are set, then a string
+ // containing only spaces is converted to the 'empty_string_value', too.
+ //
+ // junk_string_value is returned when
+ // a) ALLOW_TRAILING_JUNK is not set, and a junk character (a character not
+ // part of a double-literal) is found.
+ // b) ALLOW_TRAILING_JUNK is set, but the string does not start with a
+ // double literal.
+ //
+ // infinity_symbol and nan_symbol are strings that are used to detect
+ // inputs that represent infinity and NaN. They can be null, in which case
+ // they are ignored.
+ // The conversion routine first reads any possible signs. Then it compares the
+ // following character of the input-string with the first character of
+ // the infinity, and nan-symbol. If either matches, the function assumes, that
+ // a match has been found, and expects the following input characters to match
+ // the remaining characters of the special-value symbol.
+ // This means that the following restrictions apply to special-value symbols:
+ // - they must not start with signs ('+', or '-'),
+ // - they must not have the same first character.
+ // - they must not start with digits.
+ //
+ // Examples:
+ // flags = ALLOW_HEX | ALLOW_TRAILING_JUNK,
+ // empty_string_value = 0.0,
+ // junk_string_value = NaN,
+ // infinity_symbol = "infinity",
+ // nan_symbol = "nan":
+ // StringToDouble("0x1234") -> 4660.0.
+ // StringToDouble("0x1234K") -> 4660.0.
+ // StringToDouble("") -> 0.0 // empty_string_value.
+ // StringToDouble(" ") -> NaN // junk_string_value.
+ // StringToDouble(" 1") -> NaN // junk_string_value.
+ // StringToDouble("0x") -> NaN // junk_string_value.
+ // StringToDouble("-123.45") -> -123.45.
+ // StringToDouble("--123.45") -> NaN // junk_string_value.
+ // StringToDouble("123e45") -> 123e45.
+ // StringToDouble("123E45") -> 123e45.
+ // StringToDouble("123e+45") -> 123e45.
+ // StringToDouble("123E-45") -> 123e-45.
+ // StringToDouble("123e") -> 123.0 // trailing junk ignored.
+ // StringToDouble("123e-") -> 123.0 // trailing junk ignored.
+ // StringToDouble("+NaN") -> NaN // NaN string literal.
+ // StringToDouble("-infinity") -> -inf. // infinity literal.
+ // StringToDouble("Infinity") -> NaN // junk_string_value.
+ //
+ // flags = ALLOW_OCTAL | ALLOW_LEADING_SPACES,
+ // empty_string_value = 0.0,
+ // junk_string_value = NaN,
+ // infinity_symbol = NULL,
+ // nan_symbol = NULL:
+ // StringToDouble("0x1234") -> NaN // junk_string_value.
+ // StringToDouble("01234") -> 668.0.
+ // StringToDouble("") -> 0.0 // empty_string_value.
+ // StringToDouble(" ") -> 0.0 // empty_string_value.
+ // StringToDouble(" 1") -> 1.0
+ // StringToDouble("0x") -> NaN // junk_string_value.
+ // StringToDouble("0123e45") -> NaN // junk_string_value.
+ // StringToDouble("01239E45") -> 1239e45.
+ // StringToDouble("-infinity") -> NaN // junk_string_value.
+ // StringToDouble("NaN") -> NaN // junk_string_value.
+ StringToDoubleConverter(int flags,
+ double empty_string_value,
+ double junk_string_value,
+ const char* infinity_symbol,
+ const char* nan_symbol)
+ : flags_(flags),
+ empty_string_value_(empty_string_value),
+ junk_string_value_(junk_string_value),
+ infinity_symbol_(infinity_symbol),
+ nan_symbol_(nan_symbol) {
+ }
+
+ // Performs the conversion.
+ // The output parameter 'processed_characters_count' is set to the number
+ // of characters that have been processed to read the number.
+ // Spaces than are processed with ALLOW_{LEADING|TRAILING}_SPACES are included
+ // in the 'processed_characters_count'. Trailing junk is never included.
+ double StringToDouble(const char* buffer,
+ int length,
+ int* processed_characters_count) const;
+
+ // Same as StringToDouble above but for 16 bit characters.
+ double StringToDouble(const uc16* buffer,
+ int length,
+ int* processed_characters_count) const;
+
+ // Same as StringToDouble but reads a float.
+ // Note that this is not equivalent to static_cast<float>(StringToDouble(...))
+ // due to potential double-rounding.
+ float StringToFloat(const char* buffer,
+ int length,
+ int* processed_characters_count) const;
+
+ // Same as StringToFloat above but for 16 bit characters.
+ float StringToFloat(const uc16* buffer,
+ int length,
+ int* processed_characters_count) const;
+
+ private:
+ const int flags_;
+ const double empty_string_value_;
+ const double junk_string_value_;
+ const char* const infinity_symbol_;
+ const char* const nan_symbol_;
+
+ template <class Iterator>
+ double StringToIeee(Iterator start_pointer,
+ int length,
+ bool read_as_double,
+ int* processed_characters_count) const;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
+};
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
diff --git a/src/3rdparty/double-conversion/include/double-conversion/utils.h b/src/3rdparty/double-conversion/include/double-conversion/utils.h
new file mode 100644
index 0000000000..53eec64282
--- /dev/null
+++ b/src/3rdparty/double-conversion/include/double-conversion/utils.h
@@ -0,0 +1,330 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_UTILS_H_
+#define DOUBLE_CONVERSION_UTILS_H_
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <assert.h>
+#ifndef ASSERT
+# if defined(WINCE) || defined(_WIN32_WCE)
+# define ASSERT(condition)
+# else
+# define ASSERT(condition) \
+ assert(condition);
+# endif
+#endif
+#ifndef UNIMPLEMENTED
+# define UNIMPLEMENTED() (exit(-1))
+#endif
+#ifndef UNREACHABLE
+# define UNREACHABLE() (exit(-1))
+#endif
+
+// Double operations detection based on target architecture.
+// Linux uses a 80bit wide floating point stack on x86. This induces double
+// rounding, which in turn leads to wrong results.
+// An easy way to test if the floating-point operations are correct is to
+// evaluate: 89255.0/1e22. If the floating-point stack is 64 bits wide then
+// the result is equal to 89255e-22.
+// The best way to test this, is to create a division-function and to compare
+// the output of the division with the expected result. (Inlining must be
+// disabled.)
+// On Linux,x86 89255e-22 != Div_double(89255.0/1e22)
+#if defined(_M_X64) || defined(__x86_64__) || \
+ defined(__ARMEL__) || defined(__avr32__) || _M_ARM_FP || \
+ defined(__hppa__) || defined(__ia64__) || \
+ defined(__mips__) || \
+ defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
+ defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
+ defined(__SH4__) || defined(__alpha__) || \
+ defined(_MIPS_ARCH_MIPS32R2) || \
+ defined(__AARCH64EL__)
+#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
+#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
+#if defined(_WIN32)
+// Windows uses a 64bit wide floating point stack.
+#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
+#else
+#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
+#endif // _WIN32
+#elif defined(WINCE) || defined(_WIN32_WCE)
+#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
+#else
+#error Target architecture was not detected as supported by Double-Conversion.
+#endif
+
+#if defined(__GNUC__)
+#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
+#else
+#define DOUBLE_CONVERSION_UNUSED
+#endif
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t; // NOLINT
+typedef unsigned short uint16_t; // NOLINT
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+// intptr_t and friends are defined in crtdefs.h through stdio.h.
+
+#else
+
+#include <stdint.h>
+
+#endif
+
+typedef uint16_t uc16;
+
+// The following macro works on both 32 and 64-bit platforms.
+// Usage: instead of writing 0x1234567890123456
+// write UINT64_2PART_C(0x12345678,90123456);
+#define UINT64_2PART_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
+
+
+// The expression ARRAY_SIZE(a) is a compile-time constant of type
+// size_t which represents the number of elements of the given
+// array. You should only use ARRAY_SIZE on statically allocated
+// arrays.
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) \
+ ((sizeof(a) / sizeof(*(a))) / \
+ static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+#endif
+
+// A macro to disallow the evil copy constructor and operator= functions
+// This should be used in the private: declarations for a class
+#ifndef DISALLOW_COPY_AND_ASSIGN
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+#endif
+
+// A macro to disallow all the implicit constructors, namely the
+// default constructor, copy constructor and operator= functions.
+//
+// This should be used in the private: declarations for a class
+// that wants to prevent anyone from instantiating it. This is
+// especially useful for classes containing only static methods.
+#ifndef DISALLOW_IMPLICIT_CONSTRUCTORS
+#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+ TypeName(); \
+ DISALLOW_COPY_AND_ASSIGN(TypeName)
+#endif
+
+namespace double_conversion {
+
+static const int kCharSize = sizeof(char);
+
+// Returns the maximum of the two parameters.
+template <typename T>
+static T Max(T a, T b) {
+ return a < b ? b : a;
+}
+
+
+// Returns the minimum of the two parameters.
+template <typename T>
+static T Min(T a, T b) {
+ return a < b ? a : b;
+}
+
+
+inline int StrLength(const char* string) {
+ size_t length = strlen(string);
+ ASSERT(length == static_cast<size_t>(static_cast<int>(length)));
+ return static_cast<int>(length);
+}
+
+// This is a simplified version of V8's Vector class.
+template <typename T>
+class Vector {
+ public:
+ Vector() : start_(NULL), length_(0) {}
+ Vector(T* data, int length) : start_(data), length_(length) {
+ ASSERT(length == 0 || (length > 0 && data != NULL));
+ }
+
+ // Returns a vector using the same backing storage as this one,
+ // spanning from and including 'from', to but not including 'to'.
+ Vector<T> SubVector(int from, int to) {
+ ASSERT(to <= length_);
+ ASSERT(from < to);
+ ASSERT(0 <= from);
+ return Vector<T>(start() + from, to - from);
+ }
+
+ // Returns the length of the vector.
+ int length() const { return length_; }
+
+ // Returns whether or not the vector is empty.
+ bool is_empty() const { return length_ == 0; }
+
+ // Returns the pointer to the start of the data in the vector.
+ T* start() const { return start_; }
+
+ // Access individual vector elements - checks bounds in debug mode.
+ T& operator[](int index) const {
+ ASSERT(0 <= index && index < length_);
+ return start_[index];
+ }
+
+ T& first() { return start_[0]; }
+
+ T& last() { return start_[length_ - 1]; }
+
+ private:
+ T* start_;
+ int length_;
+};
+
+
+// Helper class for building result strings in a character buffer. The
+// purpose of the class is to use safe operations that checks the
+// buffer bounds on all operations in debug mode.
+class StringBuilder {
+ public:
+ StringBuilder(char* buffer, int size)
+ : buffer_(buffer, size), position_(0) { }
+
+ ~StringBuilder() { if (!is_finalized()) Finalize(); }
+
+ int size() const { return buffer_.length(); }
+
+ // Get the current position in the builder.
+ int position() const {
+ ASSERT(!is_finalized());
+ return position_;
+ }
+
+ // Reset the position.
+ void Reset() { position_ = 0; }
+
+ // Add a single character to the builder. It is not allowed to add
+ // 0-characters; use the Finalize() method to terminate the string
+ // instead.
+ void AddCharacter(char c) {
+ ASSERT(c != '\0');
+ ASSERT(!is_finalized() && position_ < buffer_.length());
+ buffer_[position_++] = c;
+ }
+
+ // Add an entire string to the builder. Uses strlen() internally to
+ // compute the length of the input string.
+ void AddString(const char* s) {
+ AddSubstring(s, StrLength(s));
+ }
+
+ // Add the first 'n' characters of the given string 's' to the
+ // builder. The input string must have enough characters.
+ void AddSubstring(const char* s, int n) {
+ ASSERT(!is_finalized() && position_ + n < buffer_.length());
+ ASSERT(static_cast<size_t>(n) <= strlen(s));
+ memmove(&buffer_[position_], s, n * kCharSize);
+ position_ += n;
+ }
+
+
+ // Add character padding to the builder. If count is non-positive,
+ // nothing is added to the builder.
+ void AddPadding(char c, int count) {
+ for (int i = 0; i < count; i++) {
+ AddCharacter(c);
+ }
+ }
+
+ // Finalize the string by 0-terminating it and returning the buffer.
+ char* Finalize() {
+ ASSERT(!is_finalized() && position_ < buffer_.length());
+ buffer_[position_] = '\0';
+ // Make sure nobody managed to add a 0-character to the
+ // buffer while building the string.
+ ASSERT(strlen(buffer_.start()) == static_cast<size_t>(position_));
+ position_ = -1;
+ ASSERT(is_finalized());
+ return buffer_.start();
+ }
+
+ private:
+ Vector<char> buffer_;
+ int position_;
+
+ bool is_finalized() const { return position_ < 0; }
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
+};
+
+// The type-based aliasing rule allows the compiler to assume that pointers of
+// different types (for some definition of different) never alias each other.
+// Thus the following code does not work:
+//
+// float f = foo();
+// int fbits = *(int*)(&f);
+//
+// The compiler 'knows' that the int pointer can't refer to f since the types
+// don't match, so the compiler may cache f in a register, leaving random data
+// in fbits. Using C++ style casts makes no difference, however a pointer to
+// char data is assumed to alias any other pointer. This is the 'memcpy
+// exception'.
+//
+// Bit_cast uses the memcpy exception to move the bits from a variable of one
+// type of a variable of another type. Of course the end result is likely to
+// be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005)
+// will completely optimize BitCast away.
+//
+// There is an additional use for BitCast.
+// Recent gccs will warn when they see casts that may result in breakage due to
+// the type-based aliasing rule. If you have checked that there is no breakage
+// you can use BitCast to cast one pointer type to another. This confuses gcc
+// enough that it can no longer see that you have cast one pointer type to
+// another thus avoiding the warning.
+template <class Dest, class Source>
+inline Dest BitCast(const Source& source) {
+ // Compile time assertion: sizeof(Dest) == sizeof(Source)
+ // A compile error here means your Dest and Source have different sizes.
+ DOUBLE_CONVERSION_UNUSED
+ typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
+
+ Dest dest;
+ memmove(&dest, &source, sizeof(dest));
+ return dest;
+}
+
+template <class Dest, class Source>
+inline Dest BitCast(Source* source) {
+ return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
+}
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_UTILS_H_
diff --git a/src/3rdparty/double-conversion/strtod.cc b/src/3rdparty/double-conversion/strtod.cc
new file mode 100644
index 0000000000..34717562bd
--- /dev/null
+++ b/src/3rdparty/double-conversion/strtod.cc
@@ -0,0 +1,555 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdarg.h>
+#include <limits.h>
+
+#include "strtod.h"
+#include "bignum.h"
+#include "cached-powers.h"
+#include "ieee.h"
+
+namespace double_conversion {
+
+// 2^53 = 9007199254740992.
+// Any integer with at most 15 decimal digits will hence fit into a double
+// (which has a 53bit significand) without loss of precision.
+static const int kMaxExactDoubleIntegerDecimalDigits = 15;
+// 2^64 = 18446744073709551616 > 10^19
+static const int kMaxUint64DecimalDigits = 19;
+
+// Max double: 1.7976931348623157 x 10^308
+// Min non-zero double: 4.9406564584124654 x 10^-324
+// Any x >= 10^309 is interpreted as +infinity.
+// Any x <= 10^-324 is interpreted as 0.
+// Note that 2.5e-324 (despite being smaller than the min double) will be read
+// as non-zero (equal to the min non-zero double).
+static const int kMaxDecimalPower = 309;
+static const int kMinDecimalPower = -324;
+
+// 2^64 = 18446744073709551616
+static const uint64_t kMaxUint64 = UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF);
+
+
+static const double exact_powers_of_ten[] = {
+ 1.0, // 10^0
+ 10.0,
+ 100.0,
+ 1000.0,
+ 10000.0,
+ 100000.0,
+ 1000000.0,
+ 10000000.0,
+ 100000000.0,
+ 1000000000.0,
+ 10000000000.0, // 10^10
+ 100000000000.0,
+ 1000000000000.0,
+ 10000000000000.0,
+ 100000000000000.0,
+ 1000000000000000.0,
+ 10000000000000000.0,
+ 100000000000000000.0,
+ 1000000000000000000.0,
+ 10000000000000000000.0,
+ 100000000000000000000.0, // 10^20
+ 1000000000000000000000.0,
+ // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22
+ 10000000000000000000000.0
+};
+static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten);
+
+// Maximum number of significant digits in the decimal representation.
+// In fact the value is 772 (see conversions.cc), but to give us some margin
+// we round up to 780.
+static const int kMaxSignificantDecimalDigits = 780;
+
+static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) {
+ for (int i = 0; i < buffer.length(); i++) {
+ if (buffer[i] != '0') {
+ return buffer.SubVector(i, buffer.length());
+ }
+ }
+ return Vector<const char>(buffer.start(), 0);
+}
+
+
+static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
+ for (int i = buffer.length() - 1; i >= 0; --i) {
+ if (buffer[i] != '0') {
+ return buffer.SubVector(0, i + 1);
+ }
+ }
+ return Vector<const char>(buffer.start(), 0);
+}
+
+
+static void CutToMaxSignificantDigits(Vector<const char> buffer,
+ int exponent,
+ char* significant_buffer,
+ int* significant_exponent) {
+ for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) {
+ significant_buffer[i] = buffer[i];
+ }
+ // The input buffer has been trimmed. Therefore the last digit must be
+ // different from '0'.
+ ASSERT(buffer[buffer.length() - 1] != '0');
+ // Set the last digit to be non-zero. This is sufficient to guarantee
+ // correct rounding.
+ significant_buffer[kMaxSignificantDecimalDigits - 1] = '1';
+ *significant_exponent =
+ exponent + (buffer.length() - kMaxSignificantDecimalDigits);
+}
+
+
+// Trims the buffer and cuts it to at most kMaxSignificantDecimalDigits.
+// If possible the input-buffer is reused, but if the buffer needs to be
+// modified (due to cutting), then the input needs to be copied into the
+// buffer_copy_space.
+static void TrimAndCut(Vector<const char> buffer, int exponent,
+ char* buffer_copy_space, int space_size,
+ Vector<const char>* trimmed, int* updated_exponent) {
+ Vector<const char> left_trimmed = TrimLeadingZeros(buffer);
+ Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed);
+ exponent += left_trimmed.length() - right_trimmed.length();
+ if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
+ (void) space_size; // Mark variable as used.
+ ASSERT(space_size >= kMaxSignificantDecimalDigits);
+ CutToMaxSignificantDigits(right_trimmed, exponent,
+ buffer_copy_space, updated_exponent);
+ *trimmed = Vector<const char>(buffer_copy_space,
+ kMaxSignificantDecimalDigits);
+ } else {
+ *trimmed = right_trimmed;
+ *updated_exponent = exponent;
+ }
+}
+
+
+// Reads digits from the buffer and converts them to a uint64.
+// Reads in as many digits as fit into a uint64.
+// When the string starts with "1844674407370955161" no further digit is read.
+// Since 2^64 = 18446744073709551616 it would still be possible read another
+// digit if it was less or equal than 6, but this would complicate the code.
+static uint64_t ReadUint64(Vector<const char> buffer,
+ int* number_of_read_digits) {
+ uint64_t result = 0;
+ int i = 0;
+ while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) {
+ int digit = buffer[i++] - '0';
+ ASSERT(0 <= digit && digit <= 9);
+ result = 10 * result + digit;
+ }
+ *number_of_read_digits = i;
+ return result;
+}
+
+
+// Reads a DiyFp from the buffer.
+// The returned DiyFp is not necessarily normalized.
+// If remaining_decimals is zero then the returned DiyFp is accurate.
+// Otherwise it has been rounded and has error of at most 1/2 ulp.
+static void ReadDiyFp(Vector<const char> buffer,
+ DiyFp* result,
+ int* remaining_decimals) {
+ int read_digits;
+ uint64_t significand = ReadUint64(buffer, &read_digits);
+ if (buffer.length() == read_digits) {
+ *result = DiyFp(significand, 0);
+ *remaining_decimals = 0;
+ } else {
+ // Round the significand.
+ if (buffer[read_digits] >= '5') {
+ significand++;
+ }
+ // Compute the binary exponent.
+ int exponent = 0;
+ *result = DiyFp(significand, exponent);
+ *remaining_decimals = buffer.length() - read_digits;
+ }
+}
+
+
+static bool DoubleStrtod(Vector<const char> trimmed,
+ int exponent,
+ double* result) {
+#if !defined(DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS)
+ // On x86 the floating-point stack can be 64 or 80 bits wide. If it is
+ // 80 bits wide (as is the case on Linux) then double-rounding occurs and the
+ // result is not accurate.
+ // We know that Windows32 uses 64 bits and is therefore accurate.
+ // Note that the ARM simulator is compiled for 32bits. It therefore exhibits
+ // the same problem.
+ return false;
+#endif
+ if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
+ int read_digits;
+ // The trimmed input fits into a double.
+ // If the 10^exponent (resp. 10^-exponent) fits into a double too then we
+ // can compute the result-double simply by multiplying (resp. dividing) the
+ // two numbers.
+ // This is possible because IEEE guarantees that floating-point operations
+ // return the best possible approximation.
+ if (exponent < 0 && -exponent < kExactPowersOfTenSize) {
+ // 10^-exponent fits into a double.
+ *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
+ ASSERT(read_digits == trimmed.length());
+ *result /= exact_powers_of_ten[-exponent];
+ return true;
+ }
+ if (0 <= exponent && exponent < kExactPowersOfTenSize) {
+ // 10^exponent fits into a double.
+ *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
+ ASSERT(read_digits == trimmed.length());
+ *result *= exact_powers_of_ten[exponent];
+ return true;
+ }
+ int remaining_digits =
+ kMaxExactDoubleIntegerDecimalDigits - trimmed.length();
+ if ((0 <= exponent) &&
+ (exponent - remaining_digits < kExactPowersOfTenSize)) {
+ // The trimmed string was short and we can multiply it with
+ // 10^remaining_digits. As a result the remaining exponent now fits
+ // into a double too.
+ *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
+ ASSERT(read_digits == trimmed.length());
+ *result *= exact_powers_of_ten[remaining_digits];
+ *result *= exact_powers_of_ten[exponent - remaining_digits];
+ return true;
+ }
+ }
+ return false;
+}
+
+
+// Returns 10^exponent as an exact DiyFp.
+// The given exponent must be in the range [1; kDecimalExponentDistance[.
+static DiyFp AdjustmentPowerOfTen(int exponent) {
+ ASSERT(0 < exponent);
+ ASSERT(exponent < PowersOfTenCache::kDecimalExponentDistance);
+ // Simply hardcode the remaining powers for the given decimal exponent
+ // distance.
+ ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8);
+ switch (exponent) {
+ case 1: return DiyFp(UINT64_2PART_C(0xa0000000, 00000000), -60);
+ case 2: return DiyFp(UINT64_2PART_C(0xc8000000, 00000000), -57);
+ case 3: return DiyFp(UINT64_2PART_C(0xfa000000, 00000000), -54);
+ case 4: return DiyFp(UINT64_2PART_C(0x9c400000, 00000000), -50);
+ case 5: return DiyFp(UINT64_2PART_C(0xc3500000, 00000000), -47);
+ case 6: return DiyFp(UINT64_2PART_C(0xf4240000, 00000000), -44);
+ case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40);
+ default:
+ UNREACHABLE();
+ }
+}
+
+
+// If the function returns true then the result is the correct double.
+// Otherwise it is either the correct double or the double that is just below
+// the correct double.
+static bool DiyFpStrtod(Vector<const char> buffer,
+ int exponent,
+ double* result) {
+ DiyFp input;
+ int remaining_decimals;
+ ReadDiyFp(buffer, &input, &remaining_decimals);
+ // Since we may have dropped some digits the input is not accurate.
+ // If remaining_decimals is different than 0 than the error is at most
+ // .5 ulp (unit in the last place).
+ // We don't want to deal with fractions and therefore keep a common
+ // denominator.
+ const int kDenominatorLog = 3;
+ const int kDenominator = 1 << kDenominatorLog;
+ // Move the remaining decimals into the exponent.
+ exponent += remaining_decimals;
+ int error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
+
+ int old_e = input.e();
+ input.Normalize();
+ error <<= old_e - input.e();
+
+ ASSERT(exponent <= PowersOfTenCache::kMaxDecimalExponent);
+ if (exponent < PowersOfTenCache::kMinDecimalExponent) {
+ *result = 0.0;
+ return true;
+ }
+ DiyFp cached_power;
+ int cached_decimal_exponent;
+ PowersOfTenCache::GetCachedPowerForDecimalExponent(exponent,
+ &cached_power,
+ &cached_decimal_exponent);
+
+ if (cached_decimal_exponent != exponent) {
+ int adjustment_exponent = exponent - cached_decimal_exponent;
+ DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent);
+ input.Multiply(adjustment_power);
+ if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) {
+ // The product of input with the adjustment power fits into a 64 bit
+ // integer.
+ ASSERT(DiyFp::kSignificandSize == 64);
+ } else {
+ // The adjustment power is exact. There is hence only an error of 0.5.
+ error += kDenominator / 2;
+ }
+ }
+
+ input.Multiply(cached_power);
+ // The error introduced by a multiplication of a*b equals
+ // error_a + error_b + error_a*error_b/2^64 + 0.5
+ // Substituting a with 'input' and b with 'cached_power' we have
+ // error_b = 0.5 (all cached powers have an error of less than 0.5 ulp),
+ // error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64
+ int error_b = kDenominator / 2;
+ int error_ab = (error == 0 ? 0 : 1); // We round up to 1.
+ int fixed_error = kDenominator / 2;
+ error += error_b + error_ab + fixed_error;
+
+ old_e = input.e();
+ input.Normalize();
+ error <<= old_e - input.e();
+
+ // See if the double's significand changes if we add/subtract the error.
+ int order_of_magnitude = DiyFp::kSignificandSize + input.e();
+ int effective_significand_size =
+ Double::SignificandSizeForOrderOfMagnitude(order_of_magnitude);
+ int precision_digits_count =
+ DiyFp::kSignificandSize - effective_significand_size;
+ if (precision_digits_count + kDenominatorLog >= DiyFp::kSignificandSize) {
+ // This can only happen for very small denormals. In this case the
+ // half-way multiplied by the denominator exceeds the range of an uint64.
+ // Simply shift everything to the right.
+ int shift_amount = (precision_digits_count + kDenominatorLog) -
+ DiyFp::kSignificandSize + 1;
+ input.set_f(input.f() >> shift_amount);
+ input.set_e(input.e() + shift_amount);
+ // We add 1 for the lost precision of error, and kDenominator for
+ // the lost precision of input.f().
+ error = (error >> shift_amount) + 1 + kDenominator;
+ precision_digits_count -= shift_amount;
+ }
+ // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too.
+ ASSERT(DiyFp::kSignificandSize == 64);
+ ASSERT(precision_digits_count < 64);
+ uint64_t one64 = 1;
+ uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1;
+ uint64_t precision_bits = input.f() & precision_bits_mask;
+ uint64_t half_way = one64 << (precision_digits_count - 1);
+ precision_bits *= kDenominator;
+ half_way *= kDenominator;
+ DiyFp rounded_input(input.f() >> precision_digits_count,
+ input.e() + precision_digits_count);
+ if (precision_bits >= half_way + error) {
+ rounded_input.set_f(rounded_input.f() + 1);
+ }
+ // If the last_bits are too close to the half-way case than we are too
+ // inaccurate and round down. In this case we return false so that we can
+ // fall back to a more precise algorithm.
+
+ *result = Double(rounded_input).value();
+ if (half_way - error < precision_bits && precision_bits < half_way + error) {
+ // Too imprecise. The caller will have to fall back to a slower version.
+ // However the returned number is guaranteed to be either the correct
+ // double, or the next-lower double.
+ return false;
+ } else {
+ return true;
+ }
+}
+
+
+// Returns
+// - -1 if buffer*10^exponent < diy_fp.
+// - 0 if buffer*10^exponent == diy_fp.
+// - +1 if buffer*10^exponent > diy_fp.
+// Preconditions:
+// buffer.length() + exponent <= kMaxDecimalPower + 1
+// buffer.length() + exponent > kMinDecimalPower
+// buffer.length() <= kMaxDecimalSignificantDigits
+static int CompareBufferWithDiyFp(Vector<const char> buffer,
+ int exponent,
+ DiyFp diy_fp) {
+ ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1);
+ ASSERT(buffer.length() + exponent > kMinDecimalPower);
+ ASSERT(buffer.length() <= kMaxSignificantDecimalDigits);
+ // Make sure that the Bignum will be able to hold all our numbers.
+ // Our Bignum implementation has a separate field for exponents. Shifts will
+ // consume at most one bigit (< 64 bits).
+ // ln(10) == 3.3219...
+ ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits);
+ Bignum buffer_bignum;
+ Bignum diy_fp_bignum;
+ buffer_bignum.AssignDecimalString(buffer);
+ diy_fp_bignum.AssignUInt64(diy_fp.f());
+ if (exponent >= 0) {
+ buffer_bignum.MultiplyByPowerOfTen(exponent);
+ } else {
+ diy_fp_bignum.MultiplyByPowerOfTen(-exponent);
+ }
+ if (diy_fp.e() > 0) {
+ diy_fp_bignum.ShiftLeft(diy_fp.e());
+ } else {
+ buffer_bignum.ShiftLeft(-diy_fp.e());
+ }
+ return Bignum::Compare(buffer_bignum, diy_fp_bignum);
+}
+
+
+// Returns true if the guess is the correct double.
+// Returns false, when guess is either correct or the next-lower double.
+static bool ComputeGuess(Vector<const char> trimmed, int exponent,
+ double* guess) {
+ if (trimmed.length() == 0) {
+ *guess = 0.0;
+ return true;
+ }
+ if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) {
+ *guess = Double::Infinity();
+ return true;
+ }
+ if (exponent + trimmed.length() <= kMinDecimalPower) {
+ *guess = 0.0;
+ return true;
+ }
+
+ if (DoubleStrtod(trimmed, exponent, guess) ||
+ DiyFpStrtod(trimmed, exponent, guess)) {
+ return true;
+ }
+ if (*guess == Double::Infinity()) {
+ return true;
+ }
+ return false;
+}
+
+double Strtod(Vector<const char> buffer, int exponent) {
+ char copy_buffer[kMaxSignificantDecimalDigits];
+ Vector<const char> trimmed;
+ int updated_exponent;
+ TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
+ &trimmed, &updated_exponent);
+ exponent = updated_exponent;
+
+ double guess;
+ bool is_correct = ComputeGuess(trimmed, exponent, &guess);
+ if (is_correct) return guess;
+
+ DiyFp upper_boundary = Double(guess).UpperBoundary();
+ int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
+ if (comparison < 0) {
+ return guess;
+ } else if (comparison > 0) {
+ return Double(guess).NextDouble();
+ } else if ((Double(guess).Significand() & 1) == 0) {
+ // Round towards even.
+ return guess;
+ } else {
+ return Double(guess).NextDouble();
+ }
+}
+
+float Strtof(Vector<const char> buffer, int exponent) {
+ char copy_buffer[kMaxSignificantDecimalDigits];
+ Vector<const char> trimmed;
+ int updated_exponent;
+ TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
+ &trimmed, &updated_exponent);
+ exponent = updated_exponent;
+
+ double double_guess;
+ bool is_correct = ComputeGuess(trimmed, exponent, &double_guess);
+
+ float float_guess = static_cast<float>(double_guess);
+ if (float_guess == double_guess) {
+ // This shortcut triggers for integer values.
+ return float_guess;
+ }
+
+ // We must catch double-rounding. Say the double has been rounded up, and is
+ // now a boundary of a float, and rounds up again. This is why we have to
+ // look at previous too.
+ // Example (in decimal numbers):
+ // input: 12349
+ // high-precision (4 digits): 1235
+ // low-precision (3 digits):
+ // when read from input: 123
+ // when rounded from high precision: 124.
+ // To do this we simply look at the neigbors of the correct result and see
+ // if they would round to the same float. If the guess is not correct we have
+ // to look at four values (since two different doubles could be the correct
+ // double).
+
+ double double_next = Double(double_guess).NextDouble();
+ double double_previous = Double(double_guess).PreviousDouble();
+
+ float f1 = static_cast<float>(double_previous);
+ float f2 = float_guess;
+ float f3 = static_cast<float>(double_next);
+ float f4;
+ if (is_correct) {
+ f4 = f3;
+ } else {
+ double double_next2 = Double(double_next).NextDouble();
+ f4 = static_cast<float>(double_next2);
+ }
+ (void) f2; // Mark variable as used.
+ ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
+
+ // If the guess doesn't lie near a single-precision boundary we can simply
+ // return its float-value.
+ if (f1 == f4) {
+ return float_guess;
+ }
+
+ ASSERT((f1 != f2 && f2 == f3 && f3 == f4) ||
+ (f1 == f2 && f2 != f3 && f3 == f4) ||
+ (f1 == f2 && f2 == f3 && f3 != f4));
+
+ // guess and next are the two possible canditates (in the same way that
+ // double_guess was the lower candidate for a double-precision guess).
+ float guess = f1;
+ float next = f4;
+ DiyFp upper_boundary;
+ if (guess == 0.0f) {
+ float min_float = 1e-45f;
+ upper_boundary = Double(static_cast<double>(min_float) / 2).AsDiyFp();
+ } else {
+ upper_boundary = Single(guess).UpperBoundary();
+ }
+ int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
+ if (comparison < 0) {
+ return guess;
+ } else if (comparison > 0) {
+ return next;
+ } else if ((Single(guess).Significand() & 1) == 0) {
+ // Round towards even.
+ return guess;
+ } else {
+ return next;
+ }
+}
+
+} // namespace double_conversion
diff --git a/src/3rdparty/double-conversion/strtod.h b/src/3rdparty/double-conversion/strtod.h
new file mode 100644
index 0000000000..ed0293b8f5
--- /dev/null
+++ b/src/3rdparty/double-conversion/strtod.h
@@ -0,0 +1,45 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef DOUBLE_CONVERSION_STRTOD_H_
+#define DOUBLE_CONVERSION_STRTOD_H_
+
+#include "utils.h"
+
+namespace double_conversion {
+
+// The buffer must only contain digits in the range [0-9]. It must not
+// contain a dot or a sign. It must not start with '0', and must not be empty.
+double Strtod(Vector<const char> buffer, int exponent);
+
+// The buffer must only contain digits in the range [0-9]. It must not
+// contain a dot or a sign. It must not start with '0', and must not be empty.
+float Strtof(Vector<const char> buffer, int exponent);
+
+} // namespace double_conversion
+
+#endif // DOUBLE_CONVERSION_STRTOD_H_
diff --git a/src/3rdparty/sqlite/0001-Fixing-the-SQLite3-build-for-WEC2013-again.patch b/src/3rdparty/sqlite/0001-Fixing-the-SQLite3-build-for-WEC2013-again.patch
new file mode 100644
index 0000000000..2d92cfffa7
--- /dev/null
+++ b/src/3rdparty/sqlite/0001-Fixing-the-SQLite3-build-for-WEC2013-again.patch
@@ -0,0 +1,33 @@
+From c7bbe85015995c1e0627d88bac6fd5715b1338a0 Mon Sep 17 00:00:00 2001
+From: Bjoern Breitmeyer <bjoern.breitmeyer@kdab.com>
+Date: Fri, 3 Jul 2015 14:08:04 +0200
+Subject: [PATCH] Fixing the SQLite3 build for WEC2013 again.
+
+The new version broke the build again
+-> fix it again.
+
+Change-Id: I75761d134d97a2784f1de5076412aa814fdf9bcd
+---
+ src/3rdparty/sqlite/sqlite3.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
+index 71f6c10..040a9e1 100644
+--- a/src/3rdparty/sqlite/sqlite3.c
++++ b/src/3rdparty/sqlite/sqlite3.c
+@@ -15474,9 +15474,11 @@ static void clearYMD_HMS_TZ(DateTime *p){
+ #define HAVE_LOCALTIME_S 1
+ #endif
+
+-#if defined(_WIN32_WCE)
++#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
+ #undef HAVE_LOCALTIME_S
+ struct tm *__cdecl localtime(const time_t *t);
++#elif defined(_WIN32_WCE) && _WIN32_WCE >= 0x800
++# define SQLITE_MSVC_LOCALTIME_API 1
+ #endif
+
+ #ifndef SQLITE_OMIT_LOCALTIME
+--
+1.8.1.msysgit.1
+
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index 06f6d154f1..65379a822d 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -15742,9 +15742,11 @@ static void clearYMD_HMS_TZ(DateTime *p){
#define HAVE_LOCALTIME_S 1
#endif
-#if defined(_WIN32_WCE)
+#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
#undef HAVE_LOCALTIME_S
struct tm *__cdecl localtime(const time_t *t);
+#elif defined(_WIN32_WCE) && _WIN32_WCE >= 0x800
+# define SQLITE_MSVC_LOCALTIME_API 1
#endif
#ifndef SQLITE_OMIT_LOCALTIME
diff --git a/src/android/accessibility/accessibility.pro b/src/android/accessibility/accessibility.pro
deleted file mode 100644
index df5846945d..0000000000
--- a/src/android/accessibility/accessibility.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS = jar
diff --git a/src/android/accessibility/jar/AndroidManifest.xml b/src/android/accessibility/jar/AndroidManifest.xml
deleted file mode 100644
index dc8343a55a..0000000000
--- a/src/android/accessibility/jar/AndroidManifest.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- android:versionCode="1"
- android:versionName="1.0"
- package="org.qtproject.qt5.android.accessibility">
- <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
-</manifest>
diff --git a/src/android/accessibility/jar/bundledjar.pro b/src/android/accessibility/jar/bundledjar.pro
deleted file mode 100644
index 85ba810310..0000000000
--- a/src/android/accessibility/jar/bundledjar.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TARGET = QtAndroidAccessibility-bundled
-CONFIG += bundled_jar_file
-include(jar.pri)
diff --git a/src/android/accessibility/jar/distributedjar.pro b/src/android/accessibility/jar/distributedjar.pro
deleted file mode 100644
index d161cf0cf6..0000000000
--- a/src/android/accessibility/jar/distributedjar.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-TARGET = QtAndroidAccessibility
-include(jar.pri)
diff --git a/src/android/accessibility/jar/jar.pri b/src/android/accessibility/jar/jar.pri
deleted file mode 100644
index 3ae9fed59d..0000000000
--- a/src/android/accessibility/jar/jar.pri
+++ /dev/null
@@ -1,15 +0,0 @@
-CONFIG += java
-DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar
-API_VERSION = android-16
-
-PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/accessibility
-
-JAVACLASSPATH += $$PWD/src/ \
- $$DESTDIR/QtAndroid-bundled.jar
-JAVASOURCES += \
- $$PATHPREFIX/QtAccessibilityDelegate.java \
- $$PATHPREFIX/QtNativeAccessibility.java
-
-# install
-target.path = $$[QT_INSTALL_PREFIX]/jar
-INSTALLS += target \ No newline at end of file
diff --git a/src/android/accessibility/jar/jar.pro b/src/android/accessibility/jar/jar.pro
deleted file mode 100644
index 8d19c1b7d6..0000000000
--- a/src/android/accessibility/jar/jar.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-TEMPLATE = subdirs
-SUBDIRS += bundledjar.pro distributedjar.pro
diff --git a/src/android/android.pro b/src/android/android.pro
index b17dd15cd4..1174084591 100644
--- a/src/android/android.pro
+++ b/src/android/android.pro
@@ -1,3 +1,3 @@
TEMPLATE = subdirs
CONFIG += ordered
-SUBDIRS = jar java templates accessibility
+SUBDIRS = jar java templates
diff --git a/src/android/jar/jar.pri b/src/android/jar/jar.pri
index a962af18ab..b45b353f95 100644
--- a/src/android/jar/jar.pri
+++ b/src/android/jar/jar.pri
@@ -6,6 +6,8 @@ PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/
JAVACLASSPATH += $$PWD/src/
JAVASOURCES += \
+ $$PATHPREFIX/accessibility/QtAccessibilityDelegate.java \
+ $$PATHPREFIX/accessibility/QtNativeAccessibility.java \
$$PATHPREFIX/QtActivityDelegate.java \
$$PATHPREFIX/QtEditText.java \
$$PATHPREFIX/QtInputConnection.java \
@@ -14,9 +16,7 @@ JAVASOURCES += \
$$PATHPREFIX/QtNative.java \
$$PATHPREFIX/QtNativeLibrariesDir.java \
$$PATHPREFIX/QtSurface.java \
- $$PATHPREFIX/ExtractStyle.java \
- $$PATHPREFIX/QtPopupMenu.java \
- $$PATHPREFIX/QtPopupMenu14.java
+ $$PATHPREFIX/ExtractStyle.java
# install
target.path = $$[QT_INSTALL_PREFIX]/jar
diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
index f5dac1fa60..9d0031d0de 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
@@ -1813,11 +1813,7 @@ public class ExtractStyle {
jsonWriter.name("simple_spinner_item").value(extractItemStyle(android.R.layout.simple_spinner_item, "simple_spinner_item", -1));
jsonWriter.name("simple_spinner_dropdown_item").value(extractItemStyle(android.R.layout.simple_spinner_dropdown_item, "simple_spinner_dropdown_item",android.R.style.TextAppearance_Large));
jsonWriter.name("simple_dropdown_item_1line").value(extractItemStyle(android.R.layout.simple_dropdown_item_1line, "simple_dropdown_item_1line",android.R.style.TextAppearance_Large));
- if (Build.VERSION.SDK_INT > 10) {
- Class<?> layoutClass = Class.forName("android.R$layout");
- int styleId = layoutClass.getDeclaredField("simple_selectable_list_item").getInt(null);
- jsonWriter.name("simple_selectable_list_item").value(extractItemStyle(styleId, "simple_selectable_list_item",android.R.style.TextAppearance_Large));
- }
+ jsonWriter.name("simple_selectable_list_item").value(extractItemStyle(android.R.layout.simple_selectable_list_item, "simple_selectable_list_item",android.R.style.TextAppearance_Large));
} catch (Exception e) {
e.printStackTrace();
}
@@ -2018,9 +2014,7 @@ public class ExtractStyle {
extractProgressBar(jsonWriter, "progressBarStyleSmall", null);
extractProgressBar(jsonWriter, "progressBarStyle", null);
extractAbsSeekBar(jsonWriter, "seekBarStyle", "QSlider");
- if (Build.VERSION.SDK_INT > 13) {
- extractSwitch(jsonWriter, "switchStyle", null);
- }
+ extractSwitch(jsonWriter, "switchStyle", null);
extractCompoundButton(jsonWriter, "checkboxStyle", "QCheckBox");
jsonWriter.name("editTextStyle").value(extractTextAppearanceInformations("editTextStyle", "QLineEdit", null, -1));
extractCompoundButton(jsonWriter, "radioButtonStyle", "QRadioButton");
@@ -2030,15 +2024,13 @@ public class ExtractStyle {
jsonWriter.name("listSeparatorTextViewStyle").value(extractTextAppearanceInformations("listSeparatorTextViewStyle", null, null, -1));
extractItemsStyle(jsonWriter);
extractCompoundButton(jsonWriter, "buttonStyleToggle", null);
- if (Build.VERSION.SDK_INT > 10) {
- extractCalendar(jsonWriter, "calendarViewStyle", "QCalendarWidget");
- extractToolBar(jsonWriter, "actionBarStyle", "QToolBar");
- jsonWriter.name("actionButtonStyle").value(extractTextAppearanceInformations("actionButtonStyle", "QToolButton", null, -1));
- jsonWriter.name("actionBarTabTextStyle").value(extractTextAppearanceInformations("actionBarTabTextStyle", null, null, -1));
- jsonWriter.name("actionBarTabStyle").value(extractTextAppearanceInformations("actionBarTabStyle", null, null, -1));
- jsonWriter.name("actionOverflowButtonStyle").value(extractImageViewInformations("actionOverflowButtonStyle", null));
- extractTabBar(jsonWriter, "actionBarTabBarStyle", "QTabBar");
- }
+ extractCalendar(jsonWriter, "calendarViewStyle", "QCalendarWidget");
+ extractToolBar(jsonWriter, "actionBarStyle", "QToolBar");
+ jsonWriter.name("actionButtonStyle").value(extractTextAppearanceInformations("actionButtonStyle", "QToolButton", null, -1));
+ jsonWriter.name("actionBarTabTextStyle").value(extractTextAppearanceInformations("actionBarTabTextStyle", null, null, -1));
+ jsonWriter.name("actionBarTabStyle").value(extractTextAppearanceInformations("actionBarTabStyle", null, null, -1));
+ jsonWriter.name("actionOverflowButtonStyle").value(extractImageViewInformations("actionOverflowButtonStyle", null));
+ extractTabBar(jsonWriter, "actionBarTabBarStyle", "QTabBar");
} catch (Exception e) {
e.printStackTrace();
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index dd5a7b4fec..0a10a12660 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -67,6 +67,7 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.view.ViewTreeObserver;
+import android.widget.PopupMenu;
import android.graphics.Rect;
import java.io.BufferedReader;
@@ -80,6 +81,8 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
+import org.qtproject.qt5.android.accessibility.QtAccessibilityDelegate;
+
public class QtActivityDelegate
{
private Activity m_activity = null;
@@ -135,35 +138,23 @@ public class QtActivityDelegate
m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
try {
- if (Build.VERSION.SDK_INT >= 14) {
- int flags = View.class.getDeclaredField("SYSTEM_UI_FLAG_HIDE_NAVIGATION").getInt(null);
- if (Build.VERSION.SDK_INT >= 16) {
- flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_STABLE").getInt(null);
- flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION").getInt(null);
- flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN").getInt(null);
- flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_FULLSCREEN").getInt(null);
-
- if (Build.VERSION.SDK_INT >= 19)
- flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null);
- }
- Method m = View.class.getMethod("setSystemUiVisibility", int.class);
- m.invoke(m_activity.getWindow().getDecorView(), flags | View.INVISIBLE);
- }
+ int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+ flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
+ flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ flags |= View.SYSTEM_UI_FLAG_FULLSCREEN;
+
+ if (Build.VERSION.SDK_INT >= 19)
+ flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null);
+
+ m_activity.getWindow().getDecorView().setSystemUiVisibility(flags | View.INVISIBLE);
} catch (Exception e) {
e.printStackTrace();
}
} else {
m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
- if (Build.VERSION.SDK_INT >= 14) {
- try {
- int ui_flag_visible = View.class.getDeclaredField("SYSTEM_UI_FLAG_VISIBLE").getInt(null);
- Method m = View.class.getMethod("setSystemUiVisibility", int.class);
- m.invoke(m_activity.getWindow().getDecorView(), ui_flag_visible);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
+ m_activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
}
m_layout.requestLayout();
}
@@ -286,8 +277,7 @@ public class QtActivityDelegate
imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_NEXT;
break;
case EnterKeyPrevious:
- if (Build.VERSION.SDK_INT > 10)
- imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_PREVIOUS;
+ imeOptions = android.view.inputmethod.EditorInfo.IME_ACTION_PREVIOUS;
break;
}
@@ -300,7 +290,7 @@ public class QtActivityDelegate
| android.text.InputType.TYPE_NUMBER_FLAG_SIGNED);
}
- if (Build.VERSION.SDK_INT > 10 && (inputHints & ImhHiddenText) != 0)
+ if ((inputHints & ImhHiddenText) != 0)
inputType |= 0x10 /* TYPE_NUMBER_VARIATION_PASSWORD */;
} else if ((inputHints & ImhDialableCharactersOnly) != 0) {
inputType = android.text.InputType.TYPE_CLASS_PHONE;
@@ -478,13 +468,7 @@ public class QtActivityDelegate
m_super_onKeyUp = m_activity.getClass().getMethod("super_onKeyUp", Integer.TYPE, KeyEvent.class);
m_super_onConfigurationChanged = m_activity.getClass().getMethod("super_onConfigurationChanged", Configuration.class);
m_super_onActivityResult = m_activity.getClass().getMethod("super_onActivityResult", Integer.TYPE, Integer.TYPE, Intent.class);
- if (Build.VERSION.SDK_INT >= 12) {
- try {
- m_super_dispatchGenericMotionEvent = m_activity.getClass().getMethod("super_dispatchGenericMotionEvent", MotionEvent.class);
- } catch (Exception e) {
- }
- }
-
+ m_super_dispatchGenericMotionEvent = m_activity.getClass().getMethod("super_dispatchGenericMotionEvent", MotionEvent.class);
} catch (Exception e) {
e.printStackTrace();
return false;
@@ -500,10 +484,8 @@ public class QtActivityDelegate
+ "\tNECESSITAS_API_LEVEL=" + necessitasApiLevel
+ "\tHOME=" + m_activity.getFilesDir().getAbsolutePath()
+ "\tTMPDIR=" + m_activity.getFilesDir().getAbsolutePath();
- if (Build.VERSION.SDK_INT < 14)
- additionalEnvironmentVariables += "\tQT_ANDROID_FONTS=Droid Sans;Droid Sans Fallback";
- else
- additionalEnvironmentVariables += "\tQT_ANDROID_FONTS=Roboto;Droid Sans;Droid Sans Fallback";
+
+ additionalEnvironmentVariables += "\tQT_ANDROID_FONTS=Roboto;Droid Sans;Droid Sans Fallback";
additionalEnvironmentVariables += getAppIconSize(activity);
@@ -884,21 +866,7 @@ public class QtActivityDelegate
public void initializeAccessibility()
{
- // Initialize accessibility
- try {
- final String a11yDelegateClassName = "org.qtproject.qt5.android.accessibility.QtAccessibilityDelegate";
- Class<?> qtDelegateClass = Class.forName(a11yDelegateClassName);
- Constructor constructor = qtDelegateClass.getConstructor(android.app.Activity.class,
- android.view.ViewGroup.class,
- this.getClass());
- Object accessibilityDelegate = constructor.newInstance(m_activity, m_layout, this);
- } catch (ClassNotFoundException e) {
- // Class not found is fine since we are compatible with Android API < 16, but the function will
- // only be available with that API level.
- } catch (Exception e) {
- // Unknown exception means something went wrong.
- Log.w("Qt A11y", "Unknown exception: " + e.toString());
- }
+ new QtAccessibilityDelegate(m_activity, m_layout, this);
}
public void onConfigurationChanged(Configuration configuration)
@@ -908,6 +876,23 @@ public class QtActivityDelegate
} catch (Exception e) {
e.printStackTrace();
}
+
+ // if splash screen is defined, then show it
+ // Note: QtActivity handles settting the splash screen
+ // in onCreate, change that too if you are changing
+ // how the splash screen should be displayed
+ try {
+ if (m_surfaces.size() == 0) {
+ ActivityInfo info = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), PackageManager.GET_META_DATA);
+ if (info.metaData.containsKey("android.app.splash_screen_drawable"))
+ m_activity.getWindow().setBackgroundDrawableResource(info.metaData.getInt("android.app.splash_screen_drawable"));
+ else
+ m_activity.getWindow().setBackgroundDrawable(new ColorDrawable(0xff000000));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
int rotation = m_activity.getWindowManager().getDefaultDisplay().getRotation();
if (rotation != m_currentRotation) {
QtNative.handleOrientationChanged(rotation, m_nativeOrientation);
@@ -1102,17 +1087,9 @@ public class QtActivityDelegate
public void resetOptionsMenu()
{
- if (Build.VERSION.SDK_INT > 10) {
- try {
- Activity.class.getMethod("invalidateOptionsMenu").invoke(m_activity);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- else
- if (m_optionsMenuIsVisible)
- m_activity.closeOptionsMenu();
+ m_activity.invalidateOptionsMenu();
}
+
private boolean m_contextMenuVisible = false;
public void onCreateContextMenu(ContextMenu menu,
View v,
@@ -1148,15 +1125,22 @@ public class QtActivityDelegate
m_layout.postDelayed(new Runnable() {
@Override
public void run() {
- if (Build.VERSION.SDK_INT < 11 || w <= 0 || h <= 0) {
- m_activity.openContextMenu(m_layout);
- } else if (Build.VERSION.SDK_INT < 14) {
- m_layout.setLayoutParams(m_editText, new QtLayout.LayoutParams(w, h, x, y), false);
- QtPopupMenu.getInstance().showMenu(m_editText);
- } else {
- m_layout.setLayoutParams(m_editText, new QtLayout.LayoutParams(w, h, x, y), false);
- QtPopupMenu14.getInstance().showMenu(m_editText);
- }
+ m_layout.setLayoutParams(m_editText, new QtLayout.LayoutParams(w, h, x, y), false);
+ PopupMenu popup = new PopupMenu(m_activity, m_editText);
+ QtActivityDelegate.this.onCreatePopupMenu(popup.getMenu());
+ popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem menuItem) {
+ return QtActivityDelegate.this.onContextItemSelected(menuItem);
+ }
+ });
+ popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
+ @Override
+ public void onDismiss(PopupMenu popupMenu) {
+ QtActivityDelegate.this.onContextMenuClosed(popupMenu.getMenu());
+ }
+ });
+ popup.show();
}
}, 100);
}
@@ -1166,46 +1150,12 @@ public class QtActivityDelegate
m_activity.closeContextMenu();
}
- private boolean hasPermanentMenuKey()
- {
- try {
- return Build.VERSION.SDK_INT < 11 || (Build.VERSION.SDK_INT >= 14 &&
- (Boolean)ViewConfiguration.class.getMethod("hasPermanentMenuKey").invoke(ViewConfiguration.get(m_activity)));
- } catch (Exception e) {
- e.printStackTrace();
- return false;
- }
- }
-
- private Object getActionBar()
- {
- try {
- return Activity.class.getMethod("getActionBar").invoke(m_activity);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
private void setActionBarVisibility(boolean visible)
{
- if (hasPermanentMenuKey() || !visible) {
- if (Build.VERSION.SDK_INT > 10 && getActionBar() != null) {
- try {
- Class.forName("android.app.ActionBar").getMethod("hide").invoke(getActionBar());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- } else {
- if (Build.VERSION.SDK_INT > 10 && getActionBar() != null)
- try {
- Class.forName("android.app.ActionBar").getMethod("show").invoke(getActionBar());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
+ if (ViewConfiguration.get(m_activity).hasPermanentMenuKey() || !visible)
+ m_activity.getActionBar().hide();
+ else
+ m_activity.getActionBar().show();
}
public void insertNativeView(int id, View view, int x, int y, int w, int h) {
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtMessageDialogHelper.java b/src/android/jar/src/org/qtproject/qt5/android/QtMessageDialogHelper.java
index 341bc159c8..c0ebf3980f 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtMessageDialogHelper.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtMessageDialogHelper.java
@@ -100,14 +100,12 @@ public class QtMessageDialogHelper
if (m_icon == 0)
return null;
- if (Build.VERSION.SDK_INT > 10) {
- try {
- TypedValue typedValue = new TypedValue();
- m_theme.resolveAttribute(Class.forName("android.R$attr").getDeclaredField("alertDialogIcon").getInt(null), typedValue, true);
- return m_activity.getResources().getDrawable(typedValue.resourceId);
- } catch (Exception e) {
- e.printStackTrace();
- }
+ try {
+ TypedValue typedValue = new TypedValue();
+ m_theme.resolveAttribute(android.R.attr.alertDialogIcon, typedValue, true);
+ return m_activity.getResources().getDrawable(typedValue.resourceId);
+ } catch (Exception e) {
+ e.printStackTrace();
}
// Information, Warning, Critical, Question
@@ -115,7 +113,7 @@ public class QtMessageDialogHelper
{
case 1: // Information
try {
- return m_activity.getResources().getDrawable(Class.forName("android.R$drawable").getDeclaredField("ic_dialog_info").getInt(null));
+ return m_activity.getResources().getDrawable(android.R.drawable.ic_dialog_info);
} catch (Exception e) {
e.printStackTrace();
}
@@ -129,14 +127,14 @@ public class QtMessageDialogHelper
// break;
case 3: // Critical
try {
- return m_activity.getResources().getDrawable(Class.forName("android.R$drawable").getDeclaredField("ic_dialog_alert").getInt(null));
+ return m_activity.getResources().getDrawable(android.R.drawable.ic_dialog_alert);
} catch (Exception e) {
e.printStackTrace();
}
break;
case 4: // Question
try {
- return m_activity.getResources().getDrawable(Class.forName("android.R$drawable").getDeclaredField("ic_menu_help").getInt(null));
+ return m_activity.getResources().getDrawable(android.R.drawable.ic_menu_help);
} catch (Exception e) {
e.printStackTrace();
}
@@ -310,15 +308,11 @@ public class QtMessageDialogHelper
for (ButtonStruct button: m_buttonsList)
{
Button bv;
- if (Build.VERSION.SDK_INT > 10) {
- try {
- bv = new Button(m_activity, null, Class.forName("android.R$attr").getDeclaredField("borderlessButtonStyle").getInt(null));
- } catch (Exception e) {
- bv = new Button(m_activity);
- e.printStackTrace();
- }
- } else {
+ try {
+ bv = new Button(m_activity, null, Class.forName("android.R$attr").getDeclaredField("borderlessButtonStyle").getInt(null));
+ } catch (Exception e) {
bv = new Button(m_activity);
+ e.printStackTrace();
}
bv.setText(button.m_text);
@@ -327,14 +321,12 @@ public class QtMessageDialogHelper
{
LinearLayout.LayoutParams layout = null;
View spacer = new View(m_activity);
- if (Build.VERSION.SDK_INT > 10) {
- try {
- layout = new LinearLayout.LayoutParams(1, RelativeLayout.LayoutParams.MATCH_PARENT);
- spacer.setBackgroundDrawable(getStyledDrawable("dividerVertical"));
- buttonsLayout.addView(spacer, layout);
- } catch (Exception e) {
- e.printStackTrace();
- }
+ try {
+ layout = new LinearLayout.LayoutParams(1, RelativeLayout.LayoutParams.MATCH_PARENT);
+ spacer.setBackgroundDrawable(getStyledDrawable("dividerVertical"));
+ buttonsLayout.addView(spacer, layout);
+ } catch (Exception e) {
+ e.printStackTrace();
}
}
LinearLayout.LayoutParams layout = null;
@@ -343,23 +335,21 @@ public class QtMessageDialogHelper
firstButton = false;
}
- if (Build.VERSION.SDK_INT > 10) {
- try {
- View horizontalDevider = new View(m_activity);
- horizontalDevider.setId(id++);
- horizontalDevider.setBackgroundDrawable(getStyledDrawable("dividerHorizontal"));
- RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 1);
- relativeParams.setMargins(0, 10, 0, 0);
- if (lastView != null) {
- relativeParams.addRule(RelativeLayout.BELOW, lastView.getId());
- }
- else
- relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
- dialogLayout.addView(horizontalDevider, relativeParams);
- lastView = horizontalDevider;
- } catch (Exception e) {
- e.printStackTrace();
+ try {
+ View horizontalDevider = new View(m_activity);
+ horizontalDevider.setId(id++);
+ horizontalDevider.setBackgroundDrawable(getStyledDrawable("dividerHorizontal"));
+ RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 1);
+ relativeParams.setMargins(0, 10, 0, 0);
+ if (lastView != null) {
+ relativeParams.addRule(RelativeLayout.BELOW, lastView.getId());
}
+ else
+ relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
+ dialogLayout.addView(horizontalDevider, relativeParams);
+ lastView = horizontalDevider;
+ } catch (Exception e) {
+ e.printStackTrace();
}
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
if (lastView != null) {
@@ -367,10 +357,7 @@ public class QtMessageDialogHelper
}
else
relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
- if (Build.VERSION.SDK_INT < 11)
- relativeParams.setMargins(2, 12, 2, 4);
- else
- relativeParams.setMargins(2, 0, 2, 0);
+ relativeParams.setMargins(2, 0, 2, 0);
dialogLayout.addView(buttonsLayout, relativeParams);
}
scrollView.addView(dialogLayout);
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 2349ea6db1..5ff5bbc32f 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -333,16 +333,14 @@ public class QtNative
{
int pointerType = 0;
- if (Build.VERSION.SDK_INT >= 14) {
- switch (event.getToolType(0)) {
- case MotionEvent.TOOL_TYPE_STYLUS:
- pointerType = 1; // QTabletEvent::Pen
- break;
- case MotionEvent.TOOL_TYPE_ERASER:
- pointerType = 3; // QTabletEvent::Eraser
- break;
- // TODO TOOL_TYPE_MOUSE
- }
+ switch (event.getToolType(0)) {
+ case MotionEvent.TOOL_TYPE_STYLUS:
+ pointerType = 1; // QTabletEvent::Pen
+ break;
+ case MotionEvent.TOOL_TYPE_ERASER:
+ pointerType = 3; // QTabletEvent::Eraser
+ break;
+ // TODO TOOL_TYPE_MOUSE
}
if (pointerType != 0) {
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtPopupMenu.java b/src/android/jar/src/org/qtproject/qt5/android/QtPopupMenu.java
deleted file mode 100644
index d89b454b77..0000000000
--- a/src/android/jar/src/org/qtproject/qt5/android/QtPopupMenu.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Android port of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-package org.qtproject.qt5.android;
-
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.PopupMenu;
-
-public class QtPopupMenu {
- private QtPopupMenu() { }
-
- private static class QtPopupMenuHolder {
- private static final QtPopupMenu INSTANCE = new QtPopupMenu();
- }
-
- public static QtPopupMenu getInstance() {
- return QtPopupMenuHolder.INSTANCE;
- }
-
- public void showMenu(View anchor)
- {
- PopupMenu popup = new PopupMenu(QtNative.activity(), anchor);
- QtNative.activityDelegate().onCreatePopupMenu(popup.getMenu());
- popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem menuItem) {
- boolean res = QtNative.onContextItemSelected(menuItem.getItemId(), menuItem.isChecked());
- if (res)
- QtNative.activityDelegate().onContextMenuClosed(null);
- return res;
- }
- });
- popup.show();
- }
-}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtPopupMenu14.java b/src/android/jar/src/org/qtproject/qt5/android/QtPopupMenu14.java
deleted file mode 100644
index edef682dec..0000000000
--- a/src/android/jar/src/org/qtproject/qt5/android/QtPopupMenu14.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Android port of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-package org.qtproject.qt5.android;
-
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.PopupMenu;
-
-public class QtPopupMenu14 {
- private QtPopupMenu14() { }
-
- private static class QtPopupMenu14Holder {
- private static final QtPopupMenu14 INSTANCE = new QtPopupMenu14();
- }
-
- public static QtPopupMenu14 getInstance() {
- return QtPopupMenu14Holder.INSTANCE;
- }
-
- public void showMenu(View anchor)
- {
- PopupMenu popup = new PopupMenu(QtNative.activity(), anchor);
- QtNative.activityDelegate().onCreatePopupMenu(popup.getMenu());
- popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
- @Override
- public boolean onMenuItemClick(MenuItem menuItem) {
- return QtNative.activityDelegate().onContextItemSelected(menuItem);
- }
- });
- popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
- @Override
- public void onDismiss(PopupMenu popupMenu) {
- QtNative.activityDelegate().onContextMenuClosed(popupMenu.getMenu());
- }
- });
- popup.show();
- }
-}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
index 74433d2b65..51d0410816 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
@@ -62,9 +62,6 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
else
getHolder().setFormat(PixelFormat.RGBA_8888);
- if (android.os.Build.VERSION.SDK_INT < 11)
- getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
-
setId(id);
m_gestureDetector =
new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
diff --git a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
index 6f95675597..6f95675597 100644
--- a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
diff --git a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java b/src/android/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java
index bfda2d55b7..bfda2d55b7 100644
--- a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/accessibility/QtNativeAccessibility.java
diff --git a/src/android/java/res/values-ro/strings.xml b/src/android/java/res/values-ro/strings.xml
index f88a442b35..fef52ad3bd 100644
--- a/src/android/java/res/values-ro/strings.xml
+++ b/src/android/java/res/values-ro/strings.xml
@@ -3,4 +3,5 @@
<string name="ministro_not_found_msg">Serviciul Ministro nu poate fi găsit.\nAplicaţia nu poate porni.</string>
<string name="ministro_needed_msg">Această aplicaţie necesită serviciul Ministro.\nDoriţi să-l instalaţi?</string>
<string name="fatal_error_msg">Aplicaţia dumneavoastră a întâmpinat o eroare fatală şi nu poate continua.</string>
+ <string name="unsupported_android_version">Versiune Android nesuportată.</string>
</resources>
diff --git a/src/android/java/res/values/strings.xml b/src/android/java/res/values/strings.xml
index fcc3eb097b..95b3385924 100644
--- a/src/android/java/res/values/strings.xml
+++ b/src/android/java/res/values/strings.xml
@@ -4,4 +4,5 @@
<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>
<string name="fatal_error_msg">Your application encountered a fatal error and cannot continue.</string>
+ <string name="unsupported_android_version">Unsupported Android version.</string>
</resources>
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 146d6b34f2..0859318fe1 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
@@ -183,11 +183,7 @@ public class QtActivity extends Activity
public QtActivity()
{
- if (Build.VERSION.SDK_INT <= 10) {
- QT_ANDROID_THEMES = new String[] {"Theme_Light"};
- QT_ANDROID_DEFAULT_THEME = "Theme_Light";
- }
- else if ((Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT <= 13) || Build.VERSION.SDK_INT >= 21){
+ if (Build.VERSION.SDK_INT >= 21) {
QT_ANDROID_THEMES = new String[] {"Theme_Holo_Light"};
QT_ANDROID_DEFAULT_THEME = "Theme_Holo_Light";
} else {
@@ -843,7 +839,6 @@ public class QtActivity extends Activity
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
-
try {
m_activityInfo = getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
for (Field f : Class.forName("android.R$style").getDeclaredFields()) {
@@ -858,21 +853,30 @@ public class QtActivity extends Activity
return;
}
+ if (Build.VERSION.SDK_INT < 16) {
+ // fatal error, show the error and quit
+ AlertDialog errorDialog = new AlertDialog.Builder(QtActivity.this).create();
+ if (m_activityInfo.metaData.containsKey("android.app.unsupported_android_version"))
+ errorDialog.setMessage(m_activityInfo.metaData.getString("android.app.unsupported_android_version"));
+ else
+ errorDialog.setMessage("Unsupported Android version.");
+ errorDialog.setButton(getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ finish();
+ }
+ });
+ errorDialog.show();
+ return;
+ }
+
try {
setTheme(Class.forName("android.R$style").getDeclaredField(QT_ANDROID_DEFAULT_THEME).getInt(null));
} catch (Exception e) {
e.printStackTrace();
}
- if (Build.VERSION.SDK_INT > 10) {
- try {
- requestWindowFeature(Window.class.getField("FEATURE_ACTION_BAR").getInt(null));
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- }
+ requestWindowFeature(Window.FEATURE_ACTION_BAR);
if (QtApplication.m_delegateObject != null && QtApplication.onCreate != null) {
QtApplication.invokeDelegateMethod(QtApplication.onCreate, savedInstanceState);
@@ -886,6 +890,9 @@ public class QtActivity extends Activity
if (null == getLastNonConfigurationInstance()) {
// if splash screen is defined, then show it
+ // Note: QtActivityDelegate handles updating the splash screen
+ // in onConfigurationChanged, change that too if you are changing
+ // how the splash screen should be displayed
if (m_activityInfo.metaData.containsKey("android.app.splash_screen_drawable"))
getWindow().setBackgroundDrawableResource(m_activityInfo.metaData.getInt("android.app.splash_screen_drawable"));
else
diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml
index 262a5f6dba..2a6d0b6fa3 100644
--- a/src/android/templates/AndroidManifest.xml
+++ b/src/android/templates/AndroidManifest.xml
@@ -50,7 +50,7 @@
<!-- auto screen scale factor -->
</activity>
</application>
- <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/>
+ <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="16"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in
index 91a4eb619a..a5ed8b2ea3 100644
--- a/src/corelib/Qt5CoreConfigExtras.cmake.in
+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in
@@ -114,6 +114,8 @@ set(Qt5_DISABLED_FEATURES
set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS $<$<NOT:$<CONFIG:Debug>>:QT_NO_DEBUG>)
+set_property(TARGET Qt5::Core PROPERTY INTERFACE_COMPILE_FEATURES cxx_decltype)
+
!!IF contains(QT_CONFIG, reduce_exports)
set(QT_VISIBILITY_AVAILABLE \"True\")
!!ENDIF
diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake
index 9fab04fb26..9235641544 100644
--- a/src/corelib/Qt5CoreMacros.cmake
+++ b/src/corelib/Qt5CoreMacros.cmake
@@ -53,8 +53,8 @@ macro(QT5_MAKE_OUTPUT_FILE infile prefix ext outfile )
else()
file(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile})
endif()
- if(WIN32 AND rel MATCHES "^[a-zA-Z]:") # absolute path
- string(REGEX REPLACE "^([a-zA-Z]):(.*)$" "\\1_\\2" rel "${rel}")
+ if(WIN32 AND rel MATCHES "^([a-zA-Z]):(.*)$") # absolute path
+ set(rel "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}")
endif()
set(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${rel}")
string(REPLACE ".." "__" _outfile ${_outfile})
@@ -94,7 +94,7 @@ endmacro()
# helper macro to set up a moc rule
-macro(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target moc_depends)
+function(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target moc_depends)
# Pass the parameters in a file. Set the working directory to
# be that containing the parameters file and reference it by
# just the file name. This is necessary because the moc tool on
@@ -134,7 +134,7 @@ macro(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target moc
DEPENDS ${infile} ${moc_depends}
${_moc_working_dir}
VERBATIM)
-endmacro()
+endfunction()
function(QT5_GENERATE_MOC infile outfile )
diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp
index a64b3d167e..a8a0687d7a 100644
--- a/src/corelib/codecs/qutfcodec.cpp
+++ b/src/corelib/codecs/qutfcodec.cpp
@@ -256,8 +256,32 @@ QString QUtf8::convertToUnicode(const char *chars, int len)
// The table holds for invalid sequences too: we'll insert one replacement char
// per invalid byte.
QString result(len, Qt::Uninitialized);
+ QChar *data = const_cast<QChar*>(result.constData()); // we know we're not shared
+ const QChar *end = convertToUnicode(data, chars, len);
+ result.truncate(end - data);
+ return result;
+}
- ushort *dst = reinterpret_cast<ushort *>(const_cast<QChar *>(result.constData()));
+/*!
+ \since 5.7
+ \overload
+
+ Converts the UTF-8 sequence of \a len octets beginning at \a chars to
+ a sequence of QChar starting at \a buffer. The buffer is expected to be
+ large enough to hold the result. An upper bound for the size of the
+ buffer is \a len QChars.
+
+ If, during decoding, an error occurs, a QChar::ReplacementCharacter is
+ written.
+
+ Returns a pointer to one past the last QChar written.
+
+ This function never throws.
+*/
+
+QChar *QUtf8::convertToUnicode(QChar *buffer, const char *chars, int len) Q_DECL_NOTHROW
+{
+ ushort *dst = reinterpret_cast<ushort *>(buffer);
const uchar *src = reinterpret_cast<const uchar *>(chars);
const uchar *end = src + len;
@@ -288,8 +312,7 @@ QString QUtf8::convertToUnicode(const char *chars, int len)
}
}
- result.truncate(dst - reinterpret_cast<const ushort *>(result.constData()));
- return result;
+ return reinterpret_cast<QChar *>(dst);
}
QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::ConverterState *state)
diff --git a/src/corelib/codecs/qutfcodec_p.h b/src/corelib/codecs/qutfcodec_p.h
index d97145c6fc..62540213f9 100644
--- a/src/corelib/codecs/qutfcodec_p.h
+++ b/src/corelib/codecs/qutfcodec_p.h
@@ -279,6 +279,7 @@ enum DataEndianness
struct QUtf8
{
+ static QChar *convertToUnicode(QChar *, const char *, int) Q_DECL_NOTHROW;
static QString convertToUnicode(const char *, int);
static QString convertToUnicode(const char *, int, QTextCodec::ConverterState *);
static QByteArray convertFromUnicode(const QChar *, int);
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 5cd0bde87b..a8c8f65d37 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -16,13 +16,11 @@ CONFIG += optimize_full
QMAKE_DOCS = $$PWD/doc/qtcore.qdocconf
ANDROID_JAR_DEPENDENCIES = \
- jar/QtAndroid.jar \
- jar/QtAndroidAccessibility.jar
+ jar/QtAndroid.jar
ANDROID_LIB_DEPENDENCIES = \
plugins/platforms/android/libqtforandroid.so
ANDROID_BUNDLED_JAR_DEPENDENCIES = \
- jar/QtAndroid-bundled.jar \
- jar/QtAndroidAccessibility-bundled.jar
+ jar/QtAndroid-bundled.jar
ANDROID_PERMISSIONS = \
android.permission.INTERNET \
android.permission.WRITE_EXTERNAL_STORAGE
diff --git a/src/corelib/doc/snippets/code/doc_src_qpair.cpp b/src/corelib/doc/snippets/code/doc_src_qpair.cpp
index 1473d3bd4f..85dc1cdac7 100644
--- a/src/corelib/doc/snippets/code/doc_src_qpair.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_qpair.cpp
@@ -48,6 +48,15 @@ pair.first = "pi";
pair.second = 3.14159265358979323846;
//! [1]
+//! [struct]
+struct Variable {
+ QString name;
+ double value;
+};
+Variable v;
+v.name = "pi";
+v.value = 3.14159265358979323846;
+//! [struct]
//! [2]
QList<QPair<int, double> > list;
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
index 6ff4f57945..ccf8399e0d 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
@@ -439,6 +439,11 @@ qWarning("%s: %s", qUtf8Printable(key), qUtf8Printable(value));
//! [37]
+//! [qUtf16Printable]
+qWarning("%ls: %ls", qUtf16Printable(key), qUtf16Printable(value));
+//! [qUtf16Printable]
+
+
//! [38]
struct Point2D
{
diff --git a/src/corelib/doc/snippets/qprocess/qprocess-createprocessargumentsmodifier.cpp b/src/corelib/doc/snippets/qprocess/qprocess-createprocessargumentsmodifier.cpp
new file mode 100644
index 0000000000..4dd32dd58a
--- /dev/null
+++ b/src/corelib/doc/snippets/qprocess/qprocess-createprocessargumentsmodifier.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <QProcess>
+#include <qt_windows.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+//! [0]
+ QProcess process;
+ process.setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args)
+ {
+ args->flags |= CREATE_NEW_CONSOLE;
+ args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES;
+ args->startupInfo->dwFlags |= STARTF_USEFILLATTRIBUTE;
+ args->startupInfo->dwFillAttribute = BACKGROUND_BLUE | FOREGROUND_RED
+ | FOREGROUND_INTENSITY;
+ });
+ process.start("C:\\Windows\\System32\\cmd.exe", QStringList() << "/k" << "title" << "The Child Process");
+//! [0]
+
+ return app.exec();
+}
diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp
index 07ff9301bf..c68d185916 100644
--- a/src/corelib/doc/snippets/qstring/main.cpp
+++ b/src/corelib/doc/snippets/qstring/main.cpp
@@ -625,7 +625,7 @@ void Widget::resizeFunction()
//! [46]
QString t = "Hello";
- t += QString(10, 'X');
+ r.resize(t.size() + 10, 'X');
// t == "HelloXXXXXXXXXX"
//! [46]
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index ba830977ad..24d022059d 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -1119,6 +1119,37 @@
#endif
/*
+ * SG10's SD-6 feature detection and some useful extensions from Clang and GCC
+ * https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations
+ * http://clang.llvm.org/docs/LanguageExtensions.html#feature-checking-macros
+ */
+#ifdef __has_builtin
+# define QT_HAS_BUILTIN(x) __has_builtin(x)
+#else
+# define QT_HAS_BUILTIN(x) 0
+#endif
+#ifdef __has_attribute
+# define QT_HAS_ATTRIBUTE(x) __has_attribute(x)
+#else
+# define QT_HAS_ATTRIBUTE(x) 0
+#endif
+#ifdef __has_cpp_attribute
+# define QT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
+#else
+# define QT_HAS_CPP_ATTRIBUTE(x) 0
+#endif
+#ifdef __has_include
+# define QT_HAS_INCLUDE(x) __has_include(x)
+#else
+# define QT_HAS_INCLUDE(x) 0
+#endif
+#ifdef __has_include_next
+# define QT_HAS_INCLUDE_NEXT(x) __has_include_next(x)
+#else
+# define QT_HAS_INCLUDE_NEXT(x) 0
+#endif
+
+/*
* Warning/diagnostic handling
*/
diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h
index 2ddefaec8b..dd0e5a7e5a 100644
--- a/src/corelib/global/qendian.h
+++ b/src/corelib/global/qendian.h
@@ -87,12 +87,6 @@ template <typename T> inline T qFromUnaligned(const uchar *src)
*/
template <typename T> T qbswap(T source);
-#ifdef __has_builtin
-# define QT_HAS_BUILTIN(x) __has_builtin(x)
-#else
-# define QT_HAS_BUILTIN(x) 0
-#endif
-
// GCC 4.3 implemented all the intrinsics, but the 16-bit one only got implemented in 4.8;
// Clang 2.6 implemented the 32- and 64-bit but waited until 3.2 to implement the 16-bit one
#if (defined(Q_CC_GNU) && Q_CC_GNU >= 403) || QT_HAS_BUILTIN(__builtin_bswap32)
@@ -154,8 +148,6 @@ template <> inline quint16 qbswap<quint16>(quint16 source)
}
#endif // GCC & Clang intrinsics
-#undef QT_HAS_BUILTIN
-
// signed specializations
template <> inline qint64 qbswap<qint64>(qint64 source)
{
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index e8c50dff2b..606a60db5a 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -77,10 +77,6 @@
#include <private/qjni_p.h>
#endif
-#if defined(Q_OS_BLACKBERRY)
-# include <bps/deviceinfo.h>
-#endif
-
#if defined(Q_OS_SOLARIS)
# include <sys/systeminfo.h>
#endif
@@ -1173,30 +1169,35 @@ bool qSharedBuild() Q_DECL_NOTHROW
\macro Q_OS_DARWIN
\relates <QtGlobal>
- Defined on Darwin-based operating systems such as OS X and iOS,
- including any open source version(s) of Darwin.
+ Defined on Darwin-based operating systems such as OS X, iOS, watchOS, and tvOS.
*/
/*!
- \macro Q_OS_MAC
+ \macro Q_OS_OSX
\relates <QtGlobal>
- Defined on Darwin-based operating systems distributed by Apple, which
- currently includes OS X and iOS, but not the open source versions of Darwin.
+ Defined on OS X.
*/
/*!
- \macro Q_OS_OSX
+ \macro Q_OS_IOS
\relates <QtGlobal>
- Defined on OS X.
+ Defined on iOS.
*/
/*!
- \macro Q_OS_IOS
+ \macro Q_OS_WATCHOS
\relates <QtGlobal>
- Defined on iOS.
+ Defined on watchOS.
+ */
+
+/*!
+ \macro Q_OS_TVOS
+ \relates <QtGlobal>
+
+ Defined on tvOS.
*/
/*!
@@ -1913,9 +1914,9 @@ static inline HMODULE moduleHandleForFunction(LPCVOID address)
}
#endif
-static inline OSVERSIONINFO winOsVersion()
+static inline OSVERSIONINFOEX determineWinOsVersion()
{
- OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0, {'\0'}};
+ OSVERSIONINFOEX result = { sizeof(OSVERSIONINFOEX), 0, 0, 0, 0, {'\0'}, 0, 0, 0, 0, 0};
#ifndef Q_OS_WINCE
#define GetProcAddressA GetProcAddress
@@ -1958,7 +1959,13 @@ static inline OSVERSIONINFO winOsVersion()
// GetVersionEx() has been deprecated in Windows 8.1 and will return
// only Windows 8 from that version on, so use the kernel API function.
- pRtlGetVersion(&result); // always returns STATUS_SUCCESS
+ pRtlGetVersion((LPOSVERSIONINFO) &result); // always returns STATUS_SUCCESS
+ return result;
+}
+
+static OSVERSIONINFOEX winOsVersion()
+{
+ static OSVERSIONINFOEX result = determineWinOsVersion();
return result;
}
@@ -1981,7 +1988,7 @@ QSysInfo::WinVersion QSysInfo::windowsVersion()
if (winver)
return winver;
winver = QSysInfo::WV_NT;
- const OSVERSIONINFO osver = winOsVersion();
+ const OSVERSIONINFOEX osver = winOsVersion();
if (osver.dwMajorVersion == 0)
return QSysInfo::WV_None;
#ifdef Q_OS_WINCE
@@ -2067,8 +2074,24 @@ QSysInfo::WinVersion QSysInfo::windowsVersion()
return winver;
}
+static QString winSp_helper()
+{
+ const qint16 major = winOsVersion().wServicePackMajor;
+ if (major) {
+ QString sp = QStringLiteral(" SP ") + QString::number(major);
+ const qint16 minor = winOsVersion().wServicePackMinor;
+ if (minor)
+ sp += QLatin1Char('.') + QString::number(minor);
+
+ return sp;
+ }
+ return QString();
+}
+
static const char *winVer_helper()
{
+ const bool workstation = winOsVersion().wProductType == VER_NT_WORKSTATION;
+
switch (int(QSysInfo::WindowsVersion)) {
case QSysInfo::WV_NT:
return "NT";
@@ -2079,15 +2102,15 @@ static const char *winVer_helper()
case QSysInfo::WV_2003:
return "2003";
case QSysInfo::WV_VISTA:
- return "Vista";
+ return workstation ? "Vista" : "Server 2008";
case QSysInfo::WV_WINDOWS7:
- return "7";
+ return workstation ? "7" : "Server 2008 R2";
case QSysInfo::WV_WINDOWS8:
- return "8";
+ return workstation ? "8" : "Server 2012";
case QSysInfo::WV_WINDOWS8_1:
- return "8.1";
+ return workstation ? "8.1" : "Server 2012 R2";
case QSysInfo::WV_WINDOWS10:
- return "10";
+ return workstation ? "10" : "Server 2016";
case QSysInfo::WV_CE:
return "CE";
@@ -2498,7 +2521,7 @@ static QString unknownText()
Note that this function may return surprising values: it returns "linux"
for all operating systems running Linux (including Android), "qnx" for all
- operating systems running QNX (including BlackBerry 10), "freebsd" for
+ operating systems running QNX, "freebsd" for
Debian/kFreeBSD, and "darwin" for OS X and iOS. For information on the type
of product the application is running on, see productType().
@@ -2523,7 +2546,7 @@ QString QSysInfo::kernelType()
Returns the release version of the operating system kernel. On Windows, it
returns the version of the NT or CE kernel. On Unix systems, including
- Android, BlackBerry and OS X, it returns the same as the \c{uname -r}
+ Android and OS X, it returns the same as the \c{uname -r}
command would return.
If the version could not be determined, this function may return an empty
@@ -2534,7 +2557,7 @@ QString QSysInfo::kernelType()
QString QSysInfo::kernelVersion()
{
#ifdef Q_OS_WIN
- const OSVERSIONINFO osver = winOsVersion();
+ const OSVERSIONINFOEX osver = winOsVersion();
return QString::number(int(osver.dwMajorVersion)) + QLatin1Char('.') + QString::number(int(osver.dwMinorVersion))
+ QLatin1Char('.') + QString::number(int(osver.dwBuildNumber));
#else
@@ -2564,10 +2587,6 @@ QString QSysInfo::kernelVersion()
to determine the distribution name and returns that. If determining the
distribution name failed, it returns "unknown".
- \b{BlackBerry note}: this function returns "blackberry" for QNX systems
- running the BlackBerry userspace, but "qnx" for all other QNX-based
- systems.
-
\b{Darwin, OS X and iOS note}: this function returns "osx" for OS X
systems, "ios" for iOS systems and "darwin" in case the system could not be
determined.
@@ -2595,8 +2614,6 @@ QString QSysInfo::productType()
#elif defined(Q_OS_WIN)
return QStringLiteral("windows");
-#elif defined(Q_OS_BLACKBERRY)
- return QStringLiteral("blackberry");
#elif defined(Q_OS_QNX)
return QStringLiteral("qnx");
@@ -2625,7 +2642,7 @@ QString QSysInfo::productType()
Returns the product version of the operating system in string form. If the
version could not be determined, this function returns "unknown".
- It will return the Android, BlackBerry, iOS, OS X, Windows full-product
+ It will return the Android, iOS, OS X, Windows full-product
versions on those systems. In particular, on OS X, iOS and Windows, the
returned string is similar to the macVersion() or windowsVersion() enums.
@@ -2636,7 +2653,7 @@ QString QSysInfo::productType()
In all other Unix-type systems, this function always returns "unknown".
\note The version string returned from this function is only guaranteed to
- be orderable on Android, BlackBerry, OS X and iOS. On Windows, some Windows
+ be orderable on Android, OS X and iOS. On Windows, some Windows
versions are text ("XP" and "Vista", for example). On Linux, the version of
the distribution may jump unexpectedly, please refer to the distribution's
documentation for versioning practices.
@@ -2650,22 +2667,17 @@ QString QSysInfo::productVersion()
return QString::number(version.major) + QLatin1Char('.') + QString::number(version.minor);
#elif defined(Q_OS_WIN)
const char *version = winVer_helper();
- if (version)
- return QString::fromLatin1(version).toLower();
+ if (version) {
+ const QLatin1Char spaceChar(' ');
+ return QString::fromLatin1(version).remove(spaceChar).toLower() + winSp_helper().remove(spaceChar).toLower();
+ }
// fall through
-// Android and Blackberry should not fall through to the Unix code
+// Android should not fall through to the Unix code
#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK)
return QJNIObjectPrivate::getStaticObjectField("android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").toString();
#elif defined(Q_OS_ANDROID) // Q_OS_ANDROID_NO_SDK
// TBD
-#elif defined(Q_OS_BLACKBERRY)
- deviceinfo_details_t *deviceInfo;
- if (deviceinfo_get_details(&deviceInfo) == BPS_SUCCESS) {
- QString bbVersion = QString::fromLatin1(deviceinfo_details_get_device_os_version(deviceInfo));
- deviceinfo_free_details(&deviceInfo);
- return bbVersion;
- }
#elif defined(USE_ETC_OS_RELEASE) // Q_OS_UNIX
QUnixOSVersion unixOsVersion;
findUnixOsVersion(unixOsVersion);
@@ -2738,11 +2750,9 @@ QString QSysInfo::prettyProductName()
#elif defined(Q_OS_WINPHONE)
return QLatin1String("Windows Phone ") + QLatin1String(winVer_helper());
#elif defined(Q_OS_WIN)
- return QLatin1String("Windows ") + QLatin1String(winVer_helper());
+ return QLatin1String("Windows ") + QLatin1String(winVer_helper()) + winSp_helper();
#elif defined(Q_OS_ANDROID)
return QLatin1String("Android ") + productVersion();
-#elif defined(Q_OS_BLACKBERRY)
- return QLatin1String("BlackBerry ") + productVersion();
#elif defined(Q_OS_HAIKU)
return QLatin1String("Haiku ") + productVersion();
#elif defined(Q_OS_UNIX)
@@ -3770,6 +3780,29 @@ int qrand()
*/
/*!
+ \macro const wchar_t *qUtf16Printable(const QString &str)
+ \relates <QtGlobal>
+ \since 5.7
+
+ Returns \a str as a \c{const ushort *}, but cast to a \c{const wchar_t *}
+ to avoid warnings. This is equivalent to \a{str}.utf16() plus some casting.
+
+ The only useful thing you can do with the return value of this macro is to
+ pass it to QString::asprintf() for use in a \c{%ls} conversion. In particular,
+ the return value is \e{not} a valid \c{const wchar_t*}!
+
+ In general, the pointer will be invalid after the statement in which
+ qUtf16Printable() is used. This is because the pointer may have been
+ obtained from a temporary expression, which will fall out of scope.
+
+ Example:
+
+ \snippet code/src_corelib_global_qglobal.cpp qUtf16Printable
+
+ \sa qPrintable(), qDebug(), qInfo(), qWarning(), qCritical(), qFatal()
+*/
+
+/*!
\macro Q_DECLARE_TYPEINFO(Type, Flags)
\relates <QtGlobal>
@@ -4179,7 +4212,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
Calls the message handler with the debug message \a message. If no
message handler has been installed, the message is printed to
stderr. Under Windows the message is sent to the console, if it is a
- console application; otherwise, it is sent to the debugger. On Blackberry, the
+ console application; otherwise, it is sent to the debugger. On QNX, the
message is sent to slogger2. This function does nothing if \c QT_NO_DEBUG_OUTPUT
was defined during compilation.
@@ -4216,7 +4249,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
Calls the message handler with the informational message \a message. If no
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the console, if it is a
- console application; otherwise, it is sent to the debugger. On Blackberry the
+ console application; otherwise, it is sent to the debugger. On QNX the
message is sent to slogger2. This function does nothing if \c QT_NO_INFO_OUTPUT
was defined during compilation.
@@ -4252,7 +4285,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
Calls the message handler with the warning message \a message. If no
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger.
- On Blackberry the message is sent to slogger2. This
+ On QNX the message is sent to slogger2. This
function does nothing if \c QT_NO_WARNING_OUTPUT was defined
during compilation; it exits if the environment variable \c
QT_FATAL_WARNINGS is not empty.
@@ -4286,7 +4319,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
Calls the message handler with the critical message \a message. If no
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger.
- On Blackberry the message is sent to slogger2.
+ On QNX the message is sent to slogger2
It exits if the environment variable QT_FATAL_CRITICALS is not empty.
@@ -4319,7 +4352,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
Calls the message handler with the fatal message \a message. If no
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger.
- On Blackberry the message is sent to slogger2.
+ On QNX the message is sent to slogger2
If you are using the \b{default message handler} this function will
abort on Unix systems to create a core dump. On Windows, for debug builds,
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 2551dcb5d3..232c52b8fe 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -686,6 +686,15 @@ Q_CORE_EXPORT bool qSharedBuild() Q_DECL_NOTHROW;
# define qUtf8Printable(string) QString(string).toUtf8().constData()
#endif
+/*
+ Wrap QString::utf16() with enough casts to allow passing it
+ to QString::asprintf("%ls") without warnings.
+*/
+#ifndef qUtf16Printable
+# define qUtf16Printable(string) \
+ static_cast<const wchar_t*>(static_cast<const void*>(QString(string).utf16()))
+#endif
+
class QString;
Q_CORE_EXPORT QString qt_error_string(int errorCode = -1);
@@ -744,7 +753,7 @@ Q_CORE_EXPORT void qt_check_pointer(const char *, int);
Q_CORE_EXPORT void qBadAlloc();
#ifdef QT_NO_EXCEPTIONS
-# if defined(QT_NO_DEBUG)
+# if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
# define Q_CHECK_PTR(p) qt_noop()
# else
# define Q_CHECK_PTR(p) do {if(!(p))qt_check_pointer(__FILE__,__LINE__);} while (0)
@@ -914,8 +923,6 @@ QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantic
# endif
#endif
-#if defined(Q_COMPILER_DECLTYPE) || defined(Q_CC_GNU)
-/* make use of decltype or GCC's __typeof__ extension */
template <typename T>
class QForeachContainer {
QForeachContainer &operator=(const QForeachContainer &) Q_DECL_EQ_DELETE;
@@ -926,17 +933,6 @@ public:
int control;
};
-// We need to use __typeof__ if we don't have decltype or if the compiler
-// hasn't been updated to the fix of Core Language Defect Report 382
-// (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#382).
-// GCC 4.3 and 4.4 have support for decltype, but are affected by DR 382.
-# if defined(Q_COMPILER_DECLTYPE) && \
- (defined(Q_CC_CLANG) || defined(Q_CC_INTEL) || !defined(Q_CC_GNU) || Q_CC_GNU >= 405)
-# define QT_FOREACH_DECLTYPE(x) typename QtPrivate::remove_reference<decltype(x)>::type
-# else
-# define QT_FOREACH_DECLTYPE(x) __typeof__((x))
-# endif
-
// Explanation of the control word:
// - it's initialized to 1
// - that means both the inner and outer loops start
@@ -946,61 +942,12 @@ public:
// the outer loop to continue executing
// - if there was a break inside the inner loop, it will exit with control still
// set to 1; in that case, the outer loop will invert it to 0 and will exit too
-# define Q_FOREACH(variable, container) \
-for (QForeachContainer<QT_FOREACH_DECLTYPE(container)> _container_((container)); \
+#define Q_FOREACH(variable, container) \
+for (QForeachContainer<typename QtPrivate::remove_reference<decltype(container)>::type> _container_((container)); \
_container_.control && _container_.i != _container_.e; \
++_container_.i, _container_.control ^= 1) \
for (variable = *_container_.i; _container_.control; _container_.control = 0)
-#else
-
-struct QForeachContainerBase {};
-
-template <typename T>
-class QForeachContainer : public QForeachContainerBase {
- QForeachContainer &operator=(const QForeachContainer &) Q_DECL_EQ_DELETE;
-public:
- inline QForeachContainer(const T& t): c(t), brk(0), i(c.begin()), e(c.end()){}
- QForeachContainer(const QForeachContainer &other)
- : c(other.c), brk(other.brk), i(other.i), e(other.e) {}
- const T c;
- mutable int brk;
- mutable typename T::const_iterator i, e;
- inline bool condition() const { return (!brk++ && i != e); }
-};
-
-template <typename T> inline T *qForeachPointer(const T &) { return 0; }
-
-template <typename T> inline QForeachContainer<T> qForeachContainerNew(const T& t)
-{ return QForeachContainer<T>(t); }
-
-template <typename T>
-inline const QForeachContainer<T> *qForeachContainer(const QForeachContainerBase *base, const T *)
-{ return static_cast<const QForeachContainer<T> *>(base); }
-
-#if defined(Q_CC_DIAB)
-// VxWorks DIAB generates unresolvable symbols, if container is a function call
-# define Q_FOREACH(variable,container) \
- if(0){}else \
- for (const QForeachContainerBase &_container_ = qForeachContainerNew(container); \
- qForeachContainer(&_container_, (__typeof__(container) *) 0)->condition(); \
- ++qForeachContainer(&_container_, (__typeof__(container) *) 0)->i) \
- for (variable = *qForeachContainer(&_container_, (__typeof__(container) *) 0)->i; \
- qForeachContainer(&_container_, (__typeof__(container) *) 0)->brk; \
- --qForeachContainer(&_container_, (__typeof__(container) *) 0)->brk)
-
-#else
-# define Q_FOREACH(variable, container) \
- for (const QForeachContainerBase &_container_ = qForeachContainerNew(container); \
- qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->condition(); \
- ++qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->i) \
- for (variable = *qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->i; \
- qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->brk; \
- --qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->brk)
-#endif // MSVC6 || MIPSpro
-
-#endif
-
#define Q_FOREVER for(;;)
#ifndef QT_NO_KEYWORDS
# ifndef foreach
@@ -1098,8 +1045,17 @@ template <typename T> struct QEnableIf<true, T> { typedef T Type; };
template <bool B, typename T, typename F> struct QConditional { typedef T Type; };
template <typename T, typename F> struct QConditional<false, T, F> { typedef F Type; };
+
+template <typename T> struct QAddConst { typedef const T Type; };
}
+// this adds const to non-const objects (like std::as_const)
+template <typename T>
+Q_DECL_CONSTEXPR typename QtPrivate::QAddConst<T>::Type &qAsConst(T &t) Q_DECL_NOTHROW { return t; }
+// prevent rvalue arguments:
+template <typename T>
+void qAsConst(const T &&) Q_DECL_EQ_DELETE;
+
QT_END_NAMESPACE
// We need to keep QTypeInfo, QSysInfo, QFlags, qDebug & family in qglobal.h for compatibility with Qt 4.
diff --git a/src/corelib/global/qhooks.cpp b/src/corelib/global/qhooks.cpp
index 382f45f592..40a7c88f13 100644
--- a/src/corelib/global/qhooks.cpp
+++ b/src/corelib/global/qhooks.cpp
@@ -37,7 +37,7 @@ QT_BEGIN_NAMESPACE
// Only add to the end, and bump version if you do.
quintptr Q_CORE_EXPORT qtHookData[] = {
- 2, // hook data version
+ 3, // hook data version
QHooks::LastHookIndex, // size of qtHookData
QT_VERSION,
@@ -52,6 +52,15 @@ quintptr Q_CORE_EXPORT qtHookData[] = {
0,
// Startup, void(*)(), called once QCoreApplication is operational
+ 0,
+
+ // TypeInformationVersion, an integral value, bumped whenever private
+ // object sizes or member offsets that are used in Qt Creator's
+ // data structure "pretty printing" change.
+ //
+ // The required sizes and offsets are tested in tests/auto/other/toolsupport.
+ // When this fails and the change was intentional, adjust the test and
+ // adjust this value here.
0
};
diff --git a/src/corelib/global/qhooks_p.h b/src/corelib/global/qhooks_p.h
index 3ff4980abe..2beb58f8a7 100644
--- a/src/corelib/global/qhooks_p.h
+++ b/src/corelib/global/qhooks_p.h
@@ -61,6 +61,7 @@ enum HookIndex {
AddQObject = 3,
RemoveQObject = 4,
Startup = 5,
+ TypeInformationVersion = 6,
LastHookIndex
};
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 20c31f7ef8..47591a3fa8 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -75,17 +75,13 @@
# include "private/qcore_unix_p.h"
#endif
-#ifndef __has_include
-# define __has_include(x) 0
-#endif
-
#ifndef QT_BOOTSTRAPPED
#if !defined QT_NO_REGULAREXPRESSION
# ifdef __UCLIBC__
# if __UCLIBC_HAS_BACKTRACE__
# define QLOGGING_HAVE_BACKTRACE
# endif
-# elif (defined(__GLIBC__) && defined(__GLIBCXX__)) || (__has_include(<cxxabi.h>) && __has_include(<execinfo.h>))
+# elif (defined(__GLIBC__) && defined(__GLIBCXX__)) || (QT_HAS_INCLUDE(<cxxabi.h>) && QT_HAS_INCLUDE(<execinfo.h>))
# define QLOGGING_HAVE_BACKTRACE
# endif
#endif
@@ -94,7 +90,7 @@
extern char *__progname;
#endif
-#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || __has_include(<sys/syscall.h>))
+#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || QT_HAS_INCLUDE(<sys/syscall.h>))
# include <sys/syscall.h>
static long qt_gettid()
{
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index c4f5415a01..45594d1914 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -482,7 +482,8 @@ public:
AA_DontShowIconsInMenus = 2,
AA_NativeWindows = 3,
AA_DontCreateNativeWidgetSiblings = 4,
- AA_MacPluginApplication = 5,
+ AA_PluginApplication = 5,
+ AA_MacPluginApplication = AA_PluginApplication, // ### Qt 6: remove me
AA_DontUseNativeMenuBar = 6,
AA_MacDontSwapCtrlAndMeta = 7,
AA_Use96Dpi = 8,
@@ -498,6 +499,7 @@ public:
AA_SetPalette = 19,
AA_EnableHighDpiScaling = 20,
AA_DisableHighDpiScaling = 21,
+ AA_UseStyleSheetPropagationInWidgetStyles = 22, // ### Qt 6: remove me
// Add new attributes before this line
AA_AttributeCount
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 7c5263ddbd..1efcce393d 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -120,13 +120,21 @@
widgets stay non-native unless specifically set by the
Qt::WA_NativeWindow attribute.
- \value AA_MacPluginApplication Stops the Qt mac application from doing
- specific initializations that do not necessarily make sense when using Qt
- to author a plugin. This includes avoiding loading our nib for the main
- menu and not taking possession of the native menu bar. When setting this
+ \value AA_PluginApplication Indicates that Qt is used to author a plugin. Depending
+ on the operating system, it suppresses specific initializations that do not
+ necessarily make sense in the plugin case.
+
+ For example on OS X, this includes avoiding loading our nib for the main
+ menu and not taking possession of the native menu bar. Setting this
attribute to true will also set the AA_DontUseNativeMenuBar attribute
to true. It also disables native event filters.
+ This attribute has been added in Qt 5.7. It must be set before
+ \l {QGuiApplication}{Q(Gui)Application} is constructed.
+
+ \value AA_MacPluginApplication This attribute has been deprecated.
+ Use AA_PluginApplication instead.
+
\value AA_DontUseNativeMenuBar All menubars created while this attribute is
set to true won't be used as a native menubar (e.g, the menubar at
the top of the main screen on OS X or at the bottom in Windows CE).
@@ -215,6 +223,13 @@
environment variable to 0. This value has been added in Qt 5.6. This
attribute must be set before Q(Gui)Application is constructed.
+ \value AA_UseStyleSheetPropagationInWidgetStyles By default, Qt Style Sheets
+ disable regular QWidget palette and font propagation. When this flag
+ is enabled, font and palette changes propagate as though the user had
+ manually called the corresponding QWidget methods. See
+ \l{The Style Sheet Syntax#Inheritance}{The Style Sheet Syntax - Inheritance}
+ for more details. This value has been added in Qt 5.7.
+
The following values are obsolete:
\value AA_ImmediateWidgetCreation This attribute is no longer fully
@@ -2094,8 +2109,8 @@
another process or by manually using native code.
\value CoverWindow Indicates that the window represents a cover window,
- which is shown when the application is minimized
- on the BlackBerry platform for instance.
+ which is shown when the application is minimized on
+ some platforms.
There are also a number of flags which you can use to customize
the appearance of top-level windows. These have no effect on other
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index b18d521d05..e1941fcbe0 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -47,7 +47,7 @@
//
#include "QtCore/qglobal.h"
-
+#include <cmath>
#include <limits>
#if defined(Q_CC_MSVC) && !defined(Q_OS_WINCE)
@@ -56,153 +56,112 @@
# include <immintrin.h> // for _addcarry_u<nn>
#endif
-#ifndef __has_builtin
-# define __has_builtin(x) 0
+#if defined(Q_CC_MSVC)
+#include <float.h>
#endif
+#if !defined(Q_CC_MSVC) && (defined(Q_OS_QNX) || !defined(__cplusplus) || __cplusplus < 201103L)
+#include <math.h>
QT_BEGIN_NAMESPACE
-
-#if !defined(Q_CC_MIPS)
-
-static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } };
-static const union { unsigned char c[8]; double d; } qt_le_inf_bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } };
-static inline double qt_inf()
-{
- return (QSysInfo::ByteOrder == QSysInfo::BigEndian
- ? qt_be_inf_bytes.d
- : qt_le_inf_bytes.d);
+namespace qnumeric_std_wrapper {
+// the 'using namespace std' below is cases where the stdlib already put the math.h functions in the std namespace and undefined the macros.
+static inline bool math_h_isnan(double d) { using namespace std; return isnan(d); }
+static inline bool math_h_isinf(double d) { using namespace std; return isinf(d); }
+static inline bool math_h_isfinite(double d) { using namespace std; return isfinite(d); }
+static inline bool math_h_isnan(float f) { using namespace std; return isnan(f); }
+static inline bool math_h_isinf(float f) { using namespace std; return isinf(f); }
+static inline bool math_h_isfinite(float f) { using namespace std; return isfinite(f); }
}
+QT_END_NAMESPACE
+// These macros from math.h conflict with the real functions in the std namespace.
+#undef signbit
+#undef isnan
+#undef isinf
+#undef isfinite
+#endif
-// Signaling NAN
-static const union { unsigned char c[8]; double d; } qt_be_snan_bytes = { { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } };
-static const union { unsigned char c[8]; double d; } qt_le_snan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } };
-static inline double qt_snan()
-{
- return (QSysInfo::ByteOrder == QSysInfo::BigEndian
- ? qt_be_snan_bytes.d
- : qt_le_snan_bytes.d);
-}
+QT_BEGIN_NAMESPACE
-// Quiet NAN
-static const union { unsigned char c[8]; double d; } qt_be_qnan_bytes = { { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 } };
-static const union { unsigned char c[8]; double d; } qt_le_qnan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0xff } };
-static inline double qt_qnan()
-{
- return (QSysInfo::ByteOrder == QSysInfo::BigEndian
- ? qt_be_qnan_bytes.d
- : qt_le_qnan_bytes.d);
+namespace qnumeric_std_wrapper {
+#if defined(Q_CC_MSVC) && _MSC_VER < 1800
+static inline bool isnan(double d) { return !!_isnan(d); }
+static inline bool isinf(double d) { return !_finite(d) && !_isnan(d); }
+static inline bool isfinite(double d) { return !!_finite(d); }
+static inline bool isnan(float f) { return !!_isnan(f); }
+static inline bool isinf(float f) { return !_finite(f) && !_isnan(f); }
+static inline bool isfinite(float f) { return !!_finite(f); }
+#elif !defined(Q_CC_MSVC) && (defined(Q_OS_QNX) || !defined(__cplusplus) || __cplusplus < 201103L)
+static inline bool isnan(double d) { return math_h_isnan(d); }
+static inline bool isinf(double d) { return math_h_isinf(d); }
+static inline bool isfinite(double d) { return math_h_isfinite(d); }
+static inline bool isnan(float f) { return math_h_isnan(f); }
+static inline bool isinf(float f) { return math_h_isinf(f); }
+static inline bool isfinite(float f) { return math_h_isfinite(f); }
+#else
+static inline bool isnan(double d) { return std::isnan(d); }
+static inline bool isinf(double d) { return std::isinf(d); }
+static inline bool isfinite(double d) { return std::isfinite(d); }
+static inline bool isnan(float f) { return std::isnan(f); }
+static inline bool isinf(float f) { return std::isinf(f); }
+static inline bool isfinite(float f) { return std::isfinite(f); }
+#endif
}
-#else // Q_CC_MIPS
-
-static const unsigned char qt_be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
-static const unsigned char qt_le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
-static inline double qt_inf()
+Q_DECL_CONSTEXPR static inline double qt_inf() Q_DECL_NOEXCEPT
{
- const unsigned char *bytes;
- bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
- ? qt_be_inf_bytes
- : qt_le_inf_bytes);
-
- union { unsigned char c[8]; double d; } returnValue;
- memcpy(returnValue.c, bytes, sizeof(returnValue.c));
- return returnValue.d;
+ Q_STATIC_ASSERT_X(std::numeric_limits<double>::has_infinity,
+ "platform has no definition for infinity for type double");
+ return std::numeric_limits<double>::infinity();
}
-// Signaling NAN
-static const unsigned char qt_be_snan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
-static const unsigned char qt_le_snan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
-static inline double qt_snan()
+// Signaling NaN
+Q_DECL_CONSTEXPR static inline double qt_snan() Q_DECL_NOEXCEPT
{
- const unsigned char *bytes;
- bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
- ? qt_be_snan_bytes
- : qt_le_snan_bytes);
-
- union { unsigned char c[8]; double d; } returnValue;
- memcpy(returnValue.c, bytes, sizeof(returnValue.c));
- return returnValue.d;
+ Q_STATIC_ASSERT_X(std::numeric_limits<double>::has_signaling_NaN,
+ "platform has no definition for signaling NaN for type double");
+ return std::numeric_limits<double>::signaling_NaN();
}
-// Quiet NAN
-static const unsigned char qt_be_qnan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 };
-static const unsigned char qt_le_qnan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff };
-static inline double qt_qnan()
+// Quiet NaN
+Q_DECL_CONSTEXPR static inline double qt_qnan() Q_DECL_NOEXCEPT
{
- const unsigned char *bytes;
- bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
- ? qt_be_qnan_bytes
- : qt_le_qnan_bytes);
-
- union { unsigned char c[8]; double d; } returnValue;
- memcpy(returnValue.c, bytes, sizeof(returnValue.c));
- return returnValue.d;
+ Q_STATIC_ASSERT_X(std::numeric_limits<double>::has_quiet_NaN,
+ "platform has no definition for quiet NaN for type double");
+ return std::numeric_limits<double>::quiet_NaN();
}
-#endif // Q_CC_MIPS
-
static inline bool qt_is_inf(double d)
{
- uchar *ch = (uchar *)&d;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- return (ch[0] & 0x7f) == 0x7f && ch[1] == 0xf0;
- } else {
- return (ch[7] & 0x7f) == 0x7f && ch[6] == 0xf0;
- }
+ return qnumeric_std_wrapper::isinf(d);
}
static inline bool qt_is_nan(double d)
{
- uchar *ch = (uchar *)&d;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- return (ch[0] & 0x7f) == 0x7f && ch[1] > 0xf0;
- } else {
- return (ch[7] & 0x7f) == 0x7f && ch[6] > 0xf0;
- }
+ return qnumeric_std_wrapper::isnan(d);
}
static inline bool qt_is_finite(double d)
{
- uchar *ch = (uchar *)&d;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- return (ch[0] & 0x7f) != 0x7f || (ch[1] & 0xf0) != 0xf0;
- } else {
- return (ch[7] & 0x7f) != 0x7f || (ch[6] & 0xf0) != 0xf0;
- }
+ return qnumeric_std_wrapper::isfinite(d);
}
-static inline bool qt_is_inf(float d)
+static inline bool qt_is_inf(float f)
{
- uchar *ch = (uchar *)&d;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- return (ch[0] & 0x7f) == 0x7f && ch[1] == 0x80;
- } else {
- return (ch[3] & 0x7f) == 0x7f && ch[2] == 0x80;
- }
+ return qnumeric_std_wrapper::isinf(f);
}
-static inline bool qt_is_nan(float d)
+static inline bool qt_is_nan(float f)
{
- uchar *ch = (uchar *)&d;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- return (ch[0] & 0x7f) == 0x7f && ch[1] > 0x80;
- } else {
- return (ch[3] & 0x7f) == 0x7f && ch[2] > 0x80;
- }
+ return qnumeric_std_wrapper::isnan(f);
}
-static inline bool qt_is_finite(float d)
+static inline bool qt_is_finite(float f)
{
- uchar *ch = (uchar *)&d;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- return (ch[0] & 0x7f) != 0x7f || (ch[1] & 0x80) != 0x80;
- } else {
- return (ch[3] & 0x7f) != 0x7f || (ch[2] & 0x80) != 0x80;
- }
+ return qnumeric_std_wrapper::isfinite(f);
}
//
-// Overflow math
+// Unsigned overflow math
//
namespace {
template <typename T> inline typename QtPrivate::QEnableIf<QtPrivate::is_unsigned<T>::value, bool>::Type
@@ -230,28 +189,28 @@ mul_overflow(T v1, T v2, T *r)
#endif
// GCC 5 and Clang have builtins to detect overflows
-#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || __has_builtin(__builtin_uadd_overflow)
+#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_uadd_overflow)
template <> inline bool add_overflow(unsigned v1, unsigned v2, unsigned *r)
{ return __builtin_uadd_overflow(v1, v2, r); }
#endif
-#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || __has_builtin(__builtin_uaddl_overflow)
+#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_uaddl_overflow)
template <> inline bool add_overflow(unsigned long v1, unsigned long v2, unsigned long *r)
{ return __builtin_uaddl_overflow(v1, v2, r); }
#endif
-#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || __has_builtin(__builtin_uaddll_overflow)
+#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_uaddll_overflow)
template <> inline bool add_overflow(unsigned long long v1, unsigned long long v2, unsigned long long *r)
{ return __builtin_uaddll_overflow(v1, v2, r); }
#endif
-#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || __has_builtin(__builtin_umul_overflow)
+#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_umul_overflow)
template <> inline bool mul_overflow(unsigned v1, unsigned v2, unsigned *r)
{ return __builtin_umul_overflow(v1, v2, r); }
#endif
-#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || __has_builtin(__builtin_umull_overflow)
+#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_umull_overflow)
template <> inline bool mul_overflow(unsigned long v1, unsigned long v2, unsigned long *r)
{ return __builtin_umull_overflow(v1, v2, r); }
#endif
-#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || __has_builtin(__builtin_umulll_overflow)
+#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_umulll_overflow)
template <> inline bool mul_overflow(unsigned long long v1, unsigned long long v2, unsigned long long *r)
{ return __builtin_umulll_overflow(v1, v2, r); }
# define HAVE_MUL64_OVERFLOW
@@ -303,6 +262,97 @@ template <> inline bool mul_overflow(unsigned long v1, unsigned long v2, unsigne
#else
# undef HAVE_MUL64_OVERFLOW
#endif
+
+//
+// Signed overflow math
+//
+// In C++, signed overflow math is Undefined Behavior. However, many CPUs do implement some way to
+// check for overflow. Some compilers expose intrinsics to use this functionality. If the no
+// intrinsic is exposed, overflow checking can be done by widening the result type and "manually"
+// checking for overflow. Or, alternatively, by using inline assembly to use the CPU features.
+//
+// Only int overflow checking is implemented, because it's the only one used.
+#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_sadd_overflow)
+inline bool add_overflow(int v1, int v2, int *r)
+{ return __builtin_sadd_overflow(v1, v2, r); }
+#elif defined(Q_CC_GNU) && defined(Q_PROCESSOR_X86)
+inline bool add_overflow(int v1, int v2, int *r)
+{
+ quint8 overflow = 0;
+ int res = v1;
+
+ asm ("addl %2, %1\n"
+ "seto %0"
+ : "=q" (overflow), "=r" (res)
+ : "r" (v2), "1" (res)
+ : "cc"
+ );
+ *r = res;
+ return overflow;
+}
+#else
+inline bool add_overflow(int v1, int v2, int *r)
+{
+ qint64 t = qint64(v1) + v2;
+ *r = static_cast<int>(t);
+ return t > std::numeric_limits<int>::max() || t < std::numeric_limits<int>::min();
+}
+#endif
+
+#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_ssub_overflow)
+inline bool sub_overflow(int v1, int v2, int *r)
+{ return __builtin_ssub_overflow(v1, v2, r); }
+#elif defined(Q_CC_GNU) && defined(Q_PROCESSOR_X86)
+inline bool sub_overflow(int v1, int v2, int *r)
+{
+ quint8 overflow = 0;
+ int res = v1;
+
+ asm ("subl %2, %1\n"
+ "seto %0"
+ : "=q" (overflow), "=r" (res)
+ : "r" (v2), "1" (res)
+ : "cc"
+ );
+ *r = res;
+ return overflow;
+}
+#else
+inline bool sub_overflow(int v1, int v2, int *r)
+{
+ qint64 t = qint64(v1) - v2;
+ *r = static_cast<int>(t);
+ return t > std::numeric_limits<int>::max() || t < std::numeric_limits<int>::min();
+}
+#endif
+
+#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_smul_overflow)
+inline bool mul_overflow(int v1, int v2, int *r)
+{ return __builtin_smul_overflow(v1, v2, r); }
+#elif defined(Q_CC_GNU) && defined(Q_PROCESSOR_X86)
+inline bool mul_overflow(int v1, int v2, int *r)
+{
+ quint8 overflow = 0;
+ int res = v1;
+
+ asm ("imul %2, %1\n"
+ "seto %0"
+ : "=q" (overflow), "=r" (res)
+ : "r" (v2), "1" (res)
+ : "cc"
+ );
+ *r = res;
+ return overflow;
+}
+#else
+inline bool mul_overflow(int v1, int v2, int *r)
+{
+ qint64 t = qint64(v1) * v2;
+ *r = static_cast<int>(t);
+ return t > std::numeric_limits<int>::max() || t < std::numeric_limits<int>::min();
+}
+#endif
+
}
QT_END_NAMESPACE
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index f80e9c1535..b490e4a6b0 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -183,11 +183,11 @@
# if defined(_M_IX86)
# define Q_PROCESSOR_X86 (_M_IX86/100)
-# elif defined(__i686__) || defined(__athlon__) || defined(__SSE__)
+# elif defined(__i686__) || defined(__athlon__) || defined(__SSE__) || defined(__pentiumpro__)
# define Q_PROCESSOR_X86 6
-# elif defined(__i586__) || defined(__k6__)
+# elif defined(__i586__) || defined(__k6__) || defined(__pentium__)
# define Q_PROCESSOR_X86 5
-# elif defined(__i486__)
+# elif defined(__i486__) || defined(__80486__)
# define Q_PROCESSOR_X86 4
# else
# define Q_PROCESSOR_X86 3
diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h
index 751c6a9a0e..8a0a4a0a8a 100644
--- a/src/corelib/global/qsystemdetection.h
+++ b/src/corelib/global/qsystemdetection.h
@@ -41,10 +41,11 @@
/*
The operating system, must be one of: (Q_OS_x)
- DARWIN - Any Darwin system
- MAC - OS X and iOS
+ DARWIN - Any Darwin system (OS X, iOS, watchOS, tvOS)
OSX - OS X
IOS - iOS
+ WATCHOS - watchOS
+ TVOS - tvOS
MSDOS - MS-DOS and Windows
OS2 - OS/2
OS2EMX - XFree86 on OS/2 (not PM)
@@ -80,19 +81,37 @@
The following operating systems have variants:
LINUX - both Q_OS_LINUX and Q_OS_ANDROID are defined when building for Android
- only Q_OS_LINUX is defined if building for other Linux systems
- QNX - both Q_OS_QNX and Q_OS_BLACKBERRY are defined when building for Blackberry 10
- - only Q_OS_QNX is defined if building for other QNX targets
FREEBSD - Q_OS_FREEBSD is defined only when building for FreeBSD with a BSD userland
- Q_OS_FREEBSD_KERNEL is always defined on FreeBSD, even if the userland is from GNU
*/
#if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__))
-# define Q_OS_DARWIN
-# define Q_OS_BSD4
-# ifdef __LP64__
-# define Q_OS_DARWIN64
+# include <TargetConditionals.h>
+# if defined(TARGET_OS_MAC) && TARGET_OS_MAC
+# define Q_OS_DARWIN
+# define Q_OS_BSD4
+# ifdef __LP64__
+# define Q_OS_DARWIN64
+# else
+# define Q_OS_DARWIN32
+# endif
+# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+# if defined(TARGET_OS_TV) && TARGET_OS_TV
+# define Q_OS_TVOS
+# elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH
+# define Q_OS_WATCHOS
+# else
+# // TARGET_OS_IOS is only available in newer SDKs,
+# // so assume any other iOS-based platform is iOS for now
+# define Q_OS_IOS
+# endif
+# else
+# // there is no "real" OS X define (rdar://22640089),
+# // assume any non iOS-based platform is OS X for now
+# define Q_OS_OSX
+# endif
# else
-# define Q_OS_DARWIN32
+# error "Qt has not been ported to this Apple platform - see http://www.qt.io/developers"
# endif
#elif defined(__ANDROID__) || defined(ANDROID)
# define Q_OS_ANDROID
@@ -181,28 +200,26 @@
# define Q_OS_WIN
#endif
-#if defined(Q_OS_DARWIN)
-# define Q_OS_MAC
-# if defined(Q_OS_DARWIN64)
-# define Q_OS_MAC64
-# elif defined(Q_OS_DARWIN32)
-# define Q_OS_MAC32
-# endif
-# include <TargetConditionals.h>
-# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
-# define Q_OS_IOS
-# elif defined(TARGET_OS_MAC) && TARGET_OS_MAC
-# define Q_OS_OSX
-# define Q_OS_MACX // compatibility synonym
-# endif
-#endif
-
#if defined(Q_OS_WIN)
# undef Q_OS_UNIX
#elif !defined(Q_OS_UNIX)
# define Q_OS_UNIX
#endif
+// Compatibility synonyms
+#ifdef Q_OS_DARWIN
+#define Q_OS_MAC
+#endif
+#ifdef Q_OS_DARWIN32
+#define Q_OS_MAC32
+#endif
+#ifdef Q_OS_DARWIN64
+#define Q_OS_MAC64
+#endif
+#ifdef Q_OS_OSX
+#define Q_OS_MACX
+#endif
+
#ifdef Q_OS_DARWIN
# include <Availability.h>
# include <AvailabilityMacros.h>
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index b42e5998fc..cd0a83ae80 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -276,13 +276,25 @@ Q_DECLARE_TYPEINFO(double, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(long double, Q_PRIMITIVE_TYPE);
#endif
+
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
-// We can't do it now because it would break BC on QList<char32_t>
+// ### Qt 6: remove the other branch
+// This was required so that QList<T> for these types allocates out of the array storage
+# ifdef Q_COMPILER_UNICODE_STRINGS
Q_DECLARE_TYPEINFO(char16_t, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(char32_t, Q_PRIMITIVE_TYPE);
+# endif
# if !defined(Q_CC_MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
Q_DECLARE_TYPEINFO(wchar_t, Q_PRIMITIVE_TYPE);
# endif
+#else
+# ifdef Q_COMPILER_UNICODE_STRINGS
+Q_DECLARE_TYPEINFO(char16_t, Q_RELOCATABLE_TYPE);
+Q_DECLARE_TYPEINFO(char32_t, Q_RELOCATABLE_TYPE);
+# endif
+# if !defined(Q_CC_MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+Q_DECLARE_TYPEINFO(wchar_t, Q_RELOCATABLE_TYPE);
+# endif
#endif // Qt 6
QT_END_NAMESPACE
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index b2bcbdf727..218fb5b078 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -149,25 +149,15 @@ win32 {
}
freebsd: LIBS_PRIVATE += -lutil # qlockfile_unix.cpp requires this
mac {
+ SOURCES += io/qstorageinfo_mac.cpp
+ OBJECTIVE_SOURCES += io/qstandardpaths_mac.mm
osx {
OBJECTIVE_SOURCES += io/qfilesystemwatcher_fsevents.mm
HEADERS += io/qfilesystemwatcher_fsevents_p.h
- }
- macx {
- SOURCES += io/qstorageinfo_mac.cpp
- OBJECTIVE_SOURCES += io/qstandardpaths_mac.mm
LIBS += -framework DiskArbitration -framework IOKit
} else:ios {
- OBJECTIVE_SOURCES += io/qstandardpaths_ios.mm
- SOURCES += io/qstorageinfo_mac.cpp
LIBS += -framework MobileCoreServices
- } else {
- SOURCES += io/qstandardpaths_unix.cpp
}
- } else:blackberry {
- SOURCES += \
- io/qstandardpaths_blackberry.cpp \
- io/qstorageinfo_unix.cpp
} else:android:!android-no-sdk {
SOURCES += \
io/qstandardpaths_android.cpp \
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index 675178ea80..c32df4c8a6 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -527,6 +527,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_4 Version 16 (Qt 5.4)
\value Qt_5_5 Same as Qt_5_4
\value Qt_5_6 Version 17 (Qt 5.6)
+ \value Qt_5_7 Same as Qt_5_6
\omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index 5730c12907..744829c659 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -84,10 +84,11 @@ public:
Qt_5_4 = 16,
Qt_5_5 = Qt_5_4,
Qt_5_6 = 17,
-#if QT_VERSION >= 0x050700
+ Qt_5_7 = Qt_5_6,
+#if QT_VERSION >= 0x050800
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
- Qt_DefaultCompiledVersion = Qt_5_6
+ Qt_DefaultCompiledVersion = Qt_5_7
};
enum ByteOrder {
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 81af96b96b..4f85ceb084 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -704,6 +704,15 @@ QDebug &QDebug::resetFormat()
*/
/*!
+ \fn QDebug operator<<(QDebug stream, const std::list<T, Alloc> &list)
+ \relates QDebug
+ \since 5.7
+
+ Writes the contents of \a list to \a stream. \c T needs to
+ support streaming into QDebug.
+*/
+
+/*!
\fn QDebug operator<<(QDebug stream, const QVector<T> &vector)
\relates QDebug
@@ -712,6 +721,15 @@ QDebug &QDebug::resetFormat()
*/
/*!
+ \fn QDebug operator<<(QDebug stream, const std::vector<T, Alloc> &vector)
+ \relates QDebug
+ \since 5.7
+
+ Writes the contents of \a vector to \a stream. \c T needs to
+ support streaming into QDebug.
+*/
+
+/*!
\fn QDebug operator<<(QDebug stream, const QSet<T> &set)
\relates QDebug
@@ -728,6 +746,24 @@ QDebug &QDebug::resetFormat()
*/
/*!
+ \fn QDebug operator<<(QDebug stream, const std::map<Key, T, Compare, Alloc> &map)
+ \relates QDebug
+ \since 5.7
+
+ Writes the contents of \a map to \a stream. Both \c Key and
+ \c T need to support streaming into QDebug.
+*/
+
+/*!
+ \fn QDebug operator<<(QDebug stream, const std::multimap<Key, T, Compare, Alloc> &map)
+ \relates QDebug
+ \since 5.7
+
+ Writes the contents of \a map to \a stream. Both \c Key and
+ \c T need to support streaming into QDebug.
+*/
+
+/*!
\fn QDebug operator<<(QDebug stream, const QHash<Key, T> &hash)
\relates QDebug
@@ -831,6 +867,19 @@ QDebugStateSaver::~QDebugStateSaver()
d->restoreState();
}
+/*!
+ \internal
+
+ Specialization of the primary template in qdebug.h to out-of-line
+ the common case of QFlags<T>::Int being int.
+
+ Just call the generic version so the two don't get out of sync.
+*/
+void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, int value)
+{
+ qt_QMetaEnum_flagDebugOperator<int>(debug, sizeofT, value);
+}
+
#ifndef QT_NO_QOBJECT
/*!
\internal
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index b1a0396f35..858231e118 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -45,6 +45,12 @@
#include <QtCore/qset.h>
#include <QtCore/qcontiguouscache.h>
+// all these have already been included by various headers above, but don't rely on indirect includes:
+#include <vector>
+#include <list>
+#include <map>
+#include <utility>
+
QT_BEGIN_NAMESPACE
@@ -192,28 +198,63 @@ inline QDebug &QDebug::operator=(const QDebug &other)
return *this;
}
-template <class T>
-inline QDebug operator<<(QDebug debug, const QList<T> &list)
+namespace QtPrivate {
+
+template <typename SequentialContainer>
+inline QDebug printSequentialContainer(QDebug debug, const char *which, const SequentialContainer &c)
{
const bool oldSetting = debug.autoInsertSpaces();
- debug.nospace() << '(';
- for (typename QList<T>::size_type i = 0; i < list.count(); ++i) {
- if (i)
- debug << ", ";
- debug << list.at(i);
+ debug.nospace() << which << '(';
+ typename SequentialContainer::const_iterator it = c.begin(), end = c.end();
+ if (it != end) {
+ debug << *it;
+ ++it;
+ }
+ while (it != end) {
+ debug << ", " << *it;
+ ++it;
}
debug << ')';
debug.setAutoInsertSpaces(oldSetting);
return debug.maybeSpace();
}
+} // namespace QtPrivate
+
+template <class T>
+inline QDebug operator<<(QDebug debug, const QList<T> &list)
+{
+ return QtPrivate::printSequentialContainer(debug, "" /*for historical reasons*/, list);
+}
+
template <typename T>
inline QDebug operator<<(QDebug debug, const QVector<T> &vec)
{
- const bool oldSetting = debug.autoInsertSpaces();
- debug.nospace() << "QVector";
- debug.setAutoInsertSpaces(oldSetting);
- return operator<<(debug, vec.toList());
+ return QtPrivate::printSequentialContainer(debug, "QVector", vec);
+}
+
+template <typename T, typename Alloc>
+inline QDebug operator<<(QDebug debug, const std::vector<T, Alloc> &vec)
+{
+ return QtPrivate::printSequentialContainer(debug, "std::vector", vec);
+}
+
+template <typename T, typename Alloc>
+inline QDebug operator<<(QDebug debug, const std::list<T, Alloc> &vec)
+{
+ return QtPrivate::printSequentialContainer(debug, "std::list", vec);
+}
+
+template <typename Key, typename T, typename Compare, typename Alloc>
+inline QDebug operator<<(QDebug debug, const std::map<Key, T, Compare, Alloc> &map)
+{
+ return QtPrivate::printSequentialContainer(debug, "std::map", map); // yes, sequential: *it is std::pair
+}
+
+template <typename Key, typename T, typename Compare, typename Alloc>
+inline QDebug operator<<(QDebug debug, const std::multimap<Key, T, Compare, Alloc> &map)
+{
+ return QtPrivate::printSequentialContainer(debug, "std::multimap", map); // yes, sequential: *it is std::pair
}
template <class Key, class T>
@@ -252,13 +293,19 @@ inline QDebug operator<<(QDebug debug, const QPair<T1, T2> &pair)
return debug.maybeSpace();
}
-template <typename T>
-inline QDebug operator<<(QDebug debug, const QSet<T> &set)
+template <class T1, class T2>
+inline QDebug operator<<(QDebug debug, const std::pair<T1, T2> &pair)
{
const bool oldSetting = debug.autoInsertSpaces();
- debug.nospace() << "QSet";
+ debug.nospace() << "std::pair(" << pair.first << ',' << pair.second << ')';
debug.setAutoInsertSpaces(oldSetting);
- return operator<<(debug, set.toList());
+ return debug.maybeSpace();
+}
+
+template <typename T>
+inline QDebug operator<<(QDebug debug, const QSet<T> &set)
+{
+ return QtPrivate::printSequentialContainer(debug, "QSet", set);
}
template <class T>
@@ -276,6 +323,27 @@ inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
return debug.maybeSpace();
}
+Q_CORE_EXPORT void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, int value);
+
+template <typename Int>
+void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, Int value)
+{
+ const QDebugStateSaver saver(debug);
+ debug.resetFormat();
+ debug.nospace() << "QFlags(" << hex << showbase;
+ bool needSeparator = false;
+ for (uint i = 0; i < sizeofT * 8; ++i) {
+ if (value & (Int(1) << i)) {
+ if (needSeparator)
+ debug << '|';
+ else
+ needSeparator = true;
+ debug << (Int(1) << i);
+ }
+ }
+ debug << ')';
+}
+
#if !defined(QT_NO_QOBJECT) && !defined(Q_QDOC)
Q_CORE_EXPORT QDebug qt_QMetaEnum_debugOperator(QDebug&, int value, const QMetaObject *meta, const char *name);
Q_CORE_EXPORT QDebug qt_QMetaEnum_flagDebugOperator(QDebug &dbg, quint64 value, const QMetaObject *meta, const char *name);
@@ -310,20 +378,7 @@ template <class T>
inline QDebug qt_QMetaEnum_flagDebugOperator_helper(QDebug debug, const QFlags<T> &flags)
#endif
{
- QDebugStateSaver saver(debug);
- debug.resetFormat();
- debug.nospace() << "QFlags(" << hex << showbase;
- bool needSeparator = false;
- for (uint i = 0; i < sizeof(T) * 8; ++i) {
- if (flags.testFlag(T(1 << i))) {
- if (needSeparator)
- debug << '|';
- else
- needSeparator = true;
- debug << (typename QFlags<T>::Int(1) << i);
- }
- }
- debug << ')';
+ qt_QMetaEnum_flagDebugOperator(debug, sizeof(T), typename QFlags<T>::Int(flags));
return debug;
}
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index ce1684a943..2f3525bbdb 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -232,7 +232,7 @@ QFile::QFile(QFilePrivate &dd)
}
#else
/*!
- \internal
+ Constructs a QFile object.
*/
QFile::QFile()
: QFileDevice(*new QFilePrivate, 0)
diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp
index 85d9b0bfcb..83bfe47ab1 100644
--- a/src/corelib/io/qfileselector.cpp
+++ b/src/corelib/io/qfileselector.cpp
@@ -92,8 +92,6 @@ QFileSelectorPrivate::QFileSelectorPrivate()
QString defaultsPath = "data/defaults.conf";
#if defined(Q_OS_ANDROID)
defaultsPath = "data/android/defaults.conf";
-#elif defined(Q_OS_BLACKBERRY)
- defaultsPath = "data/blackberry/defaults.conf";
#elif defined(Q_OS_IOS)
defaultsPath = "data/ios/defaults.conf";
#endif
@@ -116,7 +114,6 @@ QFileSelectorPrivate::QFileSelectorPrivate()
\code
data/defaults.conf
data/+android/defaults.conf
- data/+blackberry/defaults.conf
data/+ios/+en_GB/defaults.conf
\endcode
@@ -127,9 +124,8 @@ QFileSelectorPrivate::QFileSelectorPrivate()
\code
images/background.png
images/+android/+en_GB/background.png
- images/+blackberry/+en_GB/background.png
\endcode
- With those files available, you would select a different file on android and blackberry platforms,
+ With those files available, you would select a different file on the android platform,
but only if the locale was en_GB.
QFileSelector will not attempt to select if the base file does not exist. For error handling in
@@ -145,8 +141,8 @@ QFileSelectorPrivate::QFileSelectorPrivate()
Selectors normally available are
\list
\li platform, any of the following strings which match the platform the application is running
- on (list not exhaustive): android, blackberry, ios, osx, darwin, mac, linux, wince, unix,
- windows. On Linux, if it can be determined, the name of the distribution too, like debian,
+ on (list not exhaustive): android, ios, osx, darwin, mac, linux, wince, unix, windows.
+ On Linux, if it can be determined, the name of the distribution too, like debian,
fedora or opensuse.
\li locale, same as QLocale().name().
\endlist
@@ -265,7 +261,7 @@ static QString selectionHelper(const QString &path, const QString &fileName, con
*/
Q_ASSERT(path.isEmpty() || path.endsWith(QLatin1Char('/')));
- foreach (const QString &s, selectors) {
+ for (const QString &s : selectors) {
QString prospectiveBase = path + QLatin1Char(selectorIndicator) + s + QLatin1Char('/');
QStringList remainingSelectors = selectors;
remainingSelectors.removeAll(s);
@@ -368,8 +364,8 @@ QStringList QFileSelectorPrivate::platformSelectors()
# endif
#elif defined(Q_OS_UNIX)
ret << QStringLiteral("unix");
-# if !defined(Q_OS_ANDROID) && !defined(Q_OS_BLACKBERRY)
- // we don't want "linux" for Android or "qnx" for Blackberry here
+# if !defined(Q_OS_ANDROID)
+ // we don't want "linux" for Android
ret << QSysInfo::kernelType();
# ifdef Q_OS_MAC
ret << QStringLiteral("mac"); // compatibility, since kernelType() is "darwin"
@@ -377,7 +373,7 @@ QStringList QFileSelectorPrivate::platformSelectors()
# endif
QString productName = QSysInfo::productType();
if (productName != QLatin1String("unknown"))
- ret << productName; // "opensuse", "fedora", "osx", "ios", "blackberry", "android"
+ ret << productName; // "opensuse", "fedora", "osx", "ios", "android"
#endif
return ret;
}
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 7bc2293b0d..8f6d9911e8 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -345,17 +345,17 @@ QString QFileSystemEngine::resolveUserName(uint userId)
QVarLengthArray<char, 1024> buf(size_max);
#endif
- struct passwd *pw = 0;
#if !defined(Q_OS_INTEGRITY)
+ struct passwd *pw = 0;
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS)
struct passwd entry;
getpwuid_r(userId, &entry, buf.data(), buf.size(), &pw);
#else
pw = getpwuid(userId);
#endif
-#endif
if (pw)
return QFile::decodeName(QByteArray(pw->pw_name));
+#endif
return QString();
}
@@ -369,8 +369,8 @@ QString QFileSystemEngine::resolveGroupName(uint groupId)
QVarLengthArray<char, 1024> buf(size_max);
#endif
- struct group *gr = 0;
#if !defined(Q_OS_INTEGRITY)
+ struct group *gr = 0;
#if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_VXWORKS)
size_max = sysconf(_SC_GETGR_R_SIZE_MAX);
if (size_max == -1)
@@ -390,9 +390,9 @@ QString QFileSystemEngine::resolveGroupName(uint groupId)
#else
gr = getgrgid(groupId);
#endif
-#endif
if (gr)
return QFile::decodeName(QByteArray(gr->gr_name));
+#endif
return QString();
}
@@ -694,16 +694,6 @@ QString QFileSystemEngine::tempPath()
{
#ifdef QT_UNIX_TEMP_PATH_OVERRIDE
return QLatin1String(QT_UNIX_TEMP_PATH_OVERRIDE);
-#elif defined(Q_OS_BLACKBERRY)
- QString temp = QFile::decodeName(qgetenv("TEMP"));
- if (temp.isEmpty())
- temp = QFile::decodeName(qgetenv("TMPDIR"));
-
- if (temp.isEmpty()) {
- qWarning("Neither the TEMP nor the TMPDIR environment variable is set, falling back to /var/tmp.");
- temp = QLatin1String("/var/tmp");
- }
- return QDir::cleanPath(temp);
#else
QString temp = QFile::decodeName(qgetenv("TMPDIR"));
if (temp.isEmpty())
diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp
index 709970e3ac..2dc534d356 100644
--- a/src/corelib/io/qfilesystementry.cpp
+++ b/src/corelib/io/qfilesystementry.cpp
@@ -372,7 +372,7 @@ bool QFileSystemEntry::isClean() const
int dots = 0;
bool dotok = true; // checking for ".." or "." starts to relative paths
bool slashok = true;
- for (QString::const_iterator iter = m_filePath.constBegin(); iter != m_filePath.constEnd(); iter++) {
+ for (QString::const_iterator iter = m_filePath.constBegin(); iter != m_filePath.constEnd(); ++iter) {
if (*iter == QLatin1Char('/')) {
if (dots == 1 || dots == 2)
return false; // path contains "./" or "../"
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index 8bc06cfcbe..3847e70a1c 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -37,6 +37,7 @@
#ifndef QT_NO_FILESYSTEMWATCHER
#include "private/qcore_unix_p.h"
+#include "private/qsystemerror_p.h"
#include <qdebug.h>
#include <qfile.h>
@@ -245,7 +246,7 @@ QInotifyFileSystemWatcherEngine::QInotifyFileSystemWatcherEngine(int fd, QObject
QInotifyFileSystemWatcherEngine::~QInotifyFileSystemWatcherEngine()
{
notifier.setEnabled(false);
- foreach (int id, pathToID)
+ for (int id : qAsConst(pathToID))
inotify_rm_watch(inotifyFd, id < 0 ? -id : id);
::close(inotifyFd);
@@ -287,7 +288,7 @@ QStringList QInotifyFileSystemWatcherEngine::addPaths(const QStringList &paths,
| IN_DELETE_SELF
)));
if (wd < 0) {
- perror("QInotifyFileSystemWatcherEngine::addPaths: inotify_add_watch failed");
+ qWarning().nospace() << "inotify_add_watch(" << path << ") failed: " << QSystemError(errno, QSystemError::NativeError).toString();
continue;
}
diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp
index 80cbcb26cc..43e1719a13 100644
--- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp
+++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp
@@ -82,7 +82,7 @@ QKqueueFileSystemWatcherEngine::~QKqueueFileSystemWatcherEngine()
notifier.setEnabled(false);
close(kqfd);
- foreach (int id, pathToID)
+ for (int id : qAsConst(pathToID))
::close(id < 0 ? -id : id);
}
diff --git a/src/corelib/io/qfilesystemwatcher_win.cpp b/src/corelib/io/qfilesystemwatcher_win.cpp
index 410753868e..6c263b6847 100644
--- a/src/corelib/io/qfilesystemwatcher_win.cpp
+++ b/src/corelib/io/qfilesystemwatcher_win.cpp
@@ -62,11 +62,11 @@ QWindowsFileSystemWatcherEngine::Handle::Handle()
QWindowsFileSystemWatcherEngine::~QWindowsFileSystemWatcherEngine()
{
- foreach(QWindowsFileSystemWatcherEngineThread *thread, threads) {
+ for (auto *thread : qAsConst(threads))
thread->stop();
+ for (auto *thread : qAsConst(threads))
thread->wait();
- delete thread;
- }
+ qDeleteAll(threads);
}
QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
@@ -164,7 +164,7 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
// now look for a thread to insert
bool found = false;
- foreach(QWindowsFileSystemWatcherEngineThread *thread, threads) {
+ for (QWindowsFileSystemWatcherEngineThread *thread : qAsConst(threads)) {
QMutexLocker(&(thread->mutex));
if (thread->handles.count() < MAXIMUM_WAIT_OBJECTS) {
DEBUG() << "Added handle" << handle.handle << "for" << absolutePath << "to watch" << fileInfo.absoluteFilePath()
@@ -311,7 +311,7 @@ QWindowsFileSystemWatcherEngineThread::~QWindowsFileSystemWatcherEngineThread()
CloseHandle(handles.at(0));
handles[0] = INVALID_HANDLE_VALUE;
- foreach (HANDLE h, handles) {
+ for (HANDLE h : qAsConst(handles)) {
if (h == INVALID_HANDLE_VALUE)
continue;
FindCloseChangeNotification(h);
@@ -323,7 +323,7 @@ static inline QString msgFindNextFailed(const QWindowsFileSystemWatcherEngineThr
QString result;
QTextStream str(&result);
str << "QFileSystemWatcher: FindNextChangeNotification failed for";
- foreach (const QWindowsFileSystemWatcherEngine::PathInfo &pathInfo, pathInfos)
+ for (const QWindowsFileSystemWatcherEngine::PathInfo &pathInfo : pathInfos)
str << " \"" << QDir::toNativeSeparators(pathInfo.absolutePath) << '"';
str << ' ';
return result;
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 3c7a7d69e4..64078b5c54 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -670,7 +670,7 @@ bool QIODevice::seek(qint64 pos)
// operation will then refill the buffer. We can optimize this, if we
// find that seeking backwards becomes a significant performance hit.
d->buffer.clear();
- else if (!d->buffer.isEmpty())
+ else
d->buffer.skip(offset);
#if defined QIODEVICE_DEBUG
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index 365f3e07ab..ae776d4137 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -44,7 +44,10 @@
#include "private/qabstractfileengine_p.h"
#include "private/qtemporaryfile_p.h"
+#if !defined(Q_OS_INTEGRITY)
#include <sys/file.h> // flock
+#endif
+
#include <sys/types.h> // kill
#include <signal.h> // kill
#include <unistd.h> // gethostname
@@ -54,6 +57,8 @@
#elif defined(Q_OS_LINUX)
# include <unistd.h>
# include <cstdio>
+#elif defined(Q_OS_HAIKU)
+# include <kernel/OS.h>
#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS)
# include <sys/user.h>
# if defined(__GLIBC__) && defined(__FreeBSD_kernel__)
@@ -248,6 +253,11 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
}
buf[len] = 0;
return QFileInfo(QFile::decodeName(buf)).fileName();
+#elif defined(Q_OS_HAIKU)
+ thread_info info;
+ if (get_thread_info(pid, &info) != B_OK)
+ return QString();
+ return QFile::decodeName(info.name);
#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS)
# if defined(__GLIBC__) && defined(__FreeBSD_kernel__)
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index b53e251102..3e6e61b906 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -364,8 +364,8 @@ void QLoggingRegistry::updateRules()
rules = qtConfigRules + configRules + apiRules + envRules;
- foreach (QLoggingCategory *cat, categories.keys())
- (*categoryFilter)(cat);
+ for (auto it = categories.keyBegin(), end = categories.keyEnd(); it != end; ++it)
+ (*categoryFilter)(*it);
}
/*!
@@ -383,8 +383,8 @@ QLoggingRegistry::installFilter(QLoggingCategory::CategoryFilter filter)
QLoggingCategory::CategoryFilter old = categoryFilter;
categoryFilter = filter;
- foreach (QLoggingCategory *cat, categories.keys())
- (*categoryFilter)(cat);
+ for (auto it = categories.keyBegin(), end = categories.keyEnd(); it != end; ++it)
+ (*categoryFilter)(*it);
return old;
}
@@ -400,7 +400,7 @@ QLoggingRegistry *QLoggingRegistry::instance()
*/
void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
{
- QLoggingRegistry *reg = QLoggingRegistry::instance();
+ const QLoggingRegistry *reg = QLoggingRegistry::instance();
Q_ASSERT(reg->categories.contains(cat));
QtMsgType enableForLevel = reg->categories.value(cat);
@@ -421,7 +421,7 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
}
QString categoryName = QLatin1String(cat->categoryName());
- foreach (const QLoggingRule &item, reg->rules) {
+ for (const QLoggingRule &item : reg->rules) {
int filterpass = item.pass(categoryName, QtDebugMsg);
if (filterpass != 0)
debug = (filterpass > 0);
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 952116b9db..823dc4c144 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -744,6 +744,47 @@ void QProcessPrivate::Channel::clear()
*/
/*!
+ \typedef QProcess::CreateProcessArgumentModifier
+ \note This typedef is only available on desktop Windows and Windows CE.
+
+ On Windows, QProcess uses the Win32 API function \c CreateProcess to
+ start child processes. While QProcess provides a comfortable way to start
+ processes without worrying about platform
+ details, it is in some cases desirable to fine-tune the parameters that are
+ passed to \c CreateProcess. This is done by defining a
+ \c CreateProcessArgumentModifier function and passing it to
+ \c setCreateProcessArgumentsModifier.
+
+ A \c CreateProcessArgumentModifier function takes one parameter: a pointer
+ to a \c CreateProcessArguments struct. The members of this struct will be
+ passed to \c CreateProcess after the \c CreateProcessArgumentModifier
+ function is called.
+
+ The following example demonstrates how to pass custom flags to
+ \c CreateProcess.
+ When starting a console process B from a console process A, QProcess will
+ reuse the console window of process A for process B by default. In this
+ example, a new console window with a custom color scheme is created for the
+ child process B instead.
+
+ \snippet qprocess/qprocess-createprocessargumentsmodifier.cpp 0
+
+ \sa QProcess::CreateProcessArguments
+ \sa setCreateProcessArgumentsModifier()
+*/
+
+/*!
+ \class QProcess::CreateProcessArguments
+ \note This struct is only available on the Windows platform.
+
+ This struct is a representation of all parameters of the Windows API
+ function \c CreateProcess. It is used as parameter for
+ \c CreateProcessArgumentModifier functions.
+
+ \sa QProcess::CreateProcessArgumentModifier
+*/
+
+/*!
\fn void QProcess::error(QProcess::ProcessError error)
\obsolete
@@ -833,7 +874,6 @@ QProcessPrivate::QProcessPrivate()
childStartedPipe[0] = INVALID_Q_PIPE;
childStartedPipe[1] = INVALID_Q_PIPE;
forkfd = -1;
- exitCode = 0;
crashed = false;
dying = false;
emittedReadyRead = false;
@@ -1563,6 +1603,39 @@ void QProcess::setNativeArguments(const QString &arguments)
d->nativeArguments = arguments;
}
+/*!
+ \since 5.7
+
+ Returns a previously set \c CreateProcess modifier function.
+
+ \note This function is available only on the Windows platform.
+
+ \sa setCreateProcessArgumentsModifier()
+ \sa QProcess::CreateProcessArgumentModifier
+*/
+QProcess::CreateProcessArgumentModifier QProcess::createProcessArgumentsModifier() const
+{
+ Q_D(const QProcess);
+ return d->modifyCreateProcessArgs;
+}
+
+/*!
+ \since 5.7
+
+ Sets the \a modifier for the \c CreateProcess Win32 API call.
+ Pass \c QProcess::CreateProcessArgumentModifier() to remove a previously set one.
+
+ \note This function is available only on the Windows platform and requires
+ C++11.
+
+ \sa QProcess::CreateProcessArgumentModifier
+*/
+void QProcess::setCreateProcessArgumentsModifier(CreateProcessArgumentModifier modifier)
+{
+ Q_D(QProcess);
+ d->modifyCreateProcessArgs = modifier;
+}
+
#endif
/*!
diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h
index f95358250e..52e0316857 100644
--- a/src/corelib/io/qprocess.h
+++ b/src/corelib/io/qprocess.h
@@ -38,6 +38,8 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qshareddata.h>
+#include <functional>
+
QT_BEGIN_NAMESPACE
@@ -48,6 +50,8 @@ typedef qint64 Q_PID;
#else
QT_END_NAMESPACE
typedef struct _PROCESS_INFORMATION *Q_PID;
+typedef struct _SECURITY_ATTRIBUTES Q_SECURITY_ATTRIBUTES;
+typedef struct _STARTUPINFOW Q_STARTUPINFO;
QT_BEGIN_NAMESPACE
#endif
@@ -180,7 +184,23 @@ public:
#if defined(Q_OS_WIN)
QString nativeArguments() const;
void setNativeArguments(const QString &arguments);
-#endif
+ struct CreateProcessArguments
+ {
+ const wchar_t *applicationName;
+ wchar_t *arguments;
+ Q_SECURITY_ATTRIBUTES *processAttributes;
+ Q_SECURITY_ATTRIBUTES *threadAttributes;
+ bool inheritHandles;
+ unsigned long flags;
+ void *environment;
+ const wchar_t *currentDirectory;
+ Q_STARTUPINFO *startupInfo;
+ Q_PID processInformation;
+ };
+ typedef std::function<void(CreateProcessArguments *)> CreateProcessArgumentModifier;
+ CreateProcessArgumentModifier createProcessArgumentsModifier() const;
+ void setCreateProcessArgumentsModifier(CreateProcessArgumentModifier modifier);
+#endif // Q_OS_WIN
QString workingDirectory() const;
void setWorkingDirectory(const QString &dir);
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index d3f251c399..227a583718 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -329,6 +329,7 @@ public:
QStringList arguments;
#if defined(Q_OS_WIN)
QString nativeArguments;
+ QProcess::CreateProcessArgumentModifier modifyCreateProcessArgs;
#endif
QProcessEnvironment environment;
@@ -385,11 +386,6 @@ public:
void cleanup();
void setError(QProcess::ProcessError error, const QString &description = QString());
void setErrorAndEmit(QProcess::ProcessError error, const QString &description = QString());
-
-#ifdef Q_OS_BLACKBERRY
- QList<QSocketNotifier *> defaultNotifiers() const;
-#endif // Q_OS_BLACKBERRY
-
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 8eb5ac9564..ab5734a298 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -564,7 +564,7 @@ static int doSpawn(pid_t *ppid, const posix_spawn_file_actions_t *file_actions,
qWarning("ThreadCtl(): failed to chdir to %s", oldWorkingDir);
# ifdef Q_OS_QNX
- if (ThreadCtl(_NTO_TCTL_THREADS_CONT, 0) == -1)
+ if (Q_UNLIKELY(ThreadCtl(_NTO_TCTL_THREADS_CONT, 0) == -1))
qFatal("ThreadCtl(): cannot resume threads: %s", qPrintable(qt_error_string(errno)));
# endif
}
@@ -676,6 +676,7 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv
qt_safe_close(childStartedPipe[0]);
// enter the working directory
+ const char *callthatfailed = "chdir: ";
if (workingDir && QT_CHDIR(workingDir) == -1) {
// failed, stop the process
goto report_errno;
@@ -687,6 +688,7 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv
// execute the process
if (!envp) {
qt_safe_execvp(argv[0], argv);
+ callthatfailed = "execvp: ";
} else {
if (path) {
char **arg = path;
@@ -704,15 +706,19 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv
#endif
qt_safe_execve(argv[0], argv, envp);
}
+ callthatfailed = "execve: ";
}
// notify failure
+ // we're running in the child process, so we don't need to be thread-safe;
+ // we can use strerror
report_errno:
- QString error = qt_error_string(errno);
+ const char *msg = strerror(errno);
#if defined (QPROCESS_DEBUG)
- fprintf(stderr, "QProcessPrivate::execChild() failed (%s), notifying parent process\n", qPrintable(error));
+ fprintf(stderr, "QProcessPrivate::execChild() failed (%s), notifying parent process\n", msg);
#endif
- qt_safe_write(childStartedPipe[1], error.data(), error.length() * sizeof(QChar));
+ qt_safe_write(childStartedPipe[1], callthatfailed, strlen(callthatfailed));
+ qt_safe_write(childStartedPipe[1], msg, strlen(msg));
qt_safe_close(childStartedPipe[1]);
childStartedPipe[1] = -1;
}
@@ -720,8 +726,15 @@ report_errno:
bool QProcessPrivate::processStarted(QString *errorMessage)
{
- ushort buf[errorBufferMax];
- int i = qt_safe_read(childStartedPipe[0], &buf, sizeof buf);
+ char buf[errorBufferMax];
+ int i = 0;
+ int ret;
+ do {
+ ret = qt_safe_read(childStartedPipe[0], buf + i, sizeof buf - i);
+ if (ret > 0)
+ i += ret;
+ } while (ret > 0 && i < int(sizeof buf));
+
if (startupSocketNotifier) {
startupSocketNotifier->setEnabled(false);
startupSocketNotifier->deleteLater();
@@ -736,7 +749,7 @@ bool QProcessPrivate::processStarted(QString *errorMessage)
// did we read an error message?
if ((i > 0) && errorMessage)
- *errorMessage = QString((const QChar *)buf, i / sizeof(QChar));
+ *errorMessage = QString::fromLocal8Bit(buf, i);
return i <= 0;
}
@@ -830,17 +843,6 @@ bool QProcessPrivate::waitForStarted(int msecs)
return startedEmitted;
}
-#ifdef Q_OS_BLACKBERRY
-QList<QSocketNotifier *> QProcessPrivate::defaultNotifiers() const
-{
- QList<QSocketNotifier *> notifiers;
- notifiers << stdoutChannel.notifier
- << stderrChannel.notifier
- << stdinChannel.notifier;
- return notifiers;
-}
-#endif // Q_OS_BLACKBERRY
-
bool QProcessPrivate::waitForReadyRead(int msecs)
{
#if defined (QPROCESS_DEBUG)
@@ -850,10 +852,6 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
QElapsedTimer stopWatch;
stopWatch.start();
-#ifdef Q_OS_BLACKBERRY
- QList<QSocketNotifier *> notifiers = defaultNotifiers();
-#endif
-
forever {
fd_set fdread;
fd_set fdwrite;
@@ -876,11 +874,8 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
-#ifdef Q_OS_BLACKBERRY
- int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout);
-#else
int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
-#endif
+
if (ret < 0) {
break;
}
@@ -928,10 +923,6 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
QElapsedTimer stopWatch;
stopWatch.start();
-#ifdef Q_OS_BLACKBERRY
- QList<QSocketNotifier *> notifiers = defaultNotifiers();
-#endif
-
while (!stdinChannel.buffer.isEmpty()) {
fd_set fdread;
fd_set fdwrite;
@@ -955,11 +946,8 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
-#ifdef Q_OS_BLACKBERRY
- int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout);
-#else
int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
-#endif
+
if (ret < 0) {
break;
}
@@ -1001,10 +989,6 @@ bool QProcessPrivate::waitForFinished(int msecs)
QElapsedTimer stopWatch;
stopWatch.start();
-#ifdef Q_OS_BLACKBERRY
- QList<QSocketNotifier *> notifiers = defaultNotifiers();
-#endif
-
forever {
fd_set fdread;
fd_set fdwrite;
@@ -1028,11 +1012,8 @@ bool QProcessPrivate::waitForFinished(int msecs)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
-#ifdef Q_OS_BLACKBERRY
- int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout);
-#else
int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
-#endif
+
if (ret < 0) {
break;
}
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index 80e6d5bb61..69d9ac6e87 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -497,11 +497,22 @@ void QProcessPrivate::startProcess()
0, 0, 0,
stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1]
};
- success = CreateProcess(0, (wchar_t*)args.utf16(),
- 0, 0, TRUE, dwCreationFlags,
- environment.isEmpty() ? 0 : envlist.data(),
- workingDirectory.isEmpty() ? 0 : (wchar_t*)QDir::toNativeSeparators(workingDirectory).utf16(),
- &startupInfo, pid);
+
+ const QString nativeWorkingDirectory = QDir::toNativeSeparators(workingDirectory);
+ QProcess::CreateProcessArguments cpargs = {
+ 0, (wchar_t*)args.utf16(),
+ 0, 0, TRUE, dwCreationFlags,
+ environment.isEmpty() ? 0 : envlist.data(),
+ nativeWorkingDirectory.isEmpty() ? Q_NULLPTR : (wchar_t*)nativeWorkingDirectory.utf16(),
+ &startupInfo, pid
+ };
+ if (modifyCreateProcessArgs)
+ modifyCreateProcessArgs(&cpargs);
+ success = CreateProcess(cpargs.applicationName, cpargs.arguments, cpargs.processAttributes,
+ cpargs.threadAttributes, cpargs.inheritHandles, cpargs.flags,
+ cpargs.environment, cpargs.currentDirectory, cpargs.startupInfo,
+ cpargs.processInformation);
+
QString errorString;
if (!success) {
// Capture the error string before we do CloseHandle below
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 0c44582af8..efdb86bd7f 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -100,7 +100,7 @@ using namespace ABI::Windows::Storage;
#define CSIDL_APPDATA 0x001a // <username>\Application Data
#endif
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_ANDROID)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_ANDROID)
#define Q_XDG_PLATFORM
#endif
@@ -1073,7 +1073,7 @@ static void initDefaultPaths(QMutexLocker *locker)
#else
#ifndef QSETTINGS_USE_QSTANDARDPATHS
- // Non XDG platforms (OS X, iOS, Blackberry, Android...) have used this code path erroneously
+ // Non XDG platforms (OS X, iOS, Android...) have used this code path erroneously
// for some time now. Moving away from that would require migrating existing settings.
QString userPath;
QByteArray env = qgetenv("XDG_CONFIG_HOME");
@@ -1140,7 +1140,6 @@ QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format,
org = QLatin1String("Unknown Organization");
}
-#if !defined(Q_OS_BLACKBERRY)
QString appFile = org + QDir::separator() + application + extension;
QString orgFile = org + extension;
@@ -1155,13 +1154,6 @@ QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format,
if (!application.isEmpty())
confFiles[F_System | F_Application].reset(QConfFile::fromName(systemPath + appFile, false));
confFiles[F_System | F_Organization].reset(QConfFile::fromName(systemPath + orgFile, false));
-#else
- QString confName = getPath(format, QSettings::UserScope) + org;
- if (!application.isEmpty())
- confName += QDir::separator() + application;
- confName += extension;
- confFiles[SandboxConfFile].reset(QConfFile::fromName(confName, true));
-#endif
for (i = 0; i < NumConfFiles; ++i) {
if (confFiles[i]) {
@@ -2249,7 +2241,6 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
stored in the following registry path:
\c{HKEY_LOCAL_MACHINE\Software\WOW6432node}.
- On BlackBerry only a single file is used (see \l{Platform Limitations}).
If the file format is NativeFormat, this is "Settings/MySoft/Star Runner.conf"
in the application's home directory.
@@ -2277,7 +2268,6 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
%COMMON_APPDATA% path is usually \tt{C:\\Documents and
Settings\\All Users\\Application Data}.
- On BlackBerry only a single file is used (see \l{Platform Limitations}).
If the file format is IniFormat, this is "Settings/MySoft/Star Runner.ini"
in the application's home directory.
@@ -2382,15 +2372,6 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
10.8 (Mountain Lion), only root can. However, 10.9 (Mavericks) changes
that rule again but only for the native format (plist files).
- \li On the BlackBerry platform, applications run in a sandbox. They are not
- allowed to read or write outside of this sandbox. This involves the
- following limitations:
- \list
- \li As there is only a single scope the scope is simply ignored,
- i.e. there is no difference between SystemScope and UserScope.
- \li The \l{Fallback Mechanism} is not applied, i.e. only a single
- location is considered.
- \li It is advised against setting and using custom file paths.
\endlist
\endlist
@@ -2413,14 +2394,24 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
This enum type specifies the storage format used by QSettings.
- \value NativeFormat Store the settings using the most
- appropriate storage format for the platform.
- On Windows, this means the system registry;
- on OS X and iOS, this means the CFPreferences
- API; on Unix, this means textual
- configuration files in INI format.
- \value IniFormat Store the settings in INI files.
- \value InvalidFormat Special value returned by registerFormat().
+ \value NativeFormat Store the settings using the most
+ appropriate storage format for the platform.
+ On Windows, this means the system registry;
+ on OS X and iOS, this means the CFPreferences
+ API; on Unix, this means textual
+ configuration files in INI format.
+ \value Registry32Format Windows only: Explicitly access the 32-bit system registry
+ from a 64-bit application running on 64-bit Windows.
+ On 32-bit Windows or from a 32-bit application on 64-bit Windows,
+ this works the same as specifying NativeFormat.
+ This enum value was added in Qt 5.7.
+ \value Registry64Format Windows only: Explicitly access the 64-bit system registry
+ from a 32-bit application running on 64-bit Windows.
+ On 32-bit Windows or from a 64-bit application on 64-bit Windows,
+ this works the same as specifying NativeFormat.
+ This enum value was added in Qt 5.7.
+ \value IniFormat Store the settings in INI files.
+ \value InvalidFormat Special value returned by registerFormat().
\omitvalue CustomFormat1
\omitvalue CustomFormat2
\omitvalue CustomFormat3
diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h
index 8f41273ffa..dd0c4a9bfb 100644
--- a/src/corelib/io/qsettings.h
+++ b/src/corelib/io/qsettings.h
@@ -79,6 +79,11 @@ public:
NativeFormat,
IniFormat,
+#ifdef Q_OS_WIN
+ Registry32Format,
+ Registry64Format,
+#endif
+
InvalidFormat = 16,
CustomFormat1,
CustomFormat2,
diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h
index 5a3eb58a58..919485b5c3 100644
--- a/src/corelib/io/qsettings_p.h
+++ b/src/corelib/io/qsettings_p.h
@@ -236,16 +236,11 @@ public:
because their values are respectively 1 and 2.
*/
enum {
-#if !defined(Q_OS_BLACKBERRY)
F_Application = 0x0,
F_Organization = 0x1,
F_User = 0x0,
F_System = 0x2,
NumConfFiles = 4
-#else
- SandboxConfFile = 0,
- NumConfFiles = 1
-#endif
};
QSettings::Format format;
diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp
index 1546219c3b..88f58422a8 100644
--- a/src/corelib/io/qsettings_win.cpp
+++ b/src/corelib/io/qsettings_win.cpp
@@ -41,6 +41,18 @@
#include "qdebug.h"
#include <qt_windows.h>
+// See "Accessing an Alternate Registry View" at:
+// http://msdn.microsoft.com/en-us/library/aa384129%28VS.85%29.aspx
+#ifndef KEY_WOW64_64KEY
+ // Access a 32-bit key from either a 32-bit or 64-bit application.
+# define KEY_WOW64_64KEY 0x0100
+#endif
+
+#ifndef KEY_WOW64_32KEY
+ // Access a 64-bit key from either a 32-bit or 64-bit application.
+# define KEY_WOW64_32KEY 0x0200
+#endif
+
QT_BEGIN_NAMESPACE
/* Keys are stored in QStrings. If the variable name starts with 'u', this is a "user"
@@ -135,12 +147,13 @@ static QString errorCodeToString(DWORD errorCode)
return result;
}
-// Open a key with the specified perms
-static HKEY openKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey)
+// Open a key with the specified "perms".
+// "access" is to explicitly use the 32- or 64-bit branch.
+static HKEY openKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey, REGSAM access = 0)
{
HKEY resultHandle = 0;
LONG res = RegOpenKeyEx(parentHandle, reinterpret_cast<const wchar_t *>(rSubKey.utf16()),
- 0, perms, &resultHandle);
+ 0, perms | access, &resultHandle);
if (res == ERROR_SUCCESS)
return resultHandle;
@@ -148,17 +161,18 @@ static HKEY openKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey)
return 0;
}
-// Open a key with the specified perms, create it if it does not exist
-static HKEY createOrOpenKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey)
+// Open a key with the specified "perms", create it if it does not exist.
+// "access" is to explicitly use the 32- or 64-bit branch.
+static HKEY createOrOpenKey(HKEY parentHandle, REGSAM perms, const QString &rSubKey, REGSAM access = 0)
{
// try to open it
- HKEY resultHandle = openKey(parentHandle, perms, rSubKey);
+ HKEY resultHandle = openKey(parentHandle, perms, rSubKey, access);
if (resultHandle != 0)
return resultHandle;
// try to create it
LONG res = RegCreateKeyEx(parentHandle, reinterpret_cast<const wchar_t *>(rSubKey.utf16()), 0, 0,
- REG_OPTION_NON_VOLATILE, perms, 0, &resultHandle, 0);
+ REG_OPTION_NON_VOLATILE, perms | access, 0, &resultHandle, 0);
if (res == ERROR_SUCCESS)
return resultHandle;
@@ -169,11 +183,12 @@ static HKEY createOrOpenKey(HKEY parentHandle, REGSAM perms, const QString &rSub
return 0;
}
-// Open or create a key in read-write mode if possible, otherwise read-only
-static HKEY createOrOpenKey(HKEY parentHandle, const QString &rSubKey, bool *readOnly)
+// Open or create a key in read-write mode if possible, otherwise read-only.
+// "access" is to explicitly use the 32- or 64-bit branch.
+static HKEY createOrOpenKey(HKEY parentHandle, const QString &rSubKey, bool *readOnly, REGSAM access = 0)
{
// try to open or create it read/write
- HKEY resultHandle = createOrOpenKey(parentHandle, registryPermissions, rSubKey);
+ HKEY resultHandle = createOrOpenKey(parentHandle, registryPermissions, rSubKey, access);
if (resultHandle != 0) {
if (readOnly != 0)
*readOnly = false;
@@ -181,7 +196,7 @@ static HKEY createOrOpenKey(HKEY parentHandle, const QString &rSubKey, bool *rea
}
// try to open or create it read/only
- resultHandle = createOrOpenKey(parentHandle, KEY_READ, rSubKey);
+ resultHandle = createOrOpenKey(parentHandle, KEY_READ, rSubKey, access);
if (resultHandle != 0) {
if (readOnly != 0)
*readOnly = true;
@@ -247,9 +262,9 @@ static QStringList childKeysOrGroups(HKEY parentHandle, QSettingsPrivate::ChildS
return result;
}
-static void allKeys(HKEY parentHandle, const QString &rSubKey, NameSet *result)
+static void allKeys(HKEY parentHandle, const QString &rSubKey, NameSet *result, REGSAM access = 0)
{
- HKEY handle = openKey(parentHandle, KEY_READ, rSubKey);
+ HKEY handle = openKey(parentHandle, KEY_READ, rSubKey, access);
if (handle == 0)
return;
@@ -270,11 +285,11 @@ static void allKeys(HKEY parentHandle, const QString &rSubKey, NameSet *result)
if (!s.isEmpty())
s += QLatin1Char('\\');
s += childGroups.at(i);
- allKeys(parentHandle, s, result);
+ allKeys(parentHandle, s, result, access);
}
}
-static void deleteChildGroups(HKEY parentHandle)
+static void deleteChildGroups(HKEY parentHandle, REGSAM access = 0)
{
QStringList childGroups = childKeysOrGroups(parentHandle, QSettingsPrivate::ChildGroups);
@@ -282,10 +297,10 @@ static void deleteChildGroups(HKEY parentHandle)
QString group = childGroups.at(i);
// delete subgroups in group
- HKEY childGroupHandle = openKey(parentHandle, registryPermissions, group);
+ HKEY childGroupHandle = openKey(parentHandle, registryPermissions, group, access);
if (childGroupHandle == 0)
continue;
- deleteChildGroups(childGroupHandle);
+ deleteChildGroups(childGroupHandle, access);
RegCloseKey(childGroupHandle);
// delete group itself
@@ -305,7 +320,7 @@ static void deleteChildGroups(HKEY parentHandle)
class RegistryKey
{
public:
- RegistryKey(HKEY parent_handle = 0, const QString &key = QString(), bool read_only = true);
+ RegistryKey(HKEY parent_handle = 0, const QString &key = QString(), bool read_only = true, REGSAM access = 0);
QString key() const;
HKEY handle() const;
HKEY parentHandle() const;
@@ -316,13 +331,15 @@ private:
mutable HKEY m_handle;
QString m_key;
mutable bool m_read_only;
+ REGSAM m_access;
};
-RegistryKey::RegistryKey(HKEY parent_handle, const QString &key, bool read_only)
+RegistryKey::RegistryKey(HKEY parent_handle, const QString &key, bool read_only, REGSAM access)
: m_parent_handle(parent_handle),
m_handle(0),
m_key(key),
- m_read_only(read_only)
+ m_read_only(read_only),
+ m_access(access)
{
}
@@ -337,9 +354,9 @@ HKEY RegistryKey::handle() const
return m_handle;
if (m_read_only)
- m_handle = openKey(m_parent_handle, KEY_READ, m_key);
+ m_handle = openKey(m_parent_handle, KEY_READ, m_key, m_access);
else
- m_handle = createOrOpenKey(m_parent_handle, m_key, &m_read_only);
+ m_handle = createOrOpenKey(m_parent_handle, m_key, &m_read_only, m_access);
return m_handle;
}
@@ -371,8 +388,8 @@ class QWinSettingsPrivate : public QSettingsPrivate
{
public:
QWinSettingsPrivate(QSettings::Scope scope, const QString &organization,
- const QString &application);
- QWinSettingsPrivate(QString rKey);
+ const QString &application, REGSAM access = 0);
+ QWinSettingsPrivate(QString rKey, REGSAM access = 0);
~QWinSettingsPrivate();
void remove(const QString &uKey);
@@ -390,11 +407,13 @@ public:
private:
RegistryKeyList regList; // list of registry locations to search for keys
bool deleteWriteHandleOnExit;
+ REGSAM access;
};
QWinSettingsPrivate::QWinSettingsPrivate(QSettings::Scope scope, const QString &organization,
- const QString &application)
- : QSettingsPrivate(QSettings::NativeFormat, scope, organization, application)
+ const QString &application, REGSAM access)
+ : QSettingsPrivate(QSettings::NativeFormat, scope, organization, application),
+ access(access)
{
deleteWriteHandleOnExit = false;
@@ -405,23 +424,24 @@ QWinSettingsPrivate::QWinSettingsPrivate(QSettings::Scope scope, const QString &
if (scope == QSettings::UserScope) {
if (!application.isEmpty())
- regList.append(RegistryKey(HKEY_CURRENT_USER, appPrefix, !regList.isEmpty()));
+ regList.append(RegistryKey(HKEY_CURRENT_USER, appPrefix, !regList.isEmpty(), access));
- regList.append(RegistryKey(HKEY_CURRENT_USER, orgPrefix, !regList.isEmpty()));
+ regList.append(RegistryKey(HKEY_CURRENT_USER, orgPrefix, !regList.isEmpty(), access));
}
if (!application.isEmpty())
- regList.append(RegistryKey(HKEY_LOCAL_MACHINE, appPrefix, !regList.isEmpty()));
+ regList.append(RegistryKey(HKEY_LOCAL_MACHINE, appPrefix, !regList.isEmpty(), access));
- regList.append(RegistryKey(HKEY_LOCAL_MACHINE, orgPrefix, !regList.isEmpty()));
+ regList.append(RegistryKey(HKEY_LOCAL_MACHINE, orgPrefix, !regList.isEmpty(), access));
}
if (regList.isEmpty())
setStatus(QSettings::AccessError);
}
-QWinSettingsPrivate::QWinSettingsPrivate(QString rPath)
- : QSettingsPrivate(QSettings::NativeFormat)
+QWinSettingsPrivate::QWinSettingsPrivate(QString rPath, REGSAM access)
+ : QSettingsPrivate(QSettings::NativeFormat),
+ access(access)
{
deleteWriteHandleOnExit = false;
@@ -460,9 +480,9 @@ QWinSettingsPrivate::QWinSettingsPrivate(QString rPath)
}
if (rPath.length() == keyLength)
- regList.append(RegistryKey(keyName, QString(), false));
+ regList.append(RegistryKey(keyName, QString(), false, access));
else if (rPath[keyLength] == QLatin1Char('\\'))
- regList.append(RegistryKey(keyName, rPath.mid(keyLength+1), false));
+ regList.append(RegistryKey(keyName, rPath.mid(keyLength+1), false, access));
}
bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVariant *value) const
@@ -471,7 +491,7 @@ bool QWinSettingsPrivate::readKey(HKEY parentHandle, const QString &rSubKey, QVa
QString rSubkeyPath = keyPath(rSubKey);
// open a handle on the subkey
- HKEY handle = openKey(parentHandle, KEY_READ, rSubkeyPath);
+ HKEY handle = openKey(parentHandle, KEY_READ, rSubkeyPath, access);
if (handle == 0)
return false;
@@ -604,16 +624,16 @@ void QWinSettingsPrivate::remove(const QString &uKey)
// try to delete value bar in key foo
LONG res;
- HKEY handle = openKey(writeHandle(), registryPermissions, keyPath(rKey));
+ HKEY handle = openKey(writeHandle(), registryPermissions, keyPath(rKey), access);
if (handle != 0) {
res = RegDeleteValue(handle, reinterpret_cast<const wchar_t *>(keyName(rKey).utf16()));
RegCloseKey(handle);
}
// try to delete key foo/bar and all subkeys
- handle = openKey(writeHandle(), registryPermissions, rKey);
+ handle = openKey(writeHandle(), registryPermissions, rKey, access);
if (handle != 0) {
- deleteChildGroups(handle);
+ deleteChildGroups(handle, access);
if (rKey.isEmpty()) {
QStringList childKeys = childKeysOrGroups(handle, QSettingsPrivate::ChildKeys);
@@ -661,7 +681,7 @@ void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value)
QString rKey = escapedKey(uKey);
- HKEY handle = createOrOpenKey(writeHandle(), registryPermissions, keyPath(rKey));
+ HKEY handle = createOrOpenKey(writeHandle(), registryPermissions, keyPath(rKey), access);
if (handle == 0) {
setStatus(QSettings::AccessError);
return;
@@ -775,13 +795,13 @@ QStringList QWinSettingsPrivate::children(const QString &uKey, ChildSpec spec) c
HKEY parent_handle = regList.at(i).handle();
if (parent_handle == 0)
continue;
- HKEY handle = openKey(parent_handle, KEY_READ, rKey);
+ HKEY handle = openKey(parent_handle, KEY_READ, rKey, access);
if (handle == 0)
continue;
if (spec == AllKeys) {
NameSet keys;
- allKeys(handle, QLatin1String(""), &keys);
+ allKeys(handle, QLatin1String(""), &keys, access);
mergeKeySets(&result, keys);
} else { // ChildGroups or ChildKeys
QStringList names = childKeysOrGroups(handle, spec);
@@ -836,20 +856,26 @@ bool QWinSettingsPrivate::isWritable() const
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope,
const QString &organization, const QString &application)
{
- if (format == QSettings::NativeFormat) {
+ if (format == QSettings::NativeFormat)
return new QWinSettingsPrivate(scope, organization, application);
- } else {
+ else if (format == QSettings::Registry32Format)
+ return new QWinSettingsPrivate(scope, organization, application, KEY_WOW64_32KEY);
+ else if (format == QSettings::Registry64Format)
+ return new QWinSettingsPrivate(scope, organization, application, KEY_WOW64_64KEY);
+ else
return new QConfFileSettingsPrivate(format, scope, organization, application);
- }
}
QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::Format format)
{
- if (format == QSettings::NativeFormat) {
+ if (format == QSettings::NativeFormat)
return new QWinSettingsPrivate(fileName);
- } else {
+ else if (format == QSettings::Registry32Format)
+ return new QWinSettingsPrivate(fileName, KEY_WOW64_32KEY);
+ else if (format == QSettings::Registry64Format)
+ return new QWinSettingsPrivate(fileName, KEY_WOW64_64KEY);
+ else
return new QConfFileSettingsPrivate(fileName, format);
- }
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qsettings_winrt.cpp b/src/corelib/io/qsettings_winrt.cpp
index 02c3c7624e..f380ef345c 100644
--- a/src/corelib/io/qsettings_winrt.cpp
+++ b/src/corelib/io/qsettings_winrt.cpp
@@ -533,10 +533,10 @@ QStringList QWinRTSettingsPrivate::children(const QString &uKey, ChildSpec spec)
const QStringList subContainerList = subContainerNames(container.Get(), spec == AllKeys);
if (spec == AllKeys) {
- foreach (const QString &item, subContainerList) {
+ for (const QString &item : subContainerList) {
const QString subChildren = uKey.isEmpty() ? item : (uKey + QLatin1Char('/') + item);
const QStringList subResult = children(subChildren, ChildKeys);
- foreach (const QString &subItem, subResult)
+ for (const QString &subItem : subResult)
result += item + QLatin1Char('/') + subItem;
}
}
@@ -644,7 +644,7 @@ IApplicationDataContainer *QWinRTSettingsPrivate::getContainer(IApplicationDataC
return current;
const QStringList groupPath = group.split(QLatin1Char('/'), QString::SkipEmptyParts);
- foreach (const QString &subGroup, groupPath) {
+ for (const QString &subGroup : groupPath) {
ComPtr<IApplicationDataContainer> sub = subContainer(current, subGroup);
if (!sub && create)
sub = createSubContainer(current, subGroup);
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 8828e09e8f..7544f5b177 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -210,66 +210,46 @@ QT_BEGIN_NAMESPACE
\endtable
\table
- \header \li Path type \li Blackberry \li Linux
+ \header \li Path type \li Linux
\row \li DesktopLocation
- \li "<APPROOT>/data"
\li "~/Desktop"
\row \li DocumentsLocation
- \li "<APPROOT>/shared/documents"
\li "~/Documents"
\row \li FontsLocation
- \li "/base/usr/fonts" (not writable)
\li "~/.fonts"
\row \li ApplicationsLocation
- \li not supported (directory not readable)
\li "~/.local/share/applications", "/usr/local/share/applications", "/usr/share/applications"
\row \li MusicLocation
- \li "<APPROOT>/shared/music"
\li "~/Music"
\row \li MoviesLocation
- \li "<APPROOT>/shared/videos"
\li "~/Videos"
\row \li PicturesLocation
- \li "<APPROOT>/shared/photos"
\li "~/Pictures"
\row \li TempLocation
- \li "/var/tmp"
\li "/tmp"
\row \li HomeLocation
- \li "<APPROOT>/data"
\li "~"
\row \li DataLocation
- \li "<APPROOT>/data", "<APPROOT>/app/native/assets"
\li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
\row \li CacheLocation
- \li "<APPROOT>/data/Cache"
\li "~/.cache/<APPNAME>"
\row \li GenericDataLocation
- \li "<APPROOT>/shared/misc"
\li "~/.local/share", "/usr/local/share", "/usr/share"
\row \li RuntimeLocation
- \li "/var/tmp"
\li "/run/user/<USER>"
\row \li ConfigLocation
- \li "<APPROOT>/data/Settings"
\li "~/.config", "/etc/xdg"
\row \li GenericConfigLocation
- \li "<APPROOT>/data/Settings"
\li "~/.config", "/etc/xdg"
\row \li DownloadLocation
- \li "<APPROOT>/shared/downloads"
\li "~/Downloads"
\row \li GenericCacheLocation
- \li "<APPROOT>/data/Cache" (there is no shared cache)
\li "~/.cache"
\row \li AppDataLocation
- \li "<APPROOT>/data", "<APPROOT>/app/native/assets"
\li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
\row \li AppLocalDataLocation
- \li "<APPROOT>/data", "<APPROOT>/app/native/assets"
\li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
\row \li AppConfigLocation
- \li "<APPROOT>/data/Settings"
\li "~/.config/<APPNAME>", "/etc/xdg/<APPNAME>"
\endtable
@@ -277,13 +257,13 @@ QT_BEGIN_NAMESPACE
\header \li Path type \li Android \li iOS
\row \li DesktopLocation
\li "<APPROOT>/files"
- \li "<APPROOT>/<APPDIR>" (not writable)
+ \li "<APPROOT>/Documents/Desktop"
\row \li DocumentsLocation
\li "<USER>/Documents", "<USER>/<APPNAME>/Documents"
\li "<APPROOT>/Documents"
\row \li FontsLocation
\li "/system/fonts" (not writable)
- \li "<APPROOT>/Documents/.fonts"
+ \li "<APPROOT>/Library/Fonts"
\row \li ApplicationsLocation
\li not supported (directory not readable)
\li not supported
@@ -301,7 +281,7 @@ QT_BEGIN_NAMESPACE
\li "<APPROOT>/tmp"
\row \li HomeLocation
\li "<APPROOT>/files"
- \li "<APPROOT>/<APPDIR>" (not writable)
+ \li "<APPROOT>" (not writable)
\row \li DataLocation
\li "<APPROOT>/files", "<USER>/<APPNAME>/files"
\li "<APPROOT>/Library/Application Support"
@@ -316,13 +296,13 @@ QT_BEGIN_NAMESPACE
\li not supported
\row \li ConfigLocation
\li "<APPROOT>/files/settings"
- \li "<APPROOT>/Documents"
+ \li "<APPROOT>/Library/Preferences"
\row \li GenericConfigLocation
\li "<APPROOT>/files/settings" (there is no shared settings)
- \li "<APPROOT>/Documents"
+ \li "<APPROOT>/Library/Preferences"
\row \li DownloadLocation
\li "<USER>/Downloads", "<USER>/<APPNAME>/Downloads"
- \li "<APPROOT>/Documents/Download"
+ \li "<APPROOT>/Documents/Downloads"
\row \li GenericCacheLocation
\li "<APPROOT>/cache" (there is no shared cache)
\li "<APPROOT>/Library/Caches"
@@ -331,7 +311,7 @@ QT_BEGIN_NAMESPACE
\li "<APPROOT>/Library/Application Support"
\row \li AppConfigLocation
\li "<APPROOT>/files/settings"
- \li "<APPROOT>/Documents"
+ \li "<APPROOT>/Library/Preferences/<APPNAME>"
\row \li AppLocalDataLocation
\li "<APPROOT>/files", "<USER>/<APPNAME>/files"
\li "<APPROOT>/Library/Application Support"
@@ -463,7 +443,7 @@ static inline QString searchExecutable(const QStringList &searchPaths,
const QString &executableName)
{
const QDir currentDir = QDir::current();
- foreach (const QString &searchPath, searchPaths) {
+ for (const QString &searchPath : searchPaths) {
const QString candidate = currentDir.absoluteFilePath(searchPath + QLatin1Char('/') + executableName);
const QString absPath = checkExecutable(candidate);
if (!absPath.isEmpty())
@@ -482,9 +462,9 @@ static inline QString
const QStringList &suffixes)
{
const QDir currentDir = QDir::current();
- foreach (const QString &searchPath, searchPaths) {
+ for (const QString &searchPath : searchPaths) {
const QString candidateRoot = currentDir.absoluteFilePath(searchPath + QLatin1Char('/') + executableName);
- foreach (const QString &suffix, suffixes) {
+ for (const QString &suffix : suffixes) {
const QString absPath = checkExecutable(candidateRoot + suffix);
if (!absPath.isEmpty())
return absPath;
@@ -525,7 +505,7 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr
// Remove trailing slashes, which occur on Windows.
const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(QDir::listSeparator(), QString::SkipEmptyParts);
searchPaths.reserve(rawPaths.size());
- foreach (const QString &rawPath, rawPaths) {
+ for (const QString &rawPath : rawPaths) {
QString cleanPath = QDir::cleanPath(rawPath);
if (cleanPath.size() > 1 && cleanPath.endsWith(QLatin1Char('/')))
cleanPath.truncate(cleanPath.size() - 1);
@@ -555,7 +535,7 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr
an empty QString if no relevant location can be found.
*/
-#if !defined(Q_OS_OSX) && !defined(QT_BOOTSTRAPPED)
+#if !defined(Q_OS_MAC) && !defined(QT_BOOTSTRAPPED)
QString QStandardPaths::displayName(StandardLocation type)
{
switch (type) {
diff --git a/src/corelib/io/qstandardpaths_blackberry.cpp b/src/corelib/io/qstandardpaths_blackberry.cpp
deleted file mode 100644
index 4b29ad7ed9..0000000000
--- a/src/corelib/io/qstandardpaths_blackberry.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qstandardpaths.h"
-#include <qdir.h>
-
-#ifndef QT_NO_STANDARDPATHS
-
-#include <qstring.h>
-
-QT_BEGIN_NAMESPACE
-
-static QString testModeInsert() {
- if (QStandardPaths::isTestModeEnabled())
- return QStringLiteral("/.qttest");
- else
- return QStringLiteral("");
-}
-
-QString QStandardPaths::writableLocation(StandardLocation type)
-{
- QDir sharedDir = QDir::home();
- sharedDir.cd(QLatin1String("../shared"));
-
- const QString sharedRoot = sharedDir.absolutePath();
-
- switch (type) {
- case AppDataLocation:
- case AppLocalDataLocation:
- return QDir::homePath() + testModeInsert();
- case DesktopLocation:
- case HomeLocation:
- return QDir::homePath();
- case RuntimeLocation:
- case TempLocation:
- return QDir::tempPath();
- case CacheLocation:
- case GenericCacheLocation:
- return QDir::homePath() + testModeInsert() + QLatin1String("/Cache");
- case ConfigLocation:
- case GenericConfigLocation:
- case AppConfigLocation:
- return QDir::homePath() + testModeInsert() + QLatin1String("/Settings");
- case GenericDataLocation:
- return sharedRoot + testModeInsert() + QLatin1String("/misc");
- case DocumentsLocation:
- return sharedRoot + QLatin1String("/documents");
- case PicturesLocation:
- return sharedRoot + QLatin1String("/photos");
- case FontsLocation:
- // this is not a writable location
- return QString();
- case MusicLocation:
- return sharedRoot + QLatin1String("/music");
- case MoviesLocation:
- return sharedRoot + QLatin1String("/videos");
- case DownloadLocation:
- return sharedRoot + QLatin1String("/downloads");
- case ApplicationsLocation:
- return QString();
- default:
- break;
- }
-
- return QString();
-}
-
-QStringList QStandardPaths::standardLocations(StandardLocation type)
-{
- QStringList dirs;
-
- if (type == FontsLocation)
- return QStringList(QLatin1String("/base/usr/fonts"));
-
- if (type == AppDataLocation || type == AppLocalDataLocation)
- dirs.append(QDir::homePath() + testModeInsert() + QLatin1String("native/assets"));
-
- const QString localDir = writableLocation(type);
- dirs.prepend(localDir);
- return dirs;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_STANDARDPATHS
diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm
deleted file mode 100644
index eb85e2fd23..0000000000
--- a/src/corelib/io/qstandardpaths_ios.mm
+++ /dev/null
@@ -1,133 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#import <UIKit/UIKit.h>
-
-#include "qstandardpaths.h"
-
-#ifndef QT_NO_STANDARDPATHS
-
-QT_BEGIN_NAMESPACE
-
-static QString pathForDirectory(NSSearchPathDirectory directory)
-{
- return QString::fromNSString(
- [NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES) lastObject]);
-}
-
-static QString bundlePath()
-{
- return QString::fromNSString([[NSBundle mainBundle] bundlePath]);
-}
-
-QString QStandardPaths::writableLocation(StandardLocation type)
-{
- QString location;
-
- switch (type) {
- case DocumentsLocation:
- location = pathForDirectory(NSDocumentDirectory);
- break;
- case FontsLocation:
- location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/.fonts");
- break;
- case ApplicationsLocation:
- // NSApplicationDirectory points to a non-existing write-protected path.
- break;
- case MusicLocation:
- // NSMusicDirectory points to a non-existing write-protected path. Use sensible fallback.
- location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/Music");
- break;
- case MoviesLocation:
- // NSMoviesDirectory points to a non-existing write-protected path. Use sensible fallback.
- location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/Movies");
- break;
- case PicturesLocation:
- // NSPicturesDirectory points to a non-existing write-protected path. Use sensible fallback.
- location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/Pictures");
- break;
- case TempLocation:
- location = QString::fromNSString(NSTemporaryDirectory());
- break;
- case DesktopLocation:
- case HomeLocation:
- location = bundlePath();
- break;
- case AppDataLocation:
- case AppLocalDataLocation:
- location = pathForDirectory(NSApplicationSupportDirectory);
- break;
- case GenericDataLocation:
- location = pathForDirectory(NSDocumentDirectory);
- break;
- case CacheLocation:
- case GenericCacheLocation:
- location = pathForDirectory(NSCachesDirectory);
- break;
- case ConfigLocation:
- case GenericConfigLocation:
- case AppConfigLocation:
- location = pathForDirectory(NSDocumentDirectory);
- break;
- case DownloadLocation:
- // NSDownloadsDirectory points to a non-existing write-protected path.
- location = pathForDirectory(NSDocumentDirectory) + QLatin1String("/Download");
- break;
- case RuntimeLocation:
- break;
- default:
- break;
- }
-
- return location;
-}
-
-QStringList QStandardPaths::standardLocations(StandardLocation type)
-{
- QStringList dirs;
-
- switch (type) {
- case PicturesLocation:
- dirs << writableLocation(PicturesLocation) << QLatin1String("assets-library://");
- break;
- default:
- dirs << writableLocation(type);
- break;
- }
-
- return dirs;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_STANDARDPATHS
diff --git a/src/corelib/io/qstandardpaths_mac.mm b/src/corelib/io/qstandardpaths_mac.mm
index 7b97a03db2..341a504168 100644
--- a/src/corelib/io/qstandardpaths_mac.mm
+++ b/src/corelib/io/qstandardpaths_mac.mm
@@ -32,6 +32,9 @@
****************************************************************************/
#include "qstandardpaths.h"
+
+#ifndef QT_NO_STANDARDPATHS
+
#include <qdir.h>
#include <qurl.h>
#include <private/qcore_mac_p.h>
@@ -40,63 +43,47 @@
#include <qcoreapplication.h>
#endif
-#include <CoreFoundation/CoreFoundation.h>
-#include <ApplicationServices/ApplicationServices.h>
+#import <Foundation/Foundation.h>
QT_BEGIN_NAMESPACE
-/*
- Translates a QStandardPaths::StandardLocation into the mac equivalent.
-*/
-OSType translateLocation(QStandardPaths::StandardLocation type)
+static QString pathForDirectory(NSSearchPathDirectory directory,
+ NSSearchPathDomainMask mask)
+{
+ return QString::fromNSString(
+ [NSSearchPathForDirectoriesInDomains(directory, mask, YES) lastObject]);
+}
+
+static NSSearchPathDirectory searchPathDirectory(QStandardPaths::StandardLocation type)
{
switch (type) {
- case QStandardPaths::ConfigLocation:
- case QStandardPaths::GenericConfigLocation:
- case QStandardPaths::AppConfigLocation:
- return kPreferencesFolderType;
case QStandardPaths::DesktopLocation:
- return kDesktopFolderType;
+ return NSDesktopDirectory;
case QStandardPaths::DocumentsLocation:
- return kDocumentsFolderType;
- case QStandardPaths::FontsLocation:
- // There are at least two different font directories on the mac: /Library/Fonts and ~/Library/Fonts.
- // To select a specific one we have to specify a different first parameter when calling FSFindFolder.
- return kFontsFolderType;
+ return NSDocumentDirectory;
case QStandardPaths::ApplicationsLocation:
- return kApplicationsFolderType;
+ return NSApplicationDirectory;
case QStandardPaths::MusicLocation:
- return kMusicDocumentsFolderType;
+ return NSMusicDirectory;
case QStandardPaths::MoviesLocation:
- return kMovieDocumentsFolderType;
+ return NSMoviesDirectory;
case QStandardPaths::PicturesLocation:
- return kPictureDocumentsFolderType;
- case QStandardPaths::TempLocation:
- return kTemporaryFolderType;
+ return NSPicturesDirectory;
case QStandardPaths::GenericDataLocation:
case QStandardPaths::RuntimeLocation:
case QStandardPaths::AppDataLocation:
case QStandardPaths::AppLocalDataLocation:
- return kApplicationSupportFolderType;
+ return NSApplicationSupportDirectory;
case QStandardPaths::GenericCacheLocation:
case QStandardPaths::CacheLocation:
- return kCachedDataFolderType;
+ return NSCachesDirectory;
+ case QStandardPaths::DownloadLocation:
+ return NSDownloadsDirectory;
default:
- return kDesktopFolderType;
+ return (NSSearchPathDirectory)0;
}
}
-/*
- Constructs a full unicode path from a FSRef.
-*/
-static QString getFullPath(const FSRef &ref)
-{
- QByteArray ba(2048, 0);
- if (FSRefMakePath(&ref, reinterpret_cast<UInt8 *>(ba.data()), ba.size()) == noErr)
- return QString::fromUtf8(ba.constData()).normalized(QString::NormalizationForm_C);
- return QString();
-}
-
static void appendOrganizationAndApp(QString &path)
{
#ifndef QT_BOOTSTRAPPED
@@ -111,28 +98,65 @@ static void appendOrganizationAndApp(QString &path)
#endif
}
-static QString macLocation(QStandardPaths::StandardLocation type, short domain)
+static QString baseWritableLocation(QStandardPaths::StandardLocation type,
+ NSSearchPathDomainMask mask = NSUserDomainMask,
+ bool appendOrgAndApp = false)
{
- // https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSFileManager_Class/index.html
- if (type == QStandardPaths::DownloadLocation) {
- NSFileManager *fileManager = [NSFileManager defaultManager];
- NSURL *url = [fileManager URLForDirectory:NSDownloadsDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
- if (!url)
- return QString();
- return QString::fromNSString([url path]);
+ QString path;
+ const NSSearchPathDirectory dir = searchPathDirectory(type);
+ switch (type) {
+ case QStandardPaths::HomeLocation:
+ path = QDir::homePath();
+ break;
+ case QStandardPaths::TempLocation:
+ path = QDir::tempPath();
+ break;
+#ifdef Q_OS_IOS
+ // These locations point to non-existing write-protected paths. Use sensible fallbacks.
+ case QStandardPaths::MusicLocation:
+ path = pathForDirectory(NSDocumentDirectory, mask) + QLatin1String("/Music");
+ break;
+ case QStandardPaths::MoviesLocation:
+ path = pathForDirectory(NSDocumentDirectory, mask) + QLatin1String("/Movies");
+ break;
+ case QStandardPaths::PicturesLocation:
+ path = pathForDirectory(NSDocumentDirectory, mask) + QLatin1String("/Pictures");
+ break;
+ case QStandardPaths::DownloadLocation:
+ path = pathForDirectory(NSDocumentDirectory, mask) + QLatin1String("/Downloads");
+ break;
+ case QStandardPaths::DesktopLocation:
+ path = pathForDirectory(NSDocumentDirectory, mask) + QLatin1String("/Desktop");
+ break;
+ case QStandardPaths::ApplicationsLocation:
+ break;
+#endif
+ case QStandardPaths::FontsLocation:
+ path = pathForDirectory(NSLibraryDirectory, mask) + QLatin1String("/Fonts");
+ break;
+ case QStandardPaths::ConfigLocation:
+ case QStandardPaths::GenericConfigLocation:
+ case QStandardPaths::AppConfigLocation:
+ path = pathForDirectory(NSLibraryDirectory, mask) + QLatin1String("/Preferences");
+ break;
+ default:
+ path = pathForDirectory(dir, mask);
+ break;
}
- // http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html
- FSRef ref;
- OSErr err = FSFindFolder(domain, translateLocation(type), false, &ref);
- if (err)
- return QString();
-
- QString path = getFullPath(ref);
+ if (appendOrgAndApp) {
+ switch (type) {
+ case QStandardPaths::AppDataLocation:
+ case QStandardPaths::AppLocalDataLocation:
+ case QStandardPaths::AppConfigLocation:
+ case QStandardPaths::CacheLocation:
+ appendOrganizationAndApp(path);
+ break;
+ default:
+ break;
+ }
+ }
- if (type == QStandardPaths::AppDataLocation || type == QStandardPaths::AppLocalDataLocation ||
- type == QStandardPaths::CacheLocation || type == QStandardPaths::AppConfigLocation)
- appendOrganizationAndApp(path);
return path;
}
@@ -167,31 +191,32 @@ QString QStandardPaths::writableLocation(StandardLocation type)
}
}
- switch (type) {
- case HomeLocation:
- return QDir::homePath();
- case TempLocation:
- return QDir::tempPath();
- case GenericDataLocation:
- case AppDataLocation:
- case AppLocalDataLocation:
- case GenericCacheLocation:
- case CacheLocation:
- case RuntimeLocation:
- return macLocation(type, kUserDomain);
- default:
- return macLocation(type, kOnAppropriateDisk);
- }
+ return baseWritableLocation(type, NSUserDomainMask, true);
}
QStringList QStandardPaths::standardLocations(StandardLocation type)
{
QStringList dirs;
- if (type == GenericDataLocation || type == AppDataLocation || type == AppLocalDataLocation || type == GenericCacheLocation || type == CacheLocation) {
- const QString path = macLocation(type, kOnAppropriateDisk);
- if (!path.isEmpty())
- dirs.append(path);
+#ifdef Q_OS_IOS
+ if (type == PicturesLocation)
+ dirs << writableLocation(PicturesLocation) << QLatin1String("assets-library://");
+#endif
+
+ if (type == GenericDataLocation || type == FontsLocation || type == ApplicationsLocation
+ || type == AppDataLocation || type == AppLocalDataLocation
+ || type == GenericCacheLocation || type == CacheLocation) {
+ QList<NSSearchPathDomainMask> masks;
+ masks << NSLocalDomainMask;
+ if (type == FontsLocation || type == GenericCacheLocation)
+ masks << NSSystemDomainMask;
+
+ for (QList<NSSearchPathDomainMask>::const_iterator it = masks.begin();
+ it != masks.end(); ++it) {
+ const QString path = baseWritableLocation(type, *it, true);
+ if (!path.isEmpty() && !dirs.contains(path))
+ dirs.append(path);
+ }
}
if (type == AppDataLocation || type == AppLocalDataLocation) {
@@ -219,28 +244,41 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
}
}
const QString localDir = writableLocation(type);
- dirs.prepend(localDir);
+ if (!localDir.isEmpty())
+ dirs.prepend(localDir);
return dirs;
}
#ifndef QT_BOOTSTRAPPED
QString QStandardPaths::displayName(StandardLocation type)
{
+ // Use "Home" instead of the user's Unix username
if (QStandardPaths::HomeLocation == type)
return QCoreApplication::translate("QStandardPaths", "Home");
- FSRef ref;
- OSErr err = FSFindFolder(kOnAppropriateDisk, translateLocation(type), false, &ref);
- if (err)
- return QString();
+ // The temporary directory returned by the old Carbon APIs is ~/Library/Caches/TemporaryItems,
+ // the display name of which ("TemporaryItems") isn't translated by the system. The standard
+ // temporary directory has no reasonable display name either, so use something more sensible.
+ if (QStandardPaths::TempLocation == type)
+ return QCoreApplication::translate("QStandardPaths", "Temporary Items");
- QCFString displayName;
- err = LSCopyDisplayNameForRef(&ref, &displayName);
- if (err)
- return QString();
+ // standardLocations() may return an empty list on some platforms
+ if (QStandardPaths::ApplicationsLocation == type)
+ return QCoreApplication::translate("QStandardPaths", "Applications");
- return static_cast<QString>(displayName);
+ if (QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+ standardLocations(type).first().toCFString(),
+ kCFURLPOSIXPathStyle, true)) {
+ QCFString name;
+ CFURLCopyResourcePropertyForKey(url, kCFURLLocalizedNameKey, &name, NULL);
+ if (name && CFStringGetLength(name))
+ return QString::fromCFString(name);
+ }
+
+ return QFileInfo(baseWritableLocation(type)).fileName();
}
#endif
QT_END_NAMESPACE
+
+#endif // QT_NO_STANDARDPATHS
diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp
index 71436c6497..1096cb8c31 100644
--- a/src/corelib/io/qtemporarydir.cpp
+++ b/src/corelib/io/qtemporarydir.cpp
@@ -45,7 +45,7 @@
#endif
#include <stdlib.h> // mkdtemp
-#if defined(Q_OS_QNX) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
+#if defined(Q_OS_QNX) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY)
#include <private/qfilesystemengine_p.h>
#endif
@@ -91,7 +91,7 @@ static QString defaultTemplateName()
return QDir::tempPath() + QLatin1Char('/') + baseName + QLatin1String("-XXXXXX");
}
-#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID)
+#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY)
static int nextRand(int &v)
{
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index a8fd2dd7ab..9f0a8c08ed 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -862,6 +862,21 @@ void QTextStreamPrivate::write(QLatin1String data)
/*!
\internal
*/
+void QTextStreamPrivate::writePadding(int len)
+{
+ if (string) {
+ // ### What about seek()??
+ string->resize(string->size() + len, params.padChar);
+ } else {
+ writeBuffer.resize(writeBuffer.size() + len, params.padChar);
+ if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE)
+ flushWriteBuffer();
+ }
+}
+
+/*!
+ \internal
+*/
inline bool QTextStreamPrivate::getChar(QChar *ch)
{
if ((string && stringOffset == string->size())
@@ -916,31 +931,24 @@ QTextStreamPrivate::PaddingResult QTextStreamPrivate::padding(int len) const
{
Q_ASSERT(params.fieldWidth > len); // calling padding() when no padding is needed is an error
- // Do NOT break NRVO in this function or kittens will die!
-
- PaddingResult result;
+ int left = 0, right = 0;
const int padSize = params.fieldWidth - len;
- result.padding.resize(padSize);
- std::fill_n(result.padding.begin(), padSize, params.padChar);
-
switch (params.fieldAlignment) {
case QTextStream::AlignLeft:
- result.left = 0;
- result.right = padSize;
+ right = padSize;
break;
case QTextStream::AlignRight:
case QTextStream::AlignAccountingStyle:
- result.left = padSize;
- result.right = 0;
+ left = padSize;
break;
case QTextStream::AlignCenter:
- result.left = padSize/2;
- result.right = padSize - padSize/2;
+ left = padSize/2;
+ right = padSize - padSize/2;
break;
}
-
+ const PaddingResult result = { left, right };
return result;
}
@@ -965,9 +973,9 @@ void QTextStreamPrivate::putString(const QChar *data, int len, bool number)
}
}
- write(pad.padding.constData(), pad.left);
+ writePadding(pad.left);
write(data, len);
- write(pad.padding.constData(), pad.right);
+ writePadding(pad.right);
} else {
write(data, len);
}
@@ -993,9 +1001,9 @@ void QTextStreamPrivate::putString(QLatin1String data, bool number)
}
}
- write(pad.padding.constData(), pad.left);
+ writePadding(pad.left);
write(data);
- write(pad.padding.constData(), pad.right);
+ writePadding(pad.right);
} else {
write(data);
}
@@ -2545,6 +2553,8 @@ QTextStream &QTextStream::operator<<(double f)
flags |= QLocaleData::Alternate;
if (locale() != QLocale::c() && !(locale().numberOptions() & QLocale::OmitGroupSeparator))
flags |= QLocaleData::ThousandsGroup;
+ if (!(locale().numberOptions() & QLocale::OmitLeadingZeroInExponent))
+ flags |= QLocaleData::ZeroPadExponent;
const QLocaleData *dd = d->locale.d->m_data;
QString num = dd->doubleToString(f, d->params.realNumberPrecision, form, -1, flags);
diff --git a/src/corelib/io/qtextstream_p.h b/src/corelib/io/qtextstream_p.h
index 115408a6dd..6c6cbe1e6e 100644
--- a/src/corelib/io/qtextstream_p.h
+++ b/src/corelib/io/qtextstream_p.h
@@ -169,6 +169,7 @@ public:
inline void write(QChar ch);
void write(const QChar *data, int len);
void write(QLatin1String data);
+ void writePadding(int len);
inline void putString(const QString &ch, bool number = false) { putString(ch.constData(), ch.length(), number); }
void putString(const QChar *data, int len, bool number = false);
void putString(QLatin1String data, bool number = false);
@@ -176,10 +177,7 @@ public:
void putNumber(qulonglong number, bool negative);
struct PaddingResult {
- enum { PreallocatedPadding = 80 }; // typical line length
-
int left, right;
- QVarLengthArray<QChar, PreallocatedPadding> padding;
};
PaddingResult padding(int len) const;
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 775a870a27..8e82f00f74 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -4064,7 +4064,7 @@ QStringList QUrl::toStringList(const QList<QUrl> &urls, FormattingOptions option
{
QStringList lst;
lst.reserve(urls.size());
- foreach (const QUrl &url, urls)
+ for (const QUrl &url : urls)
lst.append(url.toString(options));
return lst;
@@ -4080,9 +4080,8 @@ QList<QUrl> QUrl::fromStringList(const QStringList &urls, ParsingMode mode)
{
QList<QUrl> lst;
lst.reserve(urls.size());
- foreach (const QString &str, urls) {
+ for (const QString &str : urls)
lst.append(QUrl(str, mode));
- }
return lst;
}
diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp
index 2b695a4f7b..65c9dc3339 100644
--- a/src/corelib/io/qurlquery.cpp
+++ b/src/corelib/io/qurlquery.cpp
@@ -169,7 +169,6 @@ public:
Map::iterator findKey(const QString &key)
{ return itemList.begin() + findRecodedKey(recodeFromUser(key)); }
- // use QMap so we end up sorting the items by key
Map itemList;
QChar valueDelimiter;
QChar pairDelimiter;
@@ -733,7 +732,7 @@ QStringList QUrlQuery::allQueryItemValues(const QString &key, QUrl::ComponentFor
*/
void QUrlQuery::removeQueryItem(const QString &key)
{
- if (d) {
+ if (d.constData()) {
Map::iterator it = d->findKey(key);
if (it != d->itemList.end())
d->itemList.erase(it);
diff --git a/src/corelib/io/qurlquery.h b/src/corelib/io/qurlquery.h
index 8fcc1b13d5..5386d97e09 100644
--- a/src/corelib/io/qurlquery.h
+++ b/src/corelib/io/qurlquery.h
@@ -154,10 +154,10 @@ inline QList<QPair<QByteArray, QByteArray> > QUrl::encodedQueryItems() const
}
inline QList<QByteArray> QUrl::allEncodedQueryItemValues(const QByteArray &key) const
{
- QStringList items = QUrlQuery(*this).allQueryItemValues(fromEncodedComponent_helper(key), QUrl::FullyEncoded);
+ const QStringList items = QUrlQuery(*this).allQueryItemValues(fromEncodedComponent_helper(key), QUrl::FullyEncoded);
QList<QByteArray> result;
result.reserve(items.size());
- Q_FOREACH (const QString &item, items)
+ for (const QString &item : items)
result << item.toLatin1();
return result;
}
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index 90297b9115..0725d5e098 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -480,6 +480,13 @@ public:
Q_GLOBAL_STATIC(QEmptyItemModel, qEmptyModel)
+QAbstractItemModelPrivate::QAbstractItemModelPrivate()
+ : QObjectPrivate(),
+ supportedDragActions(-1),
+ roleNames(defaultRoleNames())
+{
+}
+
QAbstractItemModelPrivate::~QAbstractItemModelPrivate()
{
}
@@ -489,6 +496,30 @@ QAbstractItemModel *QAbstractItemModelPrivate::staticEmptyModel()
return qEmptyModel();
}
+void QAbstractItemModelPrivate::invalidatePersistentIndexes()
+{
+ for (QPersistentModelIndexData *data : qAsConst(persistent.indexes)) {
+ data->index = QModelIndex();
+ data->model = 0;
+ }
+ persistent.indexes.clear();
+}
+
+/*!
+ \internal
+ Clean the QPersistentModelIndex relative to the index if there is one.
+ To be used before an index is invalided
+*/
+void QAbstractItemModelPrivate::invalidatePersistentIndex(const QModelIndex &index) {
+ const auto it = persistent.indexes.constFind(index);
+ if (it != persistent.indexes.cend()) {
+ QPersistentModelIndexData *data = *it;
+ persistent.indexes.erase(it);
+ data->index = QModelIndex();
+ data->model = 0;
+ }
+}
+
namespace {
struct DefaultRoleNames : public QHash<int, QByteArray>
{
@@ -607,7 +638,7 @@ void QAbstractItemModelPrivate::rowsInserted(const QModelIndex &parent,
it != persistent_moved.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
QModelIndex old = data->index;
- persistent.indexes.erase(persistent.indexes.find(old));
+ persistent.indexes.erase(persistent.indexes.constFind(old));
data->index = q_func()->index(old.row() + count, old.column(), parent);
if (data->index.isValid()) {
persistent.insertMultiAtEnd(data->index, data);
@@ -700,7 +731,7 @@ void QAbstractItemModelPrivate::movePersistentIndexes(const QVector<QPersistentM
else
column += change;
- persistent.indexes.erase(persistent.indexes.find(data->index));
+ persistent.indexes.erase(persistent.indexes.constFind(data->index));
data->index = q_func()->index(row, column, parent);
if (data->index.isValid()) {
persistent.insertMultiAtEnd(data->index, data);
@@ -767,7 +798,7 @@ void QAbstractItemModelPrivate::rowsRemoved(const QModelIndex &parent,
it != persistent_moved.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
QModelIndex old = data->index;
- persistent.indexes.erase(persistent.indexes.find(old));
+ persistent.indexes.erase(persistent.indexes.constFind(old));
data->index = q_func()->index(old.row() - count, old.column(), parent);
if (data->index.isValid()) {
persistent.insertMultiAtEnd(data->index, data);
@@ -779,7 +810,7 @@ void QAbstractItemModelPrivate::rowsRemoved(const QModelIndex &parent,
for (QVector<QPersistentModelIndexData *>::const_iterator it = persistent_invalidated.constBegin();
it != persistent_invalidated.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
- persistent.indexes.erase(persistent.indexes.find(data->index));
+ persistent.indexes.erase(persistent.indexes.constFind(data->index));
data->index = QModelIndex();
data->model = 0;
}
@@ -812,7 +843,7 @@ void QAbstractItemModelPrivate::columnsInserted(const QModelIndex &parent,
it != persistent_moved.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
QModelIndex old = data->index;
- persistent.indexes.erase(persistent.indexes.find(old));
+ persistent.indexes.erase(persistent.indexes.constFind(old));
data->index = q_func()->index(old.row(), old.column() + count, parent);
if (data->index.isValid()) {
persistent.insertMultiAtEnd(data->index, data);
@@ -862,7 +893,7 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
it != persistent_moved.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
QModelIndex old = data->index;
- persistent.indexes.erase(persistent.indexes.find(old));
+ persistent.indexes.erase(persistent.indexes.constFind(old));
data->index = q_func()->index(old.row(), old.column() - count, parent);
if (data->index.isValid()) {
persistent.insertMultiAtEnd(data->index, data);
@@ -874,7 +905,7 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
for (QVector<QPersistentModelIndexData *>::const_iterator it = persistent_invalidated.constBegin();
it != persistent_invalidated.constEnd(); ++it) {
QPersistentModelIndexData *data = *it;
- persistent.indexes.erase(persistent.indexes.find(data->index));
+ persistent.indexes.erase(persistent.indexes.constFind(data->index));
data->index = QModelIndex();
data->model = 0;
}
@@ -3160,8 +3191,8 @@ void QAbstractItemModel::changePersistentIndex(const QModelIndex &from, const QM
if (d->persistent.indexes.isEmpty())
return;
// find the data and reinsert it sorted
- const QHash<QModelIndex, QPersistentModelIndexData *>::iterator it = d->persistent.indexes.find(from);
- if (it != d->persistent.indexes.end()) {
+ const auto it = d->persistent.indexes.constFind(from);
+ if (it != d->persistent.indexes.cend()) {
QPersistentModelIndexData *data = *it;
d->persistent.indexes.erase(it);
data->index = to;
@@ -3194,8 +3225,8 @@ void QAbstractItemModel::changePersistentIndexList(const QModelIndexList &from,
for (int i = 0; i < from.count(); ++i) {
if (from.at(i) == to.at(i))
continue;
- const QHash<QModelIndex, QPersistentModelIndexData *>::iterator it = d->persistent.indexes.find(from.at(i));
- if (it != d->persistent.indexes.end()) {
+ const auto it = d->persistent.indexes.constFind(from.at(i));
+ if (it != d->persistent.indexes.cend()) {
QPersistentModelIndexData *data = *it;
d->persistent.indexes.erase(it);
data->index = to.at(i);
diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h
index c2cbaf5298..19ee640f5c 100644
--- a/src/corelib/itemmodels/qabstractitemmodel_p.h
+++ b/src/corelib/itemmodels/qabstractitemmodel_p.h
@@ -46,7 +46,8 @@
//
//
-#include "private/qobject_p.h"
+#include "QtCore/qabstractitemmodel.h"
+#include "QtCore/private/qobject_p.h"
#include "QtCore/qstack.h"
#include "QtCore/qset.h"
#include "QtCore/qhash.h"
@@ -70,7 +71,7 @@ class Q_CORE_EXPORT QAbstractItemModelPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QAbstractItemModel)
public:
- QAbstractItemModelPrivate() : QObjectPrivate(), supportedDragActions(-1), roleNames(defaultRoleNames()) {}
+ QAbstractItemModelPrivate();
~QAbstractItemModelPrivate();
void removePersistentIndexData(QPersistentModelIndexData *data);
@@ -102,33 +103,13 @@ public:
return (index.row() >= 0) && (index.column() >= 0) && (index.model() == q_func());
}
- inline void invalidatePersistentIndexes() {
- foreach (QPersistentModelIndexData *data, persistent.indexes) {
- data->index = QModelIndex();
- data->model = 0;
- }
- persistent.indexes.clear();
- }
-
- /*!
- \internal
- clean the QPersistentModelIndex relative to the index if there is one.
- To be used before an index is invalided
- */
- inline void invalidatePersistentIndex(const QModelIndex &index) {
- QHash<QModelIndex, QPersistentModelIndexData *>::iterator it = persistent.indexes.find(index);
- if(it != persistent.indexes.end()) {
- QPersistentModelIndexData *data = *it;
- persistent.indexes.erase(it);
- data->index = QModelIndex();
- data->model = 0;
- }
- }
+ void invalidatePersistentIndexes();
+ void invalidatePersistentIndex(const QModelIndex &index);
struct Change {
- Change() : first(-1), last(-1) {}
- Change(const Change &c) : parent(c.parent), first(c.first), last(c.last), needsAdjust(c.needsAdjust) {}
- Change(const QModelIndex &p, int f, int l) : parent(p), first(f), last(l), needsAdjust(false) {}
+ Q_DECL_CONSTEXPR Change() : parent(), first(-1), last(-1), needsAdjust(false) {}
+ Q_DECL_CONSTEXPR Change(const QModelIndex &p, int f, int l) : parent(p), first(f), last(l), needsAdjust(false) {}
+
QModelIndex parent;
int first, last;
@@ -147,7 +128,7 @@ public:
// rowsMoved signal.
bool needsAdjust;
- bool isValid() { return first >= 0 && last >= 0; }
+ Q_DECL_CONSTEXPR bool isValid() const { return first >= 0 && last >= 0; }
};
QStack<Change> changes;
diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp
index dbbbbb8ff4..1dd7ceba76 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.cpp
+++ b/src/corelib/itemmodels/qabstractproxymodel.cpp
@@ -380,7 +380,7 @@ QMimeData* QAbstractProxyModel::mimeData(const QModelIndexList &indexes) const
Q_D(const QAbstractProxyModel);
QModelIndexList list;
list.reserve(indexes.count());
- foreach(const QModelIndex &index, indexes)
+ for (const QModelIndex &index : indexes)
list << mapToSource(index);
return d->model->mimeData(list);
}
diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp
index f46fd135ca..88e1e3f905 100644
--- a/src/corelib/itemmodels/qidentityproxymodel.cpp
+++ b/src/corelib/itemmodels/qidentityproxymodel.cpp
@@ -490,7 +490,8 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPe
{
Q_Q(QIdentityProxyModel);
- foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) {
+ const auto proxyPersistentIndexes = q->persistentIndexList();
+ for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) {
proxyIndexes << proxyPersistentIndex;
Q_ASSERT(proxyPersistentIndex.isValid());
const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
@@ -500,7 +501,7 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPe
QList<QPersistentModelIndex> parents;
parents.reserve(sourceParents.size());
- foreach (const QPersistentModelIndex &parent, sourceParents) {
+ for (const QPersistentModelIndex &parent : sourceParents) {
if (!parent.isValid()) {
parents << QPersistentModelIndex();
continue;
@@ -526,7 +527,7 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersistentM
QList<QPersistentModelIndex> parents;
parents.reserve(sourceParents.size());
- foreach (const QPersistentModelIndex &parent, sourceParents) {
+ for (const QPersistentModelIndex &parent : sourceParents) {
if (!parent.isValid()) {
parents << QPersistentModelIndex();
continue;
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp
index 51c670f79e..243558e6d9 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.cpp
+++ b/src/corelib/itemmodels/qitemselectionmodel.cpp
@@ -482,7 +482,7 @@ static QVector<QPersistentModelIndex> qSelectionPersistentindexes(const QItemSel
static QVector<QPair<QPersistentModelIndex, uint> > qSelectionPersistentRowLengths(const QItemSelection &sel)
{
QVector<QPair<QPersistentModelIndex, uint> > result;
- Q_FOREACH (const QItemSelectionRange &range, sel)
+ for (const QItemSelectionRange &range : sel)
rowLengthsFromRange(range, result);
return result;
}
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 0771fd0e30..a3dad1ae07 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -1013,7 +1013,7 @@ QModelIndexPairList QSortFilterProxyModelPrivate::store_persistent_indexes()
Q_Q(QSortFilterProxyModel);
QModelIndexPairList source_indexes;
source_indexes.reserve(persistent.indexes.count());
- foreach (QPersistentModelIndexData *data, persistent.indexes) {
+ for (QPersistentModelIndexData *data : qAsConst(persistent.indexes)) {
QModelIndex proxy_index = data->index;
QModelIndex source_index = q->mapToSource(proxy_index);
source_indexes.append(qMakePair(proxy_index, QPersistentModelIndex(source_index)));
@@ -1325,7 +1325,7 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<Q
saved_persistent_indexes.clear();
QList<QPersistentModelIndex> parents;
- foreach (const QPersistentModelIndex &parent, sourceParents) {
+ for (const QPersistentModelIndex &parent : sourceParents) {
if (!parent.isValid()) {
parents << QPersistentModelIndex();
continue;
@@ -1366,7 +1366,7 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersisten
}
QList<QPersistentModelIndex> parents;
- foreach (const QPersistentModelIndex &parent, sourceParents) {
+ for (const QPersistentModelIndex &parent : sourceParents) {
if (!parent.isValid()) {
parents << QPersistentModelIndex();
continue;
diff --git a/src/corelib/json/qjsonwriter.cpp b/src/corelib/json/qjsonwriter.cpp
index 45a05e93a3..0ab8b2bb80 100644
--- a/src/corelib/json/qjsonwriter.cpp
+++ b/src/corelib/json/qjsonwriter.cpp
@@ -32,6 +32,7 @@
**
****************************************************************************/
+#include <qlocale.h>
#include "qjsonwriter_p.h"
#include "qjson_p.h"
#include "private/qutfcodec_p.h"
@@ -123,7 +124,7 @@ static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value &
case QJsonValue::Double: {
const double d = v.toDouble(b);
if (qIsFinite(d)) // +2 to format to ensure the expected precision
- json += QByteArray::number(d, 'g', std::numeric_limits<double>::digits10 + 2); // ::digits10 is 15
+ json += QByteArray::number(d, 'g', QLocale::FloatingPointShortest);
else
json += "null"; // +INF || -INF || NaN (see RFC4627#section2.4)
break;
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index bc93791c2e..adcc9c5581 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -143,8 +143,14 @@ unix|integrity {
kernel/qcore_unix_p.h \
kernel/qcrashhandler_p.h \
kernel/qeventdispatcher_unix_p.h \
+ kernel/qpoll_p.h \
kernel/qtimerinfo_unix_p.h
+ contains(QT_CONFIG, poll_select): SOURCES += kernel/qpoll.cpp
+ contains(QT_CONFIG, poll_poll): DEFINES += QT_HAVE_POLL
+ contains(QT_CONFIG, poll_ppoll): DEFINES += QT_HAVE_POLL QT_HAVE_PPOLL
+ contains(QT_CONFIG, poll_pollts): DEFINES += QT_HAVE_POLL QT_HAVE_POLLTS
+
contains(QT_CONFIG, glib) {
SOURCES += \
kernel/qeventdispatcher_glib.cpp
@@ -176,13 +182,6 @@ vxworks {
kernel/qfunctions_vxworks.h
}
-blackberry {
- SOURCES += \
- kernel/qeventdispatcher_blackberry.cpp
- HEADERS += \
- kernel/qeventdispatcher_blackberry_p.h
-}
-
qqnx_pps {
LIBS_PRIVATE += -lpps
SOURCES += \
diff --git a/src/corelib/kernel/qabstractnativeeventfilter.cpp b/src/corelib/kernel/qabstractnativeeventfilter.cpp
index 9892cc7333..66bfa415a7 100644
--- a/src/corelib/kernel/qabstractnativeeventfilter.cpp
+++ b/src/corelib/kernel/qabstractnativeeventfilter.cpp
@@ -92,9 +92,6 @@ QAbstractNativeEventFilter::~QAbstractNativeEventFilter()
On Mac, \a eventType is set to "mac_generic_NSEvent", and the \a message can be casted to an EventRef.
- On Blackberry (not plain QNX) \a eventType is set to "bps_event_t", and the \a message can be casted
- to a bps_event_t pointer.
-
In your reimplementation of this function, if you want to filter
the \a message out, i.e. stop it being handled further, return
true; otherwise return false.
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index 5695cb3ec5..97c0efc36f 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -50,12 +50,13 @@
#include <mach/mach_time.h>
#endif
-#ifdef Q_OS_BLACKBERRY
-#include <qsocketnotifier.h>
-#endif // Q_OS_BLACKBERRY
-
QT_BEGIN_NAMESPACE
+#if !defined(QT_HAVE_PPOLL) && defined(QT_HAVE_POLLTS)
+# define ppoll pollts
+# define QT_HAVE_PPOLL
+#endif
+
static inline bool time_update(struct timespec *tv, const struct timespec &start,
const struct timespec &timeout)
{
@@ -85,9 +86,7 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
#ifndef Q_OS_QNX
ret = ::pselect(nfds, fdread, fdwrite, fdexcept, &timeout, 0);
#else
- timeval timeoutVal;
- timeoutVal.tv_sec = timeout.tv_sec;
- timeoutVal.tv_usec = timeout.tv_nsec / 1000;
+ timeval timeoutVal = timespecToTimeval(timeout);
ret = ::select(nfds, fdread, fdwrite, fdexcept, &timeoutVal);
#endif
if (ret != -1 || errno != EINTR)
@@ -102,43 +101,80 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
}
}
+static inline struct timespec millisecsToTimespec(const unsigned int ms)
+{
+ struct timespec tv;
+
+ tv.tv_sec = ms / 1000;
+ tv.tv_nsec = (ms % 1000) * 1000 * 1000;
+
+ return tv;
+}
+
int qt_select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout)
{
if (timeout < 0)
return qt_safe_select(nfds, fdread, fdwrite, 0, 0);
- struct timespec tv;
- tv.tv_sec = timeout / 1000;
- tv.tv_nsec = (timeout % 1000) * 1000 * 1000;
+ struct timespec tv = millisecsToTimespec(timeout);
return qt_safe_select(nfds, fdread, fdwrite, 0, &tv);
}
-#ifdef Q_OS_BLACKBERRY
-// The BlackBerry event dispatcher uses bps_get_event. Unfortunately, already registered
-// socket notifiers are disabled by a call to select. This is to rearm the standard streams.
-int bb_select(QList<QSocketNotifier *> socketNotifiers, int nfds, fd_set *fdread, fd_set *fdwrite,
- int timeout)
+#if !defined(QT_HAVE_PPOLL) && defined(QT_HAVE_POLL)
+static inline int timespecToMillisecs(const struct timespec *ts)
{
- QList<bool> socketNotifiersEnabled;
- socketNotifiersEnabled.reserve(socketNotifiers.count());
- for (int a = 0; a < socketNotifiers.count(); ++a) {
- if (socketNotifiers.at(a) && socketNotifiers.at(a)->isEnabled()) {
- socketNotifiersEnabled.append(true);
- socketNotifiers.at(a)->setEnabled(false);
- } else {
- socketNotifiersEnabled.append(false);
- }
- }
+ return (ts == NULL) ? -1 :
+ (ts->tv_sec * 1000) + (ts->tv_nsec / 1000000);
+}
+#endif
+
+// defined in qpoll.cpp
+int qt_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts);
+
+static inline int qt_ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts)
+{
+#if defined(QT_HAVE_PPOLL)
+ return ::ppoll(fds, nfds, timeout_ts, Q_NULLPTR);
+#elif defined(QT_HAVE_POLL)
+ return ::poll(fds, nfds, timespecToMillisecs(timeout_ts));
+#else
+ return qt_poll(fds, nfds, timeout_ts);
+#endif
+}
+
- const int ret = qt_select_msecs(nfds, fdread, fdwrite, timeout);
+/*!
+ \internal
- for (int a = 0; a < socketNotifiers.count(); ++a) {
- if (socketNotifiersEnabled.at(a) == true)
- socketNotifiers.at(a)->setEnabled(true);
+ Behaves as close to POSIX poll(2) as practical but may be implemented
+ using select(2) where necessary. In that case, returns -1 and sets errno
+ to EINVAL if passed any descriptor greater than or equal to FD_SETSIZE.
+*/
+int qt_safe_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts)
+{
+ if (!timeout_ts) {
+ // no timeout -> block forever
+ int ret;
+ EINTR_LOOP(ret, qt_ppoll(fds, nfds, Q_NULLPTR));
+ return ret;
}
- return ret;
+ timespec start = qt_gettime();
+ timespec timeout = *timeout_ts;
+
+ // loop and recalculate the timeout as needed
+ forever {
+ const int ret = qt_ppoll(fds, nfds, &timeout);
+ if (ret != -1 || errno != EINTR)
+ return ret;
+
+ // recalculate the timeout
+ if (!time_update(&timeout, start, *timeout_ts)) {
+ // timeout during update
+ // or clock reset, fake timeout error
+ return 0;
+ }
+ }
}
-#endif // Q_OS_BLACKBERRY
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index f80dcb5a50..fcc65589a0 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -66,6 +66,12 @@
# include <ioLib.h>
#endif
+#ifdef QT_NO_NATIVE_POLL
+# include "qpoll_p.h"
+#else
+# include <poll.h>
+#endif
+
struct sockaddr;
#define EINTR_LOOP(var, cmd) \
@@ -121,6 +127,14 @@ inline timespec operator*(const timespec &t1, int mul)
tmp.tv_nsec = t1.tv_nsec * mul;
return normalizedTimespec(tmp);
}
+inline timeval timespecToTimeval(const timespec &ts)
+{
+ timeval tv;
+ tv.tv_sec = ts.tv_sec;
+ tv.tv_usec = ts.tv_nsec / 1000;
+ return tv;
+}
+
inline void qt_ignore_sigpipe()
{
@@ -303,17 +317,13 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options)
timespec qt_gettime() Q_DECL_NOTHROW;
void qt_nanosleep(timespec amount);
+Q_CORE_EXPORT int qt_safe_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts);
+
Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
const struct timespec *tv);
int qt_select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout);
-#ifdef Q_OS_BLACKBERRY
-class QSocketNotifier;
-Q_CORE_EXPORT int bb_select(QList<QSocketNotifier *> socketNotifiers, int nfds, fd_set *fdread,
- fd_set *fdwrite, int timeout);
-#endif // Q_OS_BLACKBERRY
-
// according to X/OPEN we have to define semun ourselves
// we use prefix as on some systems sem.h will have it
struct semid_ds;
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index abc5af94cb..8d9b923e61 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -66,19 +66,14 @@
#ifndef QT_NO_QOBJECT
#if defined(Q_OS_UNIX)
-# if defined(Q_OS_BLACKBERRY)
-# include "qeventdispatcher_blackberry_p.h"
-# include <process.h>
-# include <unistd.h>
-# elif defined(Q_OS_OSX)
-# include "qeventdispatcher_cf_p.h"
-# include "qeventdispatcher_unix_p.h"
-# else
-# if !defined(QT_NO_GLIB)
-# include "qeventdispatcher_glib_p.h"
-# endif
-# include "qeventdispatcher_unix_p.h"
+# if defined(Q_OS_OSX)
+# include "qeventdispatcher_cf_p.h"
+# else
+# if !defined(QT_NO_GLIB)
+# include "qeventdispatcher_glib_p.h"
# endif
+# endif
+# include "qeventdispatcher_unix_p.h"
#endif
#ifdef Q_OS_WIN
# ifdef Q_OS_WINRT
@@ -338,34 +333,6 @@ struct QCoreApplicationData {
#endif
}
-#ifdef Q_OS_BLACKBERRY
- //The QCoreApplicationData struct is only populated on demand, because it is rarely needed and would
- //affect startup time
- void loadManifest() {
- static bool manifestLoadAttempt = false;
- if (manifestLoadAttempt)
- return;
-
- manifestLoadAttempt = true;
-
- QFile metafile(QStringLiteral("app/META-INF/MANIFEST.MF"));
- if (!metafile.open(QIODevice::ReadOnly)) {
- qWarning("Could not open application metafile for reading")
- } else {
- while (!metafile.atEnd() && (application.isEmpty() || applicationVersion.isEmpty() || orgName.isEmpty())) {
- QByteArray line = metafile.readLine();
- if (line.startsWith("Application-Name:"))
- application = QString::fromUtf8(line.mid(18).trimmed());
- else if (line.startsWith("Application-Version:"))
- applicationVersion = QString::fromUtf8(line.mid(21).trimmed());
- else if (line.startsWith("Package-Author:"))
- orgName = QString::fromUtf8(line.mid(16).trimmed());
- }
- metafile.close();
- }
- }
-#endif
-
QString orgName, orgDomain;
QString application; // application name, initially from argv[0], can then be modified.
QString applicationVersion;
@@ -450,7 +417,7 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
QCoreApplicationPrivate::is_app_closing = false;
# if defined(Q_OS_UNIX)
- if (!setuidAllowed && (geteuid() != getuid()))
+ if (Q_UNLIKELY(!setuidAllowed && (geteuid() != getuid())))
qFatal("FATAL: The application binary appears to be running setuid, this is a security hole.");
# endif // Q_OS_UNIX
@@ -506,9 +473,7 @@ void QCoreApplicationPrivate::createEventDispatcher()
{
Q_Q(QCoreApplication);
#if defined(Q_OS_UNIX)
-# if defined(Q_OS_BLACKBERRY)
- eventDispatcher = new QEventDispatcherBlackberry(q);
-# elif defined(Q_OS_OSX)
+# if defined(Q_OS_OSX)
bool ok = false;
int value = qEnvironmentVariableIntValue("QT_EVENT_DISPATCHER_CORE_FOUNDATION", &ok);
if (ok && value > 0)
@@ -600,7 +565,7 @@ void QCoreApplicationPrivate::initLocale()
if (qt_locale_initialized)
return;
qt_locale_initialized = true;
-#ifdef Q_OS_UNIX
+#if defined(Q_OS_UNIX) && !defined(QT_BOOTSTRAPPED)
setlocale(LC_ALL, "");
#endif
}
@@ -2135,33 +2100,6 @@ QString QCoreApplication::applicationFilePath()
#if defined(Q_OS_WIN)
QCoreApplicationPrivate::setApplicationFilePath(QFileInfo(qAppFileName()).filePath());
return *QCoreApplicationPrivate::cachedApplicationFilePath;
-#elif defined(Q_OS_BLACKBERRY)
- if (!arguments().isEmpty()) { // args is never empty, but the navigator can change behaviour some day
- QFileInfo fileInfo(arguments().at(0));
- const bool zygotized = fileInfo.exists();
- if (zygotized) {
- // Handle the zygotized case:
- QCoreApplicationPrivate::setApplicationFilePath(QDir::cleanPath(fileInfo.absoluteFilePath()));
- return *QCoreApplicationPrivate::cachedApplicationFilePath;
- }
- }
-
- // Handle the non-zygotized case:
- const size_t maximum_path = static_cast<size_t>(pathconf("/",_PC_PATH_MAX));
- char buff[maximum_path+1];
- if (_cmdname(buff)) {
- QCoreApplicationPrivate::setApplicationFilePath(QDir::cleanPath(QString::fromLocal8Bit(buff)));
- } else {
- qWarning("QCoreApplication::applicationFilePath: _cmdname() failed");
- // _cmdname() won't fail, but just in case, fallback to the old method
- QDir dir(QStringLiteral("./app/native/"));
- QStringList executables = dir.entryList(QDir::Executable | QDir::Files);
- if (!executables.empty()) {
- //We assume that there is only one executable in the folder
- QCoreApplicationPrivate::setApplicationFilePath(dir.absoluteFilePath(executables.first()));
- }
- }
- return *QCoreApplicationPrivate::cachedApplicationFilePath;
#elif defined(Q_OS_MAC)
QString qAppFileName_str = qAppFileName();
if(!qAppFileName_str.isEmpty()) {
@@ -2327,9 +2265,6 @@ QStringList QCoreApplication::arguments()
organizationName(). On all other platforms, QSettings uses
organizationName() as the organization.
- On BlackBerry this property is read-only. It is obtained from the
- BAR application descriptor file.
-
\sa organizationDomain, applicationName
*/
@@ -2354,9 +2289,6 @@ void QCoreApplication::setOrganizationName(const QString &orgName)
QString QCoreApplication::organizationName()
{
-#ifdef Q_OS_BLACKBERRY
- coreappdata()->loadManifest();
-#endif
return coreappdata()->orgName;
}
@@ -2407,9 +2339,6 @@ QString QCoreApplication::organizationDomain()
If not set, the application name defaults to the executable name (since 5.0).
- On BlackBerry this property is read-only. It is obtained from the
- BAR application descriptor file.
-
\sa organizationName, organizationDomain, applicationVersion, applicationFilePath()
*/
/*!
@@ -2435,9 +2364,6 @@ void QCoreApplication::setApplicationName(const QString &application)
QString QCoreApplication::applicationName()
{
-#ifdef Q_OS_BLACKBERRY
- coreappdata()->loadManifest();
-#endif
return coreappdata() ? coreappdata()->application : QString();
}
@@ -2452,9 +2378,6 @@ Q_CORE_EXPORT QString qt_applicationName_noFallback()
\since 4.4
\brief the version of this application
- On BlackBerry this property is read-only. It is obtained from the
- BAR application descriptor file.
-
\sa applicationName, organizationName, organizationDomain
*/
/*!
@@ -2476,9 +2399,6 @@ void QCoreApplication::setApplicationVersion(const QString &version)
QString QCoreApplication::applicationVersion()
{
-#ifdef Q_OS_BLACKBERRY
- coreappdata()->loadManifest();
-#endif
return coreappdata()->applicationVersion;
}
@@ -2698,7 +2618,7 @@ void QCoreApplication::removeLibraryPath(const QString &path)
i.e. MSG or XCB event structs.
\note Native event filters will be disabled in the application when the
- Qt::AA_MacPluginApplication attribute is set.
+ Qt::AA_PluginApplication attribute is set.
For maximum portability, you should always try to use QEvent
and QObject::installEventFilter() whenever possible.
@@ -2709,8 +2629,8 @@ void QCoreApplication::removeLibraryPath(const QString &path)
*/
void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
{
- if (QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
- qWarning("Native event filters are not applied when the Qt::AA_MacPluginApplication attribute is set");
+ if (QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
+ qWarning("Native event filters are not applied when the Qt::AA_PluginApplication attribute is set");
return;
}
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index 53da4a849b..d9de828fa1 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -276,6 +276,8 @@ public:
PlatformSurface = 217, // Platform surface created or about to be destroyed
+ Pointer = 218, // QQuickPointerEvent; ### Qt 6: QPointerEvent
+
// 512 reserved for Qt Jambi's MetaCall event
// 513 reserved for Qt Jambi's DeleteOnMainThread event
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry.cpp b/src/corelib/kernel/qeventdispatcher_blackberry.cpp
deleted file mode 100644
index a8e3d3c766..0000000000
--- a/src/corelib/kernel/qeventdispatcher_blackberry.cpp
+++ /dev/null
@@ -1,502 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeventdispatcher_blackberry_p.h"
-#include "qsocketnotifier.h"
-#include "qdebug.h"
-#include "qelapsedtimer.h"
-#include "private/qthread_p.h"
-
-#include <bps/bps.h>
-#include <bps/event.h>
-
-//#define QEVENTDISPATCHERBLACKBERRY_DEBUG
-
-#ifdef QEVENTDISPATCHERBLACKBERRY_DEBUG
-#include <QThread>
-#define qEventDispatcherDebug qDebug() << QThread::currentThread()
-#else
-#define qEventDispatcherDebug QT_NO_QDEBUG_MACRO()
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class BpsChannelScopeSwitcher
-{
-public:
- BpsChannelScopeSwitcher(int scopeChannel) : innerChannel(scopeChannel)
- {
- outerChannel = bps_channel_get_active();
- if (outerChannel != innerChannel)
- bps_channel_set_active(innerChannel);
- }
-
- ~BpsChannelScopeSwitcher()
- {
- if (outerChannel != innerChannel)
- bps_channel_set_active(outerChannel);
- }
-
-private:
- int innerChannel;
- int outerChannel;
-};
-
-class BBScopedLoopLevelCounter
-{
- QEventDispatcherBlackberryPrivate *d;
-
-public:
- inline BBScopedLoopLevelCounter(QEventDispatcherBlackberryPrivate *p)
- : d(p)
- { ++d->loop_level; }
-
- inline ~BBScopedLoopLevelCounter()
- { --d->loop_level; }
-};
-
-struct bpsIOHandlerData
-{
- bpsIOHandlerData()
- : count(0), readfds(0), writefds(0), exceptfds(0)
- {
- }
-
- int count;
- fd_set *readfds;
- fd_set *writefds;
- fd_set *exceptfds;
-};
-
-static int bpsUnblockDomain = -1;
-
-static int bpsIOHandler(int fd, int io_events, void *data)
-{
- qEventDispatcherDebug;
- // decode callback payload
- bpsIOHandlerData *ioData = static_cast<bpsIOHandlerData*>(data);
-
- // check if first file is ready
- bool firstReady = (ioData->count == 0);
-
- // update ready state of file
- if (io_events & BPS_IO_INPUT) {
- qEventDispatcherDebug << fd << "ready for Read";
- FD_SET(fd, ioData->readfds);
- ioData->count++;
- }
-
- if (io_events & BPS_IO_OUTPUT) {
- qEventDispatcherDebug << fd << "ready for Write";
- FD_SET(fd, ioData->writefds);
- ioData->count++;
- }
-
- if (io_events & BPS_IO_EXCEPT) {
- qEventDispatcherDebug << fd << "ready for Exception";
- FD_SET(fd, ioData->exceptfds);
- ioData->count++;
- }
-
- // force bps_get_event() to return immediately by posting an event to ourselves;
- // but this only needs to happen once if multiple files become ready at the same time
- if (firstReady) {
- qEventDispatcherDebug << "Sending bpsIOReadyDomain event";
- // create unblock event
- bps_event_t *event;
- int result = bps_event_create(&event, bpsUnblockDomain, 0, NULL, NULL);
- if (Q_UNLIKELY(result != BPS_SUCCESS)) {
- qWarning("QEventDispatcherBlackberry: bps_event_create failed");
- return BPS_FAILURE;
- }
-
- // post unblock event to our thread; in this callback the bps channel is
- // guaranteed to be the same that was active when bps_add_fd was called
- result = bps_push_event(event);
- if (Q_UNLIKELY(result != BPS_SUCCESS)) {
- qWarning("QEventDispatcherBlackberry: bps_push_event failed");
- bps_event_destroy(event);
- return BPS_FAILURE;
- }
- }
-
- return BPS_SUCCESS;
-}
-
-QEventDispatcherBlackberryPrivate::QEventDispatcherBlackberryPrivate()
- : loop_level(0)
- , ioData(new bpsIOHandlerData)
-{
- // prepare to use BPS
- int result = bps_initialize();
- if (Q_UNLIKELY(result != BPS_SUCCESS))
- qFatal("QEventDispatcherBlackberry: bps_initialize failed");
-
- 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();
- if (Q_UNLIKELY(bpsUnblockDomain == -1))
- qWarning("QEventDispatcherBlackberry: bps_register_domain failed");
- }
-}
-
-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();
-}
-
-int QEventDispatcherBlackberryPrivate::initThreadWakeUp()
-{
- return -1; // no fd's used
-}
-
-int QEventDispatcherBlackberryPrivate::processThreadWakeUp(int nsel)
-{
- Q_UNUSED(nsel);
- return wakeUps.fetchAndStoreRelaxed(0);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-QEventDispatcherBlackberry::QEventDispatcherBlackberry(QObject *parent)
- : QEventDispatcherUNIX(*new QEventDispatcherBlackberryPrivate, parent)
-{
-}
-
-QEventDispatcherBlackberry::QEventDispatcherBlackberry(QEventDispatcherBlackberryPrivate &dd, QObject *parent)
- : QEventDispatcherUNIX(dd, parent)
-{
-}
-
-QEventDispatcherBlackberry::~QEventDispatcherBlackberry()
-{
-}
-
-void QEventDispatcherBlackberry::registerSocketNotifier(QSocketNotifier *notifier)
-{
- Q_ASSERT(notifier);
- Q_D(QEventDispatcherBlackberry);
-
- int sockfd = notifier->socket();
- int type = notifier->type();
-
- qEventDispatcherDebug << "fd =" << sockfd;
-
- if (Q_UNLIKELY(sockfd >= FD_SETSIZE)) {
- qWarning() << "QEventDispatcherBlackberry: cannot register QSocketNotifier (fd too high)"
- << sockfd;
- return;
- }
-
- // Register the fd with bps
- BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
- int io_events = ioEvents(sockfd);
- if (io_events)
- bps_remove_fd(sockfd);
-
- switch (type) {
- case QSocketNotifier::Read:
- qEventDispatcherDebug << "Registering" << sockfd << "for Reads";
- io_events |= BPS_IO_INPUT;
- break;
- case QSocketNotifier::Write:
- qEventDispatcherDebug << "Registering" << sockfd << "for Writes";
- io_events |= BPS_IO_OUTPUT;
- break;
- case QSocketNotifier::Exception:
- default:
- qEventDispatcherDebug << "Registering" << sockfd << "for Exceptions";
- io_events |= BPS_IO_EXCEPT;
- break;
- }
-
- const int result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
- if (Q_UNLIKELY(result != BPS_SUCCESS))
- qWarning() << "QEventDispatcherBlackberry: bps_add_fd failed";
-
- // Call the base Unix implementation. Needed to allow select() to be called correctly
- QEventDispatcherUNIX::registerSocketNotifier(notifier);
-}
-
-void QEventDispatcherBlackberry::unregisterSocketNotifier(QSocketNotifier *notifier)
-{
- Q_D(QEventDispatcherBlackberry);
-
- int sockfd = notifier->socket();
-
- qEventDispatcherDebug << "fd =" << sockfd;
-
- if (Q_UNLIKELY(sockfd >= FD_SETSIZE)) {
- qWarning() << "QEventDispatcherBlackberry: cannot unregister QSocketNotifier" << sockfd;
- return;
- }
-
- // Allow the base Unix implementation to unregister the fd too (before call to ioEvents()!)
- QEventDispatcherUNIX::unregisterSocketNotifier(notifier);
-
- // Unregister the fd with bps
- BpsChannelScopeSwitcher channelSwitcher(d->bps_channel);
- int result = bps_remove_fd(sockfd);
- if (Q_UNLIKELY(result != BPS_SUCCESS))
- qWarning() << "QEventDispatcherBlackberry: bps_remove_fd failed" << sockfd;
-
- const int io_events = ioEvents(sockfd);
- // if other socket notifier is watching sockfd, readd it
- if (io_events) {
- result = bps_add_fd(sockfd, io_events, &bpsIOHandler, d->ioData.data());
- if (Q_UNLIKELY(result != BPS_SUCCESS))
- qWarning("QEventDispatcherBlackberry: bps_add_fd error");
- }
-}
-
-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);
-
- // prepare file sets for bps callback
- d->ioData->count = 0;
- d->ioData->readfds = readfds;
- d->ioData->writefds = writefds;
- d->ioData->exceptfds = exceptfds;
-
- // reset all file sets
- if (readfds)
- FD_ZERO(readfds);
-
- if (writefds)
- FD_ZERO(writefds);
-
- if (exceptfds)
- FD_ZERO(exceptfds);
-
- 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)
- timeoutTotal = timespecToMillisecs(*timeout);
- int timeoutLeft = timeoutTotal;
- timespec startTime = qt_gettime();
-
- // This loop exists such that we can drain the bps event queue of all native events
- // more efficiently than if we were to return control to Qt after each event. This
- // is important for handling touch events which can come in rapidly.
- forever {
- // Only emit the awake() and aboutToBlock() signals in the second iteration. For the
- // first iteration, the UNIX event dispatcher will have taken care of that already.
- // Also native events are actually processed one loop iteration after they were
- // retrieved with bps_get_event().
-
- // Filtering the native event should happen between the awake() and aboutToBlock()
- // signal emissions. The calls awake() - filterNativeEvent() - aboutToBlock() -
- // bps_get_event() need not to be interrupted by a break or return statement.
- if (eventCount > 0) {
- if (event) {
- 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
- // Clock source is monotonic, so we can recalculate how much timeout is left
- if (timeoutTotal != -1) {
- timespec t2 = qt_gettime();
- timeoutLeft = timeoutTotal
- - (timespecToMillisecs(t2) - timespecToMillisecs(startTime));
- if (timeoutLeft < 0)
- timeoutLeft = 0;
- }
-
- timespec tnext;
- if (d->timerList.timerWait(tnext)) {
- int timeoutNext = timespecToMillisecs(tnext);
- if (timeoutNext < timeoutLeft || timeoutTotal == -1) {
- timeoutTotal = timeoutLeft = timeoutNext;
- startTime = qt_gettime();
- }
- }
- }
-
- event = 0;
- { // We need to increase loop level in this scope,
- // because bps_get_event can also invoke callbacks
- QScopedLoopLevelCounter loopLevelCounter(d->threadData);
-
- // Wait for event or file to be ready
- const int result = bps_get_event(&event, timeoutLeft);
- if (Q_UNLIKELY(result != BPS_SUCCESS))
- qWarning("QEventDispatcherBlackberry: bps_get_event failed");
- }
-
- if (!event) // In case of !event, we break out of the loop to let Qt process the timers
- break; // (since timeout has expired) and socket notifiers that are now ready.
-
- 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;
-
- // Make sure we are not trapped in this loop due to continuous native events
- // also we cannot recalculate the timeout without a monotonic clock as the time may have changed
- const unsigned int maximumEventCount = 12;
- if (Q_UNLIKELY((eventCount > maximumEventCount && timeoutLeft == 0)
- || !QElapsedTimer::isMonotonic())) {
- 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;
-}
-
-void QEventDispatcherBlackberry::wakeUp()
-{
- Q_D(QEventDispatcherBlackberry);
- if (d->wakeUps.testAndSetAcquire(0, 1)) {
- bps_event_t *event;
- if (Q_LIKELY(bps_event_create(&event, bpsUnblockDomain, 0, 0, 0) == BPS_SUCCESS)) {
- if (Q_LIKELY(bps_channel_push_event(d->bps_channel, event) == BPS_SUCCESS))
- return;
- else
- bps_event_destroy(event);
- }
- qWarning("QEventDispatcherBlackberry: wakeUp failed");
- }
-}
-
-int QEventDispatcherBlackberry::ioEvents(int fd)
-{
- int io_events = 0;
-
- Q_D(QEventDispatcherBlackberry);
-
- if (FD_ISSET(fd, &d->sn_vec[0].enabled_fds))
- io_events |= BPS_IO_INPUT;
-
- if (FD_ISSET(fd, &d->sn_vec[1].enabled_fds))
- io_events |= BPS_IO_OUTPUT;
-
- if (FD_ISSET(fd, &d->sn_vec[2].enabled_fds))
- io_events |= BPS_IO_EXCEPT;
-
- return io_events;
-}
-
-QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qeventdispatcher_blackberry_p.h b/src/corelib/kernel/qeventdispatcher_blackberry_p.h
deleted file mode 100644
index 7912ae83c5..0000000000
--- a/src/corelib/kernel/qeventdispatcher_blackberry_p.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEVENTDISPATCHER_BLACKBERRY_P_H
-#define QEVENTDISPATCHER_BLACKBERRY_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qeventdispatcher_unix_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QEventDispatcherBlackberryPrivate;
-
-class Q_CORE_EXPORT QEventDispatcherBlackberry : public QEventDispatcherUNIX
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QEventDispatcherBlackberry)
-
-public:
- explicit QEventDispatcherBlackberry(QObject *parent = 0);
- ~QEventDispatcherBlackberry();
-
- void registerSocketNotifier(QSocketNotifier *notifier);
- void unregisterSocketNotifier(QSocketNotifier *notifier);
-
- void wakeUp();
-
-protected:
- QEventDispatcherBlackberry(QEventDispatcherBlackberryPrivate &dd, QObject *parent = 0);
-
- int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- timespec *timeout);
- int ioEvents(int fd);
-};
-
-struct bpsIOHandlerData;
-
-class Q_CORE_EXPORT QEventDispatcherBlackberryPrivate : public QEventDispatcherUNIXPrivate
-{
- Q_DECLARE_PUBLIC(QEventDispatcherBlackberry)
-
-public:
- QEventDispatcherBlackberryPrivate();
- ~QEventDispatcherBlackberryPrivate();
-
- int initThreadWakeUp();
- int processThreadWakeUp(int nsel);
-
- int bps_channel;
- int holding_channel;
- int loop_level;
- QScopedPointer<bpsIOHandlerData> ioData;
-};
-
-QT_END_NAMESPACE
-
-#endif // QEVENTDISPATCHER_BLACKBERRY_P_H
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 155f7b7aa2..f8102195cc 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -68,7 +68,7 @@
QT_BEGIN_NAMESPACE
-#if defined(Q_OS_INTEGRITY) || defined(Q_OS_VXWORKS)
+#if defined(Q_OS_VXWORKS)
static void initThreadPipeFD(int fd)
{
int ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -87,22 +87,11 @@ static void initThreadPipeFD(int fd)
QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
{
- extern Qt::HANDLE qt_application_thread_id;
- mainThread = (QThread::currentThreadId() == qt_application_thread_id);
bool pipefail = false;
// initialize the common parts of the event loop
-#if defined(Q_OS_NACL) || defined (Q_OS_BLACKBERRY)
+#if defined(Q_OS_NACL)
// do nothing.
-#elif defined(Q_OS_INTEGRITY)
- // INTEGRITY doesn't like a "select" on pipes, so use socketpair instead
- if (socketpair(AF_INET, SOCK_STREAM, 0, thread_pipe) == -1) {
- perror("QEventDispatcherUNIXPrivate(): Unable to create socket pair");
- pipefail = true;
- } else {
- initThreadPipeFD(thread_pipe[0]);
- initThreadPipeFD(thread_pipe[1]);
- }
#elif defined(Q_OS_VXWORKS)
char name[20];
qsnprintf(name, sizeof(name), "/pipe/qt_%08x", int(taskIdSelf()));
@@ -135,7 +124,7 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
}
#endif
- if (pipefail)
+ if (Q_UNLIKELY(pipefail))
qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe");
sn_highest = -1;
@@ -143,7 +132,7 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate()
QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate()
{
-#if defined(Q_OS_NACL) || defined (Q_OS_BLACKBERRY)
+#if defined(Q_OS_NACL)
// do nothing.
#elif defined(Q_OS_VXWORKS)
close(thread_pipe[0]);
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index df080809b6..18a96c6e9a 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -86,12 +86,6 @@ public:
class QEventDispatcherUNIXPrivate;
-#ifdef Q_OS_QNX
-# define FINAL_EXCEPT_BLACKBERRY
-#else
-# define FINAL_EXCEPT_BLACKBERRY Q_DECL_FINAL
-#endif
-
class Q_CORE_EXPORT QEventDispatcherUNIX : public QAbstractEventDispatcher
{
Q_OBJECT
@@ -104,8 +98,8 @@ public:
bool processEvents(QEventLoop::ProcessEventsFlags flags) Q_DECL_OVERRIDE;
bool hasPendingEvents() Q_DECL_OVERRIDE;
- void registerSocketNotifier(QSocketNotifier *notifier) FINAL_EXCEPT_BLACKBERRY;
- void unregisterSocketNotifier(QSocketNotifier *notifier) FINAL_EXCEPT_BLACKBERRY;
+ void registerSocketNotifier(QSocketNotifier *notifier) Q_DECL_FINAL;
+ void unregisterSocketNotifier(QSocketNotifier *notifier) Q_DECL_FINAL;
void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) Q_DECL_FINAL;
bool unregisterTimer(int timerId) Q_DECL_FINAL;
@@ -114,7 +108,7 @@ public:
int remainingTime(int timerId) Q_DECL_FINAL;
- void wakeUp() FINAL_EXCEPT_BLACKBERRY;
+ void wakeUp() Q_DECL_FINAL;
void interrupt() Q_DECL_FINAL;
void flush() Q_DECL_OVERRIDE;
@@ -140,10 +134,8 @@ public:
~QEventDispatcherUNIXPrivate();
int doSelect(QEventLoop::ProcessEventsFlags flags, timespec *timeout);
- virtual int initThreadWakeUp() FINAL_EXCEPT_BLACKBERRY;
- virtual int processThreadWakeUp(int nsel) FINAL_EXCEPT_BLACKBERRY;
-
- bool mainThread;
+ virtual int initThreadWakeUp() Q_DECL_FINAL;
+ virtual int processThreadWakeUp(int nsel) Q_DECL_FINAL;
// note for eventfd(7) support:
// if thread_pipe[1] is -1, then eventfd(7) is in use and is stored in thread_pipe[0]
@@ -163,8 +155,6 @@ public:
QAtomicInt interrupt; // bool
};
-#undef FINAL_EXCEPT_BLACKBERRY
-
QT_END_NAMESPACE
#endif // QEVENTDISPATCHER_UNIX_P_H
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index bb091e9f6d..62aaca88e9 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -667,7 +667,7 @@ void QEventDispatcherWin32::installMessageHook()
#ifndef Q_OS_WINCE
// setup GetMessage hook needed to drive our posted events
d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
- if (!d->getMessageHook) {
+ if (Q_UNLIKELY(!d->getMessageHook)) {
int errorCode = GetLastError();
qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s",
errorCode, qPrintable(qt_error_string(errorCode)));
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index 021e137273..c2302cbc5e 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -36,6 +36,7 @@
#include "qobject_p.h"
#include "qmetaobject_p.h"
+#include <vector>
#include <stdlib.h>
QT_BEGIN_NAMESPACE
@@ -88,7 +89,6 @@ static inline Q_DECL_UNUSED const QMetaObjectPrivate *priv(const uint* data)
class QMetaMethodBuilderPrivate
{
public:
- QMetaMethodBuilderPrivate() {} // for QVector, don't use
QMetaMethodBuilderPrivate
(QMetaMethod::MethodType _methodType,
const QByteArray& _signature,
@@ -145,7 +145,6 @@ Q_DECLARE_TYPEINFO(QMetaMethodBuilderPrivate, Q_MOVABLE_TYPE);
class QMetaPropertyBuilderPrivate
{
public:
- QMetaPropertyBuilderPrivate() {} // for QVector, don't use
QMetaPropertyBuilderPrivate
(const QByteArray& _name, const QByteArray& _type, int notifierIdx=-1,
int _revision = 0)
@@ -184,7 +183,6 @@ Q_DECLARE_TYPEINFO(QMetaPropertyBuilderPrivate, Q_MOVABLE_TYPE);
class QMetaEnumBuilderPrivate
{
public:
- QMetaEnumBuilderPrivate() {} // for QVector, don't use
QMetaEnumBuilderPrivate(const QByteArray& _name)
: name(_name), isFlag(false)
{
@@ -213,20 +211,20 @@ public:
QByteArray className;
const QMetaObject *superClass;
QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction;
- QVector<QMetaMethodBuilderPrivate> methods;
- QVector<QMetaMethodBuilderPrivate> constructors;
- QVector<QMetaPropertyBuilderPrivate> properties;
+ std::vector<QMetaMethodBuilderPrivate> methods;
+ std::vector<QMetaMethodBuilderPrivate> constructors;
+ std::vector<QMetaPropertyBuilderPrivate> properties;
QList<QByteArray> classInfoNames;
QList<QByteArray> classInfoValues;
- QVector<QMetaEnumBuilderPrivate> enumerators;
+ std::vector<QMetaEnumBuilderPrivate> enumerators;
QList<const QMetaObject *> relatedMetaObjects;
int flags;
};
bool QMetaObjectBuilderPrivate::hasRevisionedProperties() const
{
- for (int i = 0; i < properties.size(); ++i) {
- if (properties.at(i).revision)
+ for (const auto &property : properties) {
+ if (property.revision)
return true;
}
return false;
@@ -234,8 +232,8 @@ bool QMetaObjectBuilderPrivate::hasRevisionedProperties() const
bool QMetaObjectBuilderPrivate::hasRevisionedMethods() const
{
- for (int i = 0; i < methods.size(); ++i) {
- if (methods.at(i).revision)
+ for (const auto &method : methods) {
+ if (method.revision)
return true;
}
return false;
@@ -353,7 +351,7 @@ void QMetaObjectBuilder::setFlags(MetaObjectFlags flags)
*/
int QMetaObjectBuilder::methodCount() const
{
- return d->methods.size();
+ return int(d->methods.size());
}
/*!
@@ -363,7 +361,7 @@ int QMetaObjectBuilder::methodCount() const
*/
int QMetaObjectBuilder::constructorCount() const
{
- return d->constructors.size();
+ return int(d->constructors.size());
}
/*!
@@ -374,7 +372,7 @@ int QMetaObjectBuilder::constructorCount() const
*/
int QMetaObjectBuilder::propertyCount() const
{
- return d->properties.size();
+ return int(d->properties.size());
}
/*!
@@ -386,7 +384,7 @@ int QMetaObjectBuilder::propertyCount() const
*/
int QMetaObjectBuilder::enumeratorCount() const
{
- return d->enumerators.size();
+ return int(d->enumerators.size());
}
/*!
@@ -427,8 +425,8 @@ int QMetaObjectBuilder::relatedMetaObjectCount() const
*/
QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray& signature)
{
- int index = d->methods.size();
- d->methods.append(QMetaMethodBuilderPrivate(QMetaMethod::Method, signature));
+ int index = int(d->methods.size());
+ d->methods.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Method, signature));
return QMetaMethodBuilder(this, index);
}
@@ -444,8 +442,8 @@ QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray& signature)
QMetaMethodBuilder QMetaObjectBuilder::addMethod
(const QByteArray& signature, const QByteArray& returnType)
{
- int index = d->methods.size();
- d->methods.append(QMetaMethodBuilderPrivate
+ int index = int(d->methods.size());
+ d->methods.push_back(QMetaMethodBuilderPrivate
(QMetaMethod::Method, signature, returnType));
return QMetaMethodBuilder(this, index);
}
@@ -491,8 +489,8 @@ QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod& prototype)
*/
QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray& signature)
{
- int index = d->methods.size();
- d->methods.append(QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature));
+ int index = int(d->methods.size());
+ d->methods.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature));
return QMetaMethodBuilder(this, index);
}
@@ -506,8 +504,8 @@ QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray& signature)
*/
QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature)
{
- int index = d->methods.size();
- d->methods.append(QMetaMethodBuilderPrivate
+ int index = int(d->methods.size());
+ d->methods.push_back(QMetaMethodBuilderPrivate
(QMetaMethod::Signal, signature, QByteArray("void"), QMetaMethod::Public));
return QMetaMethodBuilder(this, index);
}
@@ -523,9 +521,9 @@ QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray& signature)
*/
QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray& signature)
{
- int index = d->constructors.size();
- d->constructors.append(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature,
- /*returnType=*/QByteArray()));
+ int index = int(d->constructors.size());
+ d->constructors.push_back(QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature,
+ /*returnType=*/QByteArray()));
return QMetaMethodBuilder(this, -(index + 1));
}
@@ -564,8 +562,8 @@ QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod& prototy
QMetaPropertyBuilder QMetaObjectBuilder::addProperty
(const QByteArray& name, const QByteArray& type, int notifierId)
{
- int index = d->properties.size();
- d->properties.append(QMetaPropertyBuilderPrivate(name, type, notifierId));
+ int index = int(d->properties.size());
+ d->properties.push_back(QMetaPropertyBuilderPrivate(name, type, notifierId));
return QMetaPropertyBuilder(this, index);
}
@@ -615,8 +613,8 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot
*/
QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray& name)
{
- int index = d->enumerators.size();
- d->enumerators.append(QMetaEnumBuilderPrivate(name));
+ int index = int(d->enumerators.size());
+ d->enumerators.push_back(QMetaEnumBuilderPrivate(name));
return QMetaEnumBuilder(this, index);
}
@@ -762,7 +760,7 @@ void QMetaObjectBuilder::addMetaObject
*/
QMetaMethodBuilder QMetaObjectBuilder::method(int index) const
{
- if (index >= 0 && index < d->methods.size())
+ if (uint(index) < d->methods.size())
return QMetaMethodBuilder(this, index);
else
return QMetaMethodBuilder();
@@ -775,7 +773,7 @@ QMetaMethodBuilder QMetaObjectBuilder::method(int index) const
*/
QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const
{
- if (index >= 0 && index < d->constructors.size())
+ if (uint(index) < d->constructors.size())
return QMetaMethodBuilder(this, -(index + 1));
else
return QMetaMethodBuilder();
@@ -788,7 +786,7 @@ QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const
*/
QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const
{
- if (index >= 0 && index < d->properties.size())
+ if (uint(index) < d->properties.size())
return QMetaPropertyBuilder(this, index);
else
return QMetaPropertyBuilder();
@@ -802,7 +800,7 @@ QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const
*/
QMetaEnumBuilder QMetaObjectBuilder::enumerator(int index) const
{
- if (index >= 0 && index < d->enumerators.size())
+ if (uint(index) < d->enumerators.size())
return QMetaEnumBuilder(this, index);
else
return QMetaEnumBuilder();
@@ -866,15 +864,15 @@ QByteArray QMetaObjectBuilder::classInfoValue(int index) const
*/
void QMetaObjectBuilder::removeMethod(int index)
{
- if (index >= 0 && index < d->methods.size()) {
- d->methods.removeAt(index);
- for (int prop = 0; prop < d->properties.size(); ++prop) {
+ if (uint(index) < d->methods.size()) {
+ d->methods.erase(d->methods.begin() + index);
+ for (auto &property : d->properties) {
// Adjust the indices of property notify signal references.
- if (d->properties[prop].notifySignal == index) {
- d->properties[prop].notifySignal = -1;
- d->properties[prop].setFlag(Notify, false);
- } else if (d->properties[prop].notifySignal > index)
- (d->properties[prop].notifySignal)--;
+ if (property.notifySignal == index) {
+ property.notifySignal = -1;
+ property.setFlag(Notify, false);
+ } else if (property.notifySignal > index)
+ property.notifySignal--;
}
}
}
@@ -888,8 +886,8 @@ void QMetaObjectBuilder::removeMethod(int index)
*/
void QMetaObjectBuilder::removeConstructor(int index)
{
- if (index >= 0 && index < d->constructors.size())
- d->constructors.removeAt(index);
+ if (uint(index) < d->constructors.size())
+ d->constructors.erase(d->constructors.begin() + index);
}
/*!
@@ -900,8 +898,8 @@ void QMetaObjectBuilder::removeConstructor(int index)
*/
void QMetaObjectBuilder::removeProperty(int index)
{
- if (index >= 0 && index < d->properties.size())
- d->properties.removeAt(index);
+ if (uint(index) < d->properties.size())
+ d->properties.erase(d->properties.begin() + index);
}
/*!
@@ -913,8 +911,8 @@ void QMetaObjectBuilder::removeProperty(int index)
*/
void QMetaObjectBuilder::removeEnumerator(int index)
{
- if (index >= 0 && index < d->enumerators.size())
- d->enumerators.removeAt(index);
+ if (uint(index) < d->enumerators.size())
+ d->enumerators.erase(d->enumerators.begin() + index);
}
/*!
@@ -959,9 +957,9 @@ void QMetaObjectBuilder::removeRelatedMetaObject(int index)
int QMetaObjectBuilder::indexOfMethod(const QByteArray& signature)
{
QByteArray sig = QMetaObject::normalizedSignature(signature);
- for (int index = 0; index < d->methods.size(); ++index) {
- if (sig == d->methods[index].signature)
- return index;
+ for (const auto &method : d->methods) {
+ if (sig == method.signature)
+ return int(&method - &d->methods.front());
}
return -1;
}
@@ -975,10 +973,9 @@ int QMetaObjectBuilder::indexOfMethod(const QByteArray& signature)
int QMetaObjectBuilder::indexOfSignal(const QByteArray& signature)
{
QByteArray sig = QMetaObject::normalizedSignature(signature);
- for (int index = 0; index < d->methods.size(); ++index) {
- if (sig == d->methods[index].signature &&
- d->methods[index].methodType() == QMetaMethod::Signal)
- return index;
+ for (const auto &method : d->methods) {
+ if (method.methodType() == QMetaMethod::Signal && sig == method.signature)
+ return int(&method - &d->methods.front());
}
return -1;
}
@@ -992,10 +989,9 @@ int QMetaObjectBuilder::indexOfSignal(const QByteArray& signature)
int QMetaObjectBuilder::indexOfSlot(const QByteArray& signature)
{
QByteArray sig = QMetaObject::normalizedSignature(signature);
- for (int index = 0; index < d->methods.size(); ++index) {
- if (sig == d->methods[index].signature &&
- d->methods[index].methodType() == QMetaMethod::Slot)
- return index;
+ for (const auto &method : d->methods) {
+ if (method.methodType() == QMetaMethod::Slot && sig == method.signature)
+ return int(&method - &d->methods.front());
}
return -1;
}
@@ -1009,9 +1005,9 @@ int QMetaObjectBuilder::indexOfSlot(const QByteArray& signature)
int QMetaObjectBuilder::indexOfConstructor(const QByteArray& signature)
{
QByteArray sig = QMetaObject::normalizedSignature(signature);
- for (int index = 0; index < d->constructors.size(); ++index) {
- if (sig == d->constructors[index].signature)
- return index;
+ for (const auto &constructor : d->constructors) {
+ if (sig == constructor.signature)
+ return int(&constructor - &d->constructors.front());
}
return -1;
}
@@ -1024,9 +1020,9 @@ int QMetaObjectBuilder::indexOfConstructor(const QByteArray& signature)
*/
int QMetaObjectBuilder::indexOfProperty(const QByteArray& name)
{
- for (int index = 0; index < d->properties.size(); ++index) {
- if (name == d->properties[index].name)
- return index;
+ for (const auto &property : d->properties) {
+ if (name == property.name)
+ return int(&property - &d->properties.front());
}
return -1;
}
@@ -1039,9 +1035,9 @@ int QMetaObjectBuilder::indexOfProperty(const QByteArray& name)
*/
int QMetaObjectBuilder::indexOfEnumerator(const QByteArray& name)
{
- for (int index = 0; index < d->enumerators.size(); ++index) {
- if (name == d->enumerators[index].name)
- return index;
+ for (const auto &enumerator : d->enumerators) {
+ if (name == enumerator.name)
+ return int(&enumerator - &d->enumerators.front());
}
return -1;
}
@@ -1155,11 +1151,11 @@ void QMetaStringTable::writeBlob(char *out) const
// Returns the sum of all parameters (including return type) for the given
// \a methods. This is needed for calculating the size of the methods'
// parameter type/name meta-data.
-static int aggregateParameterCount(const QVector<QMetaMethodBuilderPrivate> &methods)
+static int aggregateParameterCount(const std::vector<QMetaMethodBuilderPrivate> &methods)
{
int sum = 0;
- for (int i = 0; i < methods.size(); ++i)
- sum += methods.at(i).parameterCount() + 1; // +1 for return type
+ for (const auto &method : methods)
+ sum += method.parameterCount() + 1; // +1 for return type
return sum;
}
@@ -1200,8 +1196,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
= reinterpret_cast<QMetaObjectPrivate *>(buf + size);
int pmetaSize = size;
dataIndex = MetaObjectPrivateFieldCount;
- for (index = 0; index < d->properties.size(); ++index) {
- if (d->properties[index].notifySignal != -1) {
+ for (const auto &property : d->properties) {
+ if (property.notifySignal != -1) {
hasNotifySignals = true;
break;
}
@@ -1209,8 +1205,8 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
int methodParametersDataSize =
((aggregateParameterCount(d->methods)
+ aggregateParameterCount(d->constructors)) * 2) // types and parameter names
- - d->methods.size() // return "parameters" don't have names
- - d->constructors.size(); // "this" parameters don't have names
+ - int(d->methods.size()) // return "parameters" don't have names
+ - int(d->constructors.size()); // "this" parameters don't have names
if (buf) {
Q_STATIC_ASSERT_X(QMetaObjectPrivate::OutputRevision == 7, "QMetaObjectBuilder should generate the same version as moc");
pmeta->revision = QMetaObjectPrivate::OutputRevision;
@@ -1222,51 +1218,49 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
pmeta->classInfoData = dataIndex;
dataIndex += 2 * d->classInfoNames.size();
- pmeta->methodCount = d->methods.size();
+ pmeta->methodCount = int(d->methods.size());
pmeta->methodData = dataIndex;
- dataIndex += 5 * d->methods.size();
+ dataIndex += 5 * int(d->methods.size());
if (hasRevisionedMethods)
- dataIndex += d->methods.size();
+ dataIndex += int(d->methods.size());
paramsIndex = dataIndex;
dataIndex += methodParametersDataSize;
- pmeta->propertyCount = d->properties.size();
+ pmeta->propertyCount = int(d->properties.size());
pmeta->propertyData = dataIndex;
- dataIndex += 3 * d->properties.size();
+ dataIndex += 3 * int(d->properties.size());
if (hasNotifySignals)
- dataIndex += d->properties.size();
+ dataIndex += int(d->properties.size());
if (hasRevisionedProperties)
- dataIndex += d->properties.size();
+ dataIndex += int(d->properties.size());
- pmeta->enumeratorCount = d->enumerators.size();
+ pmeta->enumeratorCount = int(d->enumerators.size());
pmeta->enumeratorData = dataIndex;
- dataIndex += 4 * d->enumerators.size();
+ dataIndex += 4 * int(d->enumerators.size());
- pmeta->constructorCount = d->constructors.size();
+ pmeta->constructorCount = int(d->constructors.size());
pmeta->constructorData = dataIndex;
- dataIndex += 5 * d->constructors.size();
+ dataIndex += 5 * int(d->constructors.size());
} else {
- dataIndex += 2 * d->classInfoNames.size();
- dataIndex += 5 * d->methods.size();
+ dataIndex += 2 * int(d->classInfoNames.size());
+ dataIndex += 5 * int(d->methods.size());
if (hasRevisionedMethods)
- dataIndex += d->methods.size();
+ dataIndex += int(d->methods.size());
paramsIndex = dataIndex;
dataIndex += methodParametersDataSize;
- dataIndex += 3 * d->properties.size();
+ dataIndex += 3 * int(d->properties.size());
if (hasNotifySignals)
- dataIndex += d->properties.size();
+ dataIndex += int(d->properties.size());
if (hasRevisionedProperties)
- dataIndex += d->properties.size();
- dataIndex += 4 * d->enumerators.size();
- dataIndex += 5 * d->constructors.size();
+ dataIndex += int(d->properties.size());
+ dataIndex += 4 * int(d->enumerators.size());
+ dataIndex += 5 * int(d->constructors.size());
}
// Allocate space for the enumerator key names and values.
enumIndex = dataIndex;
- for (index = 0; index < d->enumerators.size(); ++index) {
- QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
- dataIndex += 2 * enumerator->keys.size();
- }
+ for (const auto &enumerator : d->enumerators)
+ dataIndex += 2 * enumerator.keys.size();
// Zero terminator at the end of the data offset table.
++dataIndex;
@@ -1305,44 +1299,41 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
// Output the methods in the class.
Q_ASSERT(!buf || dataIndex == pmeta->methodData);
- for (index = 0; index < d->methods.size(); ++index) {
- QMetaMethodBuilderPrivate *method = &(d->methods[index]);
- int name = strings.enter(method->name());
- int argc = method->parameterCount();
- int tag = strings.enter(method->tag);
- int attrs = method->attributes;
+ for (const auto &method : d->methods) {
+ int name = strings.enter(method.name());
+ int argc = method.parameterCount();
+ int tag = strings.enter(method.tag);
+ int attrs = method.attributes;
if (buf) {
data[dataIndex] = name;
data[dataIndex + 1] = argc;
data[dataIndex + 2] = paramsIndex;
data[dataIndex + 3] = tag;
data[dataIndex + 4] = attrs;
- if (method->methodType() == QMetaMethod::Signal)
+ if (method.methodType() == QMetaMethod::Signal)
pmeta->signalCount++;
}
dataIndex += 5;
paramsIndex += 1 + argc * 2;
}
if (hasRevisionedMethods) {
- for (index = 0; index < d->methods.size(); ++index) {
- QMetaMethodBuilderPrivate *method = &(d->methods[index]);
+ for (const auto &method : d->methods) {
if (buf)
- data[dataIndex] = method->revision;
+ data[dataIndex] = method.revision;
++dataIndex;
}
}
// Output the method parameters in the class.
- Q_ASSERT(!buf || dataIndex == pmeta->methodData + d->methods.size() * 5
- + (hasRevisionedMethods ? d->methods.size() : 0));
+ Q_ASSERT(!buf || dataIndex == pmeta->methodData + int(d->methods.size()) * 5
+ + (hasRevisionedMethods ? int(d->methods.size()) : 0));
for (int x = 0; x < 2; ++x) {
- QVector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors;
- for (index = 0; index < methods.size(); ++index) {
- QMetaMethodBuilderPrivate *method = &(methods[index]);
- QList<QByteArray> paramTypeNames = method->parameterTypes();
+ const std::vector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors;
+ for (const auto &method : methods) {
+ const QList<QByteArray> paramTypeNames = method.parameterTypes();
int paramCount = paramTypeNames.size();
for (int i = -1; i < paramCount; ++i) {
- const QByteArray &typeName = (i < 0) ? method->returnType : paramTypeNames.at(i);
+ const QByteArray &typeName = (i < 0) ? method.returnType : paramTypeNames.at(i);
int typeInfo;
if (QtPrivate::isBuiltinType(typeName))
typeInfo = QMetaType::type(typeName);
@@ -1353,7 +1344,7 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
++dataIndex;
}
- QList<QByteArray> paramNames = method->parameterNames;
+ QList<QByteArray> paramNames = method.parameterNames;
while (paramNames.size() < paramCount)
paramNames.append(QByteArray());
for (int i = 0; i < paramCount; ++i) {
@@ -1367,19 +1358,18 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
// Output the properties in the class.
Q_ASSERT(!buf || dataIndex == pmeta->propertyData);
- for (index = 0; index < d->properties.size(); ++index) {
- QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
- int name = strings.enter(prop->name);
+ for (const auto &prop : d->properties) {
+ int name = strings.enter(prop.name);
int typeInfo;
- if (QtPrivate::isBuiltinType(prop->type))
- typeInfo = QMetaType::type(prop->type);
+ if (QtPrivate::isBuiltinType(prop.type))
+ typeInfo = QMetaType::type(prop.type);
else
- typeInfo = IsUnresolvedType | strings.enter(prop->type);
+ typeInfo = IsUnresolvedType | strings.enter(prop.type);
- int flags = prop->flags;
+ int flags = prop.flags;
- if (!QtPrivate::isBuiltinType(prop->type))
+ if (!QtPrivate::isBuiltinType(prop.type))
flags |= EnumOrFlag;
if (buf) {
@@ -1390,11 +1380,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
dataIndex += 3;
}
if (hasNotifySignals) {
- for (index = 0; index < d->properties.size(); ++index) {
- QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
+ for (const auto &prop : d->properties) {
if (buf) {
- if (prop->notifySignal != -1)
- data[dataIndex] = prop->notifySignal;
+ if (prop.notifySignal != -1)
+ data[dataIndex] = prop.notifySignal;
else
data[dataIndex] = 0;
}
@@ -1402,21 +1391,19 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
}
}
if (hasRevisionedProperties) {
- for (index = 0; index < d->properties.size(); ++index) {
- QMetaPropertyBuilderPrivate *prop = &(d->properties[index]);
+ for (const auto &prop : d->properties) {
if (buf)
- data[dataIndex] = prop->revision;
+ data[dataIndex] = prop.revision;
++dataIndex;
}
}
// Output the enumerators in the class.
Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData);
- for (index = 0; index < d->enumerators.size(); ++index) {
- QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
- int name = strings.enter(enumerator->name);
- int isFlag = (int)(enumerator->isFlag);
- int count = enumerator->keys.size();
+ for (const auto &enumerator : d->enumerators) {
+ int name = strings.enter(enumerator.name);
+ int isFlag = (int)(enumerator.isFlag);
+ int count = enumerator.keys.size();
int enumOffset = enumIndex;
if (buf) {
data[dataIndex] = name;
@@ -1425,10 +1412,10 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
data[dataIndex + 3] = enumOffset;
}
for (int key = 0; key < count; ++key) {
- int keyIndex = strings.enter(enumerator->keys[key]);
+ int keyIndex = strings.enter(enumerator.keys[key]);
if (buf) {
data[enumOffset++] = keyIndex;
- data[enumOffset++] = enumerator->values[key];
+ data[enumOffset++] = enumerator.values[key];
}
}
dataIndex += 4;
@@ -1437,12 +1424,11 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf,
// Output the constructors in the class.
Q_ASSERT(!buf || dataIndex == pmeta->constructorData);
- for (index = 0; index < d->constructors.size(); ++index) {
- QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
- int name = strings.enter(method->name());
- int argc = method->parameterCount();
- int tag = strings.enter(method->tag);
- int attrs = method->attributes;
+ for (const auto &ctor : d->constructors) {
+ int name = strings.enter(ctor.name());
+ int argc = ctor.parameterCount();
+ int tag = strings.enter(ctor.tag);
+ int attrs = ctor.attributes;
if (buf) {
data[dataIndex] = name;
data[dataIndex + 1] = argc;
@@ -1612,10 +1598,10 @@ void QMetaObjectBuilder::serialize(QDataStream& stream) const
// Write the counts for each type of class member.
stream << d->classInfoNames.size();
- stream << d->methods.size();
- stream << d->properties.size();
- stream << d->enumerators.size();
- stream << d->constructors.size();
+ stream << int(d->methods.size());
+ stream << int(d->properties.size());
+ stream << int(d->enumerators.size());
+ stream << int(d->constructors.size());
stream << d->relatedMetaObjects.size();
// Write the items of class information.
@@ -1625,45 +1611,41 @@ void QMetaObjectBuilder::serialize(QDataStream& stream) const
}
// Write the methods.
- for (index = 0; index < d->methods.size(); ++index) {
- const QMetaMethodBuilderPrivate *method = &(d->methods[index]);
- stream << method->signature;
- stream << method->returnType;
- stream << method->parameterNames;
- stream << method->tag;
- stream << method->attributes;
- if (method->revision)
- stream << method->revision;
+ for (const auto &method : d->methods) {
+ stream << method.signature;
+ stream << method.returnType;
+ stream << method.parameterNames;
+ stream << method.tag;
+ stream << method.attributes;
+ if (method.revision)
+ stream << method.revision;
}
// Write the properties.
- for (index = 0; index < d->properties.size(); ++index) {
- const QMetaPropertyBuilderPrivate *property = &(d->properties[index]);
- stream << property->name;
- stream << property->type;
- stream << property->flags;
- stream << property->notifySignal;
- if (property->revision)
- stream << property->revision;
+ for (const auto &property : d->properties) {
+ stream << property.name;
+ stream << property.type;
+ stream << property.flags;
+ stream << property.notifySignal;
+ if (property.revision)
+ stream << property.revision;
}
// Write the enumerators.
- for (index = 0; index < d->enumerators.size(); ++index) {
- const QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
- stream << enumerator->name;
- stream << enumerator->isFlag;
- stream << enumerator->keys;
- stream << enumerator->values;
+ for (const auto &enumerator : d->enumerators) {
+ stream << enumerator.name;
+ stream << enumerator.isFlag;
+ stream << enumerator.keys;
+ stream << enumerator.values;
}
// Write the constructors.
- for (index = 0; index < d->constructors.size(); ++index) {
- const QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
- stream << method->signature;
- stream << method->returnType;
- stream << method->parameterNames;
- stream << method->tag;
- stream << method->attributes;
+ for (const auto &ctor : d->constructors) {
+ stream << ctor.signature;
+ stream << ctor.returnType;
+ stream << ctor.parameterNames;
+ stream << ctor.tag;
+ stream << ctor.attributes;
}
// Write the related meta objects.
@@ -1770,14 +1752,14 @@ void QMetaObjectBuilder::deserialize
return;
stream >> name;
addMethod(name);
- QMetaMethodBuilderPrivate *method = &(d->methods[index]);
- stream >> method->returnType;
- stream >> method->parameterNames;
- stream >> method->tag;
- stream >> method->attributes;
- if (method->attributes & MethodRevisioned)
- stream >> method->revision;
- if (method->methodType() == QMetaMethod::Constructor) {
+ QMetaMethodBuilderPrivate &method = d->methods[index];
+ stream >> method.returnType;
+ stream >> method.parameterNames;
+ stream >> method.tag;
+ stream >> method.attributes;
+ if (method.attributes & MethodRevisioned)
+ stream >> method.revision;
+ if (method.methodType() == QMetaMethod::Constructor) {
// Cannot add a constructor in this set of methods.
stream.setStatus(QDataStream::ReadCorruptData);
return;
@@ -1792,23 +1774,23 @@ void QMetaObjectBuilder::deserialize
stream >> name;
stream >> type;
addProperty(name, type);
- QMetaPropertyBuilderPrivate *property = &(d->properties[index]);
- stream >> property->flags;
- stream >> property->notifySignal;
- if (property->notifySignal < -1 ||
- property->notifySignal >= d->methods.size()) {
+ QMetaPropertyBuilderPrivate &property = d->properties[index];
+ stream >> property.flags;
+ stream >> property.notifySignal;
+ if (property.notifySignal < -1 ||
+ property.notifySignal >= int(d->methods.size())) {
// Notify signal method index is out of range.
stream.setStatus(QDataStream::ReadCorruptData);
return;
}
- if (property->notifySignal >= 0 &&
- d->methods[property->notifySignal].methodType() != QMetaMethod::Signal) {
+ if (property.notifySignal >= 0 &&
+ d->methods[property.notifySignal].methodType() != QMetaMethod::Signal) {
// Notify signal method index does not refer to a signal.
stream.setStatus(QDataStream::ReadCorruptData);
return;
}
- if (property->flags & Revisioned)
- stream >> property->revision;
+ if (property.flags & Revisioned)
+ stream >> property.revision;
}
// Read the enumerators.
@@ -1817,11 +1799,11 @@ void QMetaObjectBuilder::deserialize
return;
stream >> name;
addEnumerator(name);
- QMetaEnumBuilderPrivate *enumerator = &(d->enumerators[index]);
- stream >> enumerator->isFlag;
- stream >> enumerator->keys;
- stream >> enumerator->values;
- if (enumerator->keys.size() != enumerator->values.size()) {
+ QMetaEnumBuilderPrivate &enumerator = d->enumerators[index];
+ stream >> enumerator.isFlag;
+ stream >> enumerator.keys;
+ stream >> enumerator.values;
+ if (enumerator.keys.size() != enumerator.values.size()) {
// Mismatch between number of keys and number of values.
stream.setStatus(QDataStream::ReadCorruptData);
return;
@@ -1834,12 +1816,12 @@ void QMetaObjectBuilder::deserialize
return;
stream >> name;
addConstructor(name);
- QMetaMethodBuilderPrivate *method = &(d->constructors[index]);
- stream >> method->returnType;
- stream >> method->parameterNames;
- stream >> method->tag;
- stream >> method->attributes;
- if (method->methodType() != QMetaMethod::Constructor) {
+ QMetaMethodBuilderPrivate &method = d->constructors[index];
+ stream >> method.returnType;
+ stream >> method.parameterNames;
+ stream >> method.tag;
+ stream >> method.attributes;
+ if (method.methodType() != QMetaMethod::Constructor) {
// The type must be Constructor.
stream.setStatus(QDataStream::ReadCorruptData);
return;
@@ -1875,9 +1857,9 @@ void QMetaObjectBuilder::deserialize
QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const
{
// Positive indices indicate methods, negative indices indicate constructors.
- if (_mobj && _index >= 0 && _index < _mobj->d->methods.size())
+ if (_mobj && _index >= 0 && _index < int(_mobj->d->methods.size()))
return &(_mobj->d->methods[_index]);
- else if (_mobj && -_index >= 1 && -_index <= _mobj->d->constructors.size())
+ else if (_mobj && -_index >= 1 && -_index <= int(_mobj->d->constructors.size()))
return &(_mobj->d->constructors[(-_index) - 1]);
else
return 0;
@@ -2116,7 +2098,7 @@ void QMetaMethodBuilder::setRevision(int revision)
QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const
{
- if (_mobj && _index >= 0 && _index < _mobj->d->properties.size())
+ if (_mobj && _index >= 0 && _index < int(_mobj->d->properties.size()))
return &(_mobj->d->properties[_index]);
else
return 0;
@@ -2588,7 +2570,7 @@ void QMetaPropertyBuilder::setRevision(int revision)
QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const
{
- if (_mobj && _index >= 0 && _index < _mobj->d->enumerators.size())
+ if (_mobj && _index >= 0 && _index < int(_mobj->d->enumerators.size()))
return &(_mobj->d->enumerators[_index]);
else
return 0;
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index e6d745bb74..c0caa3cca5 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -1074,7 +1074,7 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
previousFlags = QMetaType::typeFlags(idx);
}
- if (previousSize != size) {
+ if (Q_UNLIKELY(previousSize != size)) {
qFatal("QMetaType::registerType: Binary compatibility break "
"-- Size mismatch for type '%s' [%i]. Previously registered "
"size %i, now registering size %i.",
@@ -1084,7 +1084,7 @@ int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName,
// these flags cannot change in a binary compatible way:
const int binaryCompatibilityFlag = PointerToQObject | IsEnumeration | SharedPointerToQObject
| WeakPointerToQObject | TrackingPointerToQObject;
- if ((previousFlags ^ flags) & binaryCompatibilityFlag) {
+ if (Q_UNLIKELY((previousFlags ^ flags) & binaryCompatibilityFlag)) {
const char *msg = "QMetaType::registerType: Binary compatibility break. "
"\nType flags for type '%s' [%i] don't match. Previously "
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index c316ebc69f..a4531e29eb 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -203,7 +203,7 @@ QObjectPrivate::QObjectPrivate(int version)
// This allows incompatible versions to be loaded, possibly for testing.
Q_UNUSED(version);
#else
- if (version != QObjectPrivateVersion)
+ if (Q_UNLIKELY(version != QObjectPrivateVersion))
qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
version, QObjectPrivateVersion);
#endif
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 64c5b58fd4..118316484b 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -293,7 +293,7 @@ public:
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
Qt::ConnectionType type = Qt::AutoConnection)
{
-#if defined (Q_COMPILER_DECLTYPE) && defined (Q_COMPILER_VARIADIC_TEMPLATES)
+#if defined (Q_COMPILER_VARIADIC_TEMPLATES)
typedef QtPrivate::FunctionPointer<Func1> SignalType;
const int FunctorArgumentCount = QtPrivate::ComputeFunctorArgumentCount<Func2 , typename SignalType::Arguments>::Value;
@@ -313,15 +313,7 @@ public:
Functors with overloaded or templated operator() are only supported if the compiler supports
C++11 variadic templates
*/
-#ifndef Q_COMPILER_DECLTYPE //Workaround the lack of decltype using another function as indirection
- return connect_functor(sender, signal, context, slot, &Func2::operator(), type); }
- template <typename Func1, typename Func2, typename Func2Operator>
- static inline QMetaObject::Connection connect_functor(const QObject *sender, Func1 signal, const QObject *context,
- Func2 slot, Func2Operator, Qt::ConnectionType type) {
- typedef QtPrivate::FunctionPointer<Func2Operator> SlotType ;
-#else
typedef QtPrivate::FunctionPointer<decltype(&Func2::operator())> SlotType ;
-#endif
typedef QtPrivate::FunctionPointer<Func1> SignalType;
typedef typename SlotType::ReturnType SlotReturnType;
const int SlotArgumentCount = SlotType::ArgumentCount;
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index d5574a4dd1..dc445a426d 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -593,7 +593,7 @@ namespace QtPrivate {
};
#endif
-#if defined(Q_COMPILER_DECLTYPE) && defined(Q_COMPILER_VARIADIC_TEMPLATES)
+#if defined(Q_COMPILER_VARIADIC_TEMPLATES)
/*
Find the maximum number of arguments a functor object can take and be still compatible with
the arguments from the signal.
diff --git a/src/corelib/kernel/qpoll.cpp b/src/corelib/kernel/qpoll.cpp
new file mode 100644
index 0000000000..b152518c00
--- /dev/null
+++ b/src/corelib/kernel/qpoll.cpp
@@ -0,0 +1,220 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcore_unix_p.h"
+
+QT_BEGIN_NAMESPACE
+
+#define QT_POLL_READ_MASK (POLLIN | POLLRDNORM)
+#define QT_POLL_WRITE_MASK (POLLOUT | POLLWRNORM | POLLWRBAND)
+#define QT_POLL_EXCEPT_MASK (POLLPRI | POLLRDBAND)
+#define QT_POLL_ERROR_MASK (POLLERR | POLLNVAL)
+#define QT_POLL_EVENTS_MASK (QT_POLL_READ_MASK | QT_POLL_WRITE_MASK | QT_POLL_EXCEPT_MASK)
+
+static inline int qt_poll_prepare(struct pollfd *fds, nfds_t nfds,
+ fd_set *read_fds, fd_set *write_fds, fd_set *except_fds)
+{
+ int max_fd = -1;
+
+ FD_ZERO(read_fds);
+ FD_ZERO(write_fds);
+ FD_ZERO(except_fds);
+
+ for (nfds_t i = 0; i < nfds; i++) {
+ if (fds[i].fd >= FD_SETSIZE) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((fds[i].fd < 0) || (fds[i].revents & QT_POLL_ERROR_MASK))
+ continue;
+
+ if (fds[i].events & QT_POLL_READ_MASK)
+ FD_SET(fds[i].fd, read_fds);
+
+ if (fds[i].events & QT_POLL_WRITE_MASK)
+ FD_SET(fds[i].fd, write_fds);
+
+ if (fds[i].events & QT_POLL_EXCEPT_MASK)
+ FD_SET(fds[i].fd, except_fds);
+
+ if (fds[i].events & QT_POLL_EVENTS_MASK)
+ max_fd = qMax(max_fd, fds[i].fd);
+ }
+
+ return max_fd + 1;
+}
+
+static inline void qt_poll_examine_ready_read(struct pollfd &pfd)
+{
+ int res;
+ char data;
+
+ EINTR_LOOP(res, ::recv(pfd.fd, &data, sizeof(data), MSG_PEEK));
+ const int error = (res < 0) ? errno : 0;
+
+ if (res == 0) {
+ pfd.revents |= POLLHUP;
+ } else if (res > 0 || error == ENOTSOCK || error == ENOTCONN) {
+ pfd.revents |= QT_POLL_READ_MASK & pfd.events;
+ } else {
+ switch (error) {
+ case ESHUTDOWN:
+ case ECONNRESET:
+ case ECONNABORTED:
+ case ENETRESET:
+ pfd.revents |= POLLHUP;
+ break;
+ default:
+ pfd.revents |= POLLERR;
+ break;
+ }
+ }
+}
+
+static inline int qt_poll_sweep(struct pollfd *fds, nfds_t nfds,
+ fd_set *read_fds, fd_set *write_fds, fd_set *except_fds)
+{
+ int result = 0;
+
+ for (nfds_t i = 0; i < nfds; i++) {
+ if (fds[i].fd < 0)
+ continue;
+
+ if (FD_ISSET(fds[i].fd, read_fds))
+ qt_poll_examine_ready_read(fds[i]);
+
+ if (FD_ISSET(fds[i].fd, write_fds))
+ fds[i].revents |= QT_POLL_WRITE_MASK & fds[i].events;
+
+ if (FD_ISSET(fds[i].fd, except_fds))
+ fds[i].revents |= QT_POLL_EXCEPT_MASK & fds[i].events;
+
+ if (fds[i].revents != 0)
+ result++;
+ }
+
+ return result;
+}
+
+static inline bool qt_poll_is_bad_fd(int fd)
+{
+ int ret;
+ EINTR_LOOP(ret, fcntl(fd, F_GETFD));
+ return (ret == -1 && errno == EBADF);
+}
+
+static inline int qt_poll_mark_bad_fds(struct pollfd *fds, const nfds_t nfds)
+{
+ int n_marked = 0;
+
+ for (nfds_t i = 0; i < nfds; i++) {
+ if (fds[i].fd < 0)
+ continue;
+
+ if (fds[i].revents & QT_POLL_ERROR_MASK)
+ continue;
+
+ if (qt_poll_is_bad_fd(fds[i].fd)) {
+ fds[i].revents |= POLLNVAL;
+ n_marked++;
+ }
+ }
+
+ return n_marked;
+}
+
+int qt_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts)
+{
+ if (!fds && nfds) {
+ errno = EFAULT;
+ return -1;
+ }
+
+ fd_set read_fds, write_fds, except_fds;
+ struct timeval tv, *ptv = 0;
+
+ if (timeout_ts) {
+ tv = timespecToTimeval(*timeout_ts);
+ ptv = &tv;
+ }
+
+ int n_bad_fds = 0;
+
+ for (nfds_t i = 0; i < nfds; i++) {
+ fds[i].revents = 0;
+
+ if (fds[i].fd < 0)
+ continue;
+
+ if (fds[i].events & QT_POLL_EVENTS_MASK)
+ continue;
+
+ if (qt_poll_is_bad_fd(fds[i].fd)) {
+ // Mark bad file descriptors that have no event flags set
+ // here, as we won't be passing them to select below and therefore
+ // need to do the check ourselves
+ fds[i].revents = POLLNVAL;
+ n_bad_fds++;
+ }
+ }
+
+ forever {
+ const int max_fd = qt_poll_prepare(fds, nfds, &read_fds, &write_fds, &except_fds);
+
+ if (max_fd < 0)
+ return max_fd;
+
+ if (n_bad_fds > 0) {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ ptv = &tv;
+ }
+
+ const int ret = ::select(max_fd, &read_fds, &write_fds, &except_fds, ptv);
+
+ if (ret == 0)
+ return n_bad_fds;
+
+ if (ret > 0)
+ return qt_poll_sweep(fds, nfds, &read_fds, &write_fds, &except_fds);
+
+ if (errno != EBADF)
+ return -1;
+
+ // We have at least one bad file descriptor that we waited on, find out which and try again
+ n_bad_fds += qt_poll_mark_bad_fds(fds, nfds);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qpoll_p.h b/src/corelib/kernel/qpoll_p.h
new file mode 100644
index 0000000000..497058ad6b
--- /dev/null
+++ b/src/corelib/kernel/qpoll_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPOLL_P_H
+#define QPOLL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of Qt code on Unix. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_NO_NATIVE_POLL
+
+#include <unistd.h>
+#include <time.h>
+
+struct pollfd {
+ int fd;
+ short events, revents;
+};
+
+typedef unsigned long int nfds_t;
+
+#define POLLIN 0x001
+#define POLLPRI 0x002
+#define POLLOUT 0x004
+#define POLLERR 0x008
+#define POLLHUP 0x010
+#define POLLNVAL 0x020
+#define POLLRDNORM 0x040
+#define POLLRDBAND 0x080
+#define POLLWRNORM 0x100
+#define POLLWRBAND 0x200
+
+#endif // QT_NO_NATIVE_POLL
+
+QT_END_NAMESPACE
+
+#endif // QPOLL_P_H
diff --git a/src/corelib/kernel/qsharedmemory_p.h b/src/corelib/kernel/qsharedmemory_p.h
index 2bcc0d4f6a..149bc85a15 100644
--- a/src/corelib/kernel/qsharedmemory_p.h
+++ b/src/corelib/kernel/qsharedmemory_p.h
@@ -61,7 +61,7 @@ namespace QSharedMemoryPrivate
#include "qsystemsemaphore.h"
#include "private/qobject_p.h"
-#if !defined(Q_OS_WIN) && !defined(Q_OS_ANDROID)
+#if !defined(Q_OS_WIN) && !defined(Q_OS_ANDROID) && !defined(Q_OS_INTEGRITY)
# include <sys/sem.h>
#endif
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index 794a4aaa0c..dad471c1b0 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -613,6 +613,13 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo
return false;
}
+Q_NEVER_INLINE
+static bool is_readable_file(const QString &name)
+{
+ const QFileInfo fi(name);
+ return fi.isReadable() && fi.isFile();
+}
+
static QString find_translation(const QLocale & locale,
const QString & filename,
const QString & prefix,
@@ -625,9 +632,11 @@ static QString find_translation(const QLocale & locale,
if (!path.isEmpty() && !path.endsWith(QLatin1Char('/')))
path += QLatin1Char('/');
}
+ const QString suffixOrDotQM = suffix.isNull() ? QStringLiteral(".qm") : suffix;
- QFileInfo fi;
QString realname;
+ realname += path + filename + prefix; // using += in the hope for some reserve capacity
+ const int realNameBaseSize = realname.size();
QStringList fuzzyLocales;
// see http://www.unicode.org/reports/tr35/#LanguageMatching for inspiration
@@ -646,16 +655,15 @@ static QString find_translation(const QLocale & locale,
foreach (QString localeName, languages) {
localeName.replace(QLatin1Char('-'), QLatin1Char('_'));
- realname = path + filename + prefix + localeName + (suffix.isNull() ? QLatin1String(".qm") : suffix);
- fi.setFile(realname);
- if (fi.isReadable() && fi.isFile())
+ realname += localeName + suffixOrDotQM;
+ if (is_readable_file(realname))
return realname;
- realname = path + filename + prefix + localeName;
- fi.setFile(realname);
- if (fi.isReadable() && fi.isFile())
+ realname.truncate(realNameBaseSize + localeName.size());
+ if (is_readable_file(realname))
return realname;
+ realname.truncate(realNameBaseSize);
fuzzyLocales.append(localeName);
}
@@ -668,33 +676,36 @@ static QString find_translation(const QLocale & locale,
break;
localeName.truncate(rightmost);
- realname = path + filename + prefix + localeName + (suffix.isNull() ? QLatin1String(".qm") : suffix);
- fi.setFile(realname);
- if (fi.isReadable() && fi.isFile())
+ realname += localeName + suffixOrDotQM;
+ if (is_readable_file(realname))
return realname;
- realname = path + filename + prefix + localeName;
- fi.setFile(realname);
- if (fi.isReadable() && fi.isFile())
+ realname.truncate(realNameBaseSize + localeName.size());
+ if (is_readable_file(realname))
return realname;
+
+ realname.truncate(realNameBaseSize);
}
}
+ const int realNameBaseSizeFallbacks = path.size() + filename.size();
+
+ // realname == path + filename + prefix;
if (!suffix.isNull()) {
- realname = path + filename + suffix;
- fi.setFile(realname);
- if (fi.isReadable() && fi.isFile())
+ realname.replace(realNameBaseSizeFallbacks, prefix.size(), suffix);
+ // realname == path + filename;
+ if (is_readable_file(realname))
return realname;
+ realname.replace(realNameBaseSizeFallbacks, suffix.size(), prefix);
}
- realname = path + filename + prefix;
- fi.setFile(realname);
- if (fi.isReadable() && fi.isFile())
+ // realname == path + filename + prefix;
+ if (is_readable_file(realname))
return realname;
- realname = path + filename;
- fi.setFile(realname);
- if (fi.isReadable() && fi.isFile())
+ realname.truncate(realNameBaseSizeFallbacks);
+ // realname == path + filename;
+ if (is_readable_file(realname))
return realname;
return QString();
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 3e6aefab2a..1d7128721f 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -56,6 +56,7 @@
#include "qbytearraylist.h"
#endif
#include "private/qvariant_p.h"
+#include "private/qlocale_p.h"
#include "qmetatype_p.h"
#include <qmetaobject.h>
@@ -71,18 +72,6 @@
QT_BEGIN_NAMESPACE
-#ifndef DBL_MANT_DIG
-# define DBL_MANT_DIG 53
-#endif
-#ifndef FLT_MANT_DIG
-# define FLT_MANT_DIG 24
-#endif
-
-const int log10_2_10000 = 30103; // log10(2) * 100000
-// same as C++11 std::numeric_limits<T>::max_digits10
-const int max_digits10_double = (DBL_MANT_DIG * log10_2_10000) / 100000 + 2;
-const int max_digits10_float = (FLT_MANT_DIG * log10_2_10000) / 100000 + 2;
-
namespace {
class HandlersManager
{
@@ -433,10 +422,10 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*str = QString::number(qMetaTypeUNumber(d));
break;
case QMetaType::Float:
- *str = QString::number(d->data.f, 'g', max_digits10_float);
+ *str = QString::number(d->data.f, 'g', QLocale::FloatingPointShortest);
break;
case QVariant::Double:
- *str = QString::number(d->data.d, 'g', max_digits10_double);
+ *str = QString::number(d->data.d, 'g', QLocale::FloatingPointShortest);
break;
#if !defined(QT_NO_DATESTRING)
case QVariant::Date:
@@ -625,10 +614,10 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*ba = v_cast<QString>(d)->toUtf8();
break;
case QVariant::Double:
- *ba = QByteArray::number(d->data.d, 'g', max_digits10_double);
+ *ba = QByteArray::number(d->data.d, 'g', QLocale::FloatingPointShortest);
break;
case QMetaType::Float:
- *ba = QByteArray::number(d->data.f, 'g', max_digits10_float);
+ *ba = QByteArray::number(d->data.f, 'g', QLocale::FloatingPointShortest);
break;
case QMetaType::Char:
case QMetaType::SChar:
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index bed0e193db..dc3b62bd22 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -568,6 +568,7 @@ inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
return !operator==(v1, v2);
}
#endif
+Q_DECLARE_SHARED(QVariant)
class Q_CORE_EXPORT QSequentialIterable
{
@@ -846,7 +847,6 @@ inline QT_DEPRECATED bool qVariantCanConvert(const QVariant &variant)
#endif
#endif
-Q_DECLARE_SHARED(QVariant)
#ifndef QT_NO_DEBUG_STREAM
Q_CORE_EXPORT QDebug operator<<(QDebug, const QVariant &);
diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h
index d84d702982..986eb2c467 100644
--- a/src/corelib/kernel/qvariant_p.h
+++ b/src/corelib/kernel/qvariant_p.h
@@ -202,7 +202,6 @@ class QVariantIsNull
/// \internal
/// This class checks if a type T has method called isNull. Result is kept in the Value property
/// TODO Can we somehow generalize it? A macro version?
-#if defined(Q_COMPILER_DECLTYPE) // C++11 version
template<typename T>
class HasIsNullMethod {
struct Yes { char unused[1]; };
@@ -214,44 +213,6 @@ class QVariantIsNull
public:
static const bool Value = (sizeof(test<T>(0)) == sizeof(Yes));
};
-#elif defined(Q_CC_MSVC) && _MSC_VER >= 1400 && !defined(Q_CC_INTEL) // MSVC 2005, 2008 version: no decltype, but 'sealed' classes (>=2010 has decltype)
- template<typename T>
- class HasIsNullMethod {
- struct Yes { char unused[1]; };
- struct No { char unused[2]; };
- Q_STATIC_ASSERT(sizeof(Yes) != sizeof(No));
-
- template<class C> static Yes test(char (*)[(&C::isNull == 0) + 1]);
- template<class C> static No test(...);
- public:
- static const bool Value = (sizeof(test<T>(0)) == sizeof(Yes));
- };
-#else // C++98 version (doesn't work for final classes)
- template<typename T, bool IsClass = QTypeInfo<T>::isComplex>
- class HasIsNullMethod
- {
- struct Yes { char unused[1]; };
- struct No { char unused[2]; };
- Q_STATIC_ASSERT(sizeof(Yes) != sizeof(No));
-
- struct FallbackMixin { bool isNull() const; };
- struct Derived : public T, public FallbackMixin {}; // <- doesn't work for final classes
- template<class C, C> struct TypeCheck {};
-
- template<class C> static Yes test(...);
- template<class C> static No test(TypeCheck<bool (FallbackMixin::*)() const, &C::isNull> *);
- public:
- static const bool Value = (sizeof(test<Derived>(0)) == sizeof(Yes));
- };
-
- // We need to exclude primitive types as they won't compile with HasIsNullMethod::Check classes
- // anyway it is not a problem as the types do not have isNull method.
- template<typename T>
- class HasIsNullMethod<T, /* IsClass = */ false> {
- public:
- static const bool Value = false;
- };
-#endif
// TODO This part should go to autotests during HasIsNullMethod generalization.
Q_STATIC_ASSERT(!HasIsNullMethod<bool>::Value);
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index fd11dbc787..012bc72b6e 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -47,11 +47,11 @@
#include <QtCore/QSet>
#include <QtCore/QBuffer>
#include <QtCore/QUrl>
-#include <QtCore/QStack>
#include <QtCore/QDebug>
#include <algorithm>
#include <functional>
+#include <stack>
QT_BEGIN_NAMESPACE
@@ -107,7 +107,8 @@ QStringList QMimeDatabasePrivate::mimeTypeForFileName(const QString &fileName, Q
if (fileName.endsWith(QLatin1Char('/')))
return QStringList() << QLatin1String("inode/directory");
- const QStringList matchingMimeTypes = provider()->findByFileName(QFileInfo(fileName).fileName(), foundSuffix);
+ QStringList matchingMimeTypes = provider()->findByFileName(QFileInfo(fileName).fileName(), foundSuffix);
+ matchingMimeTypes.sort(); // make it deterministic
return matchingMimeTypes;
}
@@ -186,7 +187,7 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
// "for glob_match in glob_matches:"
// "if glob_match is subclass or equal to sniffed_type, use glob_match"
const QString sniffedMime = candidateByData.name();
- foreach (const QString &m, candidatesByName) {
+ for (const QString &m : qAsConst(candidatesByName)) {
if (inherits(m, sniffedMime)) {
// We have magic + pattern pointing to this, so it's a pretty good match
*accuracyPtr = 100;
@@ -200,7 +201,6 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
if (candidatesByName.count() > 1) {
*accuracyPtr = 20;
- candidatesByName.sort(); // to make it deterministic
const QMimeType mime = mimeTypeForName(candidatesByName.at(0));
if (mime.isValid())
return mime;
@@ -218,13 +218,14 @@ bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent)
{
const QString resolvedParent = provider()->resolveAlias(parent);
//Q_ASSERT(provider()->resolveAlias(mime) == mime);
- QStack<QString> toCheck;
+ std::stack<QString, QStringList> toCheck;
toCheck.push(mime);
- while (!toCheck.isEmpty()) {
- const QString current = toCheck.pop();
- if (current == resolvedParent)
+ while (!toCheck.empty()) {
+ if (toCheck.top() == resolvedParent)
return true;
- foreach (const QString &par, provider()->parents(current))
+ const auto parents = provider()->parents(toCheck.top());
+ toCheck.pop();
+ for (const QString &par : parents)
toCheck.push(par);
}
return false;
@@ -407,7 +408,6 @@ QMimeType QMimeDatabase::mimeTypeForFile(const QString &fileName, MatchMode mode
return d->mimeTypeForName(matches.first());
} else {
// We have to pick one.
- matches.sort(); // Make it deterministic
return d->mimeTypeForName(matches.first());
}
} else {
@@ -433,11 +433,10 @@ QList<QMimeType> QMimeDatabase::mimeTypesForFileName(const QString &fileName) co
{
QMutexLocker locker(&d->mutex);
- QStringList matches = d->mimeTypeForFileName(fileName);
+ const QStringList matches = d->mimeTypeForFileName(fileName);
QList<QMimeType> mimes;
- matches.sort(); // Make it deterministic
mimes.reserve(matches.count());
- foreach (const QString &mime, matches)
+ for (const QString &mime : matches)
mimes.append(d->mimeTypeForName(mime));
return mimes;
}
diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp
index 57d834ac78..6318295558 100644
--- a/src/corelib/mimetypes/qmimeglobpattern.cpp
+++ b/src/corelib/mimetypes/qmimeglobpattern.cpp
@@ -213,9 +213,9 @@ QStringList QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QString
// (toLower because fast patterns are always case-insensitive and saved as lowercase)
const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension);
- foreach (const QString &mime, matchingMimeTypes) {
- result.addMatch(mime, 50, QLatin1String("*.") + simpleExtension);
- }
+ const QString simplePattern = QLatin1String("*.") + simpleExtension;
+ for (const QString &mime : matchingMimeTypes)
+ result.addMatch(mime, 50, simplePattern);
// Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway,
// at least those with weight 50.
}
diff --git a/src/corelib/mimetypes/qmimemagicrulematcher.cpp b/src/corelib/mimetypes/qmimemagicrulematcher.cpp
index 629e8d9d2f..c973b92061 100644
--- a/src/corelib/mimetypes/qmimemagicrulematcher.cpp
+++ b/src/corelib/mimetypes/qmimemagicrulematcher.cpp
@@ -85,7 +85,7 @@ QList<QMimeMagicRule> QMimeMagicRuleMatcher::magicRules() const
// Check for a match on contents of a file
bool QMimeMagicRuleMatcher::matches(const QByteArray &data) const
{
- foreach (const QMimeMagicRule &magicRule, m_list) {
+ for (const QMimeMagicRule &magicRule : m_list) {
if (magicRule.matches(data))
return true;
}
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 917c29b8d6..a06d050387 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -242,7 +242,7 @@ void QMimeBinaryProvider::checkCache()
// Then check if new cache files appeared
const QStringList cacheFileNames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/mime.cache"));
if (cacheFileNames != m_cacheFileNames) {
- foreach (const QString &cacheFileName, cacheFileNames) {
+ for (const QString &cacheFileName : cacheFileNames) {
CacheFile *cacheFile = m_cacheFiles.findCacheFile(cacheFileName);
if (!cacheFile) {
//qDebug() << "new file:" << cacheFileName;
@@ -287,7 +287,7 @@ QStringList QMimeBinaryProvider::findByFileName(const QString &fileName, QString
const QString lowerFileName = fileName.toLower();
QMimeGlobMatchResult result;
// TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly.
- foreach (CacheFile *cacheFile, m_cacheFiles) {
+ for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
matchGlobList(result, cacheFile, cacheFile->getUint32(PosLiteralListOffset), fileName);
matchGlobList(result, cacheFile, cacheFile->getUint32(PosGlobListOffset), fileName);
const int reverseSuffixTreeOffset = cacheFile->getUint32(PosReverseSuffixTreeOffset);
@@ -399,7 +399,7 @@ bool QMimeBinaryProvider::matchMagicRule(QMimeBinaryProvider::CacheFile *cacheFi
QMimeType QMimeBinaryProvider::findByMagic(const QByteArray &data, int *accuracyPtr)
{
checkCache();
- foreach (CacheFile *cacheFile, m_cacheFiles) {
+ for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
const int magicListOffset = cacheFile->getUint32(PosMagicListOffset);
const int numMatches = cacheFile->getUint32(magicListOffset);
//const int maxExtent = cacheFile->getUint32(magicListOffset + 4);
@@ -427,7 +427,7 @@ QStringList QMimeBinaryProvider::parents(const QString &mime)
checkCache();
const QByteArray mimeStr = mime.toLatin1();
QStringList result;
- foreach (CacheFile *cacheFile, m_cacheFiles) {
+ for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
const int parentListOffset = cacheFile->getUint32(PosParentListOffset);
const int numEntries = cacheFile->getUint32(parentListOffset);
@@ -467,7 +467,7 @@ QString QMimeBinaryProvider::resolveAlias(const QString &name)
{
checkCache();
const QByteArray input = name.toLatin1();
- foreach (CacheFile *cacheFile, m_cacheFiles) {
+ for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
const int aliasListOffset = cacheFile->getUint32(PosAliasListOffset);
const int numEntries = cacheFile->getUint32(aliasListOffset);
int begin = 0;
@@ -498,7 +498,7 @@ QStringList QMimeBinaryProvider::listAliases(const QString &name)
checkCache();
QStringList result;
const QByteArray input = name.toLatin1();
- foreach (CacheFile *cacheFile, m_cacheFiles) {
+ for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
const int aliasListOffset = cacheFile->getUint32(PosAliasListOffset);
const int numEntries = cacheFile->getUint32(aliasListOffset);
for (int pos = 0; pos < numEntries; ++pos) {
@@ -524,7 +524,7 @@ void QMimeBinaryProvider::loadMimeTypeList()
// Unfortunately mime.cache doesn't have a full list of all mimetypes.
// So we have to parse the plain-text files called "types".
const QStringList typesFilenames = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/types"));
- foreach (const QString &typeFilename, typesFilenames) {
+ for (const QString &typeFilename : typesFilenames) {
QFile file(typeFilename);
if (file.open(QIODevice::ReadOnly)) {
while (!file.atEnd()) {
@@ -677,7 +677,7 @@ void QMimeBinaryProvider::loadIcon(QMimeTypePrivate &data)
{
checkCache();
const QByteArray inputMime = data.name.toLatin1();
- foreach (CacheFile *cacheFile, m_cacheFiles) {
+ for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
const QString icon = iconForMime(cacheFile, PosIconsListOffset, inputMime);
if (!icon.isEmpty()) {
data.iconName = icon;
@@ -690,7 +690,7 @@ void QMimeBinaryProvider::loadGenericIcon(QMimeTypePrivate &data)
{
checkCache();
const QByteArray inputMime = data.name.toLatin1();
- foreach (CacheFile *cacheFile, m_cacheFiles) {
+ for (CacheFile *cacheFile : qAsConst(m_cacheFiles)) {
const QString icon = iconForMime(cacheFile, PosGenericIconsListOffset, inputMime);
if (!icon.isEmpty()) {
data.genericIconName = icon;
@@ -733,7 +733,7 @@ QMimeType QMimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr
QString candidate;
- foreach (const QMimeMagicRuleMatcher &matcher, m_magicMatchers) {
+ for (const QMimeMagicRuleMatcher &matcher : qAsConst(m_magicMatchers)) {
if (matcher.matches(data)) {
const int priority = matcher.priority();
if (priority > *accuracyPtr) {
@@ -753,7 +753,7 @@ void QMimeXMLProvider::ensureLoaded()
const QStringList packageDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/packages"), QStandardPaths::LocateDirectory);
//qDebug() << "packageDirs=" << packageDirs;
- foreach (const QString &packageDir, packageDirs) {
+ for (const QString &packageDir : packageDirs) {
QDir dir(packageDir);
const QStringList files = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
//qDebug() << static_cast<const void *>(this) << packageDir << files;
@@ -782,7 +782,7 @@ void QMimeXMLProvider::ensureLoaded()
//qDebug() << "Loading" << m_allFiles;
- foreach (const QString &file, allFiles)
+ for (const QString &file : qAsConst(allFiles))
load(file);
}
}
diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp
index e3b01bbb89..e6599d233c 100644
--- a/src/corelib/mimetypes/qmimetype.cpp
+++ b/src/corelib/mimetypes/qmimetype.cpp
@@ -241,7 +241,7 @@ QString QMimeType::comment() const
QStringList languageList;
languageList << QLocale::system().name();
languageList << QLocale::system().uiLanguages();
- Q_FOREACH (const QString &language, languageList) {
+ for (const QString &language : qAsConst(languageList)) {
const QString lang = language == QLatin1String("C") ? QLatin1String("en_US") : language;
const QString comm = d->localeComments.value(lang);
if (!comm.isEmpty())
@@ -337,17 +337,16 @@ QStringList QMimeType::parentMimeTypes() const
static void collectParentMimeTypes(const QString &mime, QStringList &allParents)
{
- QStringList parents = QMimeDatabasePrivate::instance()->provider()->parents(mime);
- foreach (const QString &parent, parents) {
+ const QStringList parents = QMimeDatabasePrivate::instance()->provider()->parents(mime);
+ for (const QString &parent : parents) {
// I would use QSet, but since order matters I better not
if (!allParents.contains(parent))
allParents.append(parent);
}
// We want a breadth-first search, so that the least-specific parent (octet-stream) is last
// This means iterating twice, unfortunately.
- foreach (const QString &parent, parents) {
+ for (const QString &parent : parents)
collectParentMimeTypes(parent, allParents);
- }
}
/*!
@@ -392,7 +391,7 @@ QStringList QMimeType::suffixes() const
QMimeDatabasePrivate::instance()->provider()->loadMimeTypePrivate(*d);
QStringList result;
- foreach (const QString &pattern, d->globPatterns) {
+ for (const QString &pattern : qAsConst(d->globPatterns)) {
// Not a simple suffix if it looks like: README or *. or *.* or *.JP*G or *.JP?
if (pattern.startsWith(QLatin1String("*.")) &&
pattern.length() > 2 &&
diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri
index 8b64f93467..9dc60c5d39 100644
--- a/src/corelib/plugin/plugin.pri
+++ b/src/corelib/plugin/plugin.pri
@@ -35,4 +35,8 @@ integrity {
SOURCES += plugin/qlibrary_unix.cpp
}
+darwin {
+ OBJECTIVE_SOURCES += plugin/quuid_darwin.mm
+}
+
LIBS_PRIVATE += $$QMAKE_LIBS_DYNLOAD
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index dcf1b1a81d..78f540cf56 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -33,7 +33,7 @@
#include "qfactoryloader_p.h"
-#ifndef QT_NO_LIBRARY
+#ifndef QT_NO_QOBJECT
#include "qfactoryinterface.h"
#include "qmap.h"
#include <qdir.h>
@@ -50,10 +50,6 @@
QT_BEGIN_NAMESPACE
-Q_GLOBAL_STATIC(QList<QFactoryLoader *>, qt_factory_loaders)
-
-Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_factoryloader_mutex, (QMutex::Recursive))
-
namespace {
// avoid duplicate QStringLiteral data:
@@ -71,16 +67,24 @@ class QFactoryLoaderPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QFactoryLoader)
public:
QFactoryLoaderPrivate(){}
+ QByteArray iid;
+#ifndef QT_NO_LIBRARY
~QFactoryLoaderPrivate();
mutable QMutex mutex;
- QByteArray iid;
QList<QLibraryPrivate*> libraryList;
QMap<QString,QLibraryPrivate*> keyMap;
QString suffix;
Qt::CaseSensitivity cs;
QStringList loadedPaths;
+#endif
};
+#ifndef QT_NO_LIBRARY
+
+Q_GLOBAL_STATIC(QList<QFactoryLoader *>, qt_factory_loaders)
+
+Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_factoryloader_mutex, (QMutex::Recursive))
+
QFactoryLoaderPrivate::~QFactoryLoaderPrivate()
{
for (int i = 0; i < libraryList.count(); ++i) {
@@ -90,25 +94,6 @@ QFactoryLoaderPrivate::~QFactoryLoaderPrivate()
}
}
-QFactoryLoader::QFactoryLoader(const char *iid,
- const QString &suffix,
- Qt::CaseSensitivity cs)
- : QObject(*new QFactoryLoaderPrivate)
-{
- moveToThread(QCoreApplicationPrivate::mainThread());
- Q_D(QFactoryLoader);
- d->iid = iid;
- d->cs = cs;
- d->suffix = suffix;
-
-
- QMutexLocker locker(qt_factoryloader_mutex());
- update();
- qt_factory_loaders()->append(this);
-}
-
-
-
void QFactoryLoader::update()
{
#ifdef QT_SHARED
@@ -229,15 +214,59 @@ QFactoryLoader::~QFactoryLoader()
qt_factory_loaders()->removeAll(this);
}
+#if defined(Q_OS_UNIX) && !defined (Q_OS_MAC)
+QLibraryPrivate *QFactoryLoader::library(const QString &key) const
+{
+ Q_D(const QFactoryLoader);
+ return d->keyMap.value(d->cs ? key : key.toLower());
+}
+#endif
+
+void QFactoryLoader::refreshAll()
+{
+ QMutexLocker locker(qt_factoryloader_mutex());
+ QList<QFactoryLoader *> *loaders = qt_factory_loaders();
+ for (QList<QFactoryLoader *>::const_iterator it = loaders->constBegin();
+ it != loaders->constEnd(); ++it) {
+ (*it)->update();
+ }
+}
+
+#endif // QT_NO_LIBRARY
+
+QFactoryLoader::QFactoryLoader(const char *iid,
+ const QString &suffix,
+ Qt::CaseSensitivity cs)
+ : QObject(*new QFactoryLoaderPrivate)
+{
+ moveToThread(QCoreApplicationPrivate::mainThread());
+ Q_D(QFactoryLoader);
+ d->iid = iid;
+#ifndef QT_NO_LIBRARY
+ d->cs = cs;
+ d->suffix = suffix;
+
+ QMutexLocker locker(qt_factoryloader_mutex());
+ update();
+ qt_factory_loaders()->append(this);
+#else
+ Q_UNUSED(suffix);
+ Q_UNUSED(cs);
+#endif
+}
+
QList<QJsonObject> QFactoryLoader::metaData() const
{
Q_D(const QFactoryLoader);
- QMutexLocker locker(&d->mutex);
QList<QJsonObject> metaData;
+#ifndef QT_NO_LIBRARY
+ QMutexLocker locker(&d->mutex);
for (int i = 0; i < d->libraryList.size(); ++i)
metaData.append(d->libraryList.at(i)->metaData);
+#endif
- foreach (const QStaticPlugin &plugin, QPluginLoader::staticPlugins()) {
+ const auto staticPlugins = QPluginLoader::staticPlugins();
+ for (const QStaticPlugin &plugin : staticPlugins) {
const QJsonObject object = plugin.metaData();
if (object.value(iidKeyLiteral()) != QLatin1String(d->iid.constData(), d->iid.size()))
continue;
@@ -252,6 +281,7 @@ QObject *QFactoryLoader::instance(int index) const
if (index < 0)
return 0;
+#ifndef QT_NO_LIBRARY
if (index < d->libraryList.size()) {
QLibraryPrivate *library = d->libraryList.at(index);
if (library->instance || library->loadPlugin()) {
@@ -266,8 +296,9 @@ QObject *QFactoryLoader::instance(int index) const
}
return 0;
}
-
index -= d->libraryList.size();
+#endif
+
QVector<QStaticPlugin> staticPlugins = QPluginLoader::staticPlugins();
for (int i = 0; i < staticPlugins.count(); ++i) {
const QJsonObject object = staticPlugins.at(i).metaData();
@@ -282,24 +313,6 @@ QObject *QFactoryLoader::instance(int index) const
return 0;
}
-#if defined(Q_OS_UNIX) && !defined (Q_OS_MAC)
-QLibraryPrivate *QFactoryLoader::library(const QString &key) const
-{
- Q_D(const QFactoryLoader);
- return d->keyMap.value(d->cs ? key : key.toLower());
-}
-#endif
-
-void QFactoryLoader::refreshAll()
-{
- QMutexLocker locker(qt_factoryloader_mutex());
- QList<QFactoryLoader *> *loaders = qt_factory_loaders();
- for (QList<QFactoryLoader *>::const_iterator it = loaders->constBegin();
- it != loaders->constEnd(); ++it) {
- (*it)->update();
- }
-}
-
QMultiMap<int, QString> QFactoryLoader::keyMap() const
{
QMultiMap<int, QString> result;
@@ -335,4 +348,4 @@ int QFactoryLoader::indexOf(const QString &needle) const
QT_END_NAMESPACE
-#endif // QT_NO_LIBRARY
+#endif // QT_NO_QOBJECT
diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h
index 1c48491b0d..e67bb98976 100644
--- a/src/corelib/plugin/qfactoryloader_p.h
+++ b/src/corelib/plugin/qfactoryloader_p.h
@@ -45,17 +45,18 @@
// We mean it.
//
+#include "QtCore/qglobal.h"
+#ifndef QT_NO_QOBJECT
+
#include "QtCore/qobject.h"
#include "QtCore/qstringlist.h"
#include "QtCore/qjsonobject.h"
#include "QtCore/qmap.h"
#include "private/qlibrary_p.h"
-#ifndef QT_NO_LIBRARY
QT_BEGIN_NAMESPACE
class QFactoryLoaderPrivate;
-
class Q_CORE_EXPORT QFactoryLoader : public QObject
{
Q_OBJECT
@@ -65,23 +66,42 @@ public:
explicit QFactoryLoader(const char *iid,
const QString &suffix = QString(),
Qt::CaseSensitivity = Qt::CaseSensitive);
+
+#ifndef QT_NO_LIBRARY
~QFactoryLoader();
- QList<QJsonObject> metaData() const;
- QObject *instance(int index) const;
+ void update();
+ static void refreshAll();
#if defined(Q_OS_UNIX) && !defined (Q_OS_MAC)
QLibraryPrivate *library(const QString &key) const;
-#endif
+#endif // Q_OS_UNIX && !Q_OS_MAC
+#endif // !QT_NO_LIBRARY
QMultiMap<int, QString> keyMap() const;
int indexOf(const QString &needle) const;
- void update();
-
- static void refreshAll();
+ QList<QJsonObject> metaData() const;
+ QObject *instance(int index) const;
};
+#ifdef Q_COMPILER_VARIADIC_TEMPLATES
+
+template <class PluginInterface, class FactoryInterface, typename ...Args>
+PluginInterface *qLoadPlugin(const QFactoryLoader *loader, const QString &key, Args &&...args)
+{
+ const int index = loader->indexOf(key);
+ if (index != -1) {
+ QObject *factoryObject = loader->instance(index);
+ if (FactoryInterface *factory = qobject_cast<FactoryInterface *>(factoryObject))
+ if (PluginInterface *result = factory->create(key, std::forward<Args>(args)...))
+ return result;
+ }
+ return nullptr;
+}
+
+#else
+
template <class PluginInterface, class FactoryInterface>
PluginInterface *qLoadPlugin(const QFactoryLoader *loader, const QString &key)
{
@@ -95,23 +115,59 @@ template <class PluginInterface, class FactoryInterface>
return 0;
}
-template <class PluginInterface, class FactoryInterface, class Parameter1>
-PluginInterface *qLoadPlugin1(const QFactoryLoader *loader,
+template <class PluginInterface, class FactoryInterface, class P1>
+PluginInterface *qLoadPlugin(const QFactoryLoader *loader,
const QString &key,
- const Parameter1 &parameter1)
+ P1 &&p1)
{
const int index = loader->indexOf(key);
if (index != -1) {
QObject *factoryObject = loader->instance(index);
if (FactoryInterface *factory = qobject_cast<FactoryInterface *>(factoryObject))
- if (PluginInterface *result = factory->create(key, parameter1))
+ if (PluginInterface *result = factory->create(key, std::forward<P1>(p1)))
return result;
}
return 0;
}
+template <class PluginInterface, class FactoryInterface, class P1, class P2>
+PluginInterface *qLoadPlugin(const QFactoryLoader *loader,
+ const QString &key,
+ P1 &&p1, P2 &&p2)
+{
+ const int index = loader->indexOf(key);
+ if (index != -1) {
+ QObject *factoryObject = loader->instance(index);
+ if (FactoryInterface *factory = qobject_cast<FactoryInterface *>(factoryObject))
+ if (PluginInterface *result = factory->create(key, std::forward<P1>(p1), std::forward<P2>(p2)))
+ return result;
+ }
+ return 0;
+}
+
+template <class PluginInterface, class FactoryInterface, class P1, class P2, class P3>
+PluginInterface *qLoadPlugin(const QFactoryLoader *loader,
+ const QString &key,
+ P1 &&p1, P2 &&p2, P3 &&p3)
+{
+ const int index = loader->indexOf(key);
+ if (index != -1) {
+ QObject *factoryObject = loader->instance(index);
+ if (FactoryInterface *factory = qobject_cast<FactoryInterface *>(factoryObject))
+ if (PluginInterface *result = factory->create(key, std::forward<P1>(p1), std::forward<P2>(p2), std::forward<P3>(p3)))
+ return result;
+ }
+ return 0;
+}
+
+#endif
+
+template <class PluginInterface, class FactoryInterface, typename Arg>
+Q_DECL_DEPRECATED PluginInterface *qLoadPlugin1(const QFactoryLoader *loader, const QString &key, Arg &&arg)
+{ return qLoadPlugin<PluginInterface, FactoryInterface>(loader, key, std::forward<Arg>(arg)); }
+
QT_END_NAMESPACE
-#endif // QT_NO_LIBRARY
+#endif // QT_NO_QOBJECT
#endif // QFACTORYLOADER_P_H
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 317c1dcdc1..45859e058e 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -302,7 +302,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
if (pos >= 0) {
if (hasMetaData) {
const char *data = filedata + pos;
- QJsonDocument doc = QLibraryPrivate::fromRawMetaData(data);
+ QJsonDocument doc = qJsonFromRawLibraryMetaData(data);
lib->metaData = doc.object();
if (qt_debug_component())
qWarning("Found metadata in lib %s, metadata=\n%s\n",
@@ -406,7 +406,7 @@ inline void QLibraryStore::cleanup()
if (qt_debug_component()) {
// dump all objects that remain
- foreach (QLibraryPrivate *lib, data->libraryMap) {
+ for (QLibraryPrivate *lib : qAsConst(data->libraryMap)) {
if (lib)
qDebug() << "On QtCore unload," << lib->fileName << "was leaked, with"
<< lib->libraryRefCount.load() << "users";
@@ -675,7 +675,7 @@ static bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryP
if (!szData)
return false;
- QJsonDocument doc = QLibraryPrivate::fromRawMetaData(szData);
+ QJsonDocument doc = qJsonFromRawLibraryMetaData(szData);
if (doc.isNull())
return false;
priv->metaData = doc.object();
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index ada90d7bfd..11b0cb1eb9 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -57,9 +57,20 @@
# include "QtCore/qt_windows.h"
#endif
+QT_BEGIN_NAMESPACE
+
+// Needed also in case of QT_NO_LIBRARY, for static plugin loading.
+inline QJsonDocument qJsonFromRawLibraryMetaData(const char *raw)
+{
+ raw += strlen("QTMETADATA ");
+ // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h),
+ // but doesn't include the size of the header (8 bytes)
+ QByteArray json(raw, qFromLittleEndian<uint>(*(const uint *)(raw + 8)) + 8);
+ return QJsonDocument::fromBinaryData(json);
+}
+
#ifndef QT_NO_LIBRARY
-QT_BEGIN_NAMESPACE
bool qt_debug_component();
@@ -104,14 +115,6 @@ public:
void updatePluginState();
bool isPlugin();
- static inline QJsonDocument fromRawMetaData(const char *raw) {
- raw += strlen("QTMETADATA ");
- // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h),
- // but doesn't include the size of the header (8 bytes)
- QByteArray json(raw, qFromLittleEndian<uint>(*(const uint *)(raw + 8)) + 8);
- return QJsonDocument::fromBinaryData(json);
- }
-
private:
explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints);
~QLibraryPrivate();
@@ -132,8 +135,8 @@ private:
friend class QLibraryStore;
};
-QT_END_NAMESPACE
-
#endif // QT_NO_LIBRARY
+QT_END_NAMESPACE
+
#endif // QLIBRARY_P_H
diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp
index f5604a24bd..47a220bf69 100644
--- a/src/corelib/plugin/qlibrary_win.cpp
+++ b/src/corelib/plugin/qlibrary_win.cpp
@@ -104,7 +104,7 @@ bool QLibraryPrivate::load_sys()
attempts.prepend(QDir::rootPath() + fileName);
#endif
- Q_FOREACH (const QString &attempt, attempts) {
+ for (const QString &attempt : qAsConst(attempts)) {
#ifndef Q_OS_WINRT
pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(attempt).utf16());
#else // Q_OS_WINRT
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index 24101be87b..af6e3e0e93 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -41,10 +41,10 @@
#include "qdebug.h"
#include "qdir.h"
-#ifndef QT_NO_LIBRARY
-
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_LIBRARY
+
/*!
\class QPluginLoader
\inmodule QtCore
@@ -300,9 +300,9 @@ static QString locatePlugin(const QString& fileName)
paths.prepend(QStringLiteral(".")); // search in current dir first
}
- foreach (const QString &path, paths) {
- foreach (const QString &prefix, prefixes) {
- foreach (const QString &suffix, suffixes) {
+ for (const QString &path : qAsConst(paths)) {
+ for (const QString &prefix : qAsConst(prefixes)) {
+ for (const QString &suffix : qAsConst(suffixes)) {
const QString fn = path + QLatin1Char('/') + basePath + prefix + baseName + suffix;
if (debug)
qDebug() << "Trying..." << fn;
@@ -382,9 +382,6 @@ QString QPluginLoader::errorString() const
return (!d || d->errorString.isEmpty()) ? tr("Unknown error") : d->errorString;
}
-typedef QVector<QStaticPlugin> StaticPluginList;
-Q_GLOBAL_STATIC(StaticPluginList, staticPluginList)
-
/*! \since 4.4
\property QPluginLoader::loadHints
@@ -413,6 +410,11 @@ QLibrary::LoadHints QPluginLoader::loadHints() const
return d ? d->loadHints() : QLibrary::LoadHints();
}
+#endif // QT_NO_LIBRARY
+
+typedef QVector<QStaticPlugin> StaticPluginList;
+Q_GLOBAL_STATIC(StaticPluginList, staticPluginList)
+
/*!
\relates QPluginLoader
\since 5.0
@@ -465,9 +467,8 @@ QVector<QStaticPlugin> QPluginLoader::staticPlugins()
*/
QJsonObject QStaticPlugin::metaData() const
{
- return QLibraryPrivate::fromRawMetaData(rawMetaData()).object();
+ return qJsonFromRawLibraryMetaData(rawMetaData()).object();
}
QT_END_NAMESPACE
-#endif // QT_NO_LIBRARY
diff --git a/src/corelib/plugin/qpluginloader.h b/src/corelib/plugin/qpluginloader.h
index 0ab25bbb07..5dc7d1b66c 100644
--- a/src/corelib/plugin/qpluginloader.h
+++ b/src/corelib/plugin/qpluginloader.h
@@ -37,10 +37,10 @@
#include <QtCore/qlibrary.h>
#include <QtCore/qplugin.h>
-#ifndef QT_NO_LIBRARY
-
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_LIBRARY
+
class QLibraryPrivate;
class QJsonObject;
@@ -78,8 +78,17 @@ private:
Q_DISABLE_COPY(QPluginLoader)
};
-QT_END_NAMESPACE
+#else
+
+class Q_CORE_EXPORT QPluginLoader
+{
+public:
+ static QObjectList staticInstances();
+ static QVector<QStaticPlugin> staticPlugins();
+};
#endif // QT_NO_LIBRARY
+QT_END_NAMESPACE
+
#endif //QPLUGINLOADER_H
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
index 253789b4f0..b7ea1f2f60 100644
--- a/src/corelib/plugin/quuid.cpp
+++ b/src/corelib/plugin/quuid.cpp
@@ -803,6 +803,39 @@ QUuid::Version QUuid::version() const Q_DECL_NOTHROW
return ver;
}
+/*! \fn QUuid QUuid::fromCFUUID(CFUUIDRef uuid)
+ \since 5.7
+
+ Constructs a new QUuid containing a copy of the \a uuid CFUUID.
+
+ \note this function is only available on Apple platforms.
+*/
+
+/*! \fn CFUUIDRef QUuid::toCFUUID() const
+ \since 5.7
+
+ Creates a CFUUID from a QUuid. The caller owns the CFUUID and is
+ responsible for releasing it.
+
+ \note this function is only available on Apple platforms.
+*/
+
+/*! \fn QUuid QUuid::fromNSUUID(const NSUUID *uuid)
+ \since 5.7
+
+ Constructs a new QUuid containing a copy of the \a uuid NSUUID.
+
+ \note this function is only available on Apple platforms.
+*/
+
+/*! \fn NSUUID QUuid::toNSUUID() const
+ \since 5.7
+
+ Creates a NSUUID from a QUuid. The NSUUID is autoreleased.
+
+ \note this function is only available on Apple platforms.
+*/
+
/*!
\fn bool QUuid::operator<(const QUuid &other) const
diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h
index f004cba77e..07cd9c4103 100644
--- a/src/corelib/plugin/quuid.h
+++ b/src/corelib/plugin/quuid.h
@@ -49,6 +49,12 @@ typedef struct _GUID
#endif
#endif
+#ifdef Q_OS_DARWIN
+Q_FORWARD_DECLARE_CF_TYPE(CFUUID);
+# ifdef __OBJC__
+Q_FORWARD_DECLARE_OBJC_CLASS(NSUUID);
+# endif
+#endif
QT_BEGIN_NAMESPACE
@@ -195,6 +201,15 @@ public:
QUuid::Variant variant() const Q_DECL_NOTHROW;
QUuid::Version version() const Q_DECL_NOTHROW;
+#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
+ static QUuid fromCFUUID(CFUUIDRef uuid);
+ CFUUIDRef toCFUUID() const Q_DECL_CF_RETURNS_RETAINED;
+# if defined(__OBJC__) || defined(Q_QDOC)
+ static QUuid fromNSUUID(const NSUUID *uuid);
+ NSUUID *toNSUUID() const Q_DECL_NS_RETURNS_AUTORELEASED;
+# endif
+#endif
+
uint data1;
ushort data2;
ushort data3;
diff --git a/src/widgets/styles/qgtkpainter.cpp b/src/corelib/plugin/quuid_darwin.mm
index e86fee079e..b316b88d52 100644
--- a/src/widgets/styles/qgtkpainter.cpp
+++ b/src/corelib/plugin/quuid_darwin.mm
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the QtWidgets module of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
@@ -31,46 +31,39 @@
**
****************************************************************************/
-#include "qgtkpainter_p.h"
+#include "quuid.h"
-#if !defined(QT_NO_STYLE_GTK)
-
-#include <private/qhexstring_p.h>
+#import <Foundation/Foundation.h>
QT_BEGIN_NAMESPACE
-QGtkPainter::QGtkPainter()
+QUuid QUuid::fromCFUUID(CFUUIDRef uuid)
{
- reset(0);
+ if (!uuid)
+ return QUuid();
+ const CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid);
+ return QUuid::fromRfc4122(QByteArray::fromRawData(reinterpret_cast<const char *>(&bytes), sizeof(bytes)));
}
-QGtkPainter::~QGtkPainter()
+CFUUIDRef QUuid::toCFUUID() const
{
+ const QByteArray bytes = toRfc4122();
+ return CFUUIDCreateFromUUIDBytes(0, *reinterpret_cast<const CFUUIDBytes *>(bytes.constData()));
}
-void QGtkPainter::reset(QPainter *painter)
+QUuid QUuid::fromNSUUID(const NSUUID *uuid)
{
- m_painter = painter;
- m_alpha = true;
- m_hflipped = false;
- m_vflipped = false;
- m_usePixmapCache = true;
- m_cliprect = QRect();
+ if (!uuid)
+ return QUuid();
+ uuid_t bytes;
+ [uuid getUUIDBytes:bytes];
+ return QUuid::fromRfc4122(QByteArray::fromRawData(reinterpret_cast<const char *>(bytes), sizeof(bytes)));
}
-QString QGtkPainter::uniqueName(const QString &key, GtkStateType state, GtkShadowType shadow,
- const QSize &size, GtkWidget *widget)
+NSUUID *QUuid::toNSUUID() const
{
- // Note the widget arg should ideally use the widget path, though would compromise performance
- QString tmp = key
- % HexString<uint>(state)
- % HexString<uint>(shadow)
- % HexString<uint>(size.width())
- % HexString<uint>(size.height())
- % HexString<quint64>(quint64(widget));
- return tmp;
+ const QByteArray bytes = toRfc4122();
+ return [[[NSUUID alloc] initWithUUIDBytes:*reinterpret_cast<const uuid_t *>(bytes.constData())] autorelease];
}
QT_END_NAMESPACE
-
-#endif //!defined(QT_NO_STYLE_GTK)
diff --git a/src/corelib/statemachine/qsignaltransition.cpp b/src/corelib/statemachine/qsignaltransition.cpp
index 7ec72df77c..e8c5f3e479 100644
--- a/src/corelib/statemachine/qsignaltransition.cpp
+++ b/src/corelib/statemachine/qsignaltransition.cpp
@@ -146,6 +146,19 @@ QSignalTransition::QSignalTransition(const QObject *sender, const char *signal,
}
/*!
+ \fn QSignalTransition::QSignalTransition(const QObject *sender,
+ PointerToMemberFunction signal, QState *sourceState);
+ \since 5.7
+ \overload
+
+ Constructs a new signal transition associated with the given \a signal of
+ the given \a sender object and with the given \a sourceSate.
+ This constructor is enabled if compiler supports delegating constructor.
+
+ \sa Q_COMPILER_DELEGATING_CONSTRUCTORS
+*/
+
+/*!
Destroys this signal transition.
*/
QSignalTransition::~QSignalTransition()
diff --git a/src/corelib/statemachine/qsignaltransition.h b/src/corelib/statemachine/qsignaltransition.h
index c388323ec4..b428cb621d 100644
--- a/src/corelib/statemachine/qsignaltransition.h
+++ b/src/corelib/statemachine/qsignaltransition.h
@@ -35,6 +35,7 @@
#define QSIGNALTRANSITION_H
#include <QtCore/qabstracttransition.h>
+#include <QtCore/qmetaobject.h>
QT_BEGIN_NAMESPACE
@@ -52,6 +53,18 @@ public:
QSignalTransition(QState *sourceState = Q_NULLPTR);
QSignalTransition(const QObject *sender, const char *signal,
QState *sourceState = Q_NULLPTR);
+#ifdef Q_QDOC
+ QSignalTransition(const QObject *object, PointerToMemberFunction signal,
+ QState *sourceState = Q_NULLPTR);
+#elif defined(Q_COMPILER_DELEGATING_CONSTRUCTORS)
+ template <typename Func>
+ QSignalTransition(const typename QtPrivate::FunctionPointer<Func>::Object *obj,
+ Func sig, QState *srcState = Q_NULLPTR)
+ : QSignalTransition(obj, QMetaMethod::fromSignal(sig).methodSignature().constData(), srcState)
+ {
+ }
+#endif
+
~QSignalTransition();
QObject *senderObject() const;
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 20d5ed890b..9c5fc9eec5 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -294,7 +294,7 @@ static inline bool isDescendant(const QAbstractState *state1, const QAbstractSta
static bool containsDecendantOf(const QSet<QAbstractState *> &states, const QAbstractState *node)
{
- foreach (QAbstractState *s, states)
+ for (QAbstractState *s : states)
if (isDescendant(s, node))
return true;
@@ -361,7 +361,8 @@ static QList<QAbstractState *> getEffectiveTargetStates(QAbstractTransition *tra
return targetsList;
QSet<QAbstractState *> targets;
- foreach (QAbstractState *s, transition->targetStates()) {
+ const auto targetStates = transition->targetStates();
+ for (QAbstractState *s : targetStates) {
if (QHistoryState *historyState = QStateMachinePrivate::toHistoryState(s)) {
QList<QAbstractState*> historyConfiguration = QHistoryStatePrivate::get(historyState)->configuration;
if (!historyConfiguration.isEmpty()) {
@@ -547,7 +548,7 @@ QList<QAbstractTransition*> QStateMachinePrivate::selectTransitions(QEvent *even
Q_Q(const QStateMachine);
QVarLengthArray<QAbstractState *> configuration_sorted;
- foreach (QAbstractState *s, configuration) {
+ for (QAbstractState *s : qAsConst(configuration)) {
if (isAtomic(s))
configuration_sorted.append(s);
}
@@ -555,7 +556,7 @@ QList<QAbstractTransition*> QStateMachinePrivate::selectTransitions(QEvent *even
QList<QAbstractTransition*> enabledTransitions;
const_cast<QStateMachine*>(q)->beginSelectTransitions(event);
- foreach (QAbstractState *state, configuration_sorted) {
+ for (QAbstractState *state : qAsConst(configuration_sorted)) {
QVector<QState*> lst = getProperAncestors(state, Q_NULLPTR);
if (QState *grp = toStandardState(state))
lst.prepend(grp);
@@ -622,7 +623,7 @@ void QStateMachinePrivate::removeConflictingTransitions(QList<QAbstractTransitio
filteredTransitions.reserve(enabledTransitions.size());
std::sort(enabledTransitions.begin(), enabledTransitions.end(), transitionStateEntryLessThan);
- foreach (QAbstractTransition *t1, enabledTransitions) {
+ for (QAbstractTransition *t1 : qAsConst(enabledTransitions)) {
bool t1Preempted = false;
const QSet<QAbstractState*> exitSetT1 = computeExitSet_Unordered(t1, cache);
QList<QAbstractTransition*>::iterator t2It = filteredTransitions.begin();
@@ -747,7 +748,7 @@ QSet<QAbstractState*> QStateMachinePrivate::computeExitSet_Unordered(const QList
Q_ASSERT(cache);
QSet<QAbstractState*> statesToExit;
- foreach (QAbstractTransition *t, enabledTransitions)
+ for (QAbstractTransition *t : enabledTransitions)
statesToExit.unite(computeExitSet_Unordered(t, cache));
return statesToExit;
}
@@ -780,7 +781,7 @@ QSet<QAbstractState*> QStateMachinePrivate::computeExitSet_Unordered(QAbstractTr
Q_ASSERT(domain != 0);
}
- foreach (QAbstractState* s, configuration) {
+ for (QAbstractState* s : qAsConst(configuration)) {
if (isDescendant(s, domain))
statesToExit.insert(s);
}
@@ -854,16 +855,15 @@ QList<QAbstractState*> QStateMachinePrivate::computeEntrySet(const QList<QAbstra
QSet<QAbstractState*> statesToEnter;
if (pendingErrorStates.isEmpty()) {
- foreach (QAbstractTransition *t, enabledTransitions) {
- foreach (QAbstractState *s, t->targetStates()) {
+ for (QAbstractTransition *t : enabledTransitions) {
+ const auto targetStates = t->targetStates();
+ for (QAbstractState *s : targetStates)
addDescendantStatesToEnter(s, statesToEnter, statesForDefaultEntry);
- }
- QList<QAbstractState *> effectiveTargetStates = getEffectiveTargetStates(t, cache);
+ const QList<QAbstractState *> effectiveTargetStates = getEffectiveTargetStates(t, cache);
QAbstractState *ancestor = getTransitionDomain(t, effectiveTargetStates, cache);
- foreach (QAbstractState *s, effectiveTargetStates) {
+ for (QAbstractState *s : effectiveTargetStates)
addAncestorStatesToEnter(s, ancestor, statesToEnter, statesForDefaultEntry);
- }
}
}
@@ -914,7 +914,7 @@ QAbstractState *QStateMachinePrivate::getTransitionDomain(QAbstractTransition *t
if (QState *tSource = t->sourceState()) {
if (isCompound(tSource)) {
bool allDescendants = true;
- foreach (QAbstractState *s, effectiveTargetStates) {
+ for (QAbstractState *s : effectiveTargetStates) {
if (!isDescendant(s, tSource)) {
allDescendants = false;
break;
@@ -1090,11 +1090,11 @@ void QStateMachinePrivate::addDescendantStatesToEnter(QAbstractState *state,
QSet<QAbstractState*> &statesForDefaultEntry)
{
if (QHistoryState *h = toHistoryState(state)) {
- QList<QAbstractState*> historyConfiguration = QHistoryStatePrivate::get(h)->configuration;
+ const QList<QAbstractState*> historyConfiguration = QHistoryStatePrivate::get(h)->configuration;
if (!historyConfiguration.isEmpty()) {
- foreach (QAbstractState *s, historyConfiguration)
+ for (QAbstractState *s : historyConfiguration)
addDescendantStatesToEnter(s, statesToEnter, statesForDefaultEntry);
- foreach (QAbstractState *s, historyConfiguration)
+ for (QAbstractState *s : historyConfiguration)
addAncestorStatesToEnter(s, state->parentState(), statesToEnter, statesForDefaultEntry);
#ifdef QSTATEMACHINE_DEBUG
@@ -1110,9 +1110,9 @@ void QStateMachinePrivate::addDescendantStatesToEnter(QAbstractState *state,
if (defaultHistoryContent.isEmpty()) {
setError(QStateMachine::NoDefaultStateInHistoryStateError, h);
} else {
- foreach (QAbstractState *s, defaultHistoryContent)
+ for (QAbstractState *s : qAsConst(defaultHistoryContent))
addDescendantStatesToEnter(s, statesToEnter, statesForDefaultEntry);
- foreach (QAbstractState *s, defaultHistoryContent)
+ for (QAbstractState *s : qAsConst(defaultHistoryContent))
addAncestorStatesToEnter(s, state->parentState(), statesToEnter, statesForDefaultEntry);
#ifdef QSTATEMACHINE_DEBUG
qDebug() << q_func() << ": initial history targets for" << state << ':' << defaultHistoryContent;
@@ -1145,7 +1145,8 @@ void QStateMachinePrivate::addDescendantStatesToEnter(QAbstractState *state,
}
} else if (isParallel(state)) {
QState *grp = toStandardState(state);
- foreach (QAbstractState *child, QStatePrivate::get(grp)->childStates()) {
+ const auto childStates = QStatePrivate::get(grp)->childStates();
+ for (QAbstractState *child : childStates) {
if (!containsDecendantOf(statesToEnter, child))
addDescendantStatesToEnter(child, statesToEnter, statesForDefaultEntry);
}
@@ -1168,12 +1169,14 @@ void QStateMachinePrivate::addAncestorStatesToEnter(QAbstractState *s, QAbstract
QSet<QAbstractState*> &statesToEnter,
QSet<QAbstractState*> &statesForDefaultEntry)
{
- foreach (QState *anc, getProperAncestors(s, ancestor)) {
+ const auto properAncestors = getProperAncestors(s, ancestor);
+ for (QState *anc : properAncestors) {
if (!anc->parentState())
continue;
statesToEnter.insert(anc);
if (isParallel(anc)) {
- foreach (QAbstractState *child, QStatePrivate::get(anc)->childStates()) {
+ const auto childStates = QStatePrivate::get(anc)->childStates();
+ for (QAbstractState *child : childStates) {
if (!containsDecendantOf(statesToEnter, child))
addDescendantStatesToEnter(child, statesToEnter, statesForDefaultEntry);
}
@@ -1341,9 +1344,8 @@ void QStateMachinePrivate::unregisterRestorables(const QList<QAbstractState *> &
if (it == registeredRestorablesForState.end())
continue;
QHash<RestorableId, QVariant> &restorables = it.value();
- QHash<RestorableId, QVariant>::iterator it2;
- it2 = restorables.find(id);
- if (it2 == restorables.end())
+ const auto it2 = restorables.constFind(id);
+ if (it2 == restorables.cend())
continue;
#ifdef QSTATEMACHINE_RESTORE_PROPERTIES_DEBUG
qDebug() << q_func() << ": unregistered for" << s;
@@ -1500,8 +1502,7 @@ void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractSta
pendingErrorStates.insert(currentErrorState);
addDescendantStatesToEnter(currentErrorState, pendingErrorStates, pendingErrorStatesForDefaultEntry);
addAncestorStatesToEnter(currentErrorState, rootState(), pendingErrorStates, pendingErrorStatesForDefaultEntry);
- foreach (QAbstractState *s, configuration)
- pendingErrorStates.remove(s);
+ pendingErrorStates -= configuration;
} else {
qWarning("Unrecoverable error detected in running state machine: %s",
qPrintable(errorString));
@@ -1511,20 +1512,18 @@ void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractSta
#ifndef QT_NO_ANIMATION
-QPair<QList<QAbstractAnimation*>, QList<QAbstractAnimation*> >
+QStateMachinePrivate::InitializeAnimationResult
QStateMachinePrivate::initializeAnimation(QAbstractAnimation *abstractAnimation,
const QPropertyAssignment &prop)
{
- QList<QAbstractAnimation*> handledAnimations;
- QList<QAbstractAnimation*> localResetEndValues;
+ InitializeAnimationResult result;
QAnimationGroup *group = qobject_cast<QAnimationGroup*>(abstractAnimation);
if (group) {
for (int i = 0; i < group->animationCount(); ++i) {
QAbstractAnimation *animationChild = group->animationAt(i);
- QPair<QList<QAbstractAnimation*>, QList<QAbstractAnimation*> > ret;
- ret = initializeAnimation(animationChild, prop);
- handledAnimations << ret.first;
- localResetEndValues << ret.second;
+ const auto ret = initializeAnimation(animationChild, prop);
+ result.handledAnimations << ret.handledAnimations;
+ result.localResetEndValues << ret.localResetEndValues;
}
} else {
QPropertyAnimation *animation = qobject_cast<QPropertyAnimation *>(abstractAnimation);
@@ -1535,12 +1534,12 @@ QStateMachinePrivate::initializeAnimation(QAbstractAnimation *abstractAnimation,
// Only change end value if it is undefined
if (!animation->endValue().isValid()) {
animation->setEndValue(prop.value);
- localResetEndValues.append(animation);
+ result.localResetEndValues.append(animation);
}
- handledAnimations.append(animation);
+ result.handledAnimations.append(animation);
}
}
- return qMakePair(handledAnimations, localResetEndValues);
+ return result;
}
void QStateMachinePrivate::_q_animationFinished()
@@ -1651,13 +1650,11 @@ void QStateMachinePrivate::initializeAnimations(QAbstractState *state, const QLi
QAbstractAnimation *anim = selectedAnimations.at(i);
QVector<QPropertyAssignment>::iterator it;
for (it = assignments.begin(); it != assignments.end(); ) {
- QPair<QList<QAbstractAnimation*>, QList<QAbstractAnimation*> > ret;
const QPropertyAssignment &assn = *it;
- ret = initializeAnimation(anim, assn);
- QList<QAbstractAnimation*> handlers = ret.first;
- if (!handlers.isEmpty()) {
- for (int j = 0; j < handlers.size(); ++j) {
- QAbstractAnimation *a = handlers.at(j);
+ const auto ret = initializeAnimation(anim, assn);
+ if (!ret.handledAnimations.isEmpty()) {
+ for (int j = 0; j < ret.handledAnimations.size(); ++j) {
+ QAbstractAnimation *a = ret.handledAnimations.at(j);
propertyForAnimation.insert(a, assn);
stateForAnimation.insert(a, state);
animationsForState[state].append(a);
@@ -1674,8 +1671,8 @@ void QStateMachinePrivate::initializeAnimations(QAbstractState *state, const QLi
} else {
++it;
}
- for (int j = 0; j < ret.second.size(); ++j)
- resetAnimationEndValues.insert(ret.second.at(j));
+ for (int j = 0; j < ret.localResetEndValues.size(); ++j)
+ resetAnimationEndValues.insert(ret.localResetEndValues.at(j));
}
// We require that at least one animation is valid.
// ### generalize
diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h
index 45c6dfcb33..98f7bbd90b 100644
--- a/src/corelib/statemachine/qstatemachine_p.h
+++ b/src/corelib/statemachine/qstatemachine_p.h
@@ -259,7 +259,18 @@ public:
#ifndef QT_NO_ANIMATION
bool animated;
- QPair<QList<QAbstractAnimation*>, QList<QAbstractAnimation*> >
+ struct InitializeAnimationResult {
+ QList<QAbstractAnimation*> handledAnimations;
+ QList<QAbstractAnimation*> localResetEndValues;
+
+ void swap(InitializeAnimationResult &other) Q_DECL_NOTHROW
+ {
+ qSwap(handledAnimations, other.handledAnimations);
+ qSwap(localResetEndValues, other.localResetEndValues);
+ }
+ };
+
+ InitializeAnimationResult
initializeAnimation(QAbstractAnimation *abstractAnimation,
const QPropertyAssignment &prop);
@@ -307,6 +318,7 @@ public:
static const Handler *handler;
};
+Q_DECLARE_SHARED(QStateMachinePrivate::InitializeAnimationResult)
Q_CORE_EXPORT const QStateMachinePrivate::Handler *qcoreStateMachineHandler();
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index 3ca742b194..191edda6d1 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -55,11 +55,14 @@
#if defined(Q_OS_MAC)
# include <mach/semaphore.h>
-#endif
-
-#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
+#elif defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
// use Linux mutexes everywhere except for LSB builds
# define QT_LINUX_FUTEX
+#elif defined(Q_OS_UNIX)
+# if _POSIX_VERSION-0 >= 200112L || _XOPEN_VERSION-0 >= 600
+# include <semaphore.h>
+# define QT_UNIX_SEMAPHORE
+# endif
#endif
struct timespec;
@@ -120,6 +123,8 @@ public:
//platform specific stuff
#if defined(Q_OS_MAC)
semaphore_t mach_semaphore;
+#elif defined(QT_UNIX_SEMAPHORE)
+ sem_t semaphore;
#elif defined(Q_OS_UNIX)
bool wakeup;
pthread_mutex_t mutex;
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index 74e0d68f94..daa09e962b 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -42,6 +43,7 @@
#include <errno.h>
#include <sys/time.h>
#include <time.h>
+#include "private/qcore_unix_p.h"
#if defined(Q_OS_VXWORKS) && defined(wakeup)
#undef wakeup
@@ -55,6 +57,51 @@ static void report_error(int code, const char *where, const char *what)
qWarning("%s: %s failure: %s", where, what, qPrintable(qt_error_string(code)));
}
+#ifdef QT_UNIX_SEMAPHORE
+
+QMutexPrivate::QMutexPrivate()
+{
+ report_error(sem_init(&semaphore, 0, 0), "QMutex", "sem_init");
+}
+
+QMutexPrivate::~QMutexPrivate()
+{
+
+ report_error(sem_destroy(&semaphore), "QMutex", "sem_destroy");
+}
+
+bool QMutexPrivate::wait(int timeout)
+{
+ int errorCode;
+ if (timeout < 0) {
+ do {
+ errorCode = sem_wait(&semaphore);
+ } while (errorCode && errno == EINTR);
+ report_error(errorCode, "QMutex::lock()", "sem_wait");
+ } else {
+ timespec ts;
+ report_error(clock_gettime(CLOCK_REALTIME, &ts), "QMutex::lock()", "clock_gettime");
+ ts.tv_sec += timeout / 1000;
+ ts.tv_nsec += timeout % 1000 * Q_UINT64_C(1000) * 1000;
+ normalizedTimespec(ts);
+ do {
+ errorCode = sem_timedwait(&semaphore, &ts);
+ } while (errorCode && errno == EINTR);
+
+ if (errorCode && errno == ETIMEDOUT)
+ return false;
+ report_error(errorCode, "QMutex::lock()", "sem_timedwait");
+ }
+ return true;
+}
+
+void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
+{
+ report_error(sem_post(&semaphore), "QMutex::unlock", "sem_post");
+}
+
+#else // QT_UNIX_SEMAPHORE
+
QMutexPrivate::QMutexPrivate()
: wakeup(false)
{
@@ -103,6 +150,7 @@ void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
report_error(pthread_mutex_unlock(&mutex), "QMutex::unlock", "mutex unlock");
}
+#endif
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index af4ce7c59e..9329c515af 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -38,18 +38,16 @@
#include <private/qcoreapplication_p.h>
#include <private/qcore_unix_p.h>
-#if defined(Q_OS_BLACKBERRY)
-# include <private/qeventdispatcher_blackberry_p.h>
-#elif defined(Q_OS_OSX)
+#if defined(Q_OS_OSX)
# include <private/qeventdispatcher_cf_p.h>
-# include <private/qeventdispatcher_unix_p.h>
#else
# if !defined(QT_NO_GLIB)
# include "../kernel/qeventdispatcher_glib_p.h"
# endif
-# include <private/qeventdispatcher_unix_p.h>
#endif
+#include <private/qeventdispatcher_unix_p.h>
+
#include "qthreadstorage.h"
#include "qthread_p.h"
@@ -250,16 +248,14 @@ typedef void*(*QtThreadCallback)(void*);
void QThreadPrivate::createEventDispatcher(QThreadData *data)
{
-#if defined(Q_OS_BLACKBERRY)
- data->eventDispatcher.storeRelease(new QEventDispatcherBlackberry);
-# elif defined(Q_OS_OSX)
+#if defined(Q_OS_OSX)
bool ok = false;
int value = qEnvironmentVariableIntValue("QT_EVENT_DISPATCHER_CORE_FOUNDATION", &ok);
if (ok && value > 0)
data->eventDispatcher.storeRelease(new QEventDispatcherCoreFoundation);
else
data->eventDispatcher.storeRelease(new QEventDispatcherUNIX);
-# elif !defined(QT_NO_GLIB)
+#elif !defined(QT_NO_GLIB)
if (qEnvironmentVariableIsEmpty("QT_NO_GLIB")
&& qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB")
&& QEventDispatcherGlib::versionSupported())
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index e4a5368281..69f7572b34 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -263,7 +263,7 @@ void QThreadPoolPrivate::reset()
allThreadsCopy.swap(allThreads);
locker.unlock();
- foreach (QThreadPoolThread *thread, allThreadsCopy) {
+ for (QThreadPoolThread *thread : qAsConst(allThreadsCopy)) {
thread->runnableReady.wakeAll();
thread->wait();
delete thread;
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index ffa3082d5e..27630aea87 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -620,7 +620,11 @@ Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint8 v) Q_DECL_NOT
Q_DECL_RELAXED_CONSTEXPR inline uint qCountTrailingZeroBits(quint16 v) Q_DECL_NOTHROW
{
#if defined(Q_CC_GNU)
+# if QT_HAS_BUILTIN(__builtin_ctzs) || defined(__BMI__)
+ return v ? __builtin_ctzs(v) : 16U;
+# else
return v ? __builtin_ctz(v) : 16U;
+# endif
#else
unsigned int c = 16; // c will be the number of zero bits on the right
v &= -signed(v);
@@ -679,7 +683,11 @@ Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint8 v) Q_DECL_NOTH
Q_DECL_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint16 v) Q_DECL_NOTHROW
{
#if defined(Q_CC_GNU)
+# if QT_HAS_BUILTIN(__builtin_clzs) || defined(__BMI__)
+ return v ? __builtin_clzs(v) : 16U;
+# else
return v ? __builtin_clz(v)-16U : 16U;
+# endif
#else
v = v | (v >> 1);
v = v | (v >> 2);
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 00d15fd518..b972be68a3 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -39,6 +39,7 @@
#include "qlist.h"
#include "qlocale.h"
#include "qlocale_p.h"
+#include "qlocale_tools_p.h"
#include "qstringalgorithms_p.h"
#include "qscopedpointer.h"
#include "qbytearray_p.h"
@@ -1713,6 +1714,14 @@ QByteArray &QByteArray::prepend(const char *str, int len)
return *this;
}
+/*! \fn QByteArray &QByteArray::prepend(int count, char ch)
+
+ \overload
+ \since 5.7
+
+ Prepends \a count copies of character \a ch to this byte array.
+*/
+
/*!
\overload
@@ -1825,6 +1834,17 @@ QByteArray &QByteArray::append(const char *str, int len)
return *this;
}
+/*! \fn QByteArray &QByteArray::append(int count, char ch)
+
+ \overload
+ \since 5.7
+
+ Appends \a count copies of character \a ch to this byte
+ array and returns a reference to this byte array.
+
+ If \a count is negative or zero nothing is appended to the byte array.
+*/
+
/*!
\overload
@@ -1941,6 +1961,33 @@ QByteArray &QByteArray::insert(int i, char ch)
return qbytearray_insert(this, i, &ch, 1);
}
+/*! \fn QByteArray &QByteArray::insert(int i, int count, char ch)
+
+ \overload
+ \since 5.7
+
+ Inserts \a count copies of character \a ch at index position \a i in the
+ byte array.
+
+ If \a i is greater than size(), the array is first extended using resize().
+*/
+
+QByteArray &QByteArray::insert(int i, int count, char ch)
+{
+ if (i < 0 || count <= 0)
+ return *this;
+
+ int oldsize = size();
+ resize(qMax(i, oldsize) + count);
+ char *dst = d->data();
+ if (i > oldsize)
+ ::memset(dst + oldsize, 0x20, i - oldsize);
+ else if (i < oldsize)
+ ::memmove(dst + i + count, dst + i, oldsize - i);
+ ::memset(dst + i, ch, count);
+ return *this;
+}
+
/*!
Removes \a len bytes from the array, starting at index position \a
pos, and returns a reference to the array.
@@ -3648,7 +3695,13 @@ ushort QByteArray::toUShort(bool *ok, int base) const
double QByteArray::toDouble(bool *ok) const
{
- return QLocaleData::bytearrayToDouble(nulTerminated().constData(), ok);
+ QByteArray nulled = nulTerminated();
+ bool nonNullOk = false;
+ int processed = 0;
+ double d = asciiToDouble(nulled.constData(), nulled.length(), nonNullOk, processed);
+ if (ok)
+ *ok = nonNullOk;
+ return d;
}
/*!
@@ -3877,10 +3930,10 @@ QByteArray &QByteArray::setNum(qulonglong n, int base)
QByteArray &QByteArray::setNum(double n, char f, int prec)
{
QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
- uint flags = 0;
+ uint flags = QLocaleData::ZeroPadExponent;
if (qIsUpper(f))
- flags = QLocaleData::CapitalEorX;
+ flags |= QLocaleData::CapitalEorX;
f = qToLower(f);
switch (f) {
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index f0032227e8..6c79a603d3 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -255,21 +255,21 @@ public:
# define Q_REQUIRED_RESULT
# define Q_REQUIRED_RESULT_pushed
# endif
- QByteArray toLower() const & Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QByteArray toLower() const & Q_REQUIRED_RESULT
{ return toLower_helper(*this); }
- QByteArray toLower() && Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QByteArray toLower() && Q_REQUIRED_RESULT
{ return toLower_helper(*this); }
- QByteArray toUpper() const & Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QByteArray toUpper() const & Q_REQUIRED_RESULT
{ return toUpper_helper(*this); }
- QByteArray toUpper() && Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QByteArray toUpper() && Q_REQUIRED_RESULT
{ return toUpper_helper(*this); }
- QByteArray trimmed() const & Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QByteArray trimmed() const & Q_REQUIRED_RESULT
{ return trimmed_helper(*this); }
- QByteArray trimmed() && Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QByteArray trimmed() && Q_REQUIRED_RESULT
{ return trimmed_helper(*this); }
- QByteArray simplified() const & Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QByteArray simplified() const & Q_REQUIRED_RESULT
{ return simplified_helper(*this); }
- QByteArray simplified() && Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QByteArray simplified() && Q_REQUIRED_RESULT
{ return simplified_helper(*this); }
# ifdef Q_REQUIRED_RESULT_pushed
# pragma pop_macro("Q_REQUIRED_RESULT")
@@ -285,14 +285,17 @@ public:
QByteArray rightJustified(int width, char fill = ' ', bool truncate = false) const Q_REQUIRED_RESULT;
QByteArray &prepend(char c);
+ QByteArray &prepend(int count, char c);
QByteArray &prepend(const char *s);
QByteArray &prepend(const char *s, int len);
QByteArray &prepend(const QByteArray &a);
QByteArray &append(char c);
+ QByteArray &append(int count, char c);
QByteArray &append(const char *s);
QByteArray &append(const char *s, int len);
QByteArray &append(const QByteArray &a);
QByteArray &insert(int i, char c);
+ QByteArray &insert(int i, int count, char c);
QByteArray &insert(int i, const char *s);
QByteArray &insert(int i, const char *s, int len);
QByteArray &insert(int i, const QByteArray &a);
@@ -568,6 +571,10 @@ inline QByteArray::const_iterator QByteArray::cend() const
{ return d->data() + d->size; }
inline QByteArray::const_iterator QByteArray::constEnd() const
{ return d->data() + d->size; }
+inline QByteArray &QByteArray::append(int n, char ch)
+{ return insert(d->size, n, ch); }
+inline QByteArray &QByteArray::prepend(int n, char ch)
+{ return insert(0, n, ch); }
inline QByteArray &QByteArray::operator+=(char c)
{ return append(c); }
inline QByteArray &QByteArray::operator+=(const char *s)
diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h
index 9833380cc8..c60b5fbf49 100644
--- a/src/corelib/tools/qchar.h
+++ b/src/corelib/tools/qchar.h
@@ -567,10 +567,10 @@ Q_DECLARE_TYPEINFO(QChar, Q_MOVABLE_TYPE);
Q_DECL_CONSTEXPR inline bool operator==(QChar c1, QChar c2) Q_DECL_NOTHROW { return c1.ucs == c2.ucs; }
Q_DECL_CONSTEXPR inline bool operator< (QChar c1, QChar c2) Q_DECL_NOTHROW { return c1.ucs < c2.ucs; }
-Q_DECL_CONSTEXPR inline bool operator!=(QChar c1, QChar c2) { return !operator==(c1, c2); }
-Q_DECL_CONSTEXPR inline bool operator>=(QChar c1, QChar c2) { return !operator< (c1, c2); }
-Q_DECL_CONSTEXPR inline bool operator> (QChar c1, QChar c2) { return operator< (c2, c1); }
-Q_DECL_CONSTEXPR inline bool operator<=(QChar c1, QChar c2) { return !operator< (c2, c1); }
+Q_DECL_CONSTEXPR inline bool operator!=(QChar c1, QChar c2) Q_DECL_NOTHROW { return !operator==(c1, c2); }
+Q_DECL_CONSTEXPR inline bool operator>=(QChar c1, QChar c2) Q_DECL_NOTHROW { return !operator< (c1, c2); }
+Q_DECL_CONSTEXPR inline bool operator> (QChar c1, QChar c2) Q_DECL_NOTHROW { return operator< (c2, c1); }
+Q_DECL_CONSTEXPR inline bool operator<=(QChar c1, QChar c2) Q_DECL_NOTHROW { return !operator< (c2, c1); }
#ifndef QT_NO_DATASTREAM
Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QChar);
diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp
index 2bc60c5b9e..1b260dd122 100644
--- a/src/corelib/tools/qcommandlineparser.cpp
+++ b/src/corelib/tools/qcommandlineparser.cpp
@@ -348,10 +348,10 @@ void QCommandLineParser::setOptionsAfterPositionalArgumentsMode(QCommandLinePars
*/
bool QCommandLineParser::addOption(const QCommandLineOption &option)
{
- QStringList optionNames = option.names();
+ const QStringList optionNames = option.names();
if (!optionNames.isEmpty()) {
- foreach (const QString &name, optionNames) {
+ for (const QString &name : optionNames) {
if (d->nameHash.contains(name))
return false;
}
@@ -359,7 +359,7 @@ bool QCommandLineParser::addOption(const QCommandLineOption &option)
d->commandLineOptionList.append(option);
const int offset = d->commandLineOptionList.size() - 1;
- foreach (const QString &name, optionNames)
+ for (const QString &name : optionNames)
d->nameHash.insert(name, offset);
return true;
@@ -797,7 +797,7 @@ bool QCommandLineParser::isSet(const QString &name) const
if (d->optionNames.contains(name))
return true;
const QStringList aliases = d->aliases(name);
- foreach (const QString &optionName, d->optionNames) {
+ for (const QString &optionName : qAsConst(d->optionNames)) {
if (aliases.contains(optionName))
return true;
}
@@ -1075,16 +1075,12 @@ QString QCommandLineParserPrivate::helpText() const
{
const QLatin1Char nl('\n');
QString text;
- const QString exeName = QCoreApplication::instance()->arguments().first();
- QString usage = exeName;
- if (!commandLineOptionList.isEmpty()) {
- usage += QLatin1Char(' ');
- usage += QCommandLineParser::tr("[options]");
- }
- foreach (const PositionalArgumentDefinition &arg, positionalArgumentDefinitions) {
- usage += QLatin1Char(' ');
- usage += arg.syntax;
- }
+ QString usage;
+ usage += QCoreApplication::instance()->arguments().constFirst(); // executable name
+ if (!commandLineOptionList.isEmpty())
+ usage += QLatin1Char(' ') + QCommandLineParser::tr("[options]");
+ for (const PositionalArgumentDefinition &arg : positionalArgumentDefinitions)
+ usage += QLatin1Char(' ') + arg.syntax;
text += QCommandLineParser::tr("Usage: %1").arg(usage) + nl;
if (!description.isEmpty())
text += description + nl;
@@ -1092,35 +1088,39 @@ QString QCommandLineParserPrivate::helpText() const
if (!commandLineOptionList.isEmpty())
text += QCommandLineParser::tr("Options:") + nl;
QStringList optionNameList;
+ optionNameList.reserve(commandLineOptionList.size());
int longestOptionNameString = 0;
- foreach (const QCommandLineOption &option, commandLineOptionList) {
- QStringList optionNames;
- foreach (const QString &optionName, option.names()) {
- if (optionName.length() == 1)
- optionNames.append(QLatin1Char('-') + optionName);
- else
- optionNames.append(QStringLiteral("--") + optionName);
+ for (const QCommandLineOption &option : commandLineOptionList) {
+ if (option.isHidden())
+ continue;
+ const QStringList optionNames = option.names();
+ QString optionNamesString;
+ for (const QString &optionName : optionNames) {
+ const int numDashes = optionName.length() == 1 ? 1 : 2;
+ optionNamesString += QLatin1String("--", numDashes) + optionName + QLatin1String(", ");
}
- QString optionNamesString = optionNames.join(QStringLiteral(", "));
- if (!option.valueName().isEmpty())
- optionNamesString += QStringLiteral(" <") + option.valueName() + QLatin1Char('>');
+ if (!optionNames.isEmpty())
+ optionNamesString.chop(2); // remove trailing ", "
+ const auto valueName = option.valueName();
+ if (!valueName.isEmpty())
+ optionNamesString += QLatin1String(" <") + valueName + QLatin1Char('>');
optionNameList.append(optionNamesString);
longestOptionNameString = qMax(longestOptionNameString, optionNamesString.length());
}
++longestOptionNameString;
- for (int i = 0; i < commandLineOptionList.count(); ++i) {
- const QCommandLineOption &option = commandLineOptionList.at(i);
+ auto optionNameIterator = optionNameList.cbegin();
+ for (const QCommandLineOption &option : commandLineOptionList) {
if (option.isHidden())
continue;
- text += wrapText(optionNameList.at(i), longestOptionNameString, option.description());
+ text += wrapText(*optionNameIterator, longestOptionNameString, option.description());
+ ++optionNameIterator;
}
if (!positionalArgumentDefinitions.isEmpty()) {
if (!commandLineOptionList.isEmpty())
text += nl;
text += QCommandLineParser::tr("Arguments:") + nl;
- foreach (const PositionalArgumentDefinition &arg, positionalArgumentDefinitions) {
+ for (const PositionalArgumentDefinition &arg : positionalArgumentDefinitions)
text += wrapText(arg.name, longestOptionNameString, arg.description);
- }
}
return text;
}
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 241b02df1b..c4aa699992 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -64,6 +64,8 @@
QT_BEGIN_NAMESPACE
+Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QDateTimePrivate>, defaultDateTimePrivate, (new QDateTimePrivate()))
+
/*****************************************************************************
Date/Time Constants
*****************************************************************************/
@@ -2924,7 +2926,7 @@ qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QTimeZone
\sa isValid()
*/
QDateTime::QDateTime()
- : d(new QDateTimePrivate)
+ : d(*defaultDateTimePrivate())
{
}
diff --git a/src/corelib/tools/qdoublescanprint_p.h b/src/corelib/tools/qdoublescanprint_p.h
new file mode 100644
index 0000000000..30ac584d06
--- /dev/null
+++ b/src/corelib/tools/qdoublescanprint_p.h
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDOUBLESCANPRINT_P_H
+#define QDOUBLESCANPRINT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qglobal.h>
+
+#if defined(Q_CC_MSVC) && (defined(QT_BOOTSTRAPPED) || defined(QT_NO_DOUBLECONVERSION))
+# include <stdio.h>
+# include <locale.h>
+
+QT_BEGIN_NAMESPACE
+
+// We can always use _sscanf_l and _snprintf_l on MSVC as those were introduced in 2005.
+
+// MSVC doesn't document what it will do with a NULL locale passed to _sscanf_l or _snprintf_l.
+// The documentation for _create_locale() does not formally document "C" to be valid, but an example
+// code snippet in the same documentation shows it.
+
+struct QCLocaleT {
+ QCLocaleT() : locale(_create_locale(LC_ALL, "C"))
+ {
+ }
+
+ ~QCLocaleT()
+ {
+ _free_locale(locale);
+ }
+
+ const _locale_t locale;
+};
+
+# define QT_CLOCALE_HOLDER Q_GLOBAL_STATIC(QCLocaleT, cLocaleT)
+# define QT_CLOCALE cLocaleT()->locale
+
+inline int qDoubleSscanf(const char *buf, _locale_t locale, const char *format, double *d,
+ int *processed)
+{
+ return _sscanf_l(buf, format, locale, d, processed);
+}
+
+inline int qDoubleSnprintf(char *buf, size_t buflen, _locale_t locale, const char *format, double d)
+{
+ return _snprintf_l(buf, buflen, format, locale, d);
+}
+
+QT_END_NAMESPACE
+
+#elif defined(QT_BOOTSTRAPPED)
+# include <stdio.h>
+
+QT_BEGIN_NAMESPACE
+
+// When bootstrapping we don't have libdouble-conversion available, yet. We can also not use locale
+// aware snprintf and sscanf variants in the general case because those are only available on select
+// platforms. We can use the regular snprintf and sscanf because we don't do setlocale(3) when
+// bootstrapping and the locale is always "C" then.
+
+# define QT_CLOCALE_HOLDER
+# define QT_CLOCALE 0
+
+inline int qDoubleSscanf(const char *buf, int, const char *format, double *d, int *processed)
+{
+ return sscanf(buf, format, d, processed);
+}
+inline int qDoubleSnprintf(char *buf, size_t buflen, int, const char *format, double d)
+{
+ return snprintf(buf, buflen, format, d);
+}
+
+QT_END_NAMESPACE
+
+#else // !QT_BOOTSTRAPPED && (!Q_CC_MSVC || !QT_NO_DOUBLECONVERSION)
+# ifdef QT_NO_DOUBLECONVERSION
+# include <stdio.h>
+# include <xlocale.h>
+
+QT_BEGIN_NAMESPACE
+
+// OS X and FreeBSD both treat NULL as the "C" locale for snprintf_l and sscanf_l.
+// When other implementations with different behavior show up, we'll have to do newlocale(3) and
+// freelocale(3) here. The arguments to those will depend on what the other implementations will
+// offer. OS X and FreeBSD again interpret a locale name of NULL as "C", but "C" itself is not
+// documented as valid locale name. Mind that the names of the LC_* constants differ between e.g.
+// BSD variants and linux.
+
+# define QT_CLOCALE_HOLDER
+# define QT_CLOCALE NULL
+
+inline int qDoubleSscanf(const char *buf, locale_t locale, const char *format, double *d,
+ int *processed)
+{
+ return sscanf_l(buf, locale, format, d, processed);
+}
+inline int qDoubleSnprintf(char *buf, size_t buflen, locale_t locale, const char *format, double d)
+{
+ return snprintf_l(buf, buflen, locale, format, d);
+}
+
+QT_END_NAMESPACE
+
+# else // !QT_NO_DOUBLECONVERSION
+# include <double-conversion/double-conversion.h>
+# define QT_CLOCALE_HOLDER
+# endif // QT_NO_DOUBLECONVERSION
+#endif // QT_BOOTSTRAPPED
+
+#endif // QDOUBLESCANPRINT_P_H
diff --git a/src/corelib/tools/qeasingcurve.h b/src/corelib/tools/qeasingcurve.h
index d04d5ef30a..da423f2ee7 100644
--- a/src/corelib/tools/qeasingcurve.h
+++ b/src/corelib/tools/qeasingcurve.h
@@ -75,12 +75,12 @@ public:
QEasingCurve &operator=(const QEasingCurve &other)
{ if ( this != &other ) { QEasingCurve copy(other); swap(copy); } return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
- QEasingCurve(QEasingCurve &&other) : d_ptr(other.d_ptr) { other.d_ptr = Q_NULLPTR; }
- QEasingCurve &operator=(QEasingCurve &&other)
+ QEasingCurve(QEasingCurve &&other) Q_DECL_NOTHROW : d_ptr(other.d_ptr) { other.d_ptr = Q_NULLPTR; }
+ QEasingCurve &operator=(QEasingCurve &&other) Q_DECL_NOTHROW
{ qSwap(d_ptr, other.d_ptr); return *this; }
#endif
- inline void swap(QEasingCurve &other) { qSwap(d_ptr, other.d_ptr); }
+ void swap(QEasingCurve &other) Q_DECL_NOTHROW { qSwap(d_ptr, other.d_ptr); }
bool operator==(const QEasingCurve &other) const;
inline bool operator!=(const QEasingCurve &other) const
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index b334a697a9..7520158293 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -682,17 +682,17 @@ void QHashData::dump()
void QHashData::checkSanity()
{
- if (fakeNext)
+ if (Q_UNLIKELY(fakeNext))
qFatal("Fake next isn't 0");
for (int i = 0; i < numBuckets; ++i) {
Node *n = buckets[i];
Node *p = n;
- if (!n)
+ if (Q_UNLIKELY(!n))
qFatal("%d: Bucket entry is 0", i);
if (n != reinterpret_cast<Node *>(this)) {
while (n != reinterpret_cast<Node *>(this)) {
- if (!n->next)
+ if (Q_UNLIKELY(!n->next))
qFatal("%d: Next of %p is 0, should be %p", i, n, this);
n = n->next;
}
@@ -711,6 +711,23 @@ void QHashData::checkSanity()
Types \c T1 and \c T2 must be supported by qHash().
*/
+/*!
+ \fn uint qHash(const std::pair<T1, T2> &key, uint seed = 0)
+ \since 5.7
+ \relates QHash
+
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+
+ Types \c T1 and \c T2 must be supported by qHash().
+
+ \note The return type of this function is \e{not} the same as that of
+ \code
+ qHash(qMakePair(key.first, key.second), seed);
+ \endcode
+ The two functions use different hashing algorithms; due to binary compatibility
+ constraints, we cannot change the QPair algorithm to match the std::pair one before Qt 6.
+*/
+
/*! \fn uint qHashRange(InputIterator first, InputIterator last, uint seed = 0)
\relates QHash
\since 5.5
@@ -1632,7 +1649,8 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
\sa keyBegin()
*/
-/*! \fn QHash::iterator QHash::erase(iterator pos)
+/*! \fn QHash::iterator QHash::erase(const_iterator pos)
+ \since 5.7
Removes the (key, value) pair associated with the iterator \a pos
from the hash, and returns an iterator to the next item in the
@@ -1648,6 +1666,10 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
\sa remove(), take(), find()
*/
+/*! \fn QHash::iterator QHash::erase(iterator pos)
+ \overload
+*/
+
/*! \fn QHash::iterator QHash::find(const Key &key)
Returns an iterator pointing to the item with the \a key in the
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index a18dd74706..1098bb6203 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -297,6 +297,7 @@ public:
{
friend class const_iterator;
friend class QHash<Key, T>;
+ friend class QSet<Key>;
QHashData::Node *i;
public:
@@ -353,6 +354,7 @@ public:
class const_iterator
{
friend class iterator;
+ friend class QHash<Key, T>;
friend class QSet<Key>;
QHashData::Node *i;
@@ -450,7 +452,8 @@ public:
inline key_iterator keyBegin() const { return key_iterator(begin()); }
inline key_iterator keyEnd() const { return key_iterator(end()); }
- iterator erase(iterator it);
+ iterator erase(iterator it) { return erase(const_iterator(it.i)); }
+ iterator erase(const_iterator it);
// more Qt
typedef iterator Iterator;
@@ -487,15 +490,18 @@ private:
static void duplicateNode(QHashData::Node *originalNode, void *newNode);
- bool isValidIterator(const iterator &it) const
+ bool isValidIterator(const iterator &it) const Q_DECL_NOTHROW
+ { return isValidNode(it.i); }
+ bool isValidIterator(const const_iterator &it) const Q_DECL_NOTHROW
+ { return isValidNode(it.i); }
+ bool isValidNode(QHashData::Node *node) const Q_DECL_NOTHROW
{
#if defined(QT_DEBUG) && !defined(Q_HASH_NO_ITERATOR_DEBUG)
- QHashData::Node *node = it.i;
while (node->next)
node = node->next;
return (static_cast<void *>(node) == d);
#else
- Q_UNUSED(it);
+ Q_UNUSED(node);
return true;
#endif
}
@@ -807,30 +813,31 @@ Q_OUTOFLINE_TEMPLATE T QHash<Key, T>::take(const Key &akey)
}
template <class Key, class T>
-Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::erase(iterator it)
+Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::erase(const_iterator it)
{
Q_ASSERT_X(isValidIterator(it), "QHash::erase", "The specified iterator argument 'it' is invalid");
- if (it == iterator(e))
- return it;
+ if (it == const_iterator(e))
+ return iterator(it.i);
if (d->ref.isShared()) {
+ // save 'it' across the detach:
int bucketNum = (it.i->h % d->numBuckets);
- iterator bucketIterator(*(d->buckets + bucketNum));
+ const_iterator bucketIterator(*(d->buckets + bucketNum));
int stepsFromBucketStartToIte = 0;
while (bucketIterator != it) {
++stepsFromBucketStartToIte;
++bucketIterator;
}
detach();
- it = iterator(*(d->buckets + bucketNum));
+ it = const_iterator(*(d->buckets + bucketNum));
while (stepsFromBucketStartToIte > 0) {
--stepsFromBucketStartToIte;
++it;
}
}
- iterator ret = it;
+ iterator ret(it.i);
++ret;
Node *node = concrete(it.i);
diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h
index e15fbb07ac..c0109f3bbb 100644
--- a/src/corelib/tools/qhashfunctions.h
+++ b/src/corelib/tools/qhashfunctions.h
@@ -147,6 +147,15 @@ template <typename T1, typename T2> inline uint qHash(const QPair<T1, T2> &key,
return ((h1 << 16) | (h1 >> 16)) ^ h2 ^ seed;
}
+template <typename T1, typename T2> inline uint qHash(const std::pair<T1, T2> &key, uint seed = 0)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed)))
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, key.first);
+ seed = hash(seed, key.second);
+ return seed;
+}
+
QT_END_NAMESPACE
#if defined(Q_CC_MSVC)
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index b1f53dc7a2..1f4d0c88c5 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -521,7 +521,7 @@ int qt_repeatCount(const QString &s, int i)
}
static const QLocaleData *default_data = 0;
-static uint default_number_options = 0;
+static QLocale::NumberOptions default_number_options = QLocale::DefaultNumberOptions;
static const QLocaleData *const c_data = locale_data;
static QLocalePrivate *c_private()
@@ -699,7 +699,8 @@ static QLocalePrivate *localePrivateByName(const QString &name)
if (name == QLatin1String("C"))
return c_private();
const QLocaleData *data = findLocaleData(name);
- return QLocalePrivate::create(data, data->m_language_id == QLocale::C ? QLocale::OmitGroupSeparator : 0);
+ return QLocalePrivate::create(data, data->m_language_id == QLocale::C ?
+ QLocale::OmitGroupSeparator : QLocale::DefaultNumberOptions);
}
static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Script script,
@@ -710,7 +711,7 @@ static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Sc
const QLocaleData *data = QLocaleData::findLocaleData(language, script, country);
- int numberOptions = 0;
+ QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions;
// If not found, should default to system
if (data->m_language_id == QLocale::C && language != QLocale::C) {
@@ -903,7 +904,7 @@ void QLocale::setNumberOptions(NumberOptions options)
*/
QLocale::NumberOptions QLocale::numberOptions() const
{
- return static_cast<NumberOption>(d->m_numberOptions);
+ return static_cast<NumberOptions>(d->m_numberOptions);
}
/*!
@@ -1071,13 +1072,13 @@ QString QLocale::name() const
}
static qlonglong toIntegral_helper(const QLocaleData *d, const QChar *data, int len, bool *ok,
- QLocaleData::GroupSeparatorMode mode, qlonglong)
+ QLocale::NumberOptions mode, qlonglong)
{
return d->stringToLongLong(data, len, 10, ok, mode);
}
static qulonglong toIntegral_helper(const QLocaleData *d, const QChar *data, int len, bool *ok,
- QLocaleData::GroupSeparatorMode mode, qulonglong)
+ QLocale::NumberOptions mode, qulonglong)
{
return d->stringToUnsLongLong(data, len, 10, ok, mode);
}
@@ -1089,13 +1090,8 @@ T toIntegral_helper(const QLocalePrivate *d, const QChar *data, int len, bool *o
const bool isUnsigned = T(0) < T(-1);
typedef typename QtPrivate::QConditional<isUnsigned, qulonglong, qlonglong>::Type Int64;
- QLocaleData::GroupSeparatorMode mode
- = d->m_numberOptions & QLocale::RejectGroupSeparator
- ? QLocaleData::FailOnGroupSeparators
- : QLocaleData::ParseGroupSeparators;
-
// we select the right overload by the last, unused parameter
- Int64 val = toIntegral_helper(d->m_data, data, len, ok, mode, Int64());
+ Int64 val = toIntegral_helper(d->m_data, data, len, ok, d->m_numberOptions, Int64());
if (T(val) != val) {
if (ok)
*ok = false;
@@ -1314,12 +1310,7 @@ float QLocale::toFloat(const QString &s, bool *ok) const
double QLocale::toDouble(const QString &s, bool *ok) const
{
- QLocaleData::GroupSeparatorMode mode
- = d->m_numberOptions & RejectGroupSeparator
- ? QLocaleData::FailOnGroupSeparators
- : QLocaleData::ParseGroupSeparators;
-
- return d->m_data->stringToDouble(s.constData(), s.size(), ok, mode);
+ return d->m_data->stringToDouble(s.constData(), s.size(), ok, d->m_numberOptions);
}
/*!
@@ -1488,12 +1479,7 @@ float QLocale::toFloat(const QStringRef &s, bool *ok) const
double QLocale::toDouble(const QStringRef &s, bool *ok) const
{
- QLocaleData::GroupSeparatorMode mode
- = d->m_numberOptions & RejectGroupSeparator
- ? QLocaleData::FailOnGroupSeparators
- : QLocaleData::ParseGroupSeparators;
-
- return d->m_data->stringToDouble(s.constData(), s.size(), ok, mode);
+ return d->m_data->stringToDouble(s.constData(), s.size(), ok, d->m_numberOptions);
}
@@ -2019,6 +2005,8 @@ QString QLocale::toString(double i, char f, int prec) const
if (!(d->m_numberOptions & OmitGroupSeparator))
flags |= QLocaleData::ThousandsGroup;
+ if (!(d->m_numberOptions & OmitLeadingZeroInExponent))
+ flags |= QLocaleData::ZeroPadExponent;
return d->m_data->doubleToString(i, prec, form, -1, flags);
}
@@ -2743,57 +2731,33 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q
const QChar exponential, const QChar group, const QChar decimal,
double d, int precision, DoubleForm form, int width, unsigned flags)
{
- if (precision < 0)
+ if (precision != QLocale::FloatingPointShortest && precision < 0)
precision = 6;
if (width < 0)
width = 0;
bool negative = false;
- bool special_number = false; // nan, +/-inf
QString num_str;
- // Detect special numbers (nan, +/-inf)
- if (qt_is_inf(d)) {
- num_str = QString::fromLatin1("inf");
- special_number = true;
- negative = d < 0;
- } else if (qt_is_nan(d)) {
- num_str = QString::fromLatin1("nan");
- special_number = true;
- }
-
- // Handle normal numbers
- if (!special_number) {
- int decpt, sign;
- QString digits;
-
- int mode;
- if (form == DFDecimal)
- mode = 3;
- else
- mode = 2;
-
- /* This next bit is a bit quirky. In DFExponent form, the precision
- is the number of digits after decpt. So that would suggest using
- mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and
- precision=0. So we get around this by using mode=2 and reasoning
- that we want precision+1 significant digits, since the decimal
- point in this mode is always after the first digit. */
- int pr = precision;
- if (form == DFExponent)
- ++pr;
-
- char *rve = 0;
- char *buff = 0;
- QT_TRY {
- digits = QLatin1String(qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff));
- } QT_CATCH(...) {
- if (buff != 0)
- free(buff);
- QT_RETHROW;
- }
- if (buff != 0)
- free(buff);
+ int decpt;
+ int bufSize = 1;
+ if (precision == QLocale::FloatingPointShortest)
+ bufSize += DoubleMaxSignificant;
+ else if (form == DFDecimal) // optimize for numbers between -512k and 512k
+ bufSize += ((d > (1 << 19) || d < -(1 << 19)) ? DoubleMaxDigitsBeforeDecimal : 6) +
+ precision;
+ else // Add extra digit due to different interpretations of precision. Also, "nan" has to fit.
+ bufSize += qMax(2, precision) + 1;
+
+ QVarLengthArray<char> buf(bufSize);
+ int length;
+
+ doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
+
+ if (qstrncmp(buf.data(), "inf", 3) == 0 || qstrncmp(buf.data(), "nan", 3) == 0) {
+ num_str = QString::fromLatin1(buf.data(), length);
+ } else { // Handle normal numbers
+ QString digits = QString::fromLatin1(buf.data(), length);
if (_zero.unicode() != '0') {
ushort z = _zero.unicode() - '0';
@@ -2806,7 +2770,7 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q
case DFExponent: {
num_str = exponentForm(_zero, decimal, exponential, group, plus, minus,
digits, decpt, precision, PMDecimalDigits,
- always_show_decpt);
+ always_show_decpt, flags & ZeroPadExponent);
break;
}
case DFDecimal: {
@@ -2819,10 +2783,23 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q
PrecisionMode mode = (flags & Alternate) ?
PMSignificantDigits : PMChopTrailingZeros;
- if (decpt != digits.length() && (decpt <= -4 || decpt > precision))
+ int cutoff = precision < 0 ? 6 : precision;
+ // Find out which representation is shorter
+ if (precision == QLocale::FloatingPointShortest && decpt > 0) {
+ cutoff = digits.length() + 4; // 'e', '+'/'-', one digit exponent
+ if (decpt <= 10) {
+ ++cutoff;
+ } else {
+ cutoff += decpt > 100 ? 2 : 1;
+ }
+ if (!always_show_decpt && digits.length() > decpt)
+ ++cutoff; // decpt shown in exponent form, but not in decimal form
+ }
+
+ if (decpt != digits.length() && (decpt <= -4 || decpt > cutoff))
num_str = exponentForm(_zero, decimal, exponential, group, plus, minus,
digits, decpt, precision, mode,
- always_show_decpt);
+ always_show_decpt, flags & ZeroPadExponent);
else
num_str = decimalForm(_zero, decimal, group,
digits, decpt, precision, mode,
@@ -2831,23 +2808,22 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q
}
}
- negative = sign != 0 && !isZero(d);
- }
-
- // pad with zeros. LeftAdjusted overrides this flag). Also, we don't
- // pad special numbers
- if (flags & QLocaleData::ZeroPadded
- && !(flags & QLocaleData::LeftAdjusted)
- && !special_number) {
- int num_pad_chars = width - num_str.length();
- // leave space for the sign
- if (negative
- || flags & QLocaleData::AlwaysShowSign
- || flags & QLocaleData::BlankBeforePositive)
- --num_pad_chars;
-
- for (int i = 0; i < num_pad_chars; ++i)
- num_str.prepend(_zero);
+ if (isZero(d))
+ negative = false;
+
+ // pad with zeros. LeftAdjusted overrides this flag). Also, we don't
+ // pad special numbers
+ if (flags & QLocaleData::ZeroPadded && !(flags & QLocaleData::LeftAdjusted)) {
+ int num_pad_chars = width - num_str.length();
+ // leave space for the sign
+ if (negative
+ || flags & QLocaleData::AlwaysShowSign
+ || flags & QLocaleData::BlankBeforePositive)
+ --num_pad_chars;
+
+ for (int i = 0; i < num_pad_chars; ++i)
+ num_str.prepend(_zero);
+ }
}
// add sign
@@ -3042,9 +3018,8 @@ QString QLocaleData::unsLongLongToString(const QChar zero, const QChar group,
number. We can't detect junk here, since we don't even know the base
of the number.
*/
-bool QLocaleData::numberToCLocale(const QChar *str, int len,
- GroupSeparatorMode group_sep_mode,
- CharBuff *result) const
+bool QLocaleData::numberToCLocale(const QChar *str, int len, QLocale::NumberOptions number_options,
+ CharBuff *result) const
{
const QChar *uc = str;
int l = len;
@@ -3066,6 +3041,7 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len,
int decpt_idx = -1;
int last_separator_idx = -1;
int start_of_digits_idx = -1;
+ int exponent_idx = -1;
while (idx < l) {
const QChar in = uc[idx];
@@ -3084,7 +3060,19 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len,
else
break;
}
- if (group_sep_mode == ParseGroupSeparators) {
+
+ if (number_options & QLocale::RejectLeadingZeroInExponent) {
+ if (out == 'e' || out == 'E') {
+ exponent_idx = idx;
+ } else if (exponent_idx != -1) {
+ if (out >= '1' && out <= '9')
+ exponent_idx = -1; // leading digit is not 0, forget exponent_idx
+ else if (out == '0' && idx < l - 1)
+ return false;
+ }
+ }
+
+ if (!(number_options & QLocale::RejectGroupSeparator)) {
if (start_of_digits_idx == -1 && out >= '0' && out <= '9') {
start_of_digits_idx = idx;
} else if (out == ',') {
@@ -3127,7 +3115,7 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len,
++idx;
}
- if (group_sep_mode == ParseGroupSeparators) {
+ if (!(number_options & QLocale::RejectGroupSeparator)) {
// group separator post-processing
// did we end in a separator?
if (last_separator_idx + 1 == idx)
@@ -3142,7 +3130,7 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len,
}
bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArray *buff,
- int decDigits, bool rejectGroupSeparators) const
+ int decDigits, QLocale::NumberOptions number_options) const
{
buff->clear();
buff->reserve(str.length());
@@ -3164,6 +3152,13 @@ bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArr
if (dec && decDigits != -1 && decDigits < ++decDigitCnt)
return false;
}
+
+ // The only non-digit character after the 'e' can be '+' or '-'.
+ // If a zero is directly after that, then the exponent is zero-padded.
+ if ((number_options & QLocale::RejectLeadingZeroInExponent) && c == '0' && eCnt > 0 &&
+ !lastWasDigit)
+ return false;
+
lastWasDigit = true;
} else {
switch (c) {
@@ -3203,7 +3198,8 @@ bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArr
case ',':
//it can only be placed after a digit which is before the decimal point
- if (rejectGroupSeparators || !lastWasDigit || decPointCnt > 0)
+ if ((number_options & QLocale::RejectGroupSeparator) || !lastWasDigit ||
+ decPointCnt > 0)
return false;
break;
@@ -3235,22 +3231,27 @@ bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArr
}
double QLocaleData::stringToDouble(const QChar *begin, int len, bool *ok,
- GroupSeparatorMode group_sep_mode) const
+ QLocale::NumberOptions number_options) const
{
CharBuff buff;
- if (!numberToCLocale(begin, len, group_sep_mode, &buff)) {
+ if (!numberToCLocale(begin, len, number_options, &buff)) {
if (ok != 0)
*ok = false;
return 0.0;
}
- return bytearrayToDouble(buff.constData(), ok);
+ int processed = 0;
+ bool nonNullOk = false;
+ double d = asciiToDouble(buff.constData(), buff.length() - 1, nonNullOk, processed);
+ if (ok)
+ *ok = nonNullOk;
+ return d;
}
-qlonglong QLocaleData::stringToLongLong(const QChar *begin, int len, int base,
- bool *ok, GroupSeparatorMode group_sep_mode) const
+qlonglong QLocaleData::stringToLongLong(const QChar *begin, int len, int base, bool *ok,
+ QLocale::NumberOptions number_options) const
{
CharBuff buff;
- if (!numberToCLocale(begin, len, group_sep_mode, &buff)) {
+ if (!numberToCLocale(begin, len, number_options, &buff)) {
if (ok != 0)
*ok = false;
return 0;
@@ -3259,11 +3260,11 @@ qlonglong QLocaleData::stringToLongLong(const QChar *begin, int len, int base,
return bytearrayToLongLong(buff.constData(), base, ok);
}
-qulonglong QLocaleData::stringToUnsLongLong(const QChar *begin, int len, int base,
- bool *ok, GroupSeparatorMode group_sep_mode) const
+qulonglong QLocaleData::stringToUnsLongLong(const QChar *begin, int len, int base, bool *ok,
+ QLocale::NumberOptions number_options) const
{
CharBuff buff;
- if (!numberToCLocale(begin, len, group_sep_mode, &buff)) {
+ if (!numberToCLocale(begin, len, number_options, &buff)) {
if (ok != 0)
*ok = false;
return 0;
@@ -3274,53 +3275,15 @@ qulonglong QLocaleData::stringToUnsLongLong(const QChar *begin, int len, int bas
double QLocaleData::bytearrayToDouble(const char *num, bool *ok, bool *overflow)
{
- if (ok != 0)
- *ok = true;
- if (overflow != 0)
- *overflow = false;
-
- if (*num == '\0') {
- if (ok != 0)
- *ok = false;
- return 0.0;
- }
-
- if (qstrcmp(num, "nan") == 0)
- return qt_snan();
-
- if (qstrcmp(num, "+inf") == 0 || qstrcmp(num, "inf") == 0)
- return qt_inf();
-
- if (qstrcmp(num, "-inf") == 0)
- return -qt_inf();
-
- bool _ok;
- const char *endptr;
- double d = qstrtod(num, &endptr, &_ok);
-
- if (!_ok) {
- // the only way strtod can fail with *endptr != '\0' on a non-empty
- // input string is overflow
- if (ok != 0)
- *ok = false;
- if (overflow != 0)
- *overflow = *endptr != '\0';
- return 0.0;
- }
-
- if (*endptr != '\0') {
- // we stopped at a non-digit character after converting some digits
- if (ok != 0)
- *ok = false;
- if (overflow != 0)
- *overflow = false;
- return 0.0;
- }
-
- if (ok != 0)
- *ok = true;
- if (overflow != 0)
- *overflow = false;
+ bool nonNullOk = false;
+ int len = static_cast<int>(strlen(num));
+ Q_ASSERT(len >= 0);
+ int processed = 0;
+ double d = asciiToDouble(num, len, nonNullOk, processed);
+ if (ok)
+ *ok = nonNullOk;
+ if (overflow)
+ *overflow = processed < len;
return d;
}
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index 729fd73a5d..e90354138c 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -843,11 +843,18 @@ public:
enum FormatType { LongFormat, ShortFormat, NarrowFormat };
enum NumberOption {
+ DefaultNumberOptions = 0x0,
OmitGroupSeparator = 0x01,
- RejectGroupSeparator = 0x02
+ RejectGroupSeparator = 0x02,
+ OmitLeadingZeroInExponent = 0x04,
+ RejectLeadingZeroInExponent = 0x08
};
Q_DECLARE_FLAGS(NumberOptions, NumberOption)
+ enum FloatingPointPrecisionOption {
+ FloatingPointShortest = -128
+ };
+
enum CurrencySymbolFormat {
CurrencyIsoCode,
CurrencySymbol,
diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc
index c87e67cf17..76195ab666 100644
--- a/src/corelib/tools/qlocale.qdoc
+++ b/src/corelib/tools/qlocale.qdoc
@@ -930,17 +930,44 @@
conversions. They can be retrieved with numberOptions() and set with
setNumberOptions().
+ \value DefaultNumberOptions This option represents the default behavior, with
+ group separators and with one leading zero in single digit exponents.
\value OmitGroupSeparator If this option is set, the number-to-string functions
will not insert group separators in their return values. The default
is to insert group separators.
\value RejectGroupSeparator If this option is set, the string-to-number functions
will fail if they encounter group separators in their input. The default
is to accept numbers containing correctly placed group separators.
+ \value OmitLeadingZeroInExponent If this option is set, the number-to-string
+ functions will not pad exponents with zeroes when printing floating point
+ numbers in scientific notation. The default is to add one leading zero to
+ single digit exponents.
+ \value RejectLeadingZeroInExponent If this option is set, the string-to-number
+ functions will fail if they encounter an exponent padded with zeroes when
+ parsing a floating point number in scientific notation. The default is to
+ accept such padding.
\sa setNumberOptions(), numberOptions()
*/
/*!
+ \enum QLocale::FloatingPointPrecisionOption
+
+ This enum defines constants that can be given as precision to QString::number(),
+ QByteArray::number(), and QLocale::toString() when converting floats or doubles,
+ in order to express a variable number of digits as precision.
+
+ \value FloatingPointShortest The conversion algorithm will try to find the
+ shortest accurate representation for the given number. "Accurate" means
+ that you get the exact same number back from an inverse conversion on
+ the generated string representation.
+
+ \sa toString(), QString, QByteArray
+
+ \since 5.7
+*/
+
+/*!
\enum QLocale::MeasurementSystem
This enum defines which units are used for measurement.
diff --git a/src/corelib/tools/qlocale_blackberry.cpp b/src/corelib/tools/qlocale_blackberry.cpp
deleted file mode 100644
index c8543ca9b8..0000000000
--- a/src/corelib/tools/qlocale_blackberry.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qlocale_blackberry.h"
-#include "qlocale_p.h"
-
-#include "qdatetime.h"
-
-#include "qcoreapplication.h"
-#include "private/qcore_unix_p.h"
-
-#include <errno.h>
-#include <sys/pps.h>
-#include <unistd.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_SYSTEMLOCALE
-
-static const char ppsUomPath[] = "/pps/services/locale/uom";
-static const char ppsRegionLocalePath[] = "/pps/services/locale/settings";
-static const char ppsLanguageLocalePath[] = "/pps/services/confstr/_CS_LOCALE";
-static const char ppsHourFormatPath[] = "/pps/system/settings";
-
-static const int MAX_PPS_SIZE = 16000;
-
-QBBSystemLocaleData::QBBSystemLocaleData()
- : languageNotifier(0)
- , regionNotifier(0)
- , measurementNotifier(0)
- , hourNotifier(0)
-{
- // Do not use qWarning to log warnings if qt_safe_open fails to open the pps file
- // since the user code may install a message handler that invokes QLocale API again
- // (i.e QDate, QDateTime, ...) which will cause a deadlock.
- if ((measurementFd = qt_safe_open(ppsUomPath, O_RDONLY)) == -1)
- fprintf(stderr, "Failed to open uom pps, errno=%d\n", errno);
-
- if ((regionFd = qt_safe_open(ppsRegionLocalePath, O_RDONLY)) == -1)
- fprintf(stderr, "Failed to open region pps, errno=%d\n", errno);
-
- if ((languageFd = qt_safe_open(ppsLanguageLocalePath, O_RDONLY)) == -1)
- fprintf(stderr, "Failed to open language pps, errno=%d\n", errno);
-
- if ((hourFd = qt_safe_open(ppsHourFormatPath, O_RDONLY)) == -1)
- fprintf(stderr, "Failed to open hour format pps, errno=%d\n", errno);
-
- // we cannot call this directly, because by the time this constructor is
- // called, the event dispatcher has not yet been created, causing the
- // subsequent call to QSocketNotifier constructor to fail.
- QMetaObject::invokeMethod(this, "installSocketNotifiers", Qt::QueuedConnection);
-
- readLanguageLocale();
- readRegionLocale();
- readMeasurementSystem();
- readHourFormat();
-}
-
-QBBSystemLocaleData::~QBBSystemLocaleData()
-{
- if (measurementFd != -1)
- qt_safe_close(measurementFd);
-
- if (languageFd != -1)
- qt_safe_close(languageFd);
-
- if (regionFd != -1)
- qt_safe_close(regionFd);
-
- if (hourFd != -1)
- qt_safe_close(hourFd);
-}
-
-uint QBBSystemLocaleData::measurementSystem()
-{
- return m_measurementSystem;
-}
-
-QVariant QBBSystemLocaleData::timeFormat(QLocale::FormatType formatType)
-{
- return getCorrectFormat(regionLocale().timeFormat(formatType), formatType);
-}
-
-QVariant QBBSystemLocaleData::dateTimeFormat(QLocale::FormatType formatType)
-{
- return getCorrectFormat(regionLocale().dateTimeFormat(formatType), formatType);
-}
-
-QLocale QBBSystemLocaleData::languageLocale()
-{
- if (!lc_language.isEmpty())
- return QLocale(QLatin1String(lc_language));
-
- return QLocale::c();
-}
-
-QLocale QBBSystemLocaleData::regionLocale()
-{
- if (!lc_region.isEmpty())
- return QLocale(QLatin1String(lc_region));
-
- return QLocale::c();
-}
-
-void QBBSystemLocaleData::installSocketNotifiers()
-{
- Q_ASSERT(!languageNotifier || !regionNotifier || !measurementNotifier || !hourNotifier);
- Q_ASSERT(QCoreApplication::instance());
-
- languageNotifier = new QSocketNotifier(languageFd, QSocketNotifier::Read, this);
- QObject::connect(languageNotifier, SIGNAL(activated(int)), this, SLOT(readLanguageLocale()));
-
- regionNotifier = new QSocketNotifier(regionFd, QSocketNotifier::Read, this);
- QObject::connect(regionNotifier, SIGNAL(activated(int)), this, SLOT(readRegionLocale()));
-
- measurementNotifier = new QSocketNotifier(measurementFd, QSocketNotifier::Read, this);
- QObject::connect(measurementNotifier, SIGNAL(activated(int)), this, SLOT(readMeasurementSystem()));
-
- hourNotifier = new QSocketNotifier(hourFd, QSocketNotifier::Read, this);
- QObject::connect(hourNotifier, SIGNAL(activated(int)), this, SLOT(readHourFormat()));
-}
-
-void QBBSystemLocaleData::readLanguageLocale()
-{
- lc_language = readPpsValue("_CS_LOCALE", languageFd);
-}
-
-void QBBSystemLocaleData::readRegionLocale()
-{
- lc_region = readPpsValue("region", regionFd);
-}
-
-void QBBSystemLocaleData::readMeasurementSystem()
-{
- QByteArray measurement = readPpsValue("uom", measurementFd);
- m_measurementSystem = (qstrcmp(measurement, "imperial") == 0) ? QLocale::ImperialSystem : QLocale::MetricSystem;
-}
-
-void QBBSystemLocaleData::readHourFormat()
-{
- QByteArray hourFormat = readPpsValue("hourFormat", hourFd);
- is24HourFormat = (qstrcmp(hourFormat, "24") == 0);
-}
-
-QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd)
-{
- QByteArray result;
- if (!ppsObject || ppsFd == -1)
- return result;
-
- // PPS objects are of unknown size, but must be read all at once.
- // Relying on the file size may not be a good idea since the size may change before reading.
- // Let's try with an initial size (512), and if the buffer is too small try with bigger one,
- // until we succeed or until other non buffer-size-related error occurs.
- // Using QVarLengthArray means the first try (of size == 512) uses a buffer on the stack - no allocation necessary.
- // Hopefully that covers most use cases.
- int bytes;
- QVarLengthArray<char, 512> buffer(512);
- for (;;) {
- errno = 0;
- bytes = qt_safe_read(ppsFd, buffer.data(), buffer.size() - 1);
- const bool bufferIsTooSmall = (bytes == -1 && errno == EMSGSIZE && buffer.size() < MAX_PPS_SIZE);
- if (!bufferIsTooSmall)
- break;
-
- buffer.resize(qMin(buffer.size()*2, MAX_PPS_SIZE));
- }
-
- // This method is called in the ctor(), so do not use qWarning to log warnings
- // if qt_safe_read fails to read the pps file
- // since the user code may install a message handler that invokes QLocale API again
- // (i.e QDate, QDateTime, ...) which will cause a deadlock.
- if (bytes == -1) {
- fprintf(stderr, "Failed to read pps object:%s, errno=%d\n", ppsObject, errno);
- return result;
- }
- // ensure data is null terminated
- buffer[bytes] = '\0';
-
- pps_decoder_t ppsDecoder;
- pps_decoder_initialize(&ppsDecoder, 0);
- if (pps_decoder_parse_pps_str(&ppsDecoder, buffer.data()) == PPS_DECODER_OK) {
- pps_decoder_push(&ppsDecoder, 0);
- const char *ppsBuff;
- if (pps_decoder_get_string(&ppsDecoder, ppsObject, &ppsBuff) == PPS_DECODER_OK) {
- result = ppsBuff;
- } else {
- int val;
- if (pps_decoder_get_int(&ppsDecoder, ppsObject, &val) == PPS_DECODER_OK)
- result = QByteArray::number(val);
- }
- }
-
- pps_decoder_cleanup(&ppsDecoder);
-
- return result;
-}
-
-QString QBBSystemLocaleData::getCorrectFormat(const QString &baseFormat, QLocale::FormatType formatType)
-{
- QString format = baseFormat;
- if (is24HourFormat) {
- if (format.contains(QStringLiteral("AP"), Qt::CaseInsensitive)) {
- format.replace(QStringLiteral("AP"), QStringLiteral(""), Qt::CaseInsensitive);
- format.replace(QStringLiteral("h"), QStringLiteral("H"), Qt::CaseSensitive);
- }
-
- } else {
-
- if (!format.contains(QStringLiteral("AP"), Qt::CaseInsensitive)) {
- format.contains(QStringLiteral("HH"), Qt::CaseSensitive) ?
- format.replace(QStringLiteral("HH"), QStringLiteral("hh"), Qt::CaseSensitive) :
- format.replace(QStringLiteral("H"), QStringLiteral("h"), Qt::CaseSensitive);
-
- formatType == QLocale::LongFormat ? format.append(QStringLiteral(" AP t")) : format.append(QStringLiteral(" AP"));
- }
- }
-
- return format;
-}
-
-Q_GLOBAL_STATIC(QBBSystemLocaleData, bbSysLocaleData)
-
-QLocale QSystemLocale::fallbackUiLocale() const
-{
- return bbSysLocaleData()->languageLocale();
-}
-
-QVariant QSystemLocale::query(QueryType type, QVariant in) const
-{
- QBBSystemLocaleData *d = bbSysLocaleData();
-
- QReadLocker locker(&d->lock);
-
- const QLocale &lc_language = d->languageLocale();
- const QLocale &lc_region = d->regionLocale();
-
- switch (type) {
- case DecimalPoint:
- return lc_region.decimalPoint();
- case GroupSeparator:
- return lc_region.groupSeparator();
- case NegativeSign:
- return lc_region.negativeSign();
- case PositiveSign:
- return lc_region.positiveSign();
- case DateFormatLong:
- return lc_region.dateFormat(QLocale::LongFormat);
- case DateFormatShort:
- return lc_region.dateFormat(QLocale::ShortFormat);
- case TimeFormatLong:
- return d->timeFormat(QLocale::LongFormat);
- case TimeFormatShort:
- return d->timeFormat(QLocale::ShortFormat);
- case DateTimeFormatLong:
- return d->dateTimeFormat(QLocale::LongFormat);
- case DateTimeFormatShort:
- return d->dateTimeFormat(QLocale::ShortFormat);
- case DayNameLong:
- return lc_language.dayName(in.toInt(), QLocale::LongFormat);
- case DayNameShort:
- return lc_language.dayName(in.toInt(), QLocale::ShortFormat);
- case MonthNameLong:
- return lc_language.monthName(in.toInt(), QLocale::LongFormat);
- case MonthNameShort:
- return lc_language.monthName(in.toInt(), QLocale::ShortFormat);
- case StandaloneMonthNameLong:
- return lc_language.standaloneMonthName(in.toInt(), QLocale::LongFormat);
- case StandaloneMonthNameShort:
- return lc_language.standaloneMonthName(in.toInt(), QLocale::ShortFormat);
- case DateToStringLong:
- return lc_region.toString(in.toDate(), QLocale::LongFormat);
- case DateToStringShort:
- return lc_region.toString(in.toDate(), QLocale::ShortFormat);
- case TimeToStringLong:
- return lc_region.toString(in.toTime(), d->timeFormat(QLocale::LongFormat).toString());
- case TimeToStringShort:
- return lc_region.toString(in.toTime(), d->timeFormat(QLocale::ShortFormat).toString());
- case DateTimeToStringShort:
- return lc_region.toString(in.toDateTime(), d->dateTimeFormat(QLocale::ShortFormat).toString());
- case DateTimeToStringLong:
- return lc_region.toString(in.toDateTime(), d->dateTimeFormat(QLocale::LongFormat).toString());
- case MeasurementSystem:
- return d->measurementSystem();
- case ZeroDigit:
- return lc_region.zeroDigit();
- case CountryId:
- return lc_region.country();
- case LanguageId:
- return lc_language.language();
- case AMText:
- return lc_language.amText();
- case PMText:
- return lc_language.pmText();
- default:
- break;
- }
- return QVariant();
-}
-
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlocale_blackberry.h b/src/corelib/tools/qlocale_blackberry.h
deleted file mode 100644
index 317ae375ae..0000000000
--- a/src/corelib/tools/qlocale_blackberry.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QLOCALE_BLACKBERRY_H
-#define QLOCALE_BLACKBERRY_H
-
-#include <QtCore/qsocketnotifier.h>
-#include <QtCore/qreadwritelock.h>
-#include <QtCore/qlocale.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_SYSTEMLOCALE
-
-class QBBSystemLocaleData : public QObject
-{
- Q_OBJECT
-
-public:
- QBBSystemLocaleData();
- virtual ~QBBSystemLocaleData();
- uint measurementSystem();
- QVariant timeFormat(QLocale::FormatType);
- QVariant dateTimeFormat(QLocale::FormatType);
- QLocale languageLocale();
- QLocale regionLocale();
-
- QReadWriteLock lock;
-
-public Q_SLOTS:
- void installSocketNotifiers();
- void readLanguageLocale();
- void readRegionLocale();
- void readMeasurementSystem();
- void readHourFormat();
-
-private:
- QByteArray readPpsValue(const char *ppsObject, int ppsFd);
- QString getCorrectFormat(const QString &baseFormat, QLocale::FormatType typeFormat);
-
- QByteArray lc_language;
- QByteArray lc_region;
- uint m_measurementSystem;
- bool is24HourFormat;
-
- QSocketNotifier *languageNotifier;
- QSocketNotifier *regionNotifier;
- QSocketNotifier *measurementNotifier;
- QSocketNotifier *hourNotifier;
-
- int languageFd;
- int regionFd;
- int measurementFd;
- int hourFd;
-};
-#endif // QT_NO_SYSTEMLOCALE
-
-QT_END_NAMESPACE
-
-#endif // QLOCALE_BLACKBERRY_H
-
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index b3fd7a96b8..65d4d58def 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -165,6 +165,17 @@ public:
QLocale::Country country);
static const QLocaleData *c();
+ // Maximum number of significant digits needed to represent a double.
+ // We cannot use std::numeric_limits here without constexpr.
+ static const int DoubleMantissaBits = 53;
+ static const int Log10_2_100000 = 30103; // log10(2) * 100000
+ // same as C++11 std::numeric_limits<T>::max_digits10
+ static const int DoubleMaxSignificant = (DoubleMantissaBits * Log10_2_100000) / 100000 + 2;
+
+ // Maximum number of digits before decimal point to represent a double
+ // Same as std::numeric_limits<double>::max_exponent10 + 1
+ static const int DoubleMaxDigitsBeforeDecimal = 309;
+
enum DoubleForm {
DFExponent = 0,
DFDecimal,
@@ -184,14 +195,10 @@ public:
ShowBase = 0x80,
UppercaseBase = 0x100,
+ ZeroPadExponent = 0x200,
ForcePoint = Alternate
};
- enum GroupSeparatorMode {
- FailOnGroupSeparators,
- ParseGroupSeparators
- };
-
enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };
typedef QVarLengthArray<char, 256> CharBuff;
@@ -239,24 +246,26 @@ public:
return float(d);
}
- double stringToDouble(const QChar *begin, int len, bool *ok, GroupSeparatorMode group_sep_mode) const;
- qint64 stringToLongLong(const QChar *begin, int len, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
- quint64 stringToUnsLongLong(const QChar *begin, int len, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
+ double stringToDouble(const QChar *begin, int len, bool *ok,
+ QLocale::NumberOptions number_options) const;
+ qint64 stringToLongLong(const QChar *begin, int len, int base, bool *ok,
+ QLocale::NumberOptions number_options) const;
+ quint64 stringToUnsLongLong(const QChar *begin, int len, int base, bool *ok,
+ QLocale::NumberOptions number_options) const;
// these functions are used in QIntValidator (QtGui)
Q_CORE_EXPORT static double bytearrayToDouble(const char *num, bool *ok, bool *overflow = 0);
Q_CORE_EXPORT static qint64 bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow = 0);
Q_CORE_EXPORT static quint64 bytearrayToUnsLongLong(const char *num, int base, bool *ok);
- bool numberToCLocale(const QChar *str, int len,
- GroupSeparatorMode group_sep_mode,
- CharBuff *result) const;
+ bool numberToCLocale(const QChar *str, int len, QLocale::NumberOptions number_options,
+ CharBuff *result) const;
inline char digitToCLocale(QChar c) const;
// this function is used in QIntValidator (QtGui)
- Q_CORE_EXPORT bool validateChars(const QString &str, NumberMode numMode,
- QByteArray *buff, int decDigits = -1,
- bool rejectGroupSeparators = false) const;
+ Q_CORE_EXPORT bool validateChars(
+ const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1,
+ QLocale::NumberOptions number_options = QLocale::DefaultNumberOptions) const;
public:
quint16 m_language_id, m_script_id, m_country_id;
@@ -304,7 +313,9 @@ public:
class Q_CORE_EXPORT QLocalePrivate
{
public:
- static QLocalePrivate *create(const QLocaleData *data, int numberOptions = 0)
+ static QLocalePrivate *create(
+ const QLocaleData *data,
+ QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions)
{
QLocalePrivate *retval = new QLocalePrivate;
retval->m_data = data;
@@ -351,7 +362,7 @@ public:
const QLocaleData *m_data;
QBasicAtomicInt ref;
- quint16 m_numberOptions;
+ QLocale::NumberOptions m_numberOptions;
};
template <>
diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp
index 03b911c4b3..44704b3575 100644
--- a/src/corelib/tools/qlocale_tools.cpp
+++ b/src/corelib/tools/qlocale_tools.cpp
@@ -33,9 +33,12 @@
****************************************************************************/
#include "qlocale_tools_p.h"
+#include "qdoublescanprint_p.h"
#include "qlocale_p.h"
#include "qstring.h"
+#include <private/qnumeric_p.h>
+
#include <ctype.h>
#include <errno.h>
#include <float.h>
@@ -44,10 +47,6 @@
#include <stdlib.h>
#include <time.h>
-#ifdef Q_OS_WINCE
-# include "qfunctions_wince.h" // for _control87
-#endif
-
#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
# include <fenv.h>
#endif
@@ -68,6 +67,311 @@ QT_BEGIN_NAMESPACE
#include "../../3rdparty/freebsd/strtoull.c"
#include "../../3rdparty/freebsd/strtoll.c"
+QT_CLOCALE_HOLDER
+
+void doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char *buf, int bufSize,
+ bool &sign, int &length, int &decpt)
+{
+ if (bufSize == 0) {
+ decpt = 0;
+ sign = d < 0;
+ length = 0;
+ return;
+ }
+
+ // Detect special numbers (nan, +/-inf)
+ // We cannot use the high-level API of libdouble-conversion as we need to apply locale-specific
+ // formatting, such as decimal points, thousands-separators, etc. Because of this, we have to
+ // check for infinity and NaN before calling DoubleToAscii.
+ if (qt_is_inf(d)) {
+ sign = d < 0;
+ if (bufSize >= 3) {
+ buf[0] = 'i';
+ buf[1] = 'n';
+ buf[2] = 'f';
+ length = 3;
+ } else {
+ length = 0;
+ }
+ return;
+ } else if (qt_is_nan(d)) {
+ if (bufSize >= 3) {
+ buf[0] = 'n';
+ buf[1] = 'a';
+ buf[2] = 'n';
+ length = 3;
+ } else {
+ length = 0;
+ }
+ return;
+ }
+
+ if (form == QLocaleData::DFSignificantDigits && precision == 0)
+ precision = 1; // 0 significant digits is silently converted to 1
+
+#if !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
+ // one digit before the decimal dot, counts as significant digit for DoubleToStringConverter
+ if (form == QLocaleData::DFExponent && precision >= 0)
+ ++precision;
+
+ double_conversion::DoubleToStringConverter::DtoaMode mode;
+ if (precision == QLocale::FloatingPointShortest) {
+ mode = double_conversion::DoubleToStringConverter::SHORTEST;
+ } else if (form == QLocaleData::DFSignificantDigits || form == QLocaleData::DFExponent) {
+ mode = double_conversion::DoubleToStringConverter::PRECISION;
+ } else {
+ mode = double_conversion::DoubleToStringConverter::FIXED;
+ }
+ double_conversion::DoubleToStringConverter::DoubleToAscii(d, mode, precision, buf, bufSize,
+ &sign, &length, &decpt);
+#else // QT_NO_DOUBLECONVERSION || QT_BOOTSTRAPPED
+
+ // Cut the precision at 999, to fit it into the format string. We can't get more than 17
+ // significant digits, so anything after that is mostly noise. You do get closer to the "middle"
+ // of the range covered by the given double with more digits, so to a degree it does make sense
+ // to honor higher precisions. We define that at more than 999 digits that is not the case.
+ if (precision > 999)
+ precision = 999;
+ else if (precision == QLocale::FloatingPointShortest)
+ precision = QLocaleData::DoubleMaxSignificant; // "shortest" mode not supported by snprintf
+
+ if (isZero(d)) {
+ // Negative zero is expected as simple "0", not "-0". We cannot do d < 0, though.
+ sign = false;
+ buf[0] = '0';
+ length = 1;
+ decpt = 1;
+ return;
+ } else if (d < 0) {
+ sign = true;
+ d = -d;
+ } else {
+ sign = false;
+ }
+
+ const int formatLength = 7; // '%', '.', 3 digits precision, 'f', '\0'
+ char format[formatLength];
+ format[formatLength - 1] = '\0';
+ format[0] = '%';
+ format[1] = '.';
+ format[2] = char((precision / 100) % 10) + '0';
+ format[3] = char((precision / 10) % 10) + '0';
+ format[4] = char(precision % 10) + '0';
+ int extraChars;
+ switch (form) {
+ case QLocaleData::DFDecimal:
+ format[formatLength - 2] = 'f';
+ // <anything> '.' <precision> '\0' - optimize for numbers smaller than 512k
+ extraChars = (d > (1 << 19) ? QLocaleData::DoubleMaxDigitsBeforeDecimal : 6) + 2;
+ break;
+ case QLocaleData::DFExponent:
+ format[formatLength - 2] = 'e';
+ // '.', 'e', '-', <exponent> '\0'
+ extraChars = 7;
+ break;
+ case QLocaleData::DFSignificantDigits:
+ format[formatLength - 2] = 'g';
+
+ // either the same as in the 'e' case, or '.' and '\0'
+ // precision covers part before '.'
+ extraChars = 7;
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+
+ QVarLengthArray<char> target(precision + extraChars);
+
+ length = qDoubleSnprintf(target.data(), target.size(), QT_CLOCALE, format, d);
+ int firstSignificant = 0;
+ int decptInTarget = length;
+
+ // Find the first significant digit (not 0), and note any '.' we encounter.
+ // There is no '-' at the front of target because we made sure d > 0 above.
+ while (firstSignificant < length) {
+ if (target[firstSignificant] == '.')
+ decptInTarget = firstSignificant;
+ else if (target[firstSignificant] != '0')
+ break;
+ ++firstSignificant;
+ }
+
+ // If no '.' found so far, search the rest of the target buffer for it.
+ if (decptInTarget == length)
+ decptInTarget = std::find(target.data() + firstSignificant, target.data() + length, '.') -
+ target.data();
+
+ int eSign = length;
+ if (form != QLocaleData::DFDecimal) {
+ // In 'e' or 'g' form, look for the 'e'.
+ eSign = std::find(target.data() + firstSignificant, target.data() + length, 'e') -
+ target.data();
+
+ if (eSign < length) {
+ // If 'e' is found, the final decimal point is determined by the number after 'e'.
+ // Mind that the final decimal point, decpt, is the offset of the decimal point from the
+ // start of the resulting string in buf. It may be negative or larger than bufSize, in
+ // which case the missing digits are zeroes. In the 'e' case decptInTarget is always 1,
+ // as variants of snprintf always generate numbers with one digit before the '.' then.
+ // This is why the final decimal point is offset by 1, relative to the number after 'e'.
+ bool ok;
+ const char *endptr;
+ decpt = qstrtoll(target.data() + eSign + 1, &endptr, 10, &ok) + 1;
+ Q_ASSERT(ok);
+ Q_ASSERT(endptr - target.data() <= length - eSign -1);
+ } else {
+ // No 'e' found, so it's the 'f' form. Variants of snprintf generate numbers with
+ // potentially multiple digits before the '.', but without decimal exponent then. So we
+ // get the final decimal point from the position of the '.'. The '.' itself takes up one
+ // character. We adjust by 1 below if that gets in the way.
+ decpt = decptInTarget - firstSignificant;
+ }
+ } else {
+ // In 'f' form, there can not be an 'e', so it's enough to look for the '.'
+ // (and possibly adjust by 1 below)
+ decpt = decptInTarget - firstSignificant;
+ }
+
+ // Move the actual digits from the snprintf target to the actual buffer.
+ if (decptInTarget > firstSignificant) {
+ // First move the digits before the '.', if any
+ int lengthBeforeDecpt = decptInTarget - firstSignificant;
+ memcpy(buf, target.data() + firstSignificant, qMin(lengthBeforeDecpt, bufSize));
+ if (eSign > decptInTarget && lengthBeforeDecpt < bufSize) {
+ // Then move any remaining digits, until 'e'
+ memcpy(buf + lengthBeforeDecpt, target.data() + decptInTarget + 1,
+ qMin(eSign - decptInTarget - 1, bufSize - lengthBeforeDecpt));
+ // The final length of the output is the distance between the first significant digit
+ // and 'e' minus 1, for the '.', except if the buffer is smaller.
+ length = qMin(eSign - firstSignificant - 1, bufSize);
+ } else {
+ // 'e' was before the decpt or things didn't fit. Don't subtract the '.' from the length.
+ length = qMin(eSign - firstSignificant, bufSize);
+ }
+ } else {
+ if (eSign > firstSignificant) {
+ // If there are any significant digits at all, they are all after the '.' now.
+ // Just copy them straight away.
+ memcpy(buf, target.data() + firstSignificant, qMin(eSign - firstSignificant, bufSize));
+
+ // The decimal point was before the first significant digit, so we were one off above.
+ // Consider 0.1 - buf will be just '1', and decpt should be 0. But
+ // "decptInTarget - firstSignificant" will yield -1.
+ ++decpt;
+ length = qMin(eSign - firstSignificant, bufSize);
+ } else {
+ // No significant digits means the number is just 0.
+ buf[0] = '0';
+ length = 1;
+ decpt = 1;
+ }
+ }
+#endif // QT_NO_DOUBLECONVERSION || QT_BOOTSTRAPPED
+ while (length > 1 && buf[length - 1] == '0') // drop trailing zeroes
+ --length;
+}
+
+double asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
+ TrailingJunkMode trailingJunkMode)
+{
+ if (*num == '\0') {
+ ok = false;
+ processed = 0;
+ return 0.0;
+ }
+
+ ok = true;
+
+ // We have to catch NaN before because we need NaN as marker for "garbage" in the
+ // libdouble-conversion case and, in contrast to libdouble-conversion or sscanf, we don't allow
+ // "-nan" or "+nan"
+ if (qstrcmp(num, "nan") == 0) {
+ processed = 3;
+ return qt_snan();
+ } else if ((num[0] == '-' || num[0] == '+') && qstrcmp(num + 1, "nan") == 0) {
+ processed = 0;
+ ok = false;
+ return 0.0;
+ }
+
+ // Infinity values are implementation defined in the sscanf case. In the libdouble-conversion
+ // case we need infinity as overflow marker.
+ if (qstrcmp(num, "+inf") == 0) {
+ processed = 4;
+ return qt_inf();
+ } else if (qstrcmp(num, "inf") == 0) {
+ processed = 3;
+ return qt_inf();
+ } else if (qstrcmp(num, "-inf") == 0) {
+ processed = 4;
+ return -qt_inf();
+ }
+
+ double d = 0.0;
+#if !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
+ int conv_flags = (trailingJunkMode == TrailingJunkAllowed) ?
+ double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK :
+ double_conversion::StringToDoubleConverter::NO_FLAGS;
+ double_conversion::StringToDoubleConverter conv(conv_flags, 0.0, qt_snan(), 0, 0);
+ d = conv.StringToDouble(num, numLen, &processed);
+
+ if (!qIsFinite(d)) {
+ ok = false;
+ if (qIsNaN(d)) {
+ // Garbage found. We don't accept it and return 0.
+ processed = 0;
+ return 0.0;
+ } else {
+ // Overflow. That's not OK, but we still return infinity.
+ return d;
+ }
+ }
+#else
+ if (qDoubleSscanf(num, QT_CLOCALE, "%lf%n", &d, &processed) < 1)
+ processed = 0;
+
+ if ((trailingJunkMode == TrailingJunkProhibited && processed != numLen) || qIsNaN(d)) {
+ // Implementation defined nan symbol or garbage found. We don't accept it.
+ processed = 0;
+ ok = false;
+ return 0.0;
+ }
+
+ if (!qIsFinite(d)) {
+ // Overflow. Check for implementation-defined infinity symbols and reject them.
+ // We assume that any infinity symbol has to contain a character that cannot be part of a
+ // "normal" number (that is 0-9, ., -, +, e).
+ ok = false;
+ for (int i = 0; i < processed; ++i) {
+ char c = num[i];
+ if ((c < '0' || c > '9') && c != '.' && c != '-' && c != '+' && c != 'e') {
+ // Garbage found
+ processed = 0;
+ return 0.0;
+ }
+ }
+ return d;
+ }
+#endif // !defined(QT_NO_DOUBLECONVERSION) && !defined(QT_BOOTSTRAPPED)
+
+ // Otherwise we would have gotten NaN or sorted it out above.
+ Q_ASSERT(trailingJunkMode == TrailingJunkAllowed || processed == numLen);
+
+ // Check if underflow has occurred.
+ if (isZero(d)) {
+ for (int i = 0; i < processed; ++i) {
+ if (num[i] >= '1' && num[i] <= '9') {
+ // if a digit before any 'e' is not 0, then a non-zero number was intended.
+ ok = false;
+ return 0.0;
+ } else if (num[i] == 'e') {
+ break;
+ }
+ }
+ }
+ return d;
+}
+
unsigned long long
qstrtoull(const char * nptr, const char **endptr, int base, bool *ok)
{
@@ -114,9 +418,6 @@ qstrtoll(const char * nptr, const char **endptr, int base, bool *ok)
return result;
}
-static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt,
- int *sign, char **rve, char **digits_str);
-
QString qulltoa(qulonglong l, int base, const QChar _zero)
{
ushort buff[65]; // length of MAX_ULLONG in base 2
@@ -155,7 +456,7 @@ QString qlltoa(qlonglong l, int base, const QChar zero)
}
QString &decimalForm(QChar zero, QChar decimal, QChar group,
- QString &digits, int decpt, uint precision,
+ QString &digits, int decpt, int precision,
PrecisionMode pm,
bool always_show_decpt,
bool thousands_group)
@@ -172,11 +473,11 @@ QString &decimalForm(QChar zero, QChar decimal, QChar group,
if (pm == PMDecimalDigits) {
uint decimal_digits = digits.length() - decpt;
- for (uint i = decimal_digits; i < precision; ++i)
+ for (int i = decimal_digits; i < precision; ++i)
digits.append(zero);
}
else if (pm == PMSignificantDigits) {
- for (uint i = digits.length(); i < precision; ++i)
+ for (int i = digits.length(); i < precision; ++i)
digits.append(zero);
}
else { // pm == PMChopTrailingZeros
@@ -198,18 +499,19 @@ QString &decimalForm(QChar zero, QChar decimal, QChar group,
QString &exponentForm(QChar zero, QChar decimal, QChar exponential,
QChar group, QChar plus, QChar minus,
- QString &digits, int decpt, uint precision,
+ QString &digits, int decpt, int precision,
PrecisionMode pm,
- bool always_show_decpt)
+ bool always_show_decpt,
+ bool leading_zero_in_exponent)
{
int exp = decpt - 1;
if (pm == PMDecimalDigits) {
- for (uint i = digits.length(); i < precision + 1; ++i)
+ for (int i = digits.length(); i < precision + 1; ++i)
digits.append(zero);
}
else if (pm == PMSignificantDigits) {
- for (uint i = digits.length(); i < precision; ++i)
+ for (int i = digits.length(); i < precision; ++i)
digits.append(zero);
}
else { // pm == PMChopTrailingZeros
@@ -220,2398 +522,42 @@ QString &exponentForm(QChar zero, QChar decimal, QChar exponential,
digits.append(exponential);
digits.append(QLocaleData::longLongToString(zero, group, plus, minus,
- exp, 2, 10, -1, QLocaleData::AlwaysShowSign));
+ exp, leading_zero_in_exponent ? 2 : 1, 10, -1, QLocaleData::AlwaysShowSign));
return digits;
}
-/* From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */
-/* $FreeBSD: src/lib/libc/stdlib/netbsd_strtod.c,v 1.2.2.2 2001/03/02 17:14:15 tegge Exp $ */
-
-/* Please send bug reports to
- David M. Gay
- AT&T Bell Laboratories, Room 2C-463
- 600 Mountain Avenue
- Murray Hill, NJ 07974-2070
- U.S.A.
- dmg@research.att.com or research!dmg
- */
-
-/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
- *
- * This strtod returns a nearest machine number to the input decimal
- * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
- * broken by the IEEE round-even rule. Otherwise ties are broken by
- * biased rounding (add half and chop).
- *
- * Inspired loosely by William D. Clinger's paper "How to Read Floating
- * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
- *
- * Modifications:
- *
- * 1. We only require IEEE, IBM, or VAX double-precision
- * arithmetic (not IEEE double-extended).
- * 2. We get by with floating-point arithmetic in a case that
- * Clinger missed -- when we're computing d * 10^n
- * for a small integer d and the integer n is not too
- * much larger than 22 (the maximum integer k for which
- * we can represent 10^k exactly), we may be able to
- * compute (d*10^k) * 10^(e-k) with just one roundoff.
- * 3. Rather than a bit-at-a-time adjustment of the binary
- * result in the hard case, we use floating-point
- * arithmetic to determine the adjustment to within
- * one bit; only in really hard cases do we need to
- * compute a second residual.
- * 4. Because of 3., we don't need a large table of powers of 10
- * for ten-to-e (just some small tables, e.g. of 10^k
- * for 0 <= k <= 22).
- */
-
-/*
- * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
- * significant byte has the lowest address.
- * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
- * significant byte has the lowest address.
- * #define Long int on machines with 32-bit ints and 64-bit longs.
- * #define Sudden_Underflow for IEEE-format machines without gradual
- * underflow (i.e., that flush to zero on underflow).
- * #define IBM for IBM mainframe-style floating-point arithmetic.
- * #define VAX for VAX-style floating-point arithmetic.
- * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
- * #define No_leftright to omit left-right logic in fast floating-point
- * computation of dtoa.
- * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
- * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
- * that use extended-precision instructions to compute rounded
- * products and quotients) with IBM.
- * #define ROUND_BIASED for IEEE-format with biased rounding.
- * #define Inaccurate_Divide for IEEE-format with correctly rounded
- * products but inaccurate quotients, e.g., for Intel i860.
- * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
- * integer arithmetic. Whether this speeds things up or slows things
- * down depends on the machine and the number being converted.
- * #define KR_headers for old-style C function headers.
- * #define Bad_float_h if your system lacks a float.h or if it does not
- * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
- * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
- * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
- * if memory is available and otherwise does something you deem
- * appropriate. If MALLOC is undefined, malloc will be invoked
- * directly -- and assumed always to succeed.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $");
-#endif /* LIBC_SCCS and not lint */
-
-/*
-#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
- defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
- defined(__powerpc__) || defined(Q_OS_WIN) || defined(Q_OS_DARWIN) || defined(Q_OS_MAC) || \
- defined(mips) || defined(Q_OS_AIX) || defined(Q_OS_SOLARIS)
-# define IEEE_BIG_OR_LITTLE_ENDIAN 1
-#endif
-*/
-
-// *All* of our architectures have IEEE arithmetic, don't they?
-#define IEEE_BIG_OR_LITTLE_ENDIAN 1
-
-#ifdef __arm32__
-/*
- * Although the CPU is little endian the FP has different
- * byte and word endianness. The byte order is still little endian
- * but the word order is big endian.
- */
-#define IEEE_BIG_OR_LITTLE_ENDIAN
-#endif
-
-#ifdef vax
-#define VAX
-#endif
-
-#define Long qint32
-#define ULong quint32
-
-#define MALLOC malloc
-
-#ifdef BSD_QDTOA_DEBUG
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <stdio.h>
-QT_END_INCLUDE_NAMESPACE
-
-#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
-#endif
-
-#ifdef Unsigned_Shifts
-#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
-#else
-#define Sign_Extend(a,b) /*no-op*/
-#endif
-
-#if (defined(IEEE_BIG_OR_LITTLE_ENDIAN) + defined(VAX) + defined(IBM)) != 1
-#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined.
-#endif
-
-static inline ULong getWord0(const NEEDS_VOLATILE double x)
-{
- const NEEDS_VOLATILE uchar *ptr = reinterpret_cast<const NEEDS_VOLATILE uchar *>(&x);
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3];
- } else {
- return (ptr[7]<<24) + (ptr[6]<<16) + (ptr[5]<<8) + ptr[4];
- }
-}
-
-static inline void setWord0(NEEDS_VOLATILE double *x, ULong l)
-{
- NEEDS_VOLATILE uchar *ptr = reinterpret_cast<NEEDS_VOLATILE uchar *>(x);
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- ptr[0] = uchar(l>>24);
- ptr[1] = uchar(l>>16);
- ptr[2] = uchar(l>>8);
- ptr[3] = uchar(l);
- } else {
- ptr[7] = uchar(l>>24);
- ptr[6] = uchar(l>>16);
- ptr[5] = uchar(l>>8);
- ptr[4] = uchar(l);
- }
-}
-
-static inline ULong getWord1(const NEEDS_VOLATILE double x)
-{
- const NEEDS_VOLATILE uchar *ptr = reinterpret_cast<const NEEDS_VOLATILE uchar *>(&x);
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- return (ptr[4]<<24) + (ptr[5]<<16) + (ptr[6]<<8) + ptr[7];
- } else {
- return (ptr[3]<<24) + (ptr[2]<<16) + (ptr[1]<<8) + ptr[0];
- }
-}
-static inline void setWord1(NEEDS_VOLATILE double *x, ULong l)
-{
- NEEDS_VOLATILE uchar *ptr = reinterpret_cast<uchar NEEDS_VOLATILE *>(x);
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- ptr[4] = uchar(l>>24);
- ptr[5] = uchar(l>>16);
- ptr[6] = uchar(l>>8);
- ptr[7] = uchar(l);
- } else {
- ptr[3] = uchar(l>>24);
- ptr[2] = uchar(l>>16);
- ptr[1] = uchar(l>>8);
- ptr[0] = uchar(l);
- }
-}
-
-static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c)
+double qstrtod(const char *s00, const char **se, bool *ok)
{
-
- *a = (ushort(b) << 16) | ushort(c);
- ++a;
-}
-
-/* #define P DBL_MANT_DIG */
-/* Ten_pmax = floor(P*log(2)/log(5)) */
-/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
-/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
-/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
-
-#if defined(IEEE_BIG_OR_LITTLE_ENDIAN)
-#define Exp_shift 20
-#define Exp_shift1 20
-#define Exp_msk1 0x100000
-#define Exp_msk11 0x100000
-#define Exp_mask 0x7ff00000
-#define P 53
-#define Bias 1023
-#define IEEE_Arith
-#define Emin (-1022)
-#define Exp_1 0x3ff00000
-#define Exp_11 0x3ff00000
-#define Ebits 11
-#define Frac_mask 0xfffff
-#define Frac_mask1 0xfffff
-#define Ten_pmax 22
-#define Bletch 0x10
-#define Bndry_mask 0xfffff
-#define Bndry_mask1 0xfffff
-#if defined(LSB) && defined(Q_OS_VXWORKS)
-#undef LSB
-#endif
-#define LSB 1
-#define Sign_bit 0x80000000
-#define Log2P 1
-#define Tiny0 0
-#define Tiny1 1
-#define Quick_max 14
-#define Int_max 14
-#define Infinite(x) (getWord0(x) == 0x7ff00000) /* sufficient test for here */
-#else
-#undef Sudden_Underflow
-#define Sudden_Underflow
-#ifdef IBM
-#define Exp_shift 24
-#define Exp_shift1 24
-#define Exp_msk1 0x1000000
-#define Exp_msk11 0x1000000
-#define Exp_mask 0x7f000000
-#define P 14
-#define Bias 65
-#define Exp_1 0x41000000
-#define Exp_11 0x41000000
-#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
-#define Frac_mask 0xffffff
-#define Frac_mask1 0xffffff
-#define Bletch 4
-#define Ten_pmax 22
-#define Bndry_mask 0xefffff
-#define Bndry_mask1 0xffffff
-#define LSB 1
-#define Sign_bit 0x80000000
-#define Log2P 4
-#define Tiny0 0x100000
-#define Tiny1 0
-#define Quick_max 14
-#define Int_max 15
-#else /* VAX */
-#define Exp_shift 23
-#define Exp_shift1 7
-#define Exp_msk1 0x80
-#define Exp_msk11 0x800000
-#define Exp_mask 0x7f80
-#define P 56
-#define Bias 129
-#define Exp_1 0x40800000
-#define Exp_11 0x4080
-#define Ebits 8
-#define Frac_mask 0x7fffff
-#define Frac_mask1 0xffff007f
-#define Ten_pmax 24
-#define Bletch 2
-#define Bndry_mask 0xffff007f
-#define Bndry_mask1 0xffff007f
-#define LSB 0x10000
-#define Sign_bit 0x8000
-#define Log2P 1
-#define Tiny0 0x80
-#define Tiny1 0
-#define Quick_max 15
-#define Int_max 15
-#endif
-#endif
-
-#ifndef IEEE_Arith
-#define ROUND_BIASED
-#endif
-
-#ifdef RND_PRODQUOT
-#define rounded_product(a,b) a = rnd_prod(a, b)
-#define rounded_quotient(a,b) a = rnd_quot(a, b)
-extern double rnd_prod(double, double), rnd_quot(double, double);
-#else
-#define rounded_product(a,b) a *= b
-#define rounded_quotient(a,b) a /= b
-#endif
-
-#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
-#define Big1 0xffffffff
-
-#ifndef Just_16
-/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
- * This makes some inner loops simpler and sometimes saves work
- * during multiplications, but it often seems to make things slightly
- * slower. Hence the default is now to store 32 bits per Long.
- */
-#ifndef Pack_32
-#define Pack_32
-#endif
-#endif
-
-#define Kmax 15
-
-struct
-Bigint {
- struct Bigint *next;
- int k, maxwds, sign, wds;
- ULong x[1];
-};
-
- typedef struct Bigint Bigint;
-
-static Bigint *Balloc(int k)
-{
- int x;
- Bigint *rv;
-
- x = 1 << k;
- rv = static_cast<Bigint *>(MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long)));
- Q_CHECK_PTR(rv);
- rv->k = k;
- rv->maxwds = x;
- rv->sign = rv->wds = 0;
- return rv;
-}
-
-static void Bfree(Bigint *v)
-{
- free(v);
-}
-
-#define Bcopy(x,y) memcpy(reinterpret_cast<char *>(&x->sign), reinterpret_cast<char *>(&y->sign), \
-y->wds*sizeof(Long) + 2*sizeof(int))
-
-/* multiply by m and add a */
-static Bigint *multadd(Bigint *b, int m, int a)
-{
- int i, wds;
- ULong *x, y;
-#ifdef Pack_32
- ULong xi, z;
-#endif
- Bigint *b1;
-
- wds = b->wds;
- x = b->x;
- i = 0;
- do {
-#ifdef Pack_32
- xi = *x;
- y = (xi & 0xffff) * m + a;
- z = (xi >> 16) * m + (y >> 16);
- a = (z >> 16);
- *x++ = (z << 16) + (y & 0xffff);
-#else
- y = *x * m + a;
- a = (y >> 16);
- *x++ = y & 0xffff;
-#endif
- }
- while(++i < wds);
- if (a) {
- if (wds >= b->maxwds) {
- b1 = Balloc(b->k+1);
- Bcopy(b1, b);
- Bfree(b);
- b = b1;
- }
- b->x[wds++] = a;
- b->wds = wds;
- }
- return b;
-}
-
-static Bigint *s2b(const char *s, int nd0, int nd, ULong y9)
-{
- Bigint *b;
- int i, k;
- Long x, y;
-
- x = (nd + 8) / 9;
- for(k = 0, y = 1; x > y; y <<= 1, k++) ;
-#ifdef Pack_32
- b = Balloc(k);
- b->x[0] = y9;
- b->wds = 1;
-#else
- b = Balloc(k+1);
- b->x[0] = y9 & 0xffff;
- b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
-#endif
-
- i = 9;
- if (9 < nd0) {
- s += 9;
- do b = multadd(b, 10, *s++ - '0');
- while(++i < nd0);
- s++;
- }
- else
- s += 10;
- for(; i < nd; i++)
- b = multadd(b, 10, *s++ - '0');
- return b;
-}
-
-static int hi0bits(ULong x)
-{
- int k = 0;
-
- if (!(x & 0xffff0000)) {
- k = 16;
- x <<= 16;
- }
- if (!(x & 0xff000000)) {
- k += 8;
- x <<= 8;
- }
- if (!(x & 0xf0000000)) {
- k += 4;
- x <<= 4;
- }
- if (!(x & 0xc0000000)) {
- k += 2;
- x <<= 2;
- }
- if (!(x & 0x80000000)) {
- k++;
- if (!(x & 0x40000000))
- return 32;
- }
- return k;
-}
-
-static int lo0bits(ULong *y)
-{
- int k;
- ULong x = *y;
-
- if (x & 7) {
- if (x & 1)
- return 0;
- if (x & 2) {
- *y = x >> 1;
- return 1;
- }
- *y = x >> 2;
- return 2;
- }
- k = 0;
- if (!(x & 0xffff)) {
- k = 16;
- x >>= 16;
- }
- if (!(x & 0xff)) {
- k += 8;
- x >>= 8;
- }
- if (!(x & 0xf)) {
- k += 4;
- x >>= 4;
- }
- if (!(x & 0x3)) {
- k += 2;
- x >>= 2;
- }
- if (!(x & 1)) {
- k++;
- x >>= 1;
- if (!x & 1)
- return 32;
- }
- *y = x;
- return k;
-}
-
-static Bigint *i2b(int i)
-{
- Bigint *b;
-
- b = Balloc(1);
- b->x[0] = i;
- b->wds = 1;
- return b;
-}
-
-static Bigint *mult(Bigint *a, Bigint *b)
-{
- Bigint *c;
- int k, wa, wb, wc;
- ULong carry, y, z;
- ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
-#ifdef Pack_32
- ULong z2;
-#endif
-
- if (a->wds < b->wds) {
- c = a;
- a = b;
- b = c;
- }
- k = a->k;
- wa = a->wds;
- wb = b->wds;
- wc = wa + wb;
- if (wc > a->maxwds)
- k++;
- c = Balloc(k);
- for(x = c->x, xa = x + wc; x < xa; x++)
- *x = 0;
- xa = a->x;
- xae = xa + wa;
- xb = b->x;
- xbe = xb + wb;
- xc0 = c->x;
-#ifdef Pack_32
- for(; xb < xbe; xb++, xc0++) {
- if ((y = *xb & 0xffff) != 0) {
- x = xa;
- xc = xc0;
- carry = 0;
- do {
- z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
- carry = z >> 16;
- z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
- carry = z2 >> 16;
- Storeinc(xc, z2, z);
- }
- while(x < xae);
- *xc = carry;
- }
- if ((y = *xb >> 16) != 0) {
- x = xa;
- xc = xc0;
- carry = 0;
- z2 = *xc;
- do {
- z = (*x & 0xffff) * y + (*xc >> 16) + carry;
- carry = z >> 16;
- Storeinc(xc, z, z2);
- z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
- carry = z2 >> 16;
- }
- while(x < xae);
- *xc = z2;
- }
- }
-#else
- for(; xb < xbe; xc0++) {
- if (y = *xb++) {
- x = xa;
- xc = xc0;
- carry = 0;
- do {
- z = *x++ * y + *xc + carry;
- carry = z >> 16;
- *xc++ = z & 0xffff;
- }
- while(x < xae);
- *xc = carry;
- }
- }
-#endif
- for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
- c->wds = wc;
- return c;
-}
-
-static Bigint *p5s;
-
-struct p5s_deleter
-{
- ~p5s_deleter()
- {
- while (p5s) {
- Bigint *next = p5s->next;
- Bfree(p5s);
- p5s = next;
- }
- }
-};
-
-static Bigint *pow5mult(Bigint *b, int k)
-{
- Bigint *b1, *p5, *p51;
- int i;
- static const int p05[3] = { 5, 25, 125 };
-
- if ((i = k & 3) != 0)
- b = multadd(b, p05[i-1], 0);
-
- if (!(k >>= 2))
- return b;
- if (!(p5 = p5s)) {
- /* first time */
- static p5s_deleter deleter;
- p5 = p5s = i2b(625);
- p5->next = 0;
- }
- for(;;) {
- if (k & 1) {
- b1 = mult(b, p5);
- Bfree(b);
- b = b1;
- }
- if (!(k >>= 1))
- break;
- if (!(p51 = p5->next)) {
- p51 = p5->next = mult(p5,p5);
- p51->next = 0;
- }
- p5 = p51;
- }
- return b;
-}
-
-static Bigint *lshift(Bigint *b, int k)
-{
- int i, k1, n, n1;
- Bigint *b1;
- ULong *x, *x1, *xe, z;
-
-#ifdef Pack_32
- n = k >> 5;
-#else
- n = k >> 4;
-#endif
- k1 = b->k;
- n1 = n + b->wds + 1;
- for(i = b->maxwds; n1 > i; i <<= 1)
- k1++;
- b1 = Balloc(k1);
- x1 = b1->x;
- for(i = 0; i < n; i++)
- *x1++ = 0;
- x = b->x;
- xe = x + b->wds;
-#ifdef Pack_32
- if (k &= 0x1f) {
- k1 = 32 - k;
- z = 0;
- do {
- *x1++ = *x << k | z;
- z = *x++ >> k1;
- }
- while(x < xe);
- if ((*x1 = z) != 0)
- ++n1;
- }
-#else
- if (k &= 0xf) {
- k1 = 16 - k;
- z = 0;
- do {
- *x1++ = *x << k & 0xffff | z;
- z = *x++ >> k1;
- }
- while(x < xe);
- if (*x1 = z)
- ++n1;
- }
-#endif
- else do
- *x1++ = *x++;
- while(x < xe);
- b1->wds = n1 - 1;
- Bfree(b);
- return b1;
-}
-
-static int cmp(Bigint *a, Bigint *b)
-{
- ULong *xa, *xa0, *xb, *xb0;
- int i, j;
-
- i = a->wds;
- j = b->wds;
-#ifdef BSD_QDTOA_DEBUG
- if (i > 1 && !a->x[i-1])
- Bug("cmp called with a->x[a->wds-1] == 0");
- if (j > 1 && !b->x[j-1])
- Bug("cmp called with b->x[b->wds-1] == 0");
-#endif
- if (i -= j)
- return i;
- xa0 = a->x;
- xa = xa0 + j;
- xb0 = b->x;
- xb = xb0 + j;
- for(;;) {
- if (*--xa != *--xb)
- return *xa < *xb ? -1 : 1;
- if (xa <= xa0)
- break;
- }
- return 0;
-}
-
-static Bigint *diff(Bigint *a, Bigint *b)
-{
- Bigint *c;
- int i, wa, wb;
- Long borrow, y; /* We need signed shifts here. */
- ULong *xa, *xae, *xb, *xbe, *xc;
-#ifdef Pack_32
- Long z;
-#endif
-
- i = cmp(a,b);
- if (!i) {
- c = Balloc(0);
- c->wds = 1;
- c->x[0] = 0;
- return c;
- }
- if (i < 0) {
- c = a;
- a = b;
- b = c;
- i = 1;
- }
- else
- i = 0;
- c = Balloc(a->k);
- c->sign = i;
- wa = a->wds;
- xa = a->x;
- xae = xa + wa;
- wb = b->wds;
- xb = b->x;
- xbe = xb + wb;
- xc = c->x;
- borrow = 0;
-#ifdef Pack_32
- do {
- y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
- borrow = z >> 16;
- Sign_Extend(borrow, z);
- Storeinc(xc, z, y);
- }
- while(xb < xbe);
- while(xa < xae) {
- y = (*xa & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- z = (*xa++ >> 16) + borrow;
- borrow = z >> 16;
- Sign_Extend(borrow, z);
- Storeinc(xc, z, y);
- }
-#else
- do {
- y = *xa++ - *xb++ + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- *xc++ = y & 0xffff;
- }
- while(xb < xbe);
- while(xa < xae) {
- y = *xa++ + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- *xc++ = y & 0xffff;
- }
-#endif
- while(!*--xc)
- wa--;
- c->wds = wa;
- return c;
-}
-
-static double ulp(double x)
-{
- Long L;
- double a;
-
- L = (getWord0(x) & Exp_mask) - (P-1)*Exp_msk1;
-#ifndef Sudden_Underflow
- if (L > 0) {
-#endif
-#ifdef IBM
- L |= Exp_msk1 >> 4;
-#endif
- setWord0(&a, L);
- setWord1(&a, 0);
-#ifndef Sudden_Underflow
- }
- else {
- L = -L >> Exp_shift;
- if (L < Exp_shift) {
- setWord0(&a, 0x80000 >> L);
- setWord1(&a, 0);
- }
- else {
- setWord0(&a, 0);
- L -= Exp_shift;
- setWord1(&a, L >= 31 ? 1U : 1U << (31 - L));
- }
- }
-#endif
- return a;
-}
-
-static double b2d(Bigint *a, int *e)
-{
- ULong *xa, *xa0, w, y, z;
- int k;
- double d;
-
- xa0 = a->x;
- xa = xa0 + a->wds;
- y = *--xa;
-#ifdef BSD_QDTOA_DEBUG
- if (!y) Bug("zero y in b2d");
-#endif
- k = hi0bits(y);
- *e = 32 - k;
-#ifdef Pack_32
- if (k < Ebits) {
- setWord0(&d, Exp_1 | y >> (Ebits - k));
- w = xa > xa0 ? *--xa : 0;
- setWord1(&d, y << ((32-Ebits) + k) | w >> (Ebits - k));
- goto ret_d;
- }
- z = xa > xa0 ? *--xa : 0;
- if (k -= Ebits) {
- setWord0(&d, Exp_1 | y << k | z >> (32 - k));
- y = xa > xa0 ? *--xa : 0;
- setWord1(&d, z << k | y >> (32 - k));
- }
- else {
- setWord0(&d, Exp_1 | y);
- setWord1(&d, z);
- }
-#else
- if (k < Ebits + 16) {
- z = xa > xa0 ? *--xa : 0;
- setWord0(&d, Exp_1 | y << k - Ebits | z >> Ebits + 16 - k);
- w = xa > xa0 ? *--xa : 0;
- y = xa > xa0 ? *--xa : 0;
- setWord1(&d, z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k);
- goto ret_d;
- }
- z = xa > xa0 ? *--xa : 0;
- w = xa > xa0 ? *--xa : 0;
- k -= Ebits + 16;
- setWord0(&d, Exp_1 | y << k + 16 | z << k | w >> 16 - k);
- y = xa > xa0 ? *--xa : 0;
- setWord1(&d, w << k + 16 | y << k);
-#endif
- ret_d:
- return d;
-}
-
-static Bigint *d2b(double d, int *e, int *bits)
-{
- Bigint *b;
- int de, i, k;
- ULong *x, y, z;
-
-#ifdef Pack_32
- b = Balloc(1);
-#else
- b = Balloc(2);
-#endif
- x = b->x;
-
- z = getWord0(d) & Frac_mask;
- setWord0(&d, getWord0(d) & 0x7fffffff); /* clear sign bit, which we ignore */
-#ifdef Sudden_Underflow
- de = (int)(getWord0(d) >> Exp_shift);
-#ifndef IBM
- z |= Exp_msk11;
-#endif
-#else
- if ((de = int(getWord0(d) >> Exp_shift)) != 0)
- z |= Exp_msk1;
-#endif
-#ifdef Pack_32
- if ((y = getWord1(d)) != 0) {
- if ((k = lo0bits(&y)) != 0) {
- x[0] = y | z << (32 - k);
- z >>= k;
- }
- else
- x[0] = y;
- i = b->wds = (x[1] = z) ? 2 : 1;
- }
- else {
-#ifdef BSD_QDTOA_DEBUG
- if (!z)
- Bug("Zero passed to d2b");
-#endif
- k = lo0bits(&z);
- x[0] = z;
- i = b->wds = 1;
- k += 32;
- }
-#else
- if (y = getWord1(d)) {
- if (k = lo0bits(&y))
- if (k >= 16) {
- x[0] = y | z << 32 - k & 0xffff;
- x[1] = z >> k - 16 & 0xffff;
- x[2] = z >> k;
- i = 2;
- }
- else {
- x[0] = y & 0xffff;
- x[1] = y >> 16 | z << 16 - k & 0xffff;
- x[2] = z >> k & 0xffff;
- x[3] = z >> k+16;
- i = 3;
- }
- else {
- x[0] = y & 0xffff;
- x[1] = y >> 16;
- x[2] = z & 0xffff;
- x[3] = z >> 16;
- i = 3;
- }
- }
- else {
-#ifdef BSD_QDTOA_DEBUG
- if (!z)
- Bug("Zero passed to d2b");
-#endif
- k = lo0bits(&z);
- if (k >= 16) {
- x[0] = z;
- i = 0;
- }
- else {
- x[0] = z & 0xffff;
- x[1] = z >> 16;
- i = 1;
- }
- k += 32;
- }
- while(!x[i])
- --i;
- b->wds = i + 1;
-#endif
-#ifndef Sudden_Underflow
- if (de) {
-#endif
-#ifdef IBM
- *e = (de - Bias - (P-1) << 2) + k;
- *bits = 4*P + 8 - k - hi0bits(getWord0(d) & Frac_mask);
-#else
- *e = de - Bias - (P-1) + k;
- *bits = P - k;
-#endif
-#ifndef Sudden_Underflow
- }
- else {
- *e = de - Bias - (P-1) + 1 + k;
-#ifdef Pack_32
- *bits = 32*i - hi0bits(x[i-1]);
-#else
- *bits = (i+2)*16 - hi0bits(x[i]);
-#endif
- }
-#endif
- return b;
-}
-
-static double ratio(Bigint *a, Bigint *b)
-{
- double da, db;
- int k, ka, kb;
-
- da = b2d(a, &ka);
- db = b2d(b, &kb);
-#ifdef Pack_32
- k = ka - kb + 32*(a->wds - b->wds);
-#else
- k = ka - kb + 16*(a->wds - b->wds);
-#endif
-#ifdef IBM
- if (k > 0) {
- setWord0(&da, getWord0(da) + (k >> 2)*Exp_msk1);
- if (k &= 3)
- da *= 1 << k;
- }
- else {
- k = -k;
- setWord0(&db, getWord0(db) + (k >> 2)*Exp_msk1);
- if (k &= 3)
- db *= 1 << k;
- }
-#else
- if (k > 0)
- setWord0(&da, getWord0(da) + k*Exp_msk1);
- else {
- k = -k;
- setWord0(&db, getWord0(db) + k*Exp_msk1);
- }
-#endif
- return da / db;
-}
-
-static const double tens[] = {
- 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
- 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
- 1e20, 1e21, 1e22
-#ifdef VAX
- , 1e23, 1e24
-#endif
-};
-
-#ifdef IEEE_Arith
-static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
-static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
-#define n_bigtens 5
-#else
-#ifdef IBM
-static const double bigtens[] = { 1e16, 1e32, 1e64 };
-static const double tinytens[] = { 1e-16, 1e-32, 1e-64 };
-#define n_bigtens 3
-#else
-static const double bigtens[] = { 1e16, 1e32 };
-static const double tinytens[] = { 1e-16, 1e-32 };
-#define n_bigtens 2
-#endif
-#endif
-
-/*
- The pre-release gcc3.3 shipped with SuSE 8.2 has a bug which causes
- the comparison 1e-100 == 0.0 to return true. As a workaround, we
- compare it to a global variable containing 0.0, which produces
- correct assembler output.
-
- ### consider detecting the broken compilers and using the static
- ### double for these, and use a #define for all working compilers
-*/
-static double g_double_zero = 0.0;
-
-Q_CORE_EXPORT double qstrtod(const char *s00, const char **se, bool *ok)
-{
- int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
- e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
- const char *s, *s0, *s1;
- double aadj, aadj1, adj, rv, rv0;
- Long L;
- ULong y, z;
- Bigint *bb1, *bd0;
- Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
-
- /*
- #ifndef KR_headers
- const char decimal_point = localeconv()->decimal_point[0];
- #else
- const char decimal_point = '.';
- #endif */
- if (ok != 0)
- *ok = true;
-
- const char decimal_point = '.';
-
- sign = nz0 = nz = 0;
- rv = 0.;
-
-
- for(s = s00; ascii_isspace(uchar(*s)); s++)
- ;
-
- if (*s == '-') {
- sign = 1;
- s++;
- } else if (*s == '+') {
- s++;
- }
-
- if (*s == '\0') {
- s = s00;
- goto ret;
- }
-
- if (*s == '0') {
- nz0 = 1;
- while(*++s == '0') ;
- if (!*s)
- goto ret;
- }
- s0 = s;
- y = z = 0;
- for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
- if (nd < 9)
- y = 10*y + c - '0';
- else if (nd < 16)
- z = 10*z + c - '0';
- nd0 = nd;
- if (c == decimal_point) {
- c = *++s;
- if (!nd) {
- for(; c == '0'; c = *++s)
- nz++;
- if (c > '0' && c <= '9') {
- s0 = s;
- nf += nz;
- nz = 0;
- goto have_dig;
- }
- goto dig_done;
- }
- for(; c >= '0' && c <= '9'; c = *++s) {
- have_dig:
- nz++;
- if (c -= '0') {
- nf += nz;
- for(i = 1; i < nz; i++)
- if (nd++ < 9)
- y *= 10;
- else if (nd <= DBL_DIG + 1)
- z *= 10;
- if (nd++ < 9)
- y = 10*y + c;
- else if (nd <= DBL_DIG + 1)
- z = 10*z + c;
- nz = 0;
- }
- }
- }
- dig_done:
- e = 0;
- if (c == 'e' || c == 'E') {
- if (!nd && !nz && !nz0) {
- s = s00;
- goto ret;
- }
- s00 = s;
- esign = 0;
- switch(c = *++s) {
- case '-':
- esign = 1;
- case '+':
- c = *++s;
- }
- if (c >= '0' && c <= '9') {
- while(c == '0')
- c = *++s;
- if (c > '0' && c <= '9') {
- L = c - '0';
- s1 = s;
- while((c = *++s) >= '0' && c <= '9')
- L = 10*L + c - '0';
- if (s - s1 > 8 || L > 19999)
- /* Avoid confusion from exponents
- * so large that e might overflow.
- */
- e = 19999; /* safe for 16 bit ints */
- else
- e = int(L);
- if (esign)
- e = -e;
- }
- else
- e = 0;
- }
- else
- s = s00;
- }
- if (!nd) {
- if (!nz && !nz0)
- s = s00;
- goto ret;
- }
- e1 = e -= nf;
-
- /* Now we have nd0 digits, starting at s0, followed by a
- * decimal point, followed by nd-nd0 digits. The number we're
- * after is the integer represented by those digits times
- * 10**e */
-
- if (!nd0)
- nd0 = nd;
- k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
- rv = y;
- if (k > 9)
- rv = tens[k - 9] * rv + z;
-
- bd0 = 0;
- if (nd <= DBL_DIG
-#ifndef RND_PRODQUOT
- && FLT_ROUNDS == 1
-#endif
- ) {
- if (!e)
- goto ret;
- if (e > 0) {
- if (e <= Ten_pmax) {
-#ifdef VAX
- goto vax_ovfl_check;
-#else
- /* rv = */ rounded_product(rv, tens[e]);
- goto ret;
-#endif
- }
- i = DBL_DIG - nd;
- if (e <= Ten_pmax + i) {
- /* A fancier test would sometimes let us do
- * this for larger i values.
- */
- e -= i;
- rv *= tens[i];
-#ifdef VAX
- /* VAX exponent range is so narrow we must
- * worry about overflow here...
- */
- vax_ovfl_check:
- setWord0(&rv, getWord0(rv) - P*Exp_msk1);
- /* rv = */ rounded_product(rv, tens[e]);
- if ((getWord0(rv) & Exp_mask)
- > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
- goto ovfl;
- setWord0(&rv, getWord0(rv) + P*Exp_msk1);
-#else
- /* rv = */ rounded_product(rv, tens[e]);
-#endif
- goto ret;
- }
- }
-#ifndef Inaccurate_Divide
- else if (e >= -Ten_pmax) {
- /* rv = */ rounded_quotient(rv, tens[-e]);
- goto ret;
- }
-#endif
- }
- e1 += nd - k;
-
- /* Get starting approximation = rv * 10**e1 */
-
- if (e1 > 0) {
- if ((i = e1 & 15) != 0)
- rv *= tens[i];
- if (e1 &= ~15) {
- if (e1 > DBL_MAX_10_EXP) {
- ovfl:
- // errno = ERANGE;
- if (ok != 0)
- *ok = false;
-#ifdef __STDC__
- rv = HUGE_VAL;
-#else
- /* Can't trust HUGE_VAL */
-#ifdef IEEE_Arith
- setWord0(&rv, Exp_mask);
- setWord1(&rv, 0);
-#else
- setWord0(&rv, Big0);
- setWord1(&rv, Big1);
-#endif
-#endif
- if (bd0)
- goto retfree;
- goto ret;
- }
- if (e1 >>= 4) {
- for(j = 0; e1 > 1; j++, e1 >>= 1)
- if (e1 & 1)
- rv *= bigtens[j];
- /* The last multiplication could overflow. */
- setWord0(&rv, getWord0(rv) - P*Exp_msk1);
- rv *= bigtens[j];
- if ((z = getWord0(rv) & Exp_mask)
- > Exp_msk1*(DBL_MAX_EXP+Bias-P))
- goto ovfl;
- if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
- /* set to largest number */
- /* (Can't trust DBL_MAX) */
- setWord0(&rv, Big0);
- setWord1(&rv, Big1);
- }
- else
- setWord0(&rv, getWord0(rv) + P*Exp_msk1);
- }
-
- }
- }
- else if (e1 < 0) {
- e1 = -e1;
- if ((i = e1 & 15) != 0)
- rv /= tens[i];
- if (e1 &= ~15) {
- e1 >>= 4;
- if (e1 >= 1 << n_bigtens)
- goto undfl;
- for(j = 0; e1 > 1; j++, e1 >>= 1)
- if (e1 & 1)
- rv *= tinytens[j];
- /* The last multiplication could underflow. */
- rv0 = rv;
- rv *= tinytens[j];
- if (rv == g_double_zero)
- {
- rv = 2.*rv0;
- rv *= tinytens[j];
- if (rv == g_double_zero)
- {
- undfl:
- rv = 0.;
- // errno = ERANGE;
- if (ok != 0)
- *ok = false;
- if (bd0)
- goto retfree;
- goto ret;
- }
- setWord0(&rv, Tiny0);
- setWord1(&rv, Tiny1);
- /* The refinement below will clean
- * this approximation up.
- */
- }
- }
- }
-
- /* Now the hard part -- adjusting rv to the correct value.*/
-
- /* Put digits into bd: true value = bd * 10^e */
-
- bd0 = s2b(s0, nd0, nd, y);
-
- for(;;) {
- bd = Balloc(bd0->k);
- Bcopy(bd, bd0);
- bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
- bs = i2b(1);
-
- if (e >= 0) {
- bb2 = bb5 = 0;
- bd2 = bd5 = e;
- }
- else {
- bb2 = bb5 = -e;
- bd2 = bd5 = 0;
- }
- if (bbe >= 0)
- bb2 += bbe;
- else
- bd2 -= bbe;
- bs2 = bb2;
-#ifdef Sudden_Underflow
-#ifdef IBM
- j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
-#else
- j = P + 1 - bbbits;
-#endif
-#else
- i = bbe + bbbits - 1; /* logb(rv) */
- if (i < Emin) /* denormal */
- j = bbe + (P-Emin);
- else
- j = P + 1 - bbbits;
-#endif
- bb2 += j;
- bd2 += j;
- i = bb2 < bd2 ? bb2 : bd2;
- if (i > bs2)
- i = bs2;
- if (i > 0) {
- bb2 -= i;
- bd2 -= i;
- bs2 -= i;
- }
- if (bb5 > 0) {
- bs = pow5mult(bs, bb5);
- bb1 = mult(bs, bb);
- Bfree(bb);
- bb = bb1;
- }
- if (bb2 > 0)
- bb = lshift(bb, bb2);
- if (bd5 > 0)
- bd = pow5mult(bd, bd5);
- if (bd2 > 0)
- bd = lshift(bd, bd2);
- if (bs2 > 0)
- bs = lshift(bs, bs2);
- delta = diff(bb, bd);
- dsign = delta->sign;
- delta->sign = 0;
- i = cmp(delta, bs);
- if (i < 0) {
- /* Error is less than half an ulp -- check for
- * special case of mantissa a power of two.
- */
- if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask)
- break;
- delta = lshift(delta,Log2P);
- if (cmp(delta, bs) > 0)
- goto drop_down;
- break;
- }
- if (i == 0) {
- /* exactly half-way between */
- if (dsign) {
- if ((getWord0(rv) & Bndry_mask1) == Bndry_mask1
- && getWord1(rv) == 0xffffffff) {
- /*boundary case -- increment exponent*/
- setWord0(&rv, (getWord0(rv) & Exp_mask)
- + Exp_msk1
-#ifdef IBM
- | Exp_msk1 >> 4
-#endif
- );
- setWord1(&rv, 0);
- break;
- }
- }
- else if (!(getWord0(rv) & Bndry_mask) && !getWord1(rv)) {
- drop_down:
- /* boundary case -- decrement exponent */
-#ifdef Sudden_Underflow
- L = getWord0(rv) & Exp_mask;
-#ifdef IBM
- if (L < Exp_msk1)
-#else
- if (L <= Exp_msk1)
-#endif
- goto undfl;
- L -= Exp_msk1;
-#else
- L = (getWord0(rv) & Exp_mask) - Exp_msk1;
-#endif
- setWord0(&rv, L | Bndry_mask1);
- setWord1(&rv, 0xffffffff);
-#ifdef IBM
- goto cont;
-#else
- break;
-#endif
- }
-#ifndef ROUND_BIASED
- if (!(getWord1(rv) & LSB))
- break;
-#endif
- if (dsign)
- rv += ulp(rv);
-#ifndef ROUND_BIASED
- else {
- rv -= ulp(rv);
-#ifndef Sudden_Underflow
- if (rv == g_double_zero)
- goto undfl;
-#endif
- }
-#endif
- break;
- }
- if ((aadj = ratio(delta, bs)) <= 2.) {
- if (dsign)
- aadj = aadj1 = 1.;
- else if (getWord1(rv) || getWord0(rv) & Bndry_mask) {
-#ifndef Sudden_Underflow
- if (getWord1(rv) == Tiny1 && !getWord0(rv))
- goto undfl;
-#endif
- aadj = 1.;
- aadj1 = -1.;
- }
- else {
- /* special case -- power of FLT_RADIX to be */
- /* rounded down... */
-
- if (aadj < 2./FLT_RADIX)
- aadj = 1./FLT_RADIX;
- else
- aadj *= 0.5;
- aadj1 = -aadj;
- }
- }
- else {
- aadj *= 0.5;
- aadj1 = dsign ? aadj : -aadj;
-#ifdef Check_FLT_ROUNDS
- switch(FLT_ROUNDS) {
- case 2: /* towards +infinity */
- aadj1 -= 0.5;
- break;
- case 0: /* towards 0 */
- case 3: /* towards -infinity */
- aadj1 += 0.5;
- }
-#else
- if (FLT_ROUNDS == 0)
- aadj1 += 0.5;
-#endif
- }
- y = getWord0(rv) & Exp_mask;
-
- /* Check for overflow */
-
- if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
- rv0 = rv;
- setWord0(&rv, getWord0(rv) - P*Exp_msk1);
- adj = aadj1 * ulp(rv);
- rv += adj;
- if ((getWord0(rv) & Exp_mask) >=
- Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
- if (getWord0(rv0) == Big0 && getWord1(rv0) == Big1)
- goto ovfl;
- setWord0(&rv, Big0);
- setWord1(&rv, Big1);
- goto cont;
- }
- else
- setWord0(&rv, getWord0(rv) + P*Exp_msk1);
- }
- else {
-#ifdef Sudden_Underflow
- if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) {
- rv0 = rv;
- setWord0(&rv, getWord0(rv) + P*Exp_msk1);
- adj = aadj1 * ulp(rv);
- rv += adj;
-#ifdef IBM
- if ((getWord0(rv) & Exp_mask) < P*Exp_msk1)
-#else
- if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1)
-#endif
- {
- if (getWord0(rv0) == Tiny0
- && getWord1(rv0) == Tiny1)
- goto undfl;
- setWord0(&rv, Tiny0);
- setWord1(&rv, Tiny1);
- goto cont;
- }
- else
- setWord0(&rv, getWord0(rv) - P*Exp_msk1);
- }
- else {
- adj = aadj1 * ulp(rv);
- rv += adj;
- }
-#else
- /* Compute adj so that the IEEE rounding rules will
- * correctly round rv + adj in some half-way cases.
- * If rv * ulp(rv) is denormalized (i.e.,
- * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
- * trouble from bits lost to denormalization;
- * example: 1.2e-307 .
- */
- if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
- aadj1 = int(aadj + 0.5);
- if (!dsign)
- aadj1 = -aadj1;
- }
- adj = aadj1 * ulp(rv);
- rv += adj;
-#endif
- }
- z = getWord0(rv) & Exp_mask;
- if (y == z) {
- /* Can we stop now? */
- L = Long(aadj);
- aadj -= L;
- /* The tolerances below are conservative. */
- if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) {
- if (aadj < .4999999 || aadj > .5000001)
- break;
- }
- else if (aadj < .4999999/FLT_RADIX)
- break;
- }
- cont:
- Bfree(bb);
- Bfree(bd);
- Bfree(bs);
- Bfree(delta);
- }
- retfree:
- Bfree(bb);
- Bfree(bd);
- Bfree(bs);
- Bfree(bd0);
- Bfree(delta);
- ret:
+ int processed = 0;
+ bool nonNullOk = false;
+ int len = static_cast<int>(strlen(s00));
+ Q_ASSERT(len >= 0);
+ double d = asciiToDouble(s00, len, nonNullOk, processed, TrailingJunkAllowed);
if (se)
- *se = s;
- return sign ? -rv : rv;
-}
-
-static int quorem(Bigint *b, Bigint *S)
-{
- int n;
- Long borrow, y;
- ULong carry, q, ys;
- ULong *bx, *bxe, *sx, *sxe;
-#ifdef Pack_32
- Long z;
- ULong si, zs;
-#endif
-
- n = S->wds;
-#ifdef BSD_QDTOA_DEBUG
- /*debug*/ if (b->wds > n)
- /*debug*/ Bug("oversize b in quorem");
-#endif
- if (b->wds < n)
- return 0;
- sx = S->x;
- sxe = sx + --n;
- bx = b->x;
- bxe = bx + n;
- q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
-#ifdef BSD_QDTOA_DEBUG
- /*debug*/ if (q > 9)
- /*debug*/ Bug("oversized quotient in quorem");
-#endif
- if (q) {
- borrow = 0;
- carry = 0;
- do {
-#ifdef Pack_32
- si = *sx++;
- ys = (si & 0xffff) * q + carry;
- zs = (si >> 16) * q + (ys >> 16);
- carry = zs >> 16;
- y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- z = (*bx >> 16) - (zs & 0xffff) + borrow;
- borrow = z >> 16;
- Sign_Extend(borrow, z);
- Storeinc(bx, z, y);
-#else
- ys = *sx++ * q + carry;
- carry = ys >> 16;
- y = *bx - (ys & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- *bx++ = y & 0xffff;
-#endif
- }
- while(sx <= sxe);
- if (!*bxe) {
- bx = b->x;
- while(--bxe > bx && !*bxe)
- --n;
- b->wds = n;
- }
- }
- if (cmp(b, S) >= 0) {
- q++;
- borrow = 0;
- carry = 0;
- bx = b->x;
- sx = S->x;
- do {
-#ifdef Pack_32
- si = *sx++;
- ys = (si & 0xffff) + carry;
- zs = (si >> 16) + (ys >> 16);
- carry = zs >> 16;
- y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- z = (*bx >> 16) - (zs & 0xffff) + borrow;
- borrow = z >> 16;
- Sign_Extend(borrow, z);
- Storeinc(bx, z, y);
-#else
- ys = *sx++ + carry;
- carry = ys >> 16;
- y = *bx - (ys & 0xffff) + borrow;
- borrow = y >> 16;
- Sign_Extend(borrow, y);
- *bx++ = y & 0xffff;
-#endif
- }
- while(sx <= sxe);
- bx = b->x;
- bxe = bx + n;
- if (!*bxe) {
- while(--bxe > bx && !*bxe)
- --n;
- b->wds = n;
- }
- }
- return q;
-}
-
-/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
- *
- * Inspired by "How to Print Floating-Point Numbers Accurately" by
- * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
- *
- * Modifications:
- * 1. Rather than iterating, we use a simple numeric overestimate
- * to determine k = floor(log10(d)). We scale relevant
- * quantities using O(log2(k)) rather than O(k) multiplications.
- * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
- * try to generate digits strictly left to right. Instead, we
- * compute with fewer bits and propagate the carry if necessary
- * when rounding the final digit up. This is often faster.
- * 3. Under the assumption that input will be rounded nearest,
- * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
- * That is, we allow equality in stopping tests when the
- * round-nearest rule will give the same floating-point value
- * as would satisfaction of the stopping test with strict
- * inequality.
- * 4. We remove common factors of powers of 2 from relevant
- * quantities.
- * 5. When converting floating-point integers less than 1e16,
- * we use floating-point arithmetic rather than resorting
- * to multiple-precision integers.
- * 6. When asked to produce fewer than 15 digits, we first try
- * to get by with floating-point arithmetic; we resort to
- * multiple-precision integer arithmetic only if we cannot
- * guarantee that the floating-point calculation has given
- * the correctly rounded result. For k requested digits and
- * "uniformly" distributed input, the probability is
- * something like 10^(k-15) that we must resort to the Long
- * calculation.
- */
-
-#if defined(Q_OS_WIN) && defined (Q_CC_GNU) && !defined(_clear87) // See QTBUG-7576
-extern "C" {
-__attribute__ ((dllimport)) unsigned int __cdecl __MINGW_NOTHROW _control87 (unsigned int unNew, unsigned int unMask);
-__attribute__ ((dllimport)) unsigned int __cdecl __MINGW_NOTHROW _clearfp (void); /* Clear the FPU status word */
+ *se = s00 + processed;
+ if (ok)
+ *ok = nonNullOk;
+ return d;
}
-# define _clear87 _clearfp
-#endif
-
-/* This actually sometimes returns a pointer to a string literal
- cast to a char*. Do NOT try to modify the return value. */
-Q_CORE_EXPORT char *qdtoa ( double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
+QString qdtoa(qreal d, int *decpt, int *sign)
{
- // Some values of the floating-point control word can cause _qdtoa to crash with an underflow.
- // We set a safe value here.
-#ifdef Q_OS_WIN
- _clear87();
- unsigned int oldbits = _control87(0, 0);
-#ifndef MCW_EM
-# ifdef _MCW_EM
-# define MCW_EM _MCW_EM
-# else
-# define MCW_EM 0x0008001F
-# endif
-#endif
- _control87(MCW_EM, MCW_EM);
-#endif
-
-#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
- fenv_t envp;
- feholdexcept(&envp);
-#endif
-
- char *s = _qdtoa(d, mode, ndigits, decpt, sign, rve, resultp);
-
-#ifdef Q_OS_WIN
- _clear87();
-#ifndef _M_X64
- _control87(oldbits, 0xFFFFF);
-#else
-# ifndef _MCW_EM // Potentially missing on MinGW
-# define _MCW_EM 0x0008001f
-# endif
-# ifndef _MCW_RC
-# define _MCW_RC 0x00000300
-# endif
-# ifndef _MCW_DN
-# define _MCW_DN 0x03000000
-# endif
- _control87(oldbits, _MCW_EM|_MCW_DN|_MCW_RC);
-#endif //_M_X64
-#endif //Q_OS_WIN
+ bool nonNullSign = false;
+ int nonNullDecpt = 0;
+ int length = 0;
-#if defined(Q_OS_LINUX) && !defined(__UCLIBC__)
- fesetenv(&envp);
-#endif
-
- return s;
-}
+ // Some versions of libdouble-conversion like an extra digit, probably for '\0'
+ char result[QLocaleData::DoubleMaxSignificant + 1];
+ doubleToAscii(d, QLocaleData::DFSignificantDigits, QLocale::FloatingPointShortest, result,
+ QLocaleData::DoubleMaxSignificant + 1, nonNullSign, length, nonNullDecpt);
-static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
-{
- /*
- Arguments ndigits, decpt, sign are similar to those
- of ecvt and fcvt; trailing zeros are suppressed from
- the returned string. If not null, *rve is set to point
- to the end of the return value. If d is +-Infinity or NaN,
- then *decpt is set to 9999.
-
- mode:
- 0 ==> shortest string that yields d when read in
- and rounded to nearest.
- 1 ==> like 0, but with Steele & White stopping rule;
- e.g. with IEEE P754 arithmetic , mode 0 gives
- 1e23 whereas mode 1 gives 9.999999999999999e22.
- 2 ==> max(1,ndigits) significant digits. This gives a
- return value similar to that of ecvt, except
- that trailing zeros are suppressed.
- 3 ==> through ndigits past the decimal point. This
- gives a return value similar to that from fcvt,
- except that trailing zeros are suppressed, and
- ndigits can be negative.
- 4-9 should give the same return values as 2-3, i.e.,
- 4 <= mode <= 9 ==> same return as mode
- 2 + (mode & 1). These modes are mainly for
- debugging; often they run slower but sometimes
- faster than modes 2-3.
- 4,5,8,9 ==> left-to-right digit generation.
- 6-9 ==> don't try fast floating-point estimate
- (if applicable).
-
- Values of mode other than 0-9 are treated as mode 0.
-
- Sufficient space is allocated to the return value
- to hold the suppressed trailing zeros.
- */
-
- int bbits, b2, b5, be, dig, i, ieps, ilim0,
- j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
- try_quick;
- int ilim = 0, ilim1 = 0, spec_case = 0; /* pacify gcc */
- Long L;
-#ifndef Sudden_Underflow
- int denorm;
- ULong x;
-#endif
- Bigint *b, *b1, *delta, *mhi, *S;
- Bigint *mlo = NULL; /* pacify gcc */
- double d2;
- double ds, eps;
- char *s, *s0;
-
- if (getWord0(d) & Sign_bit) {
- /* set sign for everything, including 0's and NaNs */
- *sign = 1;
- setWord0(&d, getWord0(d) & ~Sign_bit); /* clear sign bit */
- }
- else
- *sign = 0;
+ if (sign)
+ *sign = nonNullSign ? 1 : 0;
+ if (decpt)
+ *decpt = nonNullDecpt;
-#if defined(IEEE_Arith) + defined(VAX)
-#ifdef IEEE_Arith
- if ((getWord0(d) & Exp_mask) == Exp_mask)
-#else
- if (getWord0(d) == 0x8000)
-#endif
- {
- /* Infinity or NaN */
- *decpt = 9999;
- s =
-#ifdef IEEE_Arith
- !getWord1(d) && !(getWord0(d) & 0xfffff) ? const_cast<char*>("Infinity") :
-#endif
- const_cast<char*>("NaN");
- if (rve)
- *rve =
-#ifdef IEEE_Arith
- s[3] ? s + 8 :
-#endif
- s + 3;
- return s;
- }
-#endif
-#ifdef IBM
- d += 0; /* normalize */
-#endif
- if (d == g_double_zero)
- {
- *decpt = 1;
- s = const_cast<char*>("0");
- if (rve)
- *rve = s + 1;
- return s;
- }
-
- b = d2b(d, &be, &bbits);
- i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
-#ifndef Sudden_Underflow
- if (i != 0) {
-#endif
- d2 = d;
- setWord0(&d2, getWord0(d2) & Frac_mask1);
- setWord0(&d2, getWord0(d2) | Exp_11);
-#ifdef IBM
- if (j = 11 - hi0bits(getWord0(d2) & Frac_mask))
- d2 /= 1 << j;
-#endif
-
- /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
- * log10(x) = log(x) / log(10)
- * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
- * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
- *
- * This suggests computing an approximation k to log10(d) by
- *
- * k = (i - Bias)*0.301029995663981
- * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
- *
- * We want k to be too large rather than too small.
- * The error in the first-order Taylor series approximation
- * is in our favor, so we just round up the constant enough
- * to compensate for any error in the multiplication of
- * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
- * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
- * adding 1e-13 to the constant term more than suffices.
- * Hence we adjust the constant term to 0.1760912590558.
- * (We could get a more accurate k by invoking log10,
- * but this is probably not worthwhile.)
- */
-
- i -= Bias;
-#ifdef IBM
- i <<= 2;
- i += j;
-#endif
-#ifndef Sudden_Underflow
- denorm = 0;
- }
- else {
- /* d is denormalized */
-
- i = bbits + be + (Bias + (P-1) - 1);
- x = i > 32 ? getWord0(d) << (64 - i) | getWord1(d) >> (i - 32)
- : getWord1(d) << (32 - i);
- d2 = x;
- setWord0(&d2, getWord0(d2) - 31*Exp_msk1); /* adjust exponent */
- i -= (Bias + (P-1) - 1) + 1;
- denorm = 1;
- }
-#endif
- ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
- k = int(ds);
- if (ds < 0. && ds != k)
- k--; /* want k = floor(ds) */
- k_check = 1;
- if (k >= 0 && k <= Ten_pmax) {
- if (d < tens[k])
- k--;
- k_check = 0;
- }
- j = bbits - i - 1;
- if (j >= 0) {
- b2 = 0;
- s2 = j;
- }
- else {
- b2 = -j;
- s2 = 0;
- }
- if (k >= 0) {
- b5 = 0;
- s5 = k;
- s2 += k;
- }
- else {
- b2 -= k;
- b5 = -k;
- s5 = 0;
- }
- if (mode < 0 || mode > 9)
- mode = 0;
- try_quick = 1;
- if (mode > 5) {
- mode -= 4;
- try_quick = 0;
- }
- leftright = 1;
- switch(mode) {
- case 0:
- case 1:
- ilim = ilim1 = -1;
- i = 18;
- ndigits = 0;
- break;
- case 2:
- leftright = 0;
- /* no break */
- case 4:
- if (ndigits <= 0)
- ndigits = 1;
- ilim = ilim1 = i = ndigits;
- break;
- case 3:
- leftright = 0;
- /* no break */
- case 5:
- i = ndigits + k + 1;
- ilim = i;
- ilim1 = i - 1;
- if (i <= 0)
- i = 1;
- }
- QT_TRY {
- *resultp = static_cast<char *>(malloc(i + 1));
- Q_CHECK_PTR(*resultp);
- } QT_CATCH(...) {
- Bfree(b);
- QT_RETHROW;
- }
- s = s0 = *resultp;
-
- if (ilim >= 0 && ilim <= Quick_max && try_quick) {
-
- /* Try to get by with floating-point arithmetic. */
-
- i = 0;
- d2 = d;
- k0 = k;
- ilim0 = ilim;
- ieps = 2; /* conservative */
- if (k > 0) {
- ds = tens[k&0xf];
- j = k >> 4;
- if (j & Bletch) {
- /* prevent overflows */
- j &= Bletch - 1;
- d /= bigtens[n_bigtens-1];
- ieps++;
- }
- for(; j; j >>= 1, i++)
- if (j & 1) {
- ieps++;
- ds *= bigtens[i];
- }
- d /= ds;
- }
- else if ((j1 = -k) != 0) {
- d *= tens[j1 & 0xf];
- for(j = j1 >> 4; j; j >>= 1, i++)
- if (j & 1) {
- ieps++;
- d *= bigtens[i];
- }
- }
- if (k_check && d < 1. && ilim > 0) {
- if (ilim1 <= 0)
- goto fast_failed;
- ilim = ilim1;
- k--;
- d *= 10.;
- ieps++;
- }
- eps = ieps*d + 7.;
- setWord0(&eps, getWord0(eps) - (P-1)*Exp_msk1);
- if (ilim == 0) {
- S = mhi = 0;
- d -= 5.;
- if (d > eps)
- goto one_digit;
- if (d < -eps)
- goto no_digits;
- goto fast_failed;
- }
-#ifndef No_leftright
- if (leftright) {
- /* Use Steele & White method of only
- * generating digits needed.
- */
- eps = 0.5/tens[ilim-1] - eps;
- for(i = 0;;) {
- L = Long(d);
- d -= L;
- *s++ = '0' + int(L);
- if (d < eps)
- goto ret1;
- if (1. - d < eps)
- goto bump_up;
- if (++i >= ilim)
- break;
- eps *= 10.;
- d *= 10.;
- }
- }
- else {
-#endif
- /* Generate ilim digits, then fix them up. */
- eps *= tens[ilim-1];
- for(i = 1;; i++, d *= 10.) {
- L = Long(d);
- d -= L;
- *s++ = '0' + int(L);
- if (i == ilim) {
- if (d > 0.5 + eps)
- goto bump_up;
- else if (d < 0.5 - eps) {
- while(*--s == '0') {}
- s++;
- goto ret1;
- }
- break;
- }
- }
-#ifndef No_leftright
- }
-#endif
- fast_failed:
- s = s0;
- d = d2;
- k = k0;
- ilim = ilim0;
- }
-
- /* Do we have a "small" integer? */
-
- if (be >= 0 && k <= Int_max) {
- /* Yes. */
- ds = tens[k];
- if (ndigits < 0 && ilim <= 0) {
- S = mhi = 0;
- if (ilim < 0 || d <= 5*ds)
- goto no_digits;
- goto one_digit;
- }
- for(i = 1;; i++) {
- L = Long(d / ds);
- d -= L*ds;
-#ifdef Check_FLT_ROUNDS
- /* If FLT_ROUNDS == 2, L will usually be high by 1 */
- if (d < 0) {
- L--;
- d += ds;
- }
-#endif
- *s++ = '0' + int(L);
- if (i == ilim) {
- d += d;
- if (d > ds || (d == ds && L & 1)) {
- bump_up:
- while(*--s == '9')
- if (s == s0) {
- k++;
- *s = '0';
- break;
- }
- ++*s++;
- }
- break;
- }
- if ((d *= 10.) == g_double_zero)
- break;
- }
- goto ret1;
- }
-
- m2 = b2;
- m5 = b5;
- mhi = mlo = 0;
- if (leftright) {
- if (mode < 2) {
- i =
-#ifndef Sudden_Underflow
- denorm ? be + (Bias + (P-1) - 1 + 1) :
-#endif
-#ifdef IBM
- 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
-#else
- 1 + P - bbits;
-#endif
- }
- else {
- j = ilim - 1;
- if (m5 >= j)
- m5 -= j;
- else {
- s5 += j -= m5;
- b5 += j;
- m5 = 0;
- }
- if ((i = ilim) < 0) {
- m2 -= i;
- i = 0;
- }
- }
- b2 += i;
- s2 += i;
- mhi = i2b(1);
- }
- if (m2 > 0 && s2 > 0) {
- i = m2 < s2 ? m2 : s2;
- b2 -= i;
- m2 -= i;
- s2 -= i;
- }
- if (b5 > 0) {
- if (leftright) {
- if (m5 > 0) {
- mhi = pow5mult(mhi, m5);
- b1 = mult(mhi, b);
- Bfree(b);
- b = b1;
- }
- if ((j = b5 - m5) != 0)
- b = pow5mult(b, j);
- }
- else
- b = pow5mult(b, b5);
- }
- S = i2b(1);
- if (s5 > 0)
- S = pow5mult(S, s5);
-
- /* Check for special case that d is a normalized power of 2. */
-
- if (mode < 2) {
- if (!getWord1(d) && !(getWord0(d) & Bndry_mask)
-#ifndef Sudden_Underflow
- && getWord0(d) & Exp_mask
-#endif
- ) {
- /* The special case */
- b2 += Log2P;
- s2 += Log2P;
- spec_case = 1;
- }
- else
- spec_case = 0;
- }
-
- /* Arrange for convenient computation of quotients:
- * shift left if necessary so divisor has 4 leading 0 bits.
- *
- * Perhaps we should just compute leading 28 bits of S once
- * and for all and pass them and a shift to quorem, so it
- * can do shifts and ors to compute the numerator for q.
- */
-#ifdef Pack_32
- if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
- i = 32 - i;
-#else
- if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
- i = 16 - i;
-#endif
- if (i > 4) {
- i -= 4;
- b2 += i;
- m2 += i;
- s2 += i;
- }
- else if (i < 4) {
- i += 28;
- b2 += i;
- m2 += i;
- s2 += i;
- }
- if (b2 > 0)
- b = lshift(b, b2);
- if (s2 > 0)
- S = lshift(S, s2);
- if (k_check) {
- if (cmp(b,S) < 0) {
- k--;
- b = multadd(b, 10, 0); /* we botched the k estimate */
- if (leftright)
- mhi = multadd(mhi, 10, 0);
- ilim = ilim1;
- }
- }
- if (ilim <= 0 && mode > 2) {
- if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
- /* no digits, fcvt style */
- no_digits:
- k = -1 - ndigits;
- goto ret;
- }
- one_digit:
- *s++ = '1';
- k++;
- goto ret;
- }
- if (leftright) {
- if (m2 > 0)
- mhi = lshift(mhi, m2);
-
- /* Compute mlo -- check for special case
- * that d is a normalized power of 2.
- */
-
- mlo = mhi;
- if (spec_case) {
- mhi = Balloc(mhi->k);
- Bcopy(mhi, mlo);
- mhi = lshift(mhi, Log2P);
- }
-
- for(i = 1;;i++) {
- dig = quorem(b,S) + '0';
- /* Do we yet have the shortest decimal string
- * that will round to d?
- */
- j = cmp(b, mlo);
- delta = diff(S, mhi);
- j1 = delta->sign ? 1 : cmp(b, delta);
- Bfree(delta);
-#ifndef ROUND_BIASED
- if (j1 == 0 && !mode && !(getWord1(d) & 1)) {
- if (dig == '9')
- goto round_9_up;
- if (j > 0)
- dig++;
- *s++ = dig;
- goto ret;
- }
-#endif
- if (j < 0 || (j == 0 && !mode
-#ifndef ROUND_BIASED
- && !(getWord1(d) & 1)
-#endif
- )) {
- if (j1 > 0) {
- b = lshift(b, 1);
- j1 = cmp(b, S);
- if ((j1 > 0 || (j1 == 0 && dig & 1))
- && dig++ == '9')
- goto round_9_up;
- }
- *s++ = dig;
- goto ret;
- }
- if (j1 > 0) {
- if (dig == '9') { /* possible if i == 1 */
- round_9_up:
- *s++ = '9';
- goto roundoff;
- }
- *s++ = dig + 1;
- goto ret;
- }
- *s++ = dig;
- if (i == ilim)
- break;
- b = multadd(b, 10, 0);
- if (mlo == mhi)
- mlo = mhi = multadd(mhi, 10, 0);
- else {
- mlo = multadd(mlo, 10, 0);
- mhi = multadd(mhi, 10, 0);
- }
- }
- }
- else
- for(i = 1;; i++) {
- *s++ = dig = quorem(b,S) + '0';
- if (i >= ilim)
- break;
- b = multadd(b, 10, 0);
- }
-
- /* Round off last digit */
-
- b = lshift(b, 1);
- j = cmp(b, S);
- if (j > 0 || (j == 0 && dig & 1)) {
- roundoff:
- while(*--s == '9')
- if (s == s0) {
- k++;
- *s++ = '1';
- goto ret;
- }
- ++*s++;
- }
- else {
- while(*--s == '0') {}
- s++;
- }
- ret:
- Bfree(S);
- if (mhi) {
- if (mlo && mlo != mhi)
- Bfree(mlo);
- Bfree(mhi);
- }
- ret1:
- Bfree(b);
- if (s == s0) { /* don't return empty string */
- *s++ = '0';
- k = 0;
- }
- *s = 0;
- *decpt = k + 1;
- if (rve)
- *rve = s;
- return s0;
+ return QLatin1String(result, length);
}
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qlocale_tools_p.h b/src/corelib/tools/qlocale_tools_p.h
index 03f35209b4..f28b3dffcd 100644
--- a/src/corelib/tools/qlocale_tools_p.h
+++ b/src/corelib/tools/qlocale_tools_p.h
@@ -66,8 +66,19 @@
QT_BEGIN_NAMESPACE
+enum TrailingJunkMode {
+ TrailingJunkProhibited,
+ TrailingJunkAllowed
+};
+
+double asciiToDouble(const char *num, int numLen, bool &ok, int &processed,
+ TrailingJunkMode trailingJunkMode = TrailingJunkProhibited);
+void doubleToAscii(double d, QLocaleData::DoubleForm form, int precision, char *buf, int bufSize,
+ bool &sign, int &length, int &decpt);
+
QString qulltoa(qulonglong l, int base, const QChar _zero);
QString qlltoa(qlonglong l, int base, const QChar zero);
+Q_CORE_EXPORT QString qdtoa(qreal d, int *decpt, int *sign);
enum PrecisionMode {
PMDecimalDigits = 0x01,
@@ -76,15 +87,16 @@ enum PrecisionMode {
};
QString &decimalForm(QChar zero, QChar decimal, QChar group,
- QString &digits, int decpt, uint precision,
+ QString &digits, int decpt, int precision,
PrecisionMode pm,
bool always_show_decpt,
bool thousands_group);
QString &exponentForm(QChar zero, QChar decimal, QChar exponential,
QChar group, QChar plus, QChar minus,
- QString &digits, int decpt, uint precision,
+ QString &digits, int decpt, int precision,
PrecisionMode pm,
- bool always_show_decpt);
+ bool always_show_decpt,
+ bool leading_zero_in_exponent);
inline bool isZero(double d)
{
@@ -96,8 +108,6 @@ inline bool isZero(double d)
}
}
-Q_CORE_EXPORT char *qdtoa(double d, int mode, int ndigits, int *decpt,
- int *sign, char **rve, char **digits_str);
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
qlonglong qstrtoll(const char *nptr, const char **endptr, int base, bool *ok);
qulonglong qstrtoull(const char *nptr, const char **endptr, int base, bool *ok);
diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp
index a5eb7ec058..14133a83f1 100644
--- a/src/corelib/tools/qlocale_win.cpp
+++ b/src/corelib/tools/qlocale_win.cpp
@@ -678,7 +678,7 @@ QVariant QSystemLocalePrivate::uiLanguages()
bool found = false;
// Since ApplicationLanguages:::Languages uses long names, we compare the "pre-dash" part of
// the language and filter it out, if it is already covered by a more specialized form.
- foreach (const QString &lang, result) {
+ for (const QString &lang : qAsConst(result)) {
int dashIndex = lang.indexOf('-');
// There will not be any long name after the first short name was found, so we can stop.
if (dashIndex == -1)
diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h
index d637067fa8..b21750f76c 100644
--- a/src/corelib/tools/qpair.h
+++ b/src/corelib/tools/qpair.h
@@ -46,30 +46,36 @@ struct QPair
typedef T2 second_type;
Q_DECL_CONSTEXPR QPair()
- Q_DECL_NOEXCEPT_EXPR(noexcept(T1()) && noexcept(T2()))
+ Q_DECL_NOEXCEPT_EXPR((std::is_nothrow_default_constructible<T1>::value &&
+ std::is_nothrow_default_constructible<T2>::value))
: first(), second() {}
Q_DECL_CONSTEXPR QPair(const T1 &t1, const T2 &t2)
- Q_DECL_NOEXCEPT_EXPR(noexcept(T1(t1)) && noexcept(T2(t2)))
+ Q_DECL_NOEXCEPT_EXPR((std::is_nothrow_copy_constructible<T1>::value &&
+ std::is_nothrow_copy_constructible<T2>::value))
: first(t1), second(t2) {}
// compiler-generated copy/move ctor/assignment operators are fine!
template <typename TT1, typename TT2>
Q_DECL_CONSTEXPR QPair(const QPair<TT1, TT2> &p)
- Q_DECL_NOEXCEPT_EXPR(noexcept(T1(p.first)) && noexcept(T2(p.second)))
+ Q_DECL_NOEXCEPT_EXPR((std::is_nothrow_constructible<T1, TT1&>::value &&
+ std::is_nothrow_constructible<T2, TT2&>::value))
: first(p.first), second(p.second) {}
template <typename TT1, typename TT2>
Q_DECL_RELAXED_CONSTEXPR QPair &operator=(const QPair<TT1, TT2> &p)
- Q_DECL_NOEXCEPT_EXPR(noexcept(std::declval<T1&>() = p.first) && noexcept(std::declval<T2&>() = p.second))
+ Q_DECL_NOEXCEPT_EXPR((std::is_nothrow_assignable<T1, TT1&>::value &&
+ std::is_nothrow_assignable<T2, TT2&>::value))
{ first = p.first; second = p.second; return *this; }
#ifdef Q_COMPILER_RVALUE_REFS
template <typename TT1, typename TT2>
Q_DECL_CONSTEXPR QPair(QPair<TT1, TT2> &&p)
+ Q_DECL_NOEXCEPT_EXPR((std::is_nothrow_constructible<T1, TT1>::value &&
+ std::is_nothrow_constructible<T2, TT2>::value))
// can't use std::move here as it's not constexpr in C++11:
- Q_DECL_NOEXCEPT_EXPR(noexcept(T1(static_cast<TT1 &&>(p.first))) && noexcept(T2(static_cast<TT2 &&>(p.second))))
: first(static_cast<TT1 &&>(p.first)), second(static_cast<TT2 &&>(p.second)) {}
template <typename TT1, typename TT2>
Q_DECL_RELAXED_CONSTEXPR QPair &operator=(QPair<TT1, TT2> &&p)
- Q_DECL_NOEXCEPT_EXPR(noexcept(std::declval<T1&>() = std::move(p.first)) && noexcept(std::declval<T2&>() = std::move(p.second)))
+ Q_DECL_NOEXCEPT_EXPR((std::is_nothrow_assignable<T1, TT1>::value &&
+ std::is_nothrow_assignable<T2, TT2>::value))
{ first = std::move(p.first); second = std::move(p.second); return *this; }
#endif
diff --git a/src/corelib/tools/qpair.qdoc b/src/corelib/tools/qpair.qdoc
index 7cba7480f0..cc0aa731fb 100644
--- a/src/corelib/tools/qpair.qdoc
+++ b/src/corelib/tools/qpair.qdoc
@@ -48,6 +48,18 @@
\snippet code/doc_src_qpair.cpp 1
+ Note, however, that it is almost always preferable to define a small struct
+ to hold the result of a function with multiple return values. A struct
+ trivially generalizes to more than two values, and allows more descriptive
+ member names than \c{first} and \c{second}:
+
+ \snippet code/doc_src_qpair.cpp struct
+
+ The advent of C++11 automatic variable type deduction (\c{auto}) shifts the
+ emphasis from the type name to the name of functions and members. Thus, QPair,
+ like \c{std::pair} and \c{std::tuple}, is mostly useful in generic (template)
+ code, where defining a dedicated type is not possible.
+
QPair's template data types (T1 and T2) must be \l{assignable
data types}. You cannot, for example, store a QWidget as a value;
instead, store a QWidget *. A few functions have additional
diff --git a/src/corelib/tools/qregexp.h b/src/corelib/tools/qregexp.h
index f384e6c51f..9c68c194e0 100644
--- a/src/corelib/tools/qregexp.h
+++ b/src/corelib/tools/qregexp.h
@@ -68,10 +68,9 @@ public:
~QRegExp();
QRegExp &operator=(const QRegExp &rx);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QRegExp &operator=(QRegExp &&other)
- { qSwap(priv,other.priv); return *this; }
+ QRegExp &operator=(QRegExp &&other) Q_DECL_NOTHROW { swap(other); return *this; }
#endif
- inline void swap(QRegExp &other) { qSwap(priv, other.priv); }
+ void swap(QRegExp &other) Q_DECL_NOTHROW { qSwap(priv, other.priv); }
bool operator==(const QRegExp &rx) const;
inline bool operator!=(const QRegExp &rx) const { return !operator==(rx); }
diff --git a/src/corelib/tools/qringbuffer.cpp b/src/corelib/tools/qringbuffer.cpp
index 85cfdaf129..e9b655c01e 100644
--- a/src/corelib/tools/qringbuffer.cpp
+++ b/src/corelib/tools/qringbuffer.cpp
@@ -65,6 +65,8 @@ const char *QRingBuffer::readPointerAtPosition(qint64 pos, qint64 &length) const
void QRingBuffer::free(qint64 bytes)
{
+ Q_ASSERT(bytes <= bufferSize);
+
while (bytes > 0) {
const qint64 blockSize = buffers.first().size() - head;
@@ -100,20 +102,25 @@ char *QRingBuffer::reserve(qint64 bytes)
if (bytes <= 0 || bytes >= MaxByteArraySize)
return 0;
- const qint64 newSize = bytes + tail;
- // if need buffer reallocation
- if (newSize > buffers.last().size()) {
- if (newSize > buffers.last().capacity() && (tail >= basicBlockSize
- || newSize >= MaxByteArraySize)) {
- // shrink this buffer to its current size
- buffers.last().resize(tail);
-
- // create a new QByteArray
- buffers.append(QByteArray());
- ++tailBuffer;
- tail = 0;
+ if (buffers.isEmpty()) {
+ buffers.append(QByteArray());
+ buffers.first().resize(qMax(basicBlockSize, int(bytes)));
+ } else {
+ const qint64 newSize = bytes + tail;
+ // if need buffer reallocation
+ if (newSize > buffers.last().size()) {
+ if (newSize > buffers.last().capacity() && (tail >= basicBlockSize
+ || newSize >= MaxByteArraySize)) {
+ // shrink this buffer to its current size
+ buffers.last().resize(tail);
+
+ // create a new QByteArray
+ buffers.append(QByteArray());
+ ++tailBuffer;
+ tail = 0;
+ }
+ buffers.last().resize(qMax(basicBlockSize, tail + int(bytes)));
}
- buffers.last().resize(qMax(basicBlockSize, tail + int(bytes)));
}
char *writePtr = buffers.last().data() + tail;
@@ -134,9 +141,13 @@ char *QRingBuffer::reserveFront(qint64 bytes)
return 0;
if (head < bytes) {
- buffers.first().remove(0, head);
- if (tailBuffer == 0)
- tail -= head;
+ if (buffers.isEmpty()) {
+ buffers.append(QByteArray());
+ } else {
+ buffers.first().remove(0, head);
+ if (tailBuffer == 0)
+ tail -= head;
+ }
head = qMax(basicBlockSize, int(bytes));
if (bufferSize == 0) {
@@ -155,6 +166,8 @@ char *QRingBuffer::reserveFront(qint64 bytes)
void QRingBuffer::chop(qint64 bytes)
{
+ Q_ASSERT(bytes <= bufferSize);
+
while (bytes > 0) {
if (tailBuffer == 0 || tail > bytes) {
// keep a single block around if it does not exceed
@@ -185,6 +198,9 @@ void QRingBuffer::chop(qint64 bytes)
void QRingBuffer::clear()
{
+ if (buffers.isEmpty())
+ return;
+
buffers.erase(buffers.begin() + 1, buffers.end());
buffers.first().clear();
@@ -193,20 +209,32 @@ void QRingBuffer::clear()
bufferSize = 0;
}
-qint64 QRingBuffer::indexOf(char c, qint64 maxLength) const
+qint64 QRingBuffer::indexOf(char c, qint64 maxLength, qint64 pos) const
{
- qint64 index = 0;
- qint64 j = head;
- for (int i = 0; index < maxLength && i < buffers.size(); ++i) {
- const char *ptr = buffers[i].constData() + j;
- j = qMin(index + (i == tailBuffer ? tail : buffers[i].size()) - j, maxLength);
-
- while (index < j) {
- if (*ptr++ == c)
- return index;
- ++index;
+ if (maxLength <= 0 || pos < 0)
+ return -1;
+
+ qint64 index = -(pos + head);
+ for (int i = 0; i < buffers.size(); ++i) {
+ const qint64 nextBlockIndex = qMin(index + (i == tailBuffer ? tail : buffers[i].size()),
+ maxLength);
+
+ if (nextBlockIndex > 0) {
+ const char *ptr = buffers[i].constData();
+ if (index < 0) {
+ ptr -= index;
+ index = 0;
+ }
+
+ const char *findPtr = reinterpret_cast<const char *>(memchr(ptr, c,
+ nextBlockIndex - index));
+ if (findPtr)
+ return qint64(findPtr - ptr) + index + pos;
+
+ if (nextBlockIndex == maxLength)
+ return -1;
}
- j = 0;
+ index = nextBlockIndex;
}
return -1;
}
@@ -288,7 +316,10 @@ qint64 QRingBuffer::peek(char *data, qint64 maxLength, qint64 pos) const
void QRingBuffer::append(const QByteArray &qba)
{
if (tail == 0) {
- buffers.last() = qba;
+ if (buffers.isEmpty())
+ buffers.append(qba);
+ else
+ buffers.last() = qba;
} else {
buffers.last().resize(tail);
buffers.append(qba);
diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h
index 68509a6a80..96c4f9acb6 100644
--- a/src/corelib/tools/qringbuffer_p.h
+++ b/src/corelib/tools/qringbuffer_p.h
@@ -54,9 +54,7 @@ class QRingBuffer
{
public:
explicit inline QRingBuffer(int growth = 4096) :
- head(0), tail(0), tailBuffer(0), basicBlockSize(growth), bufferSize(0) {
- buffers.append(QByteArray());
- }
+ head(0), tail(0), tailBuffer(0), basicBlockSize(growth), bufferSize(0) { }
inline qint64 nextDataBlockSize() const {
return (tailBuffer == 0 ? tail : buffers.first().size()) - head;
@@ -114,14 +112,17 @@ public:
Q_CORE_EXPORT void clear();
inline qint64 indexOf(char c) const { return indexOf(c, size()); }
- Q_CORE_EXPORT qint64 indexOf(char c, qint64 maxLength) const;
+ Q_CORE_EXPORT qint64 indexOf(char c, qint64 maxLength, qint64 pos = 0) const;
Q_CORE_EXPORT qint64 read(char *data, qint64 maxLength);
Q_CORE_EXPORT QByteArray read();
Q_CORE_EXPORT qint64 peek(char *data, qint64 maxLength, qint64 pos = 0) const;
Q_CORE_EXPORT void append(const QByteArray &qba);
inline qint64 skip(qint64 length) {
- return read(0, length);
+ qint64 bytesToSkip = qMin(length, bufferSize);
+
+ free(bytesToSkip);
+ return bytesToSkip;
}
Q_CORE_EXPORT qint64 readLine(char *data, qint64 maxLength);
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index 3f4208e8b3..7c894706a9 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -98,6 +98,7 @@ public:
typedef QHash<T, QHashDummyValue> Hash;
typename Hash::iterator i;
friend class const_iterator;
+ friend class QSet<T>;
public:
typedef std::bidirectional_iterator_tag iterator_category;
@@ -183,9 +184,11 @@ public:
const_reverse_iterator crend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
iterator erase(iterator i)
+ { return erase(m2c(i)); }
+ iterator erase(const_iterator i)
{
Q_ASSERT_X(isValidIterator(i), "QSet::erase", "The specified const_iterator argument 'i' is invalid");
- return q_hash.erase(reinterpret_cast<typename Hash::iterator &>(i));
+ return q_hash.erase(reinterpret_cast<typename Hash::const_iterator &>(i));
}
// more Qt
@@ -240,10 +243,18 @@ public:
private:
Hash q_hash;
+
+ static const_iterator m2c(iterator it) Q_DECL_NOTHROW
+ { return const_iterator(typename Hash::const_iterator(it.i.i)); }
+
bool isValidIterator(const iterator &i) const
{
return q_hash.isValidIterator(reinterpret_cast<const typename Hash::iterator&>(i));
}
+ bool isValidIterator(const const_iterator &i) const Q_DECL_NOTHROW
+ {
+ return q_hash.isValidIterator(reinterpret_cast<const typename Hash::const_iterator&>(i));
+ }
};
template <typename T>
diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc
index 542def4651..df33f716e9 100644
--- a/src/corelib/tools/qset.qdoc
+++ b/src/corelib/tools/qset.qdoc
@@ -257,8 +257,8 @@
*/
/*!
- \fn QSet::iterator QSet::erase(iterator pos)
- \since 4.2
+ \fn QSet::iterator QSet::erase(const_iterator pos)
+ \since 5.7
Removes the item at the iterator position \a pos from the set, and
returns an iterator positioned at the next item in the set.
@@ -270,6 +270,12 @@
\sa remove(), find()
*/
+/*!
+ \fn QSet::iterator QSet::erase(iterator pos)
+ \since 4.2
+ \overload
+*/
+
/*! \fn QSet::const_iterator QSet::find(const T &value) const
\since 4.2
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index 86f4c6a268..24eee1d1b8 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -1292,6 +1292,17 @@
compile. Use qSharedPointerConstCast to cast away the constness.
*/
+/*!
+ \fn QDebug operator<<(QDebug debug, const QSharedPointer<T> &ptr)
+ \relates QSharedPointer
+ \since 5.7
+
+ Writes the pointer tracked by \a ptr into the debug object \a debug for
+ debugging purposes.
+
+ \sa {Debugging Techniques}
+*/
+
#include <qset.h>
#include <qmutex.h>
@@ -1497,7 +1508,7 @@ void QtSharedPointer::internalSafetyCheckAdd(const void *d_ptr, const volatile v
//qDebug("Adding d=%p value=%p", d_ptr, ptr);
const void *other_d_ptr = kp->dataPointers.value(ptr, 0);
- if (other_d_ptr) {
+ if (Q_UNLIKELY(other_d_ptr)) {
# ifdef BACKTRACE_SUPPORTED
printBacktrace(knownPointers()->dPointers.value(other_d_ptr).backtrace);
# endif
@@ -1527,15 +1538,15 @@ void QtSharedPointer::internalSafetyCheckRemove(const void *d_ptr)
QMutexLocker lock(&kp->mutex);
- QHash<const void *, Data>::iterator it = kp->dPointers.find(d_ptr);
- if (it == kp->dPointers.end()) {
+ const auto it = kp->dPointers.constFind(d_ptr);
+ if (Q_UNLIKELY(it == kp->dPointers.cend())) {
qFatal("QSharedPointer: internal self-check inconsistency: pointer %p was not tracked. "
"To use QT_SHAREDPOINTER_TRACK_POINTERS, you have to enable it throughout "
"in your code.", d_ptr);
}
- QHash<const volatile void *, const void *>::iterator it2 = kp->dataPointers.find(it->pointer);
- Q_ASSERT(it2 != kp->dataPointers.end());
+ const auto it2 = kp->dataPointers.constFind(it->pointer);
+ Q_ASSERT(it2 != kp->dataPointers.cend());
//qDebug("Removing d=%p value=%p", d_ptr, it->pointer);
@@ -1555,10 +1566,10 @@ void QtSharedPointer::internalSafetyCheckCleanCheck()
KnownPointers *const kp = knownPointers();
Q_ASSERT_X(kp, "internalSafetyCheckSelfCheck()", "Called after global statics deletion!");
- if (kp->dPointers.size() != kp->dataPointers.size())
+ if (Q_UNLIKELY(kp->dPointers.size() != kp->dataPointers.size()))
qFatal("Internal consistency error: the number of pointers is not equal!");
- if (!kp->dPointers.isEmpty())
+ if (Q_UNLIKELY(!kp->dPointers.isEmpty()))
qFatal("Pointer cleaning failed: %d entries remaining", kp->dPointers.size());
# endif
}
diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h
index 279ec36a28..56e13d500f 100644
--- a/src/corelib/tools/qsharedpointer.h
+++ b/src/corelib/tools/qsharedpointer.h
@@ -153,6 +153,8 @@ template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(const QWe
template <class X, class T> QWeakPointer<X> qWeakPointerCast(const QWeakPointer<T> &src);
+template <class T> QDebug operator<<(QDebug debug, const QSharedPointer<T> &ptr);
+
QT_END_NAMESPACE
#endif // Q_QDOC
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index bd98cb326c..6827483464 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -55,6 +55,7 @@ QT_END_NAMESPACE
#include <new>
#include <QtCore/qatomic.h>
#include <QtCore/qobject.h> // for qobject_cast
+#include <QtCore/qdebug.h>
#if QT_DEPRECATED_SINCE(5, 5)
#include <QtCore/qhash.h>
#endif
@@ -305,7 +306,7 @@ public:
inline T &operator*() const { return *data(); }
inline T *operator->() const { return data(); }
- QSharedPointer() : value(Q_NULLPTR), d(Q_NULLPTR) { }
+ QSharedPointer() Q_DECL_NOTHROW : value(Q_NULLPTR), d(Q_NULLPTR) {}
~QSharedPointer() { deref(); }
inline explicit QSharedPointer(T *ptr) : value(ptr) // noexcept
@@ -315,22 +316,22 @@ public:
inline QSharedPointer(T *ptr, Deleter deleter) : value(ptr) // throws
{ internalConstruct(ptr, deleter); }
- inline QSharedPointer(const QSharedPointer &other) : value(other.value), d(other.d)
+ QSharedPointer(const QSharedPointer &other) Q_DECL_NOTHROW : value(other.value), d(other.d)
{ if (d) ref(); }
- inline QSharedPointer &operator=(const QSharedPointer &other)
+ QSharedPointer &operator=(const QSharedPointer &other) Q_DECL_NOTHROW
{
QSharedPointer copy(other);
swap(copy);
return *this;
}
#ifdef Q_COMPILER_RVALUE_REFS
- inline QSharedPointer(QSharedPointer &&other)
+ QSharedPointer(QSharedPointer &&other) Q_DECL_NOTHROW
: value(other.value), d(other.d)
{
other.d = Q_NULLPTR;
other.value = Q_NULLPTR;
}
- inline QSharedPointer &operator=(QSharedPointer &&other)
+ QSharedPointer &operator=(QSharedPointer &&other) Q_DECL_NOTHROW
{
QSharedPointer moved(std::move(other));
swap(moved);
@@ -596,7 +597,7 @@ public:
inline bool operator !() const { return isNull(); }
inline T *data() const { return d == Q_NULLPTR || d->strongref.load() == 0 ? Q_NULLPTR : value; }
- inline QWeakPointer() : d(Q_NULLPTR), value(Q_NULLPTR) { }
+ inline QWeakPointer() Q_DECL_NOTHROW : d(Q_NULLPTR), value(Q_NULLPTR) { }
inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; }
#ifndef QT_NO_QOBJECT
@@ -614,15 +615,26 @@ public:
{ return *this = QWeakPointer(ptr); }
#endif
- inline QWeakPointer(const QWeakPointer &o) : d(o.d), value(o.value)
+ QWeakPointer(const QWeakPointer &other) Q_DECL_NOTHROW : d(other.d), value(other.value)
{ if (d) d->weakref.ref(); }
- inline QWeakPointer &operator=(const QWeakPointer &o)
+#ifdef Q_COMPILER_RVALUE_REFS
+ QWeakPointer(QWeakPointer &&other) Q_DECL_NOTHROW
+ : d(other.d), value(other.value)
{
- internalSet(o.d, o.value);
+ other.d = Q_NULLPTR;
+ other.value = Q_NULLPTR;
+ }
+ QWeakPointer &operator=(QWeakPointer &&other) Q_DECL_NOTHROW
+ { QWeakPointer moved(std::move(other)); swap(moved); return *this; }
+#endif
+ QWeakPointer &operator=(const QWeakPointer &other) Q_DECL_NOTHROW
+ {
+ QWeakPointer copy(other);
+ swap(copy);
return *this;
}
- inline void swap(QWeakPointer &other)
+ void swap(QWeakPointer &other) Q_DECL_NOTHROW
{
qSwap(this->d, other.d);
qSwap(this->value, other.value);
@@ -858,6 +870,16 @@ inline void qSwap(QSharedPointer<T> &p1, QSharedPointer<T> &p2)
p1.swap(p2);
}
+#ifndef QT_NO_DEBUG_STREAM
+template <class T>
+Q_INLINE_TEMPLATE QDebug operator<<(QDebug debug, const QSharedPointer<T> &ptr)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace() << "QSharedPointer(" << ptr.data() << ")";
+ return debug;
+}
+#endif
+
QT_END_NAMESPACE
namespace std {
template <class T>
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 3e4fdfaaf1..171e87df05 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -68,6 +68,8 @@
// copied from <linux/auxvec.h>
#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
+#elif defined(Q_CC_GHS)
+#include <INTEGRITY_types.h>
#endif
QT_BEGIN_NAMESPACE
@@ -179,6 +181,10 @@ static int maxBasicCpuidSupported()
int info[4];
__cpuid(info, 0);
return info[0];
+#elif defined(Q_CC_GHS)
+ unsigned int info[4];
+ __CPUID(0, info);
+ return info[0];
#else
return 0;
#endif
@@ -198,6 +204,11 @@ static void cpuidFeatures01(uint &ecx, uint &edx)
__cpuid(info, 1);
ecx = info[2];
edx = info[3];
+#elif defined(Q_CC_GHS)
+ unsigned int info[4];
+ __CPUID(1, info);
+ ecx = info[2];
+ edx = info[3];
#endif
}
@@ -223,6 +234,11 @@ static void cpuidFeatures07_00(uint &ebx, uint &ecx)
__cpuidex(info, 7, 0);
ebx = info[1];
ecx = info[2];
+#elif defined(Q_CC_GHS)
+ unsigned int info[4];
+ __CPUIDEX(7, 0, info);
+ ebx = info[1];
+ ecx = info[2];
#endif
}
@@ -232,7 +248,7 @@ inline quint64 _xgetbv(__int64) { return 0; }
#endif
static void xgetbv(uint in, uint &eax, uint &edx)
{
-#if defined(Q_CC_GNU)
+#if defined(Q_CC_GNU) || defined(Q_CC_GHS)
asm (".byte 0x0F, 0x01, 0xD0" // xgetbv instruction
: "=a" (eax), "=d" (edx)
: "c" (in));
@@ -638,6 +654,15 @@ int ffsll(quint64 i)
#endif
#elif defined(Q_OS_ANDROID) || defined(Q_OS_QNX) || defined(Q_OS_OSX)
# define ffsll __builtin_ffsll
+#elif defined(Q_OS_INTEGRITY)
+int ffsll(quint64 i)
+{
+ unsigned long result;
+ result = __CLZ32(i);
+ if (!result)
+ result = 32 + __CLZ32(i >> 32);
+ return result;
+}
#endif
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
@@ -685,7 +710,7 @@ void qDetectCpuFeatures()
#else
bool runningOnValgrind = false;
#endif
- if (!runningOnValgrind && (minFeature != 0 && (f & minFeature) != minFeature)) {
+ if (Q_UNLIKELY(!runningOnValgrind && minFeature != 0 && (f & minFeature) != minFeature)) {
quint64 missing = minFeature & ~f;
fprintf(stderr, "Incompatible processor. This Qt build requires the following features:\n ");
for (int i = 0; i < features_count; ++i) {
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index 12a329f36c..dedee06e38 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -73,6 +73,7 @@
* SSE4_2 | x86 | I & C | I & C | I only |
* AVX | x86 | I & C | I & C | I & C |
* AVX2 | x86 | I & C | I & C | I only |
+ * AVX512xx | x86 | I & C | I & C | I only |
* I = intrinsics; C = code generation
*
* Code can use the following constructs to determine compiler support & status:
@@ -430,7 +431,23 @@ static inline quint64 qCpuFeatures()
#define qCpuHasFeature(feature) ((qCompilerCpuFeatures & (Q_UINT64_C(1) << CpuFeature ## feature)) \
|| (qCpuFeatures() & (Q_UINT64_C(1) << CpuFeature ## feature)))
-#ifdef Q_PROCESSOR_X86
+#if QT_HAS_BUILTIN(__builtin_clz) && QT_HAS_BUILTIN(__builtin_ctz) && defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
+static Q_ALWAYS_INLINE unsigned _bit_scan_reverse(unsigned val)
+{
+ Q_ASSERT(val != 0); // if val==0, the result is undefined.
+ unsigned result = static_cast<unsigned>(__builtin_clz(val)); // Count Leading Zeros
+ // Now Invert the result: clz will count *down* from the msb to the lsb, so the msb index is 31
+ // and the lsb inde is 0. The result for _bit_scan_reverse is expected to be the index when
+ // counting up: msb index is 0 (because it starts there), and the lsb index is 31.
+ result ^= sizeof(unsigned) * 8 - 1;
+ return result;
+}
+static Q_ALWAYS_INLINE unsigned _bit_scan_forward(unsigned val)
+{
+ Q_ASSERT(val != 0); // if val==0, the result is undefined.
+ return static_cast<unsigned>(__builtin_ctz(val)); // Count Trailing Zeros
+}
+#elif defined(Q_PROCESSOR_X86)
// Bit scan functions for x86
# if defined(Q_CC_MSVC) && !defined(Q_OS_WINCE)
// MSVC calls it _BitScanReverse and returns the carry flag, which we don't need
diff --git a/src/corelib/tools/qsize.cpp b/src/corelib/tools/qsize.cpp
index 24a29f0213..4e45314722 100644
--- a/src/corelib/tools/qsize.cpp
+++ b/src/corelib/tools/qsize.cpp
@@ -159,9 +159,7 @@ QT_BEGIN_NAMESPACE
void QSize::transpose() Q_DECL_NOTHROW
{
- int tmp = wd;
- wd = ht;
- ht = tmp;
+ qSwap(wd, ht);
}
/*!
@@ -592,9 +590,7 @@ QDebug operator<<(QDebug dbg, const QSize &s)
void QSizeF::transpose() Q_DECL_NOTHROW
{
- qreal tmp = wd;
- wd = ht;
- ht = tmp;
+ qSwap(wd, ht);
}
/*!
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 89d9889b2f..55289fa0e7 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -40,6 +40,7 @@
#include <qtextcodec.h>
#endif
#include <private/qutfcodec_p.h>
+#include <private/qlocale_tools_p.h>
#include "qsimd_p.h"
#include <qnumeric.h>
#include <qdatastream.h>
@@ -1651,9 +1652,7 @@ QString::QString(QChar ch)
\snippet qstring/main.cpp 45
If you want to append a certain number of identical characters to
- the string, use \l operator+=() as follows rather than resize():
-
- \snippet qstring/main.cpp 46
+ the string, use the \l {QString::}{resize(int, QChar)} overload.
If you want to expand the string so that it reaches a certain
width and fill the new positions with a particular character, use
@@ -1684,6 +1683,25 @@ void QString::resize(int size)
}
}
+/*!
+ \overload
+ \since 5.7
+
+ Unlike \l {QString::}{resize(int)}, this overload
+ initializes the new characters to \a fillChar:
+
+ \snippet qstring/main.cpp 46
+*/
+
+void QString::resize(int size, QChar fillChar)
+{
+ const int oldSize = length();
+ resize(size);
+ const int difference = length() - oldSize;
+ if (difference > 0)
+ std::fill_n(d->begin() + oldSize, difference, fillChar.unicode());
+}
+
/*! \fn int QString::capacity() const
Returns the maximum number of characters that can be stored in
@@ -2681,7 +2699,7 @@ QString &QString::replace(QChar c, QLatin1String after, Qt::CaseSensitivity cs)
expect. Consider sorting user-interface strings with
localeAwareCompare().
*/
-bool operator==(const QString &s1, const QString &s2)
+bool operator==(const QString &s1, const QString &s2) Q_DECL_NOTHROW
{
if (s1.d->size != s2.d->size)
return false;
@@ -2694,7 +2712,7 @@ bool operator==(const QString &s1, const QString &s2)
Returns \c true if this string is equal to \a other; otherwise
returns \c false.
*/
-bool QString::operator==(QLatin1String other) const
+bool QString::operator==(QLatin1String other) const Q_DECL_NOTHROW
{
if (d->size != other.size())
return false;
@@ -2745,7 +2763,7 @@ bool QString::operator==(QLatin1String other) const
expect. Consider sorting user-interface strings using the
QString::localeAwareCompare() function.
*/
-bool operator<(const QString &s1, const QString &s2)
+bool operator<(const QString &s1, const QString &s2) Q_DECL_NOTHROW
{
return ucstrcmp(s1.constData(), s1.length(), s2.constData(), s2.length()) < 0;
}
@@ -2755,7 +2773,7 @@ bool operator<(const QString &s1, const QString &s2)
Returns \c true if this string is lexically less than the parameter
string called \a other; otherwise returns \c false.
*/
-bool QString::operator<(QLatin1String other) const
+bool QString::operator<(QLatin1String other) const Q_DECL_NOTHROW
{
const uchar *c = (const uchar *) other.latin1();
if (!c || *c == 0)
@@ -2860,7 +2878,7 @@ bool QString::operator<(QLatin1String other) const
Returns \c true if this string is lexically greater than the parameter
string \a other; otherwise returns \c false.
*/
-bool QString::operator>(QLatin1String other) const
+bool QString::operator>(QLatin1String other) const Q_DECL_NOTHROW
{
const uchar *c = (const uchar *) other.latin1();
if (!c || *c == '\0')
@@ -3562,7 +3580,7 @@ QString &QString::replace(const QRegularExpression &re, const QString &after)
lastEnd = 0;
// add the after string, with replacements for the backreferences
- foreach (const QStringCapture &backReference, backReferences) {
+ for (const QStringCapture &backReference : qAsConst(backReferences)) {
// part of "after" before the backreference
len = backReference.pos - lastEnd;
if (len > 0) {
@@ -3600,7 +3618,7 @@ QString &QString::replace(const QRegularExpression &re, const QString &after)
resize(newLength);
int i = 0;
QChar *uc = data();
- foreach (const QStringRef &chunk, chunks) {
+ for (const QStringRef &chunk : qAsConst(chunks)) {
int len = chunk.length();
memcpy(uc + i, chunk.unicode(), len * sizeof(QChar));
i += len;
@@ -5343,7 +5361,7 @@ QString& QString::fill(QChar ch, int size)
Same as compare(*this, \a other, \a cs).
*/
-int QString::compare(const QString &other, Qt::CaseSensitivity cs) const
+int QString::compare(const QString &other, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW
{
if (cs == Qt::CaseSensitive)
return ucstrcmp(constData(), length(), other.constData(), other.length());
@@ -5355,7 +5373,7 @@ int QString::compare(const QString &other, Qt::CaseSensitivity cs) const
\since 4.5
*/
int QString::compare_helper(const QChar *data1, int length1, const QChar *data2, int length2,
- Qt::CaseSensitivity cs)
+ Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{
if (cs == Qt::CaseSensitive)
return ucstrcmp(data1, length1, data2, length2);
@@ -5370,7 +5388,7 @@ int QString::compare_helper(const QChar *data1, int length1, const QChar *data2,
Same as compare(*this, \a other, \a cs).
*/
-int QString::compare(QLatin1String other, Qt::CaseSensitivity cs) const
+int QString::compare(QLatin1String other, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW
{
return compare_helper(unicode(), length(), other, cs);
}
@@ -5406,7 +5424,7 @@ int QString::compare_helper(const QChar *data1, int length1, const char *data2,
\since 4.5
*/
int QString::compare_helper(const QChar *data1, int length1, QLatin1String s2,
- Qt::CaseSensitivity cs)
+ Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{
const ushort *uc = reinterpret_cast<const ushort *>(data1);
const ushort *uce = uc + length1;
@@ -5877,6 +5895,72 @@ QString &QString::vsprintf(const char *cformat, va_list ap)
return *this = vasprintf(cformat, ap);
}
+static void append_utf8(QString &qs, const char *cs, int len)
+{
+ const int oldSize = qs.size();
+ qs.resize(oldSize + len);
+ const QChar *newEnd = QUtf8::convertToUnicode(qs.data() + oldSize, cs, len);
+ qs.resize(newEnd - qs.constData());
+}
+
+static uint parse_flag_characters(const char * &c) Q_DECL_NOTHROW
+{
+ uint flags = QLocaleData::ZeroPadExponent;
+ while (true) {
+ switch (*c) {
+ case '#': flags |= QLocaleData::Alternate; break;
+ case '0': flags |= QLocaleData::ZeroPadded; break;
+ case '-': flags |= QLocaleData::LeftAdjusted; break;
+ case ' ': flags |= QLocaleData::BlankBeforePositive; break;
+ case '+': flags |= QLocaleData::AlwaysShowSign; break;
+ case '\'': flags |= QLocaleData::ThousandsGroup; break;
+ default: return flags;
+ }
+ ++c;
+ }
+}
+
+static int parse_field_width(const char * &c)
+{
+ Q_ASSERT(qIsDigit(*c));
+
+ // can't be negative - started with a digit
+ // contains at least one digit
+ const char *endp;
+ bool ok;
+ const qulonglong result = qstrtoull(c, &endp, 10, &ok);
+ c = endp;
+ while (qIsDigit(*c)) // preserve Qt 5.5 behavior of consuming all digits, no matter how many
+ ++c;
+ return ok && result < qulonglong(std::numeric_limits<int>::max()) ? int(result) : 0;
+}
+
+enum LengthMod { lm_none, lm_hh, lm_h, lm_l, lm_ll, lm_L, lm_j, lm_z, lm_t };
+
+static inline bool can_consume(const char * &c, char ch) Q_DECL_NOTHROW
+{
+ if (*c == ch) {
+ ++c;
+ return true;
+ }
+ return false;
+}
+
+static LengthMod parse_length_modifier(const char * &c) Q_DECL_NOTHROW
+{
+ switch (*c++) {
+ case 'h': return can_consume(c, 'h') ? lm_hh : lm_h;
+ case 'l': return can_consume(c, 'l') ? lm_ll : lm_l;
+ case 'L': return lm_L;
+ case 'j': return lm_j;
+ case 'z':
+ case 'Z': return lm_z;
+ case 't': return lm_t;
+ }
+ --c; // don't consume *c - it wasn't a flag
+ return lm_none;
+}
+
/*!
\fn QString::vasprintf(const char *cformat, va_list ap)
\since 5.5
@@ -5907,7 +5991,7 @@ QString QString::vasprintf(const char *cformat, va_list ap)
const char *cb = c;
while (*c != '\0' && *c != '%')
c++;
- result.append(QString::fromUtf8(cb, (int)(c - cb)));
+ append_utf8(result, cb, int(c - cb));
if (*c == '\0')
break;
@@ -5926,23 +6010,7 @@ QString QString::vasprintf(const char *cformat, va_list ap)
continue;
}
- // Parse flag characters
- uint flags = 0;
- bool no_more_flags = false;
- do {
- switch (*c) {
- case '#': flags |= QLocaleData::Alternate; break;
- case '0': flags |= QLocaleData::ZeroPadded; break;
- case '-': flags |= QLocaleData::LeftAdjusted; break;
- case ' ': flags |= QLocaleData::BlankBeforePositive; break;
- case '+': flags |= QLocaleData::AlwaysShowSign; break;
- case '\'': flags |= QLocaleData::ThousandsGroup; break;
- default: no_more_flags = true; break;
- }
-
- if (!no_more_flags)
- ++c;
- } while (!no_more_flags);
+ uint flags = parse_flag_characters(c);
if (*c == '\0') {
result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
@@ -5952,15 +6020,8 @@ QString QString::vasprintf(const char *cformat, va_list ap)
// Parse field width
int width = -1; // -1 means unspecified
if (qIsDigit(*c)) {
- QString width_str;
- while (*c != '\0' && qIsDigit(*c))
- width_str.append(QLatin1Char(*c++));
-
- // can't be negative - started with a digit
- // contains at least one digit
- width = width_str.toInt();
- }
- else if (*c == '*') {
+ width = parse_field_width(c);
+ } else if (*c == '*') { // can't parse this in another function, not portably, at least
width = va_arg(ap, int);
if (width < 0)
width = -1; // treat all negative numbers as unspecified
@@ -5977,15 +6038,8 @@ QString QString::vasprintf(const char *cformat, va_list ap)
if (*c == '.') {
++c;
if (qIsDigit(*c)) {
- QString precision_str;
- while (*c != '\0' && qIsDigit(*c))
- precision_str.append(QLatin1Char(*c++));
-
- // can't be negative - started with a digit
- // contains at least one digit
- precision = precision_str.toInt();
- }
- else if (*c == '*') {
+ precision = parse_field_width(c);
+ } else if (*c == '*') { // can't parse this in another function, not portably, at least
precision = va_arg(ap, int);
if (precision < 0)
precision = -1; // treat all negative numbers as unspecified
@@ -5998,53 +6052,7 @@ QString QString::vasprintf(const char *cformat, va_list ap)
break;
}
- // Parse the length modifier
- enum LengthMod { lm_none, lm_hh, lm_h, lm_l, lm_ll, lm_L, lm_j, lm_z, lm_t };
- LengthMod length_mod = lm_none;
- switch (*c) {
- case 'h':
- ++c;
- if (*c == 'h') {
- length_mod = lm_hh;
- ++c;
- }
- else
- length_mod = lm_h;
- break;
-
- case 'l':
- ++c;
- if (*c == 'l') {
- length_mod = lm_ll;
- ++c;
- }
- else
- length_mod = lm_l;
- break;
-
- case 'L':
- ++c;
- length_mod = lm_L;
- break;
-
- case 'j':
- ++c;
- length_mod = lm_j;
- break;
-
- case 'z':
- case 'Z':
- ++c;
- length_mod = lm_z;
- break;
-
- case 't':
- ++c;
- length_mod = lm_t;
- break;
-
- default: break;
- }
+ const LengthMod length_mod = parse_length_modifier(c);
if (*c == '\0') {
result.append(QLatin1String(escape_start)); // incomplete escape, treat as non-escape text
@@ -6186,8 +6194,7 @@ QString QString::vasprintf(const char *cformat, va_list ap)
}
case lm_ll: {
qint64 *n = va_arg(ap, qint64*);
- volatile uint tmp = result.length(); // egcs-2.91.66 gets internal
- *n = tmp; // compiler error without volatile
+ *n = result.length();
break;
}
default: {
@@ -6250,7 +6257,7 @@ qlonglong QString::toIntegral_helper(const QChar *data, int len, bool *ok, int b
}
#endif
- return QLocaleData::c()->stringToLongLong(data, len, base, ok, QLocaleData::FailOnGroupSeparators);
+ return QLocaleData::c()->stringToLongLong(data, len, base, ok, QLocale::RejectGroupSeparator);
}
@@ -6290,7 +6297,8 @@ qulonglong QString::toIntegral_helper(const QChar *data, uint len, bool *ok, int
}
#endif
- return QLocaleData::c()->stringToUnsLongLong(data, len, base, ok, QLocaleData::FailOnGroupSeparators);
+ return QLocaleData::c()->stringToUnsLongLong(data, len, base, ok,
+ QLocale::RejectGroupSeparator);
}
/*!
@@ -6491,7 +6499,7 @@ ushort QString::toUShort(bool *ok, int base) const
double QString::toDouble(bool *ok) const
{
- return QLocaleData::c()->stringToDouble(constData(), size(), ok, QLocaleData::FailOnGroupSeparators);
+ return QLocaleData::c()->stringToDouble(constData(), size(), ok, QLocale::RejectGroupSeparator);
}
/*!
@@ -7739,6 +7747,8 @@ QString QString::arg(double a, int fieldWidth, char fmt, int prec, QChar fillCha
if (!(locale.numberOptions() & QLocale::OmitGroupSeparator))
flags |= QLocaleData::ThousandsGroup;
+ if (!(locale.numberOptions() & QLocale::OmitLeadingZeroInExponent))
+ flags |= QLocaleData::ZeroPadExponent;
locale_arg = locale.d->m_data->doubleToString(a, prec, form, fieldWidth, flags);
}
@@ -8925,7 +8935,7 @@ QString QStringRef::toString() const {
Returns \c true if string reference \a s1 is lexically equal to string reference \a s2; otherwise
returns \c false.
*/
-bool operator==(const QStringRef &s1,const QStringRef &s2)
+bool operator==(const QStringRef &s1,const QStringRef &s2) Q_DECL_NOTHROW
{ return (s1.size() == s2.size() &&
qMemEquals((const ushort *)s1.unicode(), (const ushort *)s2.unicode(), s1.size()));
}
@@ -8935,7 +8945,7 @@ bool operator==(const QStringRef &s1,const QStringRef &s2)
Returns \c true if string \a s1 is lexically equal to string reference \a s2; otherwise
returns \c false.
*/
-bool operator==(const QString &s1,const QStringRef &s2)
+bool operator==(const QString &s1,const QStringRef &s2) Q_DECL_NOTHROW
{ return (s1.size() == s2.size() &&
qMemEquals((const ushort *)s1.unicode(), (const ushort *)s2.unicode(), s1.size()));
}
@@ -8945,7 +8955,7 @@ bool operator==(const QString &s1,const QStringRef &s2)
Returns \c true if string \a s1 is lexically equal to string reference \a s2; otherwise
returns \c false.
*/
-bool operator==(QLatin1String s1, const QStringRef &s2)
+bool operator==(QLatin1String s1, const QStringRef &s2) Q_DECL_NOTHROW
{
if (s1.size() != s2.size())
return false;
@@ -8967,7 +8977,7 @@ bool operator==(QLatin1String s1, const QStringRef &s2)
expect. Consider sorting user-interface strings using the
QString::localeAwareCompare() function.
*/
-bool operator<(const QStringRef &s1,const QStringRef &s2)
+bool operator<(const QStringRef &s1,const QStringRef &s2) Q_DECL_NOTHROW
{
return ucstrcmp(s1.constData(), s1.length(), s2.constData(), s2.length()) < 0;
}
@@ -10459,7 +10469,7 @@ ushort QStringRef::toUShort(bool *ok, int base) const
double QStringRef::toDouble(bool *ok) const
{
- return QLocaleData::c()->stringToDouble(constData(), size(), ok, QLocaleData::FailOnGroupSeparators);
+ return QLocaleData::c()->stringToDouble(constData(), size(), ok, QLocale::RejectGroupSeparator);
}
/*!
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 1d04bcb457..9dc770d2c5 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -233,6 +233,7 @@ public:
inline int length() const;
inline bool isEmpty() const;
void resize(int size);
+ void resize(int size, QChar fillChar);
QString &fill(QChar c, int size = -1);
void truncate(int pos);
@@ -387,25 +388,25 @@ public:
# define Q_REQUIRED_RESULT
# define Q_REQUIRED_RESULT_pushed
# endif
- QString toLower() const & Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QString toLower() const & Q_REQUIRED_RESULT
{ return toLower_helper(*this); }
- QString toLower() && Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QString toLower() && Q_REQUIRED_RESULT
{ return toLower_helper(*this); }
- QString toUpper() const & Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QString toUpper() const & Q_REQUIRED_RESULT
{ return toUpper_helper(*this); }
- QString toUpper() && Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QString toUpper() && Q_REQUIRED_RESULT
{ return toUpper_helper(*this); }
- QString toCaseFolded() const & Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QString toCaseFolded() const & Q_REQUIRED_RESULT
{ return toCaseFolded_helper(*this); }
- QString toCaseFolded() && Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QString toCaseFolded() && Q_REQUIRED_RESULT
{ return toCaseFolded_helper(*this); }
- QString trimmed() const & Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QString trimmed() const & Q_REQUIRED_RESULT
{ return trimmed_helper(*this); }
- QString trimmed() && Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QString trimmed() && Q_REQUIRED_RESULT
{ return trimmed_helper(*this); }
- QString simplified() const & Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QString simplified() const & Q_REQUIRED_RESULT
{ return simplified_helper(*this); }
- QString simplified() && Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QString simplified() && Q_REQUIRED_RESULT
{ return simplified_helper(*this); }
# ifdef Q_REQUIRED_RESULT_pushed
# pragma pop_macro("Q_REQUIRED_RESULT")
@@ -571,22 +572,23 @@ public:
QString &setUnicode(const QChar *unicode, int size);
inline QString &setUtf16(const ushort *utf16, int size);
- int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
- int compare(QLatin1String other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
+ int compare(QLatin1String other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
- static inline int compare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs = Qt::CaseSensitive)
+ static inline int compare(const QString &s1, const QString &s2,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW
{ return s1.compare(s2, cs); }
static inline int compare(const QString &s1, QLatin1String s2,
- Qt::CaseSensitivity cs = Qt::CaseSensitive)
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW
{ return s1.compare(s2, cs); }
static inline int compare(QLatin1String s1, const QString &s2,
- Qt::CaseSensitivity cs = Qt::CaseSensitive)
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW
{ return -s2.compare(s1, cs); }
- int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
static int compare(const QString &s1, const QStringRef &s2,
- Qt::CaseSensitivity = Qt::CaseSensitive);
+ Qt::CaseSensitivity = Qt::CaseSensitive) Q_DECL_NOTHROW;
int localeAwareCompare(const QString& s) const;
static int localeAwareCompare(const QString& s1, const QString& s2)
@@ -626,19 +628,19 @@ public:
static QString number(qulonglong, int base=10);
static QString number(double, char f='g', int prec=6);
- friend Q_CORE_EXPORT bool operator==(const QString &s1, const QString &s2);
- friend Q_CORE_EXPORT bool operator<(const QString &s1, const QString &s2);
- friend inline bool operator>(const QString &s1, const QString &s2) { return s2 < s1; }
- friend inline bool operator!=(const QString &s1, const QString &s2) { return !(s1 == s2); }
- friend inline bool operator<=(const QString &s1, const QString &s2) { return !(s1 > s2); }
- friend inline bool operator>=(const QString &s1, const QString &s2) { return !(s1 < s2); }
+ friend Q_CORE_EXPORT bool operator==(const QString &s1, const QString &s2) Q_DECL_NOTHROW;
+ friend Q_CORE_EXPORT bool operator<(const QString &s1, const QString &s2) Q_DECL_NOTHROW;
+ friend inline bool operator>(const QString &s1, const QString &s2) Q_DECL_NOTHROW { return s2 < s1; }
+ friend inline bool operator!=(const QString &s1, const QString &s2) Q_DECL_NOTHROW { return !(s1 == s2); }
+ friend inline bool operator<=(const QString &s1, const QString &s2) Q_DECL_NOTHROW { return !(s1 > s2); }
+ friend inline bool operator>=(const QString &s1, const QString &s2) Q_DECL_NOTHROW { return !(s1 < s2); }
- bool operator==(QLatin1String s) const;
- bool operator<(QLatin1String s) const;
- bool operator>(QLatin1String s) const;
- inline bool operator!=(QLatin1String s) const { return !operator==(s); }
- inline bool operator<=(QLatin1String s) const { return !operator>(s); }
- inline bool operator>=(QLatin1String s) const { return !operator<(s); }
+ bool operator==(QLatin1String s) const Q_DECL_NOTHROW;
+ bool operator<(QLatin1String s) const Q_DECL_NOTHROW;
+ bool operator>(QLatin1String s) const Q_DECL_NOTHROW;
+ inline bool operator!=(QLatin1String s) const Q_DECL_NOTHROW { return !operator==(s); }
+ inline bool operator<=(QLatin1String s) const Q_DECL_NOTHROW { return !operator>(s); }
+ inline bool operator>=(QLatin1String s) const Q_DECL_NOTHROW { return !operator<(s); }
// ASCII compatibility
#if defined(QT_RESTRICTED_CAST_FROM_ASCII)
@@ -798,13 +800,13 @@ private:
QString multiArg(int numArgs, const QString **args) const;
static int compare_helper(const QChar *data1, int length1,
const QChar *data2, int length2,
- Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
static int compare_helper(const QChar *data1, int length1,
const char *data2, int length2,
Qt::CaseSensitivity cs = Qt::CaseSensitive);
static int compare_helper(const QChar *data1, int length1,
QLatin1String s2,
- Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
static int localeAwareCompare_helper(const QChar *data1, int length1,
const QChar *data2, int length2);
static QString toLower_helper(const QString &str);
@@ -953,8 +955,9 @@ inline int QString::toWCharArray(wchar_t *array) const
if (sizeof(wchar_t) == sizeof(QChar)) {
memcpy(array, d->data(), sizeof(QChar) * size());
return size();
+ } else {
+ return toUcs4_helper(d->data(), size(), reinterpret_cast<uint *>(array));
}
- return toUcs4_helper(d->data(), size(), reinterpret_cast<uint *>(array));
}
QT_WARNING_POP
@@ -1463,15 +1466,15 @@ public:
inline QT_ASCII_CAST_WARN bool operator>=(const char *s) const;
#endif
- int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
- int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
- int compare(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
+ int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
+ int compare(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const Q_DECL_NOTHROW;
static int compare(const QStringRef &s1, const QString &s2,
- Qt::CaseSensitivity = Qt::CaseSensitive);
+ Qt::CaseSensitivity = Qt::CaseSensitive) Q_DECL_NOTHROW;
static int compare(const QStringRef &s1, const QStringRef &s2,
- Qt::CaseSensitivity = Qt::CaseSensitive);
+ Qt::CaseSensitivity = Qt::CaseSensitive) Q_DECL_NOTHROW;
static int compare(const QStringRef &s1, QLatin1String s2,
- Qt::CaseSensitivity cs = Qt::CaseSensitive);
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) Q_DECL_NOTHROW;
int localeAwareCompare(const QString &s) const;
int localeAwareCompare(const QStringRef &s) const;
@@ -1501,30 +1504,30 @@ inline QStringRef::QStringRef(const QString *aString, int aPosition, int aSize)
inline QStringRef::QStringRef(const QString *aString)
:m_string(aString), m_position(0), m_size(aString?aString->size() : 0){}
-Q_CORE_EXPORT bool operator==(const QStringRef &s1,const QStringRef &s2);
-inline bool operator!=(const QStringRef &s1,const QStringRef &s2)
+Q_CORE_EXPORT bool operator==(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW;
+inline bool operator!=(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW
{ return !(s1 == s2); }
-Q_CORE_EXPORT bool operator==(const QString &s1,const QStringRef &s2);
-inline bool operator!=(const QString &s1,const QStringRef &s2)
+Q_CORE_EXPORT bool operator==(const QString &s1, const QStringRef &s2) Q_DECL_NOTHROW;
+inline bool operator!=(const QString &s1, const QStringRef &s2) Q_DECL_NOTHROW
{ return !(s1 == s2); }
-inline bool operator==(const QStringRef &s1,const QString &s2)
+inline bool operator==(const QStringRef &s1, const QString &s2) Q_DECL_NOTHROW
{ return s2 == s1; }
-inline bool operator!=(const QStringRef &s1,const QString &s2)
+inline bool operator!=(const QStringRef &s1, const QString &s2) Q_DECL_NOTHROW
{ return s2 != s1; }
-Q_CORE_EXPORT bool operator==(QLatin1String s1, const QStringRef &s2);
-inline bool operator!=(QLatin1String s1, const QStringRef &s2)
+Q_CORE_EXPORT bool operator==(QLatin1String s1, const QStringRef &s2) Q_DECL_NOTHROW;
+inline bool operator!=(QLatin1String s1, const QStringRef &s2) Q_DECL_NOTHROW
{ return !(s1 == s2); }
-inline bool operator==(const QStringRef &s1, QLatin1String s2)
+inline bool operator==(const QStringRef &s1, QLatin1String s2) Q_DECL_NOTHROW
{ return s2 == s1; }
-inline bool operator!=(const QStringRef &s1, QLatin1String s2)
+inline bool operator!=(const QStringRef &s1, QLatin1String s2) Q_DECL_NOTHROW
{ return s2 != s1; }
-Q_CORE_EXPORT bool operator<(const QStringRef &s1,const QStringRef &s2);
-inline bool operator>(const QStringRef &s1, const QStringRef &s2)
+Q_CORE_EXPORT bool operator<(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW;
+inline bool operator>(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW
{ return s2 < s1; }
-inline bool operator<=(const QStringRef &s1, const QStringRef &s2)
+inline bool operator<=(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW
{ return !(s1 > s2); }
-inline bool operator>=(const QStringRef &s1, const QStringRef &s2)
+inline bool operator>=(const QStringRef &s1, const QStringRef &s2) Q_DECL_NOTHROW
{ return !(s1 < s2); }
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
@@ -1555,21 +1558,21 @@ inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QStringRef &s2)
{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) >= 0; }
#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
-inline int QString::compare(const QStringRef &s, Qt::CaseSensitivity cs) const
+inline int QString::compare(const QStringRef &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW
{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
-inline int QString::compare(const QString &s1, const QStringRef &s2, Qt::CaseSensitivity cs)
+inline int QString::compare(const QString &s1, const QStringRef &s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
-inline int QStringRef::compare(const QString &s, Qt::CaseSensitivity cs) const
+inline int QStringRef::compare(const QString &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW
{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
-inline int QStringRef::compare(const QStringRef &s, Qt::CaseSensitivity cs) const
+inline int QStringRef::compare(const QStringRef &s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW
{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
-inline int QStringRef::compare(QLatin1String s, Qt::CaseSensitivity cs) const
+inline int QStringRef::compare(QLatin1String s, Qt::CaseSensitivity cs) const Q_DECL_NOTHROW
{ return QString::compare_helper(constData(), length(), s, cs); }
-inline int QStringRef::compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity cs)
+inline int QStringRef::compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
-inline int QStringRef::compare(const QStringRef &s1, const QStringRef &s2, Qt::CaseSensitivity cs)
+inline int QStringRef::compare(const QStringRef &s1, const QStringRef &s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
-inline int QStringRef::compare(const QStringRef &s1, QLatin1String s2, Qt::CaseSensitivity cs)
+inline int QStringRef::compare(const QStringRef &s1, QLatin1String s2, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
{ return QString::compare_helper(s1.constData(), s1.length(), s2, cs); }
inline int QString::localeAwareCompare(const QStringRef &s) const
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index 333a5c3471..5900923084 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -765,10 +765,10 @@ QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime,
{
OffsetDataList list;
if (hasTransitions()) {
- QTimeZonePrivate::DataList plist = d->transitions(fromDateTime.toMSecsSinceEpoch(),
- toDateTime.toMSecsSinceEpoch());
+ const QTimeZonePrivate::DataList plist = d->transitions(fromDateTime.toMSecsSinceEpoch(),
+ toDateTime.toMSecsSinceEpoch());
list.reserve(plist.count());
- foreach (const QTimeZonePrivate::Data &pdata, plist)
+ for (const QTimeZonePrivate::Data &pdata : plist)
list.append(d->toOffsetData(pdata));
}
return list;
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 85ed345869..3e71dc0fca 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -255,7 +255,7 @@ static QMap<int, QByteArray> parseTzAbbreviations(QDataStream &ds, int tzh_charc
return map;
}
// Then extract all the substrings pointed to by types
- foreach (const QTzType &type, types) {
+ for (const QTzType &type : types) {
QByteArray abbrev;
for (int i = type.tz_abbrind; input.at(i) != '\0'; ++i)
abbrev.append(input.at(i));
@@ -629,7 +629,7 @@ void QTzTimeZonePrivate::init(const QByteArray &ianaId)
// Offsets are stored as total offset, want to know separate UTC and DST offsets
// so find the first non-dst transition to use as base UTC Offset
int utcOffset = 0;
- foreach (const QTzTransition &tran, tranList) {
+ for (const QTzTransition &tran : qAsConst(tranList)) {
if (!typeList.at(tran.tz_typeind).tz_isdst) {
utcOffset = typeList.at(tran.tz_typeind).tz_gmtoff;
break;
@@ -638,7 +638,7 @@ void QTzTimeZonePrivate::init(const QByteArray &ianaId)
// Now for each transition time calculate our rule and save them
m_tranTimes.reserve(tranList.count());
- foreach (const QTzTransition &tz_tran, tranList) {
+ for (const QTzTransition &tz_tran : qAsConst(tranList)) {
QTzTransitionTime tran;
QTzTransitionRule rule;
const QTzType tz_type = typeList.at(tz_tran.tz_typeind);
@@ -790,7 +790,7 @@ int QTzTimeZonePrivate::daylightTimeOffset(qint64 atMSecsSinceEpoch) const
bool QTzTimeZonePrivate::hasDaylightTime() const
{
// TODO Perhaps cache as frequently accessed?
- foreach (const QTzTransitionRule &rule, m_tranRules) {
+ for (const QTzTransitionRule &rule : m_tranRules) {
if (rule.dstOffset != 0)
return true;
}
@@ -983,9 +983,9 @@ QList<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds(QLocale::Country coun
{
// TODO AnyCountry
QList<QByteArray> result;
- foreach (const QByteArray &key, tzZones->keys()) {
- if (tzZones->value(key).country == country)
- result << key;
+ for (auto it = tzZones->cbegin(), end = tzZones->cend(); it != end; ++it) {
+ if (it.value().country == country)
+ result << it.key();
}
std::sort(result.begin(), result.end());
return result;
diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp
index a9bb3aa3b5..b5d45549ef 100644
--- a/src/corelib/tools/qtimezoneprivate_win.cpp
+++ b/src/corelib/tools/qtimezoneprivate_win.cpp
@@ -237,7 +237,8 @@ static QByteArray windowsSystemZoneId()
TIME_ZONE_INFORMATION sysTzi;
GetTimeZoneInformation(&sysTzi);
bool ok = false;
- foreach (const QByteArray &winId, availableWindowsIds()) {
+ const auto winIds = availableWindowsIds();
+ for (const QByteArray &winId : winIds) {
if (equalTzi(getRegistryTzi(winId, &ok), sysTzi))
return winId;
}
@@ -506,7 +507,7 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
bool QWinTimeZonePrivate::hasTransitions() const
{
- foreach (const QWinTransitionRule &rule, m_tranRules) {
+ for (const QWinTransitionRule &rule : m_tranRules) {
if (rule.standardTimeRule.wMonth > 0 && rule.daylightTimeRule.wMonth > 0)
return true;
}
@@ -637,10 +638,9 @@ QByteArray QWinTimeZonePrivate::systemTimeZoneId() const
QList<QByteArray> QWinTimeZonePrivate::availableTimeZoneIds() const
{
QList<QByteArray> result;
- foreach (const QByteArray &winId, availableWindowsIds()) {
- foreach (const QByteArray &ianaId, windowsIdToIanaIds(winId))
- result << ianaId;
- }
+ const auto winIds = availableWindowsIds();
+ for (const QByteArray &winId : winIds)
+ result += windowsIdToIanaIds(winId);
std::sort(result.begin(), result.end());
result.erase(std::unique(result.begin(), result.end()), result.end());
return result;
diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber.h
index ebf1844f38..6a2718ca28 100644
--- a/src/corelib/tools/qversionnumber.h
+++ b/src/corelib/tools/qversionnumber.h
@@ -273,7 +273,7 @@ public:
Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2) Q_REQUIRED_RESULT;
Q_CORE_EXPORT QString toString() const Q_REQUIRED_RESULT;
- Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = 0) Q_REQUIRED_RESULT;
+ Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = Q_NULLPTR) Q_REQUIRED_RESULT;
private:
#ifndef QT_NO_DATASTREAM
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index ed07f70e87..5cfeff5a4f 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -24,6 +24,7 @@ HEADERS += \
tools/qdatetime.h \
tools/qdatetime_p.h \
tools/qdatetimeparser_p.h \
+ tools/qdoublescanprint_p.h \
tools/qeasingcurve.h \
tools/qfreelist_p.h \
tools/qhash.h \
@@ -136,10 +137,6 @@ false: SOURCES += $$NO_PCH_SOURCES # Hack for QtCreator
tools/qbytearray_mac.mm \
tools/qdatetime_mac.mm
}
-else:blackberry {
- SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_blackberry.cpp tools/qtimezoneprivate_tz.cpp
- HEADERS += tools/qlocale_blackberry.h
-}
else:android {
SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_android.cpp
}
@@ -198,6 +195,14 @@ INCLUDEPATH += ../3rdparty/md5 \
../3rdparty/md4 \
../3rdparty/sha3
+contains(QT_CONFIG, doubleconversion) {
+ include($$PWD/../../3rdparty/double-conversion/double-conversion.pri)
+} else:contains(QT_CONFIG, system-doubleconversion) {
+ LIBS_PRIVATE += -ldouble-conversion
+} else {
+ DEFINES += QT_NO_DOUBLECONVERSION
+}
+
# Note: libm should be present by default becaue this is C++
!macx-icc:!vxworks:!haiku:unix:LIBS_PRIVATE += -lm
diff --git a/src/corelib/xml/qxmlstream.h b/src/corelib/xml/qxmlstream.h
index 34f26cb953..5b5a2e552e 100644
--- a/src/corelib/xml/qxmlstream.h
+++ b/src/corelib/xml/qxmlstream.h
@@ -52,7 +52,10 @@ public:
inline QXmlStreamStringRef():m_position(0), m_size(0){}
inline QXmlStreamStringRef(const QStringRef &aString)
:m_string(aString.string()?*aString.string():QString()), m_position(aString.position()), m_size(aString.size()){}
- inline QXmlStreamStringRef(const QString &aString):m_string(aString), m_position(0), m_size(aString.size()){}
+ QXmlStreamStringRef(const QString &aString) : m_string(aString), m_position(0), m_size(m_string.size()) {}
+#ifdef Q_COMPILER_RVALUE_REFS
+ QXmlStreamStringRef(QString &&aString) Q_DECL_NOTHROW : m_string(std::move(aString)), m_position(0), m_size(m_string.size()) {}
+#endif
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
QXmlStreamStringRef(const QXmlStreamStringRef &other) // = default
diff --git a/src/dbus/qdbus_symbols.cpp b/src/dbus/qdbus_symbols.cpp
index 395a436869..3f5df41582 100644
--- a/src/dbus/qdbus_symbols.cpp
+++ b/src/dbus/qdbus_symbols.cpp
@@ -130,11 +130,11 @@ void (*qdbus_resolve_conditionally(const char *name))()
void (*qdbus_resolve_me(const char *name))()
{
#ifndef QT_NO_LIBRARY
- if (!qdbus_loadLibDBus())
+ if (Q_UNLIKELY(!qdbus_loadLibDBus()))
qFatal("Cannot find libdbus-1 in your system to resolve symbol '%s'.", name);
QFunctionPointer ptr = qdbus_libdbus->resolve(name);
- if (!ptr)
+ if (Q_UNLIKELY(!ptr))
qFatal("Cannot resolve '%s' in your libdbus-1.", name);
return ptr;
diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp
index d63a317612..3f60721a52 100644
--- a/src/dbus/qdbusabstractinterface.cpp
+++ b/src/dbus/qdbusabstractinterface.cpp
@@ -364,7 +364,7 @@ bool QDBusAbstractInterface::isValid() const
}
/*!
- Returns the connection this interface is assocated with.
+ Returns the connection this interface is associated with.
*/
QDBusConnection QDBusAbstractInterface::connection() const
{
diff --git a/src/dbus/qdbusargument.h b/src/dbus/qdbusargument.h
index a6bc396861..6305239bdf 100644
--- a/src/dbus/qdbusargument.h
+++ b/src/dbus/qdbusargument.h
@@ -255,35 +255,6 @@ inline const QDBusArgument &operator>>(const QDBusArgument &arg, Container<T> &l
return arg;
}
-// QList specializations
-template<typename T>
-inline QDBusArgument &operator<<(QDBusArgument &arg, const QList<T> &list)
-{
- int id = qMetaTypeId<T>();
- arg.beginArray(id);
- typename QList<T>::ConstIterator it = list.constBegin();
- typename QList<T>::ConstIterator end = list.constEnd();
- for ( ; it != end; ++it)
- arg << *it;
- arg.endArray();
- return arg;
-}
-
-template<typename T>
-inline const QDBusArgument &operator>>(const QDBusArgument &arg, QList<T> &list)
-{
- arg.beginArray();
- list.clear();
- while (!arg.atEnd()) {
- T item;
- arg >> item;
- list.push_back(item);
- }
- arg.endArray();
-
- return arg;
-}
-
inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantList &list)
{
int id = qMetaTypeId<QDBusVariant>();
@@ -296,7 +267,6 @@ inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantList &list)
return arg;
}
-// QMap specializations
template<typename Key, typename T>
inline QDBusArgument &operator<<(QDBusArgument &arg, const QMap<Key, T> &map)
{
@@ -345,7 +315,6 @@ inline QDBusArgument &operator<<(QDBusArgument &arg, const QVariantMap &map)
return arg;
}
-// QHash specializations
template<typename Key, typename T>
inline QDBusArgument &operator<<(QDBusArgument &arg, const QHash<Key, T> &map)
{
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 0f2d799b92..3736fd56ad 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -1214,8 +1214,8 @@ void QDBusConnectionPrivate::createBusService()
ref.deref(); // busService has increased the refcounting to us
// avoid cyclic refcounting
- QObject::connect(this, SIGNAL(callWithCallbackFailed(QDBusError,QDBusMessage)),
- busService, SIGNAL(callWithCallbackFailed(QDBusError,QDBusMessage)),
+ QObject::connect(this, &QDBusConnectionPrivate::callWithCallbackFailed,
+ busService, emit &QDBusConnectionInterface::callWithCallbackFailed,
Qt::QueuedConnection);
}
diff --git a/src/dbus/qdbusconnectioninterface.cpp b/src/dbus/qdbusconnectioninterface.cpp
index ff923ba282..9dc0b3f9bd 100644
--- a/src/dbus/qdbusconnectioninterface.cpp
+++ b/src/dbus/qdbusconnectioninterface.cpp
@@ -158,10 +158,10 @@ QDBusConnectionInterface::QDBusConnectionInterface(const QDBusConnection &connec
QDBusUtil::dbusPath(),
DBUS_INTERFACE_DBUS, connection, parent)
{
- connect(this, SIGNAL(NameAcquired(QString)), this, SIGNAL(serviceRegistered(QString)));
- connect(this, SIGNAL(NameLost(QString)), this, SIGNAL(serviceUnregistered(QString)));
- connect(this, SIGNAL(NameOwnerChanged(QString,QString,QString)),
- this, SIGNAL(serviceOwnerChanged(QString,QString,QString)));
+ connect(this, &QDBusConnectionInterface::NameAcquired, this, emit &QDBusConnectionInterface::serviceRegistered);
+ connect(this, &QDBusConnectionInterface::NameLost, this, emit &QDBusConnectionInterface::serviceUnregistered);
+ connect(this, &QDBusConnectionInterface::NameOwnerChanged,
+ this, emit &QDBusConnectionInterface::serviceOwnerChanged);
}
/*!
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index f6221d51b6..c4e506ff0e 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -208,14 +208,14 @@ static dbus_bool_t qDBusAddWatch(DBusWatch *watch, void *data)
watcher.watch = watch;
watcher.read = new QSocketNotifier(fd, QSocketNotifier::Read, d);
watcher.read->setEnabled(q_dbus_watch_get_enabled(watch));
- d->connect(watcher.read, SIGNAL(activated(int)), SLOT(socketRead(int)));
+ d->connect(watcher.read, &QSocketNotifier::activated, d, &QDBusConnectionPrivate::socketRead);
}
if (flags & DBUS_WATCH_WRITABLE) {
//qDebug("addWriteWatch %d", fd);
watcher.watch = watch;
watcher.write = new QSocketNotifier(fd, QSocketNotifier::Write, d);
watcher.write->setEnabled(q_dbus_watch_get_enabled(watch));
- d->connect(watcher.write, SIGNAL(activated(int)), SLOT(socketWrite(int)));
+ d->connect(watcher.write, &QSocketNotifier::activated, d, &QDBusConnectionPrivate::socketWrite);
}
d->watchers.insertMulti(fd, watcher);
@@ -522,15 +522,14 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
static void huntAndDestroy(QObject *needle, QDBusConnectionPrivate::ObjectTreeNode &haystack)
{
- QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = haystack.children.begin();
+ for (auto &node : haystack.children)
+ huntAndDestroy(needle, node);
- while (it != haystack.children.end()) {
- huntAndDestroy(needle, *it);
- if (!it->isActive())
- it = haystack.children.erase(it);
- else
- it++;
- }
+ auto isInactive = [](QDBusConnectionPrivate::ObjectTreeNode &node) { return !node.isActive(); };
+
+ haystack.children.erase(std::remove_if(haystack.children.begin(), haystack.children.end(),
+ isInactive),
+ haystack.children.end());
if (needle == haystack.obj) {
haystack.obj = 0;
@@ -887,7 +886,7 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q
*reinterpret_cast<const QDBusArgument *>(arg.constData());
QVariant &out = auxParameters[auxParameters.count() - 1];
- if (!QDBusMetaType::demarshall(in, out.userType(), out.data()))
+ if (Q_UNLIKELY(!QDBusMetaType::demarshall(in, out.userType(), out.data())))
qFatal("Internal error: demarshalling function for type '%s' (%d) failed!",
out.typeName(), out.userType());
@@ -1921,8 +1920,8 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,
if (sendMode == QDBus::BlockWithGui) {
pcall->watcherHelper = new QDBusPendingCallWatcherHelper;
QEventLoop loop;
- loop.connect(pcall->watcherHelper, SIGNAL(reply(QDBusMessage)), SLOT(quit()));
- loop.connect(pcall->watcherHelper, SIGNAL(error(QDBusError,QDBusMessage)), SLOT(quit()));
+ loop.connect(pcall->watcherHelper, &QDBusPendingCallWatcherHelper::reply, &loop, &QEventLoop::quit);
+ loop.connect(pcall->watcherHelper, &QDBusPendingCallWatcherHelper::error, &loop, &QEventLoop::quit);
// enter the event loop and wait for a reply
loop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents);
@@ -2107,7 +2106,7 @@ void QDBusConnectionPrivate::addSignalHook(const QString &key, const SignalHook
}
signalHooks.insertMulti(key, hook);
- connect(hook.obj, SIGNAL(destroyed(QObject*)), SLOT(objectDestroyed(QObject*)),
+ connect(hook.obj, &QObject::destroyed, this, &QDBusConnectionPrivate::objectDestroyed,
Qt::ConnectionType(Qt::BlockingQueuedConnection | Qt::UniqueConnection));
MatchRefCountHash::iterator mit = matchRefCounts.find(hook.matchRule);
@@ -2233,7 +2232,7 @@ QDBusConnectionPrivate::removeSignalHookNoLock(SignalHookHash::Iterator it)
void QDBusConnectionPrivate::registerObject(const ObjectTreeNode *node)
{
- connect(node->obj, SIGNAL(destroyed(QObject*)), SLOT(objectDestroyed(QObject*)),
+ connect(node->obj, &QObject::destroyed, this, &QDBusConnectionPrivate::objectDestroyed,
Qt::ConnectionType(Qt::BlockingQueuedConnection | Qt::UniqueConnection));
if (node->flags & (QDBusConnection::ExportAdaptors
diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp
index c93d6acf84..c20b56f973 100644
--- a/src/dbus/qdbuspendingcall.cpp
+++ b/src/dbus/qdbuspendingcall.cpp
@@ -190,7 +190,7 @@ void QDBusPendingCallPrivate::setMetaTypes(int count, const int *types)
sig.reserve(count + count / 2);
for (int i = 0; i < count; ++i) {
const char *typeSig = QDBusMetaType::typeToSignature(types[i]);
- if (!typeSig) {
+ if (Q_UNLIKELY(!typeSig)) {
qFatal("QDBusPendingReply: type %s is not registered with QtDBus",
QMetaType::typeName(types[i]));
}
diff --git a/src/gui/accessible/accessible.pri b/src/gui/accessible/accessible.pri
index 86ed4c3a71..b7f341d5b7 100644
--- a/src/gui/accessible/accessible.pri
+++ b/src/gui/accessible/accessible.pri
@@ -17,5 +17,9 @@ contains(QT_CONFIG, accessibility) {
HEADERS += accessible/qaccessiblebridge.h
SOURCES += accessible/qaccessiblebridge.cpp
- OBJECTIVE_SOURCES += accessible/qaccessiblecache_mac.mm
+ mac {
+ OBJECTIVE_SOURCES += accessible/qaccessiblecache_mac.mm
+
+ LIBS_PRIVATE += -framework Foundation
+ }
}
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index aa05d72a3d..55837bcf3b 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -33,7 +33,7 @@ testcocoon {
load(testcocoon)
}
-mac:!ios: LIBS_PRIVATE += -framework Cocoa
+osx: LIBS_PRIVATE += -framework AppKit
CONFIG += simd optimize_full
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index d9e1347e4b..ca77b73033 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -920,7 +920,7 @@ void QIcon::paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment,
*/
bool QIcon::isNull() const
{
- return !d;
+ return !d || d->engine->isNull();
}
/*!\internal
@@ -935,7 +935,12 @@ bool QIcon::isDetached() const
void QIcon::detach()
{
if (d) {
- if (d->ref.load() != 1) {
+ if (d->engine->isNull()) {
+ if (!d->ref.deref())
+ delete d;
+ d = 0;
+ return;
+ } else if (d->ref.load() != 1) {
QIconPrivate *x = new QIconPrivate;
x->engine = d->engine->clone();
if (!d->ref.deref())
@@ -959,11 +964,10 @@ void QIcon::addPixmap(const QPixmap &pixmap, Mode mode, State state)
{
if (pixmap.isNull())
return;
+ detach();
if (!d) {
d = new QIconPrivate;
d->engine = new QPixmapIconEngine;
- } else {
- detach();
}
d->engine->addPixmap(pixmap, mode, state);
}
@@ -1003,6 +1007,7 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State
{
if (fileName.isEmpty())
return;
+ detach();
if (!d) {
#ifndef QT_NO_LIBRARY
QFileInfo info(fileName);
@@ -1025,8 +1030,6 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State
d = new QIconPrivate;
d->engine = new QPixmapIconEngine;
}
- } else {
- detach();
}
d->engine->addFile(fileName, size, mode, state);
@@ -1136,8 +1139,7 @@ QString QIcon::themeName()
\since 4.6
Returns the QIcon corresponding to \a name in the current
- icon theme. If no such icon is found in the current theme
- \a fallback is returned instead.
+ icon theme.
The latest version of the freedesktop icon specification and naming
specification can be obtained here:
@@ -1151,19 +1153,18 @@ QString QIcon::themeName()
\snippet code/src_gui_image_qicon.cpp 3
- Or if you want to provide a guaranteed fallback for platforms that
- do not support theme icons, you can use the second argument:
-
- \snippet code/src_gui_image_qicon.cpp 4
-
\note By default, only X11 will support themed icons. In order to
use themed icons on Mac and Windows, you will have to bundle a
compliant theme in one of your themeSearchPaths() and set the
appropriate themeName().
+ \note Qt will make use of GTK's icon-theme.cache if present to speed up
+ the lookup. These caches can be generated using gtk-update-icon-cache:
+ \l{https://developer.gnome.org/gtk3/stable/gtk-update-icon-cache.html}.
+
\sa themeName(), setThemeName(), themeSearchPaths()
*/
-QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
+QIcon QIcon::fromTheme(const QString &name)
{
QIcon icon;
@@ -1179,7 +1180,26 @@ QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
qtIconCache()->insert(name, cachedIcon);
}
- if (qApp && icon.availableSizes().isEmpty())
+ return icon;
+}
+
+/*!
+ \overload
+
+ Returns the QIcon corresponding to \a name in the current
+ icon theme. If no such icon is found in the current theme
+ \a fallback is returned instead.
+
+ If you want to provide a guaranteed fallback for platforms that
+ do not support theme icons, you can use the second argument:
+
+ \snippet code/src_gui_image_qicon.cpp 4
+*/
+QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback)
+{
+ QIcon icon = fromTheme(name);
+
+ if (icon.isNull() || icon.availableSizes().isEmpty())
return fallback;
return icon;
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 9ed7336502..989e40bbb5 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -105,7 +105,8 @@ public:
void setIsMask(bool isMask);
bool isMask() const;
- static QIcon fromTheme(const QString &name, const QIcon &fallback = QIcon());
+ static QIcon fromTheme(const QString &name);
+ static QIcon fromTheme(const QString &name, const QIcon &fallback);
static bool hasThemeIcon(const QString &name);
static QStringList themeSearchPaths();
diff --git a/src/gui/image/qiconengine.cpp b/src/gui/image/qiconengine.cpp
index c09933d45f..7411dbb054 100644
--- a/src/gui/image/qiconengine.cpp
+++ b/src/gui/image/qiconengine.cpp
@@ -150,6 +150,11 @@ void QIconEngine::addFile(const QString &/*fileName*/, const QSize &/*size*/, QI
icon, for example when instantiating an icon using
QIcon::fromTheme().
+ \value IsNullHook Allow to query if this engine represents a null
+ icon. The \a data argument of the virtual_hook() is a pointer to a
+ bool that can be set to true if the icon is null. This enum value
+ was added in Qt 5.7.
+
\sa virtual_hook()
*/
@@ -283,4 +288,16 @@ QString QIconEngine::iconName() const
return name;
}
+/*!
+ \since 5.7
+
+ Returns true if this icon engine represent a null QIcon.
+ */
+bool QIconEngine::isNull() const
+{
+ bool isNull = false;
+ const_cast<QIconEngine *>(this)->virtual_hook(QIconEngine::IsNullHook, &isNull);
+ return isNull;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/image/qiconengine.h b/src/gui/image/qiconengine.h
index 9977113054..6c45cd216f 100644
--- a/src/gui/image/qiconengine.h
+++ b/src/gui/image/qiconengine.h
@@ -58,7 +58,7 @@ public:
virtual bool read(QDataStream &in);
virtual bool write(QDataStream &out) const;
- enum IconEngineHook { AvailableSizesHook = 1, IconNameHook };
+ enum IconEngineHook { AvailableSizesHook = 1, IconNameHook, IsNullHook };
struct AvailableSizesArgument
{
@@ -71,6 +71,7 @@ public:
QIcon::State state = QIcon::Off) const;
virtual QString iconName() const;
+ bool isNull() const; // ### Qt6 make virtual
virtual void virtual_hook(int id, void *data);
};
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 3ead72dfbb..ecce7f9967 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -155,6 +155,141 @@ QStringList QIconLoader::themeSearchPaths() const
return m_iconDirs;
}
+/*!
+ \class QIconCacheGtkReader
+ \internal
+ Helper class that reads and looks up into the icon-theme.cache generated with
+ gtk-update-icon-cache. If at any point we detect a corruption in the file
+ (because the offsets point at wrong locations for example), the reader
+ is marked as invalid.
+*/
+class QIconCacheGtkReader
+{
+public:
+ explicit QIconCacheGtkReader(const QString &themeDir);
+ QVector<const char *> lookup(const QString &);
+ bool isValid() const { return m_isValid; }
+private:
+ QFile m_file;
+ const unsigned char *m_data;
+ quint64 m_size;
+ bool m_isValid;
+
+ quint16 read16(uint offset)
+ {
+ if (offset > m_size - 2 || (offset & 0x1)) {
+ m_isValid = false;
+ return 0;
+ }
+ return m_data[offset+1] | m_data[offset] << 8;
+ }
+ quint32 read32(uint offset)
+ {
+ if (offset > m_size - 4 || (offset & 0x3)) {
+ m_isValid = false;
+ return 0;
+ }
+ return m_data[offset+3] | m_data[offset+2] << 8
+ | m_data[offset+1] << 16 | m_data[offset] << 24;
+ }
+};
+
+
+QIconCacheGtkReader::QIconCacheGtkReader(const QString &dirName)
+ : m_isValid(false)
+{
+ QFileInfo info(dirName + QLatin1Literal("/icon-theme.cache"));
+ if (!info.exists() || info.lastModified() < QFileInfo(dirName).lastModified())
+ return;
+ m_file.setFileName(info.absoluteFilePath());
+ if (!m_file.open(QFile::ReadOnly))
+ return;
+ m_size = m_file.size();
+ m_data = m_file.map(0, m_size);
+ if (!m_data)
+ return;
+ if (read16(0) != 1) // VERSION_MAJOR
+ return;
+
+ m_isValid = true;
+
+ // Check that all the directories are older than the cache
+ auto lastModified = info.lastModified();
+ quint32 dirListOffset = read32(8);
+ quint32 dirListLen = read32(dirListOffset);
+ for (uint i = 0; i < dirListLen; ++i) {
+ quint32 offset = read32(dirListOffset + 4 + 4 * i);
+ if (!m_isValid || offset >= m_size || lastModified < QFileInfo(dirName + QLatin1Char('/')
+ + QString::fromUtf8(reinterpret_cast<const char*>(m_data + offset))).lastModified()) {
+ m_isValid = false;
+ return;
+ }
+ }
+}
+
+static quint32 icon_name_hash(const char *p)
+{
+ quint32 h = static_cast<signed char>(*p);
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + *p;
+ return h;
+}
+
+/*! \internal
+ lookup the icon name and return the list of subdirectories in which an icon
+ with this name is present. The char* are pointers to the mapped data.
+ For example, this would return { "32x32/apps", "24x24/apps" , ... }
+ */
+QVector<const char *> QIconCacheGtkReader::lookup(const QString &name)
+{
+ QVector<const char *> ret;
+ if (!isValid())
+ return ret;
+
+ QByteArray nameUtf8 = name.toUtf8();
+ quint32 hash = icon_name_hash(nameUtf8);
+
+ quint32 hashOffset = read32(4);
+ quint32 hashBucketCount = read32(hashOffset);
+
+ if (!isValid() || hashBucketCount == 0) {
+ m_isValid = false;
+ return ret;
+ }
+
+ quint32 bucketIndex = hash % hashBucketCount;
+ quint32 bucketOffset = read32(hashOffset + 4 + bucketIndex * 4);
+ while (bucketOffset > 0 && bucketOffset <= m_size - 12) {
+ quint32 nameOff = read32(bucketOffset + 4);
+ if (nameOff < m_size && strcmp(reinterpret_cast<const char*>(m_data + nameOff), nameUtf8) == 0) {
+ quint32 dirListOffset = read32(8);
+ quint32 dirListLen = read32(dirListOffset);
+
+ quint32 listOffset = read32(bucketOffset+8);
+ quint32 listLen = read32(listOffset);
+
+ if (!m_isValid || listOffset + 4 + 8 * listLen > m_size) {
+ m_isValid = false;
+ return ret;
+ }
+
+ ret.reserve(listLen);
+ for (uint j = 0; j < listLen && m_isValid; ++j) {
+ quint32 dirIndex = read16(listOffset + 4 + 8 * j);
+ quint32 o = read32(dirListOffset + 4 + dirIndex*4);
+ if (!m_isValid || dirIndex >= dirListLen || o >= m_size) {
+ m_isValid = false;
+ return ret;
+ }
+ ret.append(reinterpret_cast<const char*>(m_data) + o);
+ }
+ return ret;
+ }
+ bucketOffset = read32(bucketOffset);
+ }
+ return ret;
+}
+
QIconTheme::QIconTheme(const QString &themeName)
: m_valid(false)
{
@@ -166,8 +301,10 @@ QIconTheme::QIconTheme(const QString &themeName)
QString themeDir = iconDir.path() + QLatin1Char('/') + themeName;
QFileInfo themeDirInfo(themeDir);
- if (themeDirInfo.isDir())
+ if (themeDirInfo.isDir()) {
m_contentDirs << themeDir;
+ m_gtkCaches << QSharedPointer<QIconCacheGtkReader>::create(themeDir);
+ }
if (!m_valid) {
themeIndex.setFileName(themeDir + QLatin1String("/index.theme"));
@@ -257,7 +394,6 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName,
}
const QStringList contentDirs = theme.contentDirs();
- const QVector<QIconDirInfo> subDirs = theme.keyList();
QString iconNameFallback = iconName;
@@ -268,6 +404,29 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName,
// Add all relevant files
for (int i = 0; i < contentDirs.size(); ++i) {
+ QVector<QIconDirInfo> subDirs = theme.keyList();
+
+ // Try to reduce the amount of subDirs by looking in the GTK+ cache in order to save
+ // a massive amount of file stat (especially if the icon is not there)
+ auto cache = theme.m_gtkCaches.at(i);
+ if (cache->isValid()) {
+ auto result = cache->lookup(iconNameFallback);
+ if (cache->isValid()) {
+ const QVector<QIconDirInfo> subDirsCopy = subDirs;
+ subDirs.clear();
+ subDirs.reserve(result.count());
+ foreach (const char *s, result) {
+ QString path = QString::fromUtf8(s);
+ auto it = std::find_if(subDirsCopy.cbegin(), subDirsCopy.cend(),
+ [&](const QIconDirInfo &info) {
+ return info.path == path; } );
+ if (it != subDirsCopy.cend()) {
+ subDirs.append(*it);
+ }
+ }
+ }
+ }
+
QString contentDir = contentDirs.at(i) + QLatin1Char('/');
for (int j = 0; j < subDirs.size() ; ++j) {
const QIconDirInfo &dirInfo = subDirs.at(j);
@@ -587,6 +746,11 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
name = m_info.iconName;
}
break;
+ case QIconEngine::IsNullHook:
+ {
+ *reinterpret_cast<bool*>(data) = m_info.entries.isEmpty();
+ }
+ break;
default:
QIconEngine::virtual_hook(id, data);
}
diff --git a/src/gui/image/qiconloader_p.h b/src/gui/image/qiconloader_p.h
index ccf0a9d438..193154e44e 100644
--- a/src/gui/image/qiconloader_p.h
+++ b/src/gui/image/qiconloader_p.h
@@ -139,6 +139,8 @@ private:
friend class QIconLoader;
};
+class QIconCacheGtkReader;
+
class QIconTheme
{
public:
@@ -148,12 +150,13 @@ public:
QVector<QIconDirInfo> keyList() { return m_keyList; }
QStringList contentDirs() { return m_contentDirs; }
bool isValid() { return m_valid; }
-
private:
QStringList m_contentDirs;
QVector<QIconDirInfo> m_keyList;
QStringList m_parents;
bool m_valid;
+public:
+ QVector<QSharedPointer<QIconCacheGtkReader>> m_gtkCaches;
};
class Q_GUI_EXPORT QIconLoader
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 888c7beb32..9d8e3efcc4 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -168,9 +168,9 @@ public:
Format format() const;
#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QIMAGE_COMPAT_CPP)
- QImage convertToFormat(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor) const & Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QImage convertToFormat(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor) const & Q_REQUIRED_RESULT
{ return convertToFormat_helper(f, flags); }
- QImage convertToFormat(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor) && Q_REQUIRED_RESULT
+ Q_ALWAYS_INLINE QImage convertToFormat(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor) && Q_REQUIRED_RESULT
{
if (convertToFormat_inplace(f, flags))
return std::move(*this);
diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp
index 09cd788c61..ba27fb355b 100644
--- a/src/gui/image/qmovie.cpp
+++ b/src/gui/image/qmovie.cpp
@@ -965,14 +965,16 @@ void QMovie::setScaledSize(const QSize &size)
QList<QByteArray> QMovie::supportedFormats()
{
QList<QByteArray> list = QImageReader::supportedImageFormats();
- QMutableListIterator<QByteArray> it(list);
+
QBuffer buffer;
buffer.open(QIODevice::ReadOnly);
- while (it.hasNext()) {
- QImageReader reader(&buffer, it.next());
- if (!reader.supportsAnimation())
- it.remove();
- }
+
+ const auto doesntSupportAnimation =
+ [&buffer](const QByteArray &format) {
+ return !QImageReader(&buffer, format).supportsAnimation();
+ };
+
+ list.erase(std::remove_if(list.begin(), list.end(), doesntSupportAnimation), list.end());
return list;
}
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index fb62889e40..9c42cd44a6 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE
static bool qt_pixmap_thread_test()
{
- if (!QCoreApplication::instance()) {
+ if (Q_UNLIKELY(!QCoreApplication::instance())) {
qFatal("QPixmap: Must construct a QGuiApplication before a QPixmap");
return false;
}
diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp
index d29ddcf978..6265a0c16d 100644
--- a/src/gui/image/qpixmapcache.cpp
+++ b/src/gui/image/qpixmapcache.cpp
@@ -156,6 +156,16 @@ bool QPixmapCache::Key::operator ==(const Key &key) const
*/
/*!
+ Returns \c true if there is a cached pixmap associated with this key.
+ Otherwise, if pixmap was flushed, the key is no longer valid.
+ \since 5.7
+*/
+bool QPixmapCache::Key::isValid() const Q_DECL_NOTHROW
+{
+ return d && d->isValid;
+}
+
+/*!
\internal
*/
QPixmapCache::Key &QPixmapCache::Key::operator =(const Key &other)
diff --git a/src/gui/image/qpixmapcache.h b/src/gui/image/qpixmapcache.h
index 37a0588e06..ca18f299a7 100644
--- a/src/gui/image/qpixmapcache.h
+++ b/src/gui/image/qpixmapcache.h
@@ -59,6 +59,7 @@ public:
Key &operator =(const Key &other);
void swap(Key &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+ bool isValid() const Q_DECL_NOTHROW;
private:
KeyData *d;
diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp
index 2736fac8e0..36527966b7 100644
--- a/src/gui/kernel/qdrag.cpp
+++ b/src/gui/kernel/qdrag.cpp
@@ -33,6 +33,8 @@
#include <qdrag.h>
#include "private/qguiapplication_p.h"
+#include "qpa/qplatformintegration.h"
+#include "qpa/qplatformdrag.h"
#include <qpixmap.h>
#include <qpoint.h>
#include "qdnd_p.h"
@@ -223,6 +225,8 @@ QObject *QDrag::target() const
loop. Other events are still delivered to the application while
the operation is performed. On Windows, the Qt event loop is
blocked during the operation.
+
+ \sa cancel()
*/
Qt::DropAction QDrag::exec(Qt::DropActions supportedActions)
@@ -377,6 +381,21 @@ Qt::DropAction QDrag::defaultAction() const
Q_D(const QDrag);
return d->default_action;
}
+
+/*!
+ Cancels a drag operation initiated by Qt.
+
+ \note This is currently implemented on Windows and X11.
+
+ \since 5.6
+ \sa exec()
+*/
+void QDrag::cancel()
+{
+ if (QPlatformDrag *platformDrag = QGuiApplicationPrivate::platformIntegration()->drag())
+ platformDrag->cancelDrag();
+}
+
/*!
\fn void QDrag::actionChanged(Qt::DropAction action)
diff --git a/src/gui/kernel/qdrag.h b/src/gui/kernel/qdrag.h
index 0672cb00f9..961d7c89d9 100644
--- a/src/gui/kernel/qdrag.h
+++ b/src/gui/kernel/qdrag.h
@@ -77,6 +77,8 @@ public:
Qt::DropActions supportedActions() const;
Qt::DropAction defaultAction() const;
+ static void cancel();
+
Q_SIGNALS:
void actionChanged(Qt::DropAction action);
void targetChanged(QObject *newTarget);
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 2ca17692db..bd1b4d6393 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -37,6 +37,7 @@
#include "qpa/qplatformintegration.h"
#include "qpa/qplatformdrag.h"
#include "private/qevent_p.h"
+#include "qfile.h"
#include "qmetaobject.h"
#include "qmimedata.h"
#include "private/qdnd_p.h"
@@ -3963,9 +3964,11 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
QtDebugUtils::formatQEnum(dbg, static_cast<const QApplicationStateChangeEvent *>(e)->applicationState());
dbg << ')';
break;
+# ifndef QT_NO_CONTEXTMENU
case QEvent::ContextMenu:
dbg << "QContextMenuEvent(" << static_cast<const QContextMenuEvent *>(e)->pos() << ')';
break;
+# endif // !QT_NO_CONTEXTMENU
# ifndef QT_NO_TABLETEVENT
case QEvent::TabletEnterProximity:
case QEvent::TabletLeaveProximity:
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index b90fce97e0..cd65485397 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -35,20 +35,19 @@
#define QEVENT_H
#include <QtGui/qwindowdefs.h>
-#include <QtCore/qobject.h>
#include <QtGui/qregion.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qstring.h>
#include <QtGui/qkeysequence.h>
#include <QtCore/qcoreevent.h>
#include <QtCore/qvariant.h>
-#include <QtCore/qmap.h>
+#include <QtCore/qmap.h> // ### Qt 6: Remove
#include <QtCore/qvector.h>
-#include <QtCore/qset.h>
+#include <QtCore/qset.h> // ### Qt 6: Remove
#include <QtCore/qurl.h>
-#include <QtCore/qfile.h>
+#include <QtCore/qfile.h> // ### Qt 6: Replace by <qiodevice.h> and forward declare QFile
#include <QtGui/qvector2d.h>
-#include <QtGui/qtouchdevice.h>
+#include <QtGui/qtouchdevice.h> // ### Qt 6: Replace by forward declaration
QT_BEGIN_NAMESPACE
@@ -909,6 +908,9 @@ protected:
friend class QGuiApplicationPrivate;
friend class QApplication;
friend class QApplicationPrivate;
+#ifndef QT_NO_GRAPHICSVIEW
+ friend class QGraphicsScenePrivate; // direct access to _touchPoints
+#endif
};
Q_DECLARE_TYPEINFO(QTouchEvent::TouchPoint, Q_MOVABLE_TYPE);
Q_DECLARE_OPERATORS_FOR_FLAGS(QTouchEvent::TouchPoint::InfoFlags)
diff --git a/src/gui/kernel/qgenericplugin.cpp b/src/gui/kernel/qgenericplugin.cpp
index 47f3ea5811..ae423b93e3 100644
--- a/src/gui/kernel/qgenericplugin.cpp
+++ b/src/gui/kernel/qgenericplugin.cpp
@@ -33,8 +33,6 @@
#include "qgenericplugin.h"
-#ifndef QT_NO_LIBRARY
-
QT_BEGIN_NAMESPACE
/*!
@@ -90,5 +88,3 @@ QGenericPlugin::~QGenericPlugin()
*/
QT_END_NAMESPACE
-
-#endif // QT_NO_LIBRARY
diff --git a/src/gui/kernel/qgenericplugin.h b/src/gui/kernel/qgenericplugin.h
index 03c1df7fba..21ae97f045 100644
--- a/src/gui/kernel/qgenericplugin.h
+++ b/src/gui/kernel/qgenericplugin.h
@@ -39,9 +39,6 @@
QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_LIBRARY
-
#define QGenericPluginFactoryInterface_iid "org.qt-project.Qt.QGenericPluginFactoryInterface"
class Q_GUI_EXPORT QGenericPlugin : public QObject
@@ -54,8 +51,6 @@ public:
virtual QObject* create(const QString& name, const QString &spec) = 0;
};
-#endif // QT_NO_LIBRARY
-
QT_END_NAMESPACE
#endif // QGENERICPLUGIN_H
diff --git a/src/gui/kernel/qgenericpluginfactory.cpp b/src/gui/kernel/qgenericpluginfactory.cpp
index d7b9bfba06..15fa094f54 100644
--- a/src/gui/kernel/qgenericpluginfactory.cpp
+++ b/src/gui/kernel/qgenericpluginfactory.cpp
@@ -71,7 +71,7 @@ QObject *QGenericPluginFactory::create(const QString& key, const QString &specif
{
#if (!defined(Q_OS_WIN32) || defined(QT_SHARED)) && !defined(QT_NO_LIBRARY)
const QString driver = key.toLower();
- if (QObject *object = qLoadPlugin1<QObject, QGenericPlugin>(loader(), driver, specification))
+ if (QObject *object = qLoadPlugin<QObject, QGenericPlugin>(loader(), driver, specification))
return object;
#else // (!Q_OS_WIN32 || QT_SHARED) && !QT_NO_LIBRARY
Q_UNUSED(key)
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 770f847190..777ecbdb09 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -37,6 +37,7 @@
#include <qpa/qplatformintegrationfactory_p.h>
#include "private/qevent_p.h"
#include "qfont.h"
+#include "qtouchdevice.h"
#include <qpa/qplatformfontdatabase.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformnativeinterface.h>
@@ -123,8 +124,6 @@ Qt::KeyboardModifiers QGuiApplicationPrivate::modifier_buttons = Qt::NoModifier;
QPointF QGuiApplicationPrivate::lastCursorPosition(qInf(), qInf());
-Qt::MouseButtons QGuiApplicationPrivate::tabletState = Qt::NoButton;
-QWindow *QGuiApplicationPrivate::tabletPressTarget = 0;
QWindow *QGuiApplicationPrivate::currentMouseWindow = 0;
QString QGuiApplicationPrivate::styleOverride;
@@ -133,6 +132,8 @@ Qt::ApplicationState QGuiApplicationPrivate::applicationState = Qt::ApplicationI
bool QGuiApplicationPrivate::highDpiScalingUpdated = false;
+QVector<QGuiApplicationPrivate::TabletPointData> QGuiApplicationPrivate::tabletDevicePoints;
+
QPlatformIntegration *QGuiApplicationPrivate::platform_integration = 0;
QPlatformTheme *QGuiApplicationPrivate::platform_theme = 0;
@@ -150,6 +151,7 @@ QIcon *QGuiApplicationPrivate::app_icon = 0;
QString *QGuiApplicationPrivate::platform_name = 0;
QString *QGuiApplicationPrivate::displayName = 0;
+QString *QGuiApplicationPrivate::desktopFileName = 0;
QPalette *QGuiApplicationPrivate::app_pal = 0; // default application palette
@@ -607,6 +609,8 @@ QGuiApplication::~QGuiApplication()
QGuiApplicationPrivate::platform_name = 0;
delete QGuiApplicationPrivate::displayName;
QGuiApplicationPrivate::displayName = 0;
+ delete QGuiApplicationPrivate::desktopFileName;
+ QGuiApplicationPrivate::desktopFileName = 0;
}
QGuiApplicationPrivate::QGuiApplicationPrivate(int &argc, char **argv, int flags)
@@ -648,6 +652,34 @@ QString QGuiApplication::applicationDisplayName()
}
/*!
+ \property QGuiApplication::desktopFileName
+ \brief the base name of the desktop entry for this application
+ \since 5.7
+
+ This is the file name, without the full path, of the desktop entry
+ that represents this application according to the freedesktop desktop
+ entry specification.
+
+ This property gives a precise indication of what desktop entry represents
+ the application and it is needed by the windowing system to retrieve
+ such information without resorting to imprecise heuristics.
+
+ The latest version of the freedesktop desktop entry specification can be obtained
+ \l{http://standards.freedesktop.org/desktop-entry-spec/latest/}{here}.
+*/
+void QGuiApplication::setDesktopFileName(const QString &name)
+{
+ if (!QGuiApplicationPrivate::desktopFileName)
+ QGuiApplicationPrivate::desktopFileName = new QString;
+ *QGuiApplicationPrivate::desktopFileName = name;
+}
+
+QString QGuiApplication::desktopFileName()
+{
+ return QGuiApplicationPrivate::desktopFileName ? *QGuiApplicationPrivate::desktopFileName : QString();
+}
+
+/*!
Returns the most recently shown modal window. If no modal windows are
visible, this function returns zero.
@@ -1050,9 +1082,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform
// Create the platform integration.
QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath);
- if (QGuiApplicationPrivate::platform_integration) {
- QGuiApplicationPrivate::platform_name = new QString(name);
- } else {
+ if (Q_UNLIKELY(!QGuiApplicationPrivate::platform_integration)) {
QStringList keys = QPlatformIntegrationFactory::keys(platformPluginPath);
QString fatalMessage
@@ -1072,6 +1102,8 @@ static void init_platform(const QString &pluginArgument, const QString &platform
return;
}
+ QGuiApplicationPrivate::platform_name = new QString(name);
+
// Many platforms have created QScreens at this point. Finish initializing
// QHighDpiScaling to be prepared for early calls to qt_defaultDpi().
if (QGuiApplication::primaryScreen()) {
@@ -1391,16 +1423,16 @@ void QGuiApplicationPrivate::init()
if (loadTestability) {
QLibrary testLib(QStringLiteral("qttestability"));
- if (testLib.load()) {
+ if (Q_UNLIKELY(!testLib.load())) {
+ qCritical() << "Library qttestability load failed:" << testLib.errorString();
+ } else {
typedef void (*TasInitialize)(void);
TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
- if (initFunction) {
- initFunction();
- } else {
+ if (Q_UNLIKELY(!initFunction)) {
qCritical() << "Library qttestability resolve failed!";
+ } else {
+ initFunction();
}
- } else {
- qCritical() << "Library qttestability load failed:" << testLib.errorString();
}
}
#else
@@ -2180,12 +2212,26 @@ void QGuiApplicationPrivate::processFileOpenEvent(QWindowSystemInterfacePrivate:
QGuiApplication::sendSpontaneousEvent(qApp, &event);
}
+QGuiApplicationPrivate::TabletPointData &QGuiApplicationPrivate::tabletDevicePoint(qint64 deviceId)
+{
+ for (int i = 0; i < tabletDevicePoints.size(); ++i) {
+ TabletPointData &pointData = tabletDevicePoints[i];
+ if (pointData.deviceId == deviceId)
+ return pointData;
+ }
+
+ tabletDevicePoints.append(TabletPointData(deviceId));
+ return tabletDevicePoints.last();
+}
+
void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e)
{
#ifndef QT_NO_TABLETEVENT
+ TabletPointData &pointData = tabletDevicePoint(e->uid);
+
QEvent::Type type = QEvent::TabletMove;
- if (e->buttons != tabletState)
- type = (e->buttons > tabletState) ? QEvent::TabletPress : QEvent::TabletRelease;
+ if (e->buttons != pointData.state)
+ type = (e->buttons > pointData.state) ? QEvent::TabletPress : QEvent::TabletRelease;
QWindow *window = e->window.data();
modifier_buttons = e->modifiers;
@@ -2201,14 +2247,14 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
}
if (!window)
return;
- tabletPressTarget = window;
+ pointData.target = window;
} else {
if (e->nullWindow()) {
- window = tabletPressTarget;
+ window = pointData.target;
localValid = false;
}
if (type == QEvent::TabletRelease)
- tabletPressTarget = 0;
+ pointData.target = Q_NULLPTR;
if (!window)
return;
}
@@ -2217,7 +2263,7 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
QPointF delta = e->global - e->global.toPoint();
local = window->mapFromGlobal(e->global.toPoint()) + delta;
}
- Qt::MouseButtons stateChange = e->buttons ^ tabletState;
+ Qt::MouseButtons stateChange = e->buttons ^ pointData.state;
Qt::MouseButton button = Qt::NoButton;
for (int check = Qt::LeftButton; check <= int(Qt::MaxMouseButton); check = check << 1) {
if (check & stateChange) {
@@ -2231,7 +2277,7 @@ void QGuiApplicationPrivate::processTabletEvent(QWindowSystemInterfacePrivate::T
e->modifiers, e->uid, button, e->buttons);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(window, &ev);
- tabletState = e->buttons;
+ pointData.state = e->buttons;
#else
Q_UNUSED(e)
#endif
@@ -2243,7 +2289,7 @@ void QGuiApplicationPrivate::processTabletEnterProximityEvent(QWindowSystemInter
QTabletEvent ev(QEvent::TabletEnterProximity, QPointF(), QPointF(),
e->device, e->pointerType, 0, 0, 0,
0, 0, 0,
- Qt::NoModifier, e->uid, Qt::NoButton, tabletState);
+ Qt::NoModifier, e->uid, Qt::NoButton, tabletDevicePoint(e->uid).state);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
#else
@@ -2257,7 +2303,7 @@ void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInter
QTabletEvent ev(QEvent::TabletLeaveProximity, QPointF(), QPointF(),
e->device, e->pointerType, 0, 0, 0,
0, 0, 0,
- Qt::NoModifier, e->uid, Qt::NoButton, tabletState);
+ Qt::NoModifier, e->uid, Qt::NoButton, tabletDevicePoint(e->uid).state);
ev.setTimestamp(e->timestamp);
QGuiApplication::sendSpontaneousEvent(qGuiApp, &ev);
#else
@@ -3542,7 +3588,7 @@ void QGuiApplicationPrivate::_q_updateFocusObject(QObject *object)
emit q->focusObjectChanged(object);
}
-enum {
+enum MouseMasks {
MouseCapsMask = 0xFF,
MouseSourceMaskDst = 0xFF00,
MouseSourceMaskSrc = MouseCapsMask,
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index d995387d66..a773122d3e 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -67,6 +67,7 @@ class Q_GUI_EXPORT QGuiApplication : public QCoreApplication
Q_OBJECT
Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon)
Q_PROPERTY(QString applicationDisplayName READ applicationDisplayName WRITE setApplicationDisplayName)
+ Q_PROPERTY(QString desktopFileName READ desktopFileName WRITE setDesktopFileName)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(QString platformName READ platformName STORED false)
Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE setQuitOnLastWindowClosed)
@@ -83,6 +84,9 @@ public:
static void setApplicationDisplayName(const QString &name);
static QString applicationDisplayName();
+ static void setDesktopFileName(const QString &name);
+ static QString desktopFileName();
+
static QWindowList allWindows();
static QWindowList topLevelWindows();
static QWindow *topLevelAt(const QPoint &pos);
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 7c7da9790b..5ef8dee8b7 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -183,6 +183,7 @@ public:
static QIcon *app_icon;
static QString *platform_name;
static QString *displayName;
+ static QString *desktopFileName;
QWindowList modalWindowList;
static void showModalWindow(QWindow *window);
@@ -197,13 +198,20 @@ public:
static int mousePressY;
static int mouse_double_click_distance;
static QPointF lastCursorPosition;
- static Qt::MouseButtons tabletState;
- static QWindow *tabletPressTarget;
static QWindow *currentMouseWindow;
static QWindow *currentMousePressWindow;
static Qt::ApplicationState applicationState;
static bool highDpiScalingUpdated;
+ struct TabletPointData {
+ TabletPointData(qint64 devId = 0) : deviceId(devId), state(Qt::NoButton), target(Q_NULLPTR) {}
+ qint64 deviceId;
+ Qt::MouseButtons state;
+ QWindow *target;
+ };
+ static QVector<TabletPointData> tabletDevicePoints;
+ static TabletPointData &tabletDevicePoint(qint64 deviceId);
+
#ifndef QT_NO_CLIPBOARD
static QClipboard *qt_clipboard;
#endif
diff --git a/src/gui/kernel/qinputdevicemanager_p.h b/src/gui/kernel/qinputdevicemanager_p.h
index d64793c23c..4c24b1bc93 100644
--- a/src/gui/kernel/qinputdevicemanager_p.h
+++ b/src/gui/kernel/qinputdevicemanager_p.h
@@ -61,7 +61,8 @@ public:
DeviceTypeUnknown,
DeviceTypePointer,
DeviceTypeKeyboard,
- DeviceTypeTouch
+ DeviceTypeTouch,
+ DeviceTypeTablet
};
QInputDeviceManager(QObject *parent = 0);
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 3c033ea39e..8258e3999c 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -948,7 +948,7 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
if (!isValid())
return false;
- if (thread() != QThread::currentThread())
+ if (Q_UNLIKELY(thread() != QThread::currentThread()))
qFatal("Cannot make QOpenGLContext current in a different thread");
if (!surface) {
diff --git a/src/gui/kernel/qplatformdrag.cpp b/src/gui/kernel/qplatformdrag.cpp
index d789c75d1d..11230194fc 100644
--- a/src/gui/kernel/qplatformdrag.cpp
+++ b/src/gui/kernel/qplatformdrag.cpp
@@ -155,6 +155,20 @@ Qt::DropAction QPlatformDrag::defaultAction(Qt::DropActions possibleActions,
}
/*!
+ \brief Cancels the currently active drag (only for drags of
+ the current application initiated by QPlatformDrag::drag()).
+
+ The default implementation does nothing.
+
+ \since 5.6
+ */
+
+void QPlatformDrag::cancelDrag()
+{
+ Q_UNIMPLEMENTED();
+}
+
+/*!
\brief Called to notify QDrag about changes of the current action.
*/
diff --git a/src/gui/kernel/qplatformdrag.h b/src/gui/kernel/qplatformdrag.h
index 10ee88477f..72e28d2745 100644
--- a/src/gui/kernel/qplatformdrag.h
+++ b/src/gui/kernel/qplatformdrag.h
@@ -92,6 +92,7 @@ public:
virtual QMimeData *platformDropData() = 0;
virtual Qt::DropAction drag(QDrag *m_drag) = 0;
+ virtual void cancelDrag();
void updateAction(Qt::DropAction action);
virtual Qt::DropAction defaultAction(Qt::DropActions possibleActions, Qt::KeyboardModifiers modifiers) const;
diff --git a/src/gui/kernel/qplatforminputcontextfactory.cpp b/src/gui/kernel/qplatforminputcontextfactory.cpp
index fedf940dda..c80797d884 100644
--- a/src/gui/kernel/qplatforminputcontextfactory.cpp
+++ b/src/gui/kernel/qplatforminputcontextfactory.cpp
@@ -69,7 +69,7 @@ QPlatformInputContext *QPlatformInputContextFactory::create(const QString& key)
QStringList paramList = key.split(QLatin1Char(':'));
const QString platform = paramList.takeFirst().toLower();
- QPlatformInputContext *ic = qLoadPlugin1<QPlatformInputContext, QPlatformInputContextPlugin>
+ QPlatformInputContext *ic = qLoadPlugin<QPlatformInputContext, QPlatformInputContextPlugin>
(loader(), platform, paramList);
if (ic && ic->isValid())
return ic;
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 14633d8b30..82cb4dd399 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -149,13 +149,11 @@ QPlatformServices *QPlatformIntegration::services() const
/*!
\fn QPlatformWindow *QPlatformIntegration::createPlatformWindow(QWindow *window) const
- Factory function for QPlatformWindow. The \a window parameter is a pointer to the top level
- window which the QPlatformWindow is supposed to be created for.
+ Factory function for QPlatformWindow. The \a window parameter is a pointer to the window
+ which the QPlatformWindow is supposed to be created for.
- All top level windows have to have a QPlatformWindow, and it will be created when the
- QPlatformWindow is set to be visible for the first time. If the top level window's flags are
- changed, or if the top level window's QPlatformWindowFormat is changed, then the top level
- window's QPlatformWindow is deleted and a new one is created.
+ All windows have to have a QPlatformWindow, and it will be created on-demand when the
+ QWindow is made visible for the first time, or explicitly through calling QWindow::create().
In the constructor, of the QPlatformWindow, the window flags, state, title and geometry
of the \a window should be applied to the underlying window. If the resulting flags or state
@@ -559,6 +557,17 @@ void QPlatformIntegration::sync()
{
}
+/*!
+ \since 5.7
+
+ Should sound a bell, using the default volume and sound.
+
+ \sa QApplication::beep()
+*/
+void QPlatformIntegration::beep() const
+{
+}
+
#ifndef QT_NO_OPENGL
/*!
Platform integration function for querying the OpenGL implementation type.
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index af89a73455..382e16b4ca 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -176,6 +176,8 @@ public:
void removeScreen(QScreen *screen);
+ virtual void beep() const;
+
protected:
void screenAdded(QPlatformScreen *screen, bool isPrimary = false);
void destroyScreen(QPlatformScreen *screen);
diff --git a/src/gui/kernel/qplatformintegrationfactory.cpp b/src/gui/kernel/qplatformintegrationfactory.cpp
index 5a1fb3ca83..2c8a7ce0f8 100644
--- a/src/gui/kernel/qplatformintegrationfactory.cpp
+++ b/src/gui/kernel/qplatformintegrationfactory.cpp
@@ -42,23 +42,12 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QPlatformIntegrationFactoryInterface_iid, QLatin1String("/platforms"), Qt::CaseInsensitive))
+
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader,
(QPlatformIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive))
-
-static inline QPlatformIntegration *loadIntegration(QFactoryLoader *loader, const QString &key, const QStringList &parameters, int &argc, char ** argv)
-{
- const int index = loader->indexOf(key);
- if (index != -1) {
- if (QPlatformIntegrationPlugin *factory = qobject_cast<QPlatformIntegrationPlugin *>(loader->instance(index)))
- if (QPlatformIntegration *result = factory->create(key, parameters, argc, argv))
- return result;
- }
- return 0;
-}
-
#endif // !QT_NO_LIBRARY
QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platform, const QStringList &paramList, int &argc, char **argv, const QString &platformPluginPath)
@@ -67,19 +56,13 @@ QPlatformIntegration *QPlatformIntegrationFactory::create(const QString &platfor
// Try loading the plugin from platformPluginPath first:
if (!platformPluginPath.isEmpty()) {
QCoreApplication::addLibraryPath(platformPluginPath);
- if (QPlatformIntegration *ret = loadIntegration(directLoader(), platform, paramList, argc, argv))
+ if (QPlatformIntegration *ret = qLoadPlugin<QPlatformIntegration, QPlatformIntegrationPlugin>(directLoader(), platform, paramList, argc, argv))
return ret;
}
- if (QPlatformIntegration *ret = loadIntegration(loader(), platform, paramList, argc, argv))
- return ret;
#else
- Q_UNUSED(platform);
- Q_UNUSED(paramList);
- Q_UNUSED(argc);
- Q_UNUSED(argv);
Q_UNUSED(platformPluginPath);
#endif
- return 0;
+ return qLoadPlugin<QPlatformIntegration, QPlatformIntegrationPlugin>(loader(), platform, paramList, argc, argv);
}
/*!
diff --git a/src/gui/kernel/qplatformnativeinterface.cpp b/src/gui/kernel/qplatformnativeinterface.cpp
index 8fa8debcb9..48e6091571 100644
--- a/src/gui/kernel/qplatformnativeinterface.cpp
+++ b/src/gui/kernel/qplatformnativeinterface.cpp
@@ -80,6 +80,15 @@ void * QPlatformNativeInterface::nativeResourceForBackingStore(const QByteArray
return 0;
}
+#ifndef QT_NO_CURSOR
+void *QPlatformNativeInterface::nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(cursor);
+ return Q_NULLPTR;
+}
+#endif // !QT_NO_CURSOR
+
QPlatformNativeInterface::NativeResourceForIntegrationFunction QPlatformNativeInterface::nativeResourceFunctionForIntegration(const QByteArray &resource)
{
Q_UNUSED(resource);
diff --git a/src/gui/kernel/qplatformnativeinterface.h b/src/gui/kernel/qplatformnativeinterface.h
index 71a4e9c768..c8d868a41d 100644
--- a/src/gui/kernel/qplatformnativeinterface.h
+++ b/src/gui/kernel/qplatformnativeinterface.h
@@ -65,6 +65,9 @@ public:
virtual void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen);
virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *backingStore);
+#ifndef QT_NO_CURSOR
+ virtual void *nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor);
+#endif
typedef void * (*NativeResourceForIntegrationFunction)();
typedef void * (*NativeResourceForContextFunction)(QOpenGLContext *context);
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index ce8548f628..61dacfa076 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -682,6 +682,41 @@ QString QPlatformTheme::defaultStandardButtonText(int button)
return QString();
}
+QString QPlatformTheme::removeMnemonics(const QString &original)
+{
+ QString returnText(original.size(), 0);
+ int finalDest = 0;
+ int currPos = 0;
+ int l = original.length();
+ while (l) {
+ if (original.at(currPos) == QLatin1Char('&')
+ && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) {
+ ++currPos;
+ --l;
+ if (l == 0)
+ break;
+ } else if (original.at(currPos) == QLatin1Char('(') && l >= 4 &&
+ original.at(currPos + 1) == QLatin1Char('&') &&
+ original.at(currPos + 2) != QLatin1Char('&') &&
+ original.at(currPos + 3) == QLatin1Char(')')) {
+ /* remove mnemonics its format is "\s*(&X)" */
+ int n = 0;
+ while (finalDest > n && returnText.at(finalDest - n - 1).isSpace())
+ ++n;
+ finalDest -= n;
+ currPos += 4;
+ l -= 4;
+ continue;
+ }
+ returnText[finalDest] = original.at(currPos);
+ ++currPos;
+ ++finalDest;
+ --l;
+ }
+ returnText.truncate(finalDest);
+ return returnText;
+}
+
unsigned QPlatformThemePrivate::currentKeyPlatforms()
{
const uint keyboardScheme = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::KeyboardScheme).toInt();
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 36fa7a65aa..71f5fea820 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -240,6 +240,7 @@ public:
MediaSeekBackward,
MediaVolume,
MediaVolumeMuted,
+ LineEditClearButton,
// do not add any values below/greater than this
CustomBase = 0xf0000000
};
@@ -303,6 +304,7 @@ public:
static QVariant defaultThemeHint(ThemeHint hint);
static QString defaultStandardButtonText(int button);
+ static QString removeMnemonics(const QString &original);
protected:
explicit QPlatformTheme(QPlatformThemePrivate *priv);
diff --git a/src/gui/kernel/qplatformthemefactory.cpp b/src/gui/kernel/qplatformthemefactory.cpp
index bcc37dad06..a89e3088ea 100644
--- a/src/gui/kernel/qplatformthemefactory.cpp
+++ b/src/gui/kernel/qplatformthemefactory.cpp
@@ -51,23 +51,22 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader,
QPlatformTheme *QPlatformThemeFactory::create(const QString& key, const QString &platformPluginPath)
{
+#ifndef QT_NO_LIBRARY
QStringList paramList = key.split(QLatin1Char(':'));
const QString platform = paramList.takeFirst().toLower();
-#ifndef QT_NO_LIBRARY
// Try loading the plugin from platformPluginPath first:
if (!platformPluginPath.isEmpty()) {
QCoreApplication::addLibraryPath(platformPluginPath);
- if (QPlatformTheme *ret = qLoadPlugin1<QPlatformTheme, QPlatformThemePlugin>(directLoader(), platform, paramList))
+ if (QPlatformTheme *ret = qLoadPlugin<QPlatformTheme, QPlatformThemePlugin>(directLoader(), platform, paramList))
return ret;
}
- if (QPlatformTheme *ret = qLoadPlugin1<QPlatformTheme, QPlatformThemePlugin>(loader(), platform, paramList))
- return ret;
+ return qLoadPlugin<QPlatformTheme, QPlatformThemePlugin>(loader(), platform, paramList);
#else
Q_UNUSED(key);
Q_UNUSED(platformPluginPath);
-#endif
return 0;
+#endif
}
/*!
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index 9f38c9b78a..706786385b 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -191,6 +191,14 @@ Qt::DropAction QBasicDrag::drag(QDrag *o)
return m_executed_drop_action;
}
+void QBasicDrag::cancelDrag()
+{
+ if (m_eventLoop) {
+ cancel();
+ m_eventLoop->quit();
+ }
+}
+
void QBasicDrag::restoreCursor()
{
if (m_restoreCursor) {
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index 055136c436..d5dacd8fd2 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -66,6 +66,7 @@ public:
virtual ~QBasicDrag();
virtual Qt::DropAction drag(QDrag *drag) Q_DECL_OVERRIDE;
+ void cancelDrag() Q_DECL_OVERRIDE;
virtual bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE;
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 7fc89112e6..eea26c05ed 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -65,6 +65,7 @@ class QStyleHintsPrivate : public QObjectPrivate
public:
inline QStyleHintsPrivate()
: m_mouseDoubleClickInterval(-1)
+ , m_mousePressAndHoldInterval(-1)
, m_startDragDistance(-1)
, m_startDragTime(-1)
, m_keyboardInputInterval(-1)
@@ -72,6 +73,7 @@ public:
{}
int m_mouseDoubleClickInterval;
+ int m_mousePressAndHoldInterval;
int m_startDragDistance;
int m_startDragTime;
int m_keyboardInputInterval;
@@ -129,6 +131,21 @@ int QStyleHints::mouseDoubleClickInterval() const
}
/*!
+ Sets the \a mousePressAndHoldInterval.
+ \internal
+ \sa mousePressAndHoldInterval()
+ \since 5.7
+*/
+void QStyleHints::setMousePressAndHoldInterval(int mousePressAndHoldInterval)
+{
+ Q_D(QStyleHints);
+ if (d->m_mousePressAndHoldInterval == mousePressAndHoldInterval)
+ return;
+ d->m_mousePressAndHoldInterval = mousePressAndHoldInterval;
+ emit mousePressAndHoldIntervalChanged(mousePressAndHoldInterval);
+}
+
+/*!
\property QStyleHints::mousePressAndHoldInterval
\brief the time limit in milliseconds that activates
a press and hold.
@@ -137,7 +154,10 @@ int QStyleHints::mouseDoubleClickInterval() const
*/
int QStyleHints::mousePressAndHoldInterval() const
{
- return themeableHint(QPlatformTheme::MousePressAndHoldInterval, QPlatformIntegration::MousePressAndHoldInterval).toInt();
+ Q_D(const QStyleHints);
+ return d->m_mousePressAndHoldInterval >= 0 ?
+ d->m_mousePressAndHoldInterval :
+ themeableHint(QPlatformTheme::MousePressAndHoldInterval, QPlatformIntegration::MousePressAndHoldInterval).toInt();
}
/*!
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index c5b8241e07..7c46eaa746 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -51,7 +51,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject
Q_PROPERTY(int keyboardAutoRepeatRate READ keyboardAutoRepeatRate STORED false CONSTANT FINAL)
Q_PROPERTY(int keyboardInputInterval READ keyboardInputInterval NOTIFY keyboardInputIntervalChanged FINAL)
Q_PROPERTY(int mouseDoubleClickInterval READ mouseDoubleClickInterval NOTIFY mouseDoubleClickIntervalChanged FINAL)
- Q_PROPERTY(int mousePressAndHoldInterval READ mousePressAndHoldInterval STORED false CONSTANT FINAL)
+ Q_PROPERTY(int mousePressAndHoldInterval READ mousePressAndHoldInterval NOTIFY mousePressAndHoldIntervalChanged FINAL)
Q_PROPERTY(QChar passwordMaskCharacter READ passwordMaskCharacter STORED false CONSTANT FINAL)
Q_PROPERTY(int passwordMaskDelay READ passwordMaskDelay STORED false CONSTANT FINAL)
Q_PROPERTY(bool setFocusOnTouchRelease READ setFocusOnTouchRelease STORED false CONSTANT FINAL)
@@ -67,6 +67,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject
public:
void setMouseDoubleClickInterval(int mouseDoubleClickInterval);
int mouseDoubleClickInterval() const;
+ void setMousePressAndHoldInterval(int mousePressAndHoldInterval);
int mousePressAndHoldInterval() const;
void setStartDragDistance(int startDragDistance);
int startDragDistance() const;
@@ -92,6 +93,7 @@ Q_SIGNALS:
void cursorFlashTimeChanged(int cursorFlashTime);
void keyboardInputIntervalChanged(int keyboardInputInterval);
void mouseDoubleClickIntervalChanged(int mouseDoubleClickInterval);
+ void mousePressAndHoldIntervalChanged(int mousePressAndHoldInterval);
void startDragDistanceChanged(int startDragDistance);
void startDragTimeChanged(int startDragTime);
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 21734f1619..45e0acec63 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -212,7 +212,7 @@ void QWindowPrivate::init()
// If your application aborts here, you are probably creating a QWindow
// before the screen list is populated.
- if (!parentWindow && !topLevelScreen) {
+ if (Q_UNLIKELY(!parentWindow && !topLevelScreen)) {
qFatal("Cannot create window: no screens available");
exit(1);
}
@@ -392,6 +392,9 @@ void QWindowPrivate::create(bool recursive)
if (platformWindow)
return;
+ if (q->parent())
+ q->parent()->create();
+
platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q);
Q_ASSERT(platformWindow);
@@ -403,13 +406,21 @@ void QWindowPrivate::create(bool recursive)
QObjectList childObjects = q->children();
for (int i = 0; i < childObjects.size(); i ++) {
QObject *object = childObjects.at(i);
- if (object->isWindowType()) {
- QWindow *window = static_cast<QWindow *>(object);
- if (recursive)
- window->d_func()->create(true);
- if (window->d_func()->platformWindow)
- window->d_func()->platformWindow->setParent(platformWindow);
- }
+ if (!object->isWindowType())
+ continue;
+
+ QWindow *childWindow = static_cast<QWindow *>(object);
+ if (recursive)
+ childWindow->d_func()->create(recursive);
+
+ // The child may have had deferred creation due to this window not being created
+ // at the time setVisible was called, so we re-apply the visible state, which
+ // may result in creating the child, and emitting the appropriate signals.
+ if (childWindow->isVisible())
+ childWindow->setVisible(true);
+
+ if (QPlatformWindow *childPlatformWindow = childWindow->d_func()->platformWindow)
+ childPlatformWindow->setParent(this->platformWindow);
}
QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
@@ -474,14 +485,23 @@ void QWindow::setVisible(bool visible)
{
Q_D(QWindow);
- if (d->visible == visible)
+ if (d->visible != visible) {
+ d->visible = visible;
+ emit visibleChanged(visible);
+ d->updateVisibility();
+ } else if (d->platformWindow) {
+ // Visibility hasn't changed, and the platform window is in sync
return;
- d->visible = visible;
- emit visibleChanged(visible);
- d->updateVisibility();
+ }
- if (!d->platformWindow)
- create();
+ if (!d->platformWindow) {
+ // If we have a parent window, but the parent hasn't been created yet, we
+ // can defer creation until the parent is created or we're re-parented.
+ if (parent() && !parent()->handle())
+ return;
+ else
+ create();
+ }
if (visible) {
// remove posted quit events when showing a new window
@@ -520,6 +540,7 @@ void QWindow::setVisible(bool visible)
if (visible && (d->hasCursor || QGuiApplication::overrideCursor()))
d->applyCursor();
#endif
+
d->platformWindow->setVisible(visible);
if (!visible) {
@@ -616,12 +637,17 @@ void QWindow::setParent(QWindow *parent)
else
d->connectToScreen(newScreen);
+ // If we were set visible, but not created because we were a child, and we're now
+ // re-parented into a created parent, or to being a top level, we need re-apply the
+ // visibility state, which will also create.
+ if (isVisible() && (!parent || parent->handle()))
+ setVisible(true);
+
if (d->platformWindow) {
- if (parent && parent->d_func()->platformWindow) {
- d->platformWindow->setParent(parent->d_func()->platformWindow);
- } else {
- d->platformWindow->setParent(0);
- }
+ if (parent)
+ parent->create();
+
+ d->platformWindow->setParent(parent ? parent->d_func()->platformWindow : 0);
}
QGuiApplicationPrivate::updateBlockedStatus(this);
@@ -1654,8 +1680,12 @@ void QWindow::destroy()
QGuiApplicationPrivate::currentMouseWindow = parent();
if (QGuiApplicationPrivate::currentMousePressWindow == this)
QGuiApplicationPrivate::currentMousePressWindow = parent();
- if (QGuiApplicationPrivate::tabletPressTarget == this)
- QGuiApplicationPrivate::tabletPressTarget = parent();
+
+ for (int i = 0; i < QGuiApplicationPrivate::tabletDevicePoints.size(); ++i) {
+ QGuiApplicationPrivate::TabletPointData &pointData = QGuiApplicationPrivate::tabletDevicePoints[i];
+ if (pointData.target == this)
+ pointData.target = parent();
+ }
bool wasVisible = isVisible();
d->visibilityOnDestroy = wasVisible && d->platformWindow;
diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp
index 40f4ce94c2..7bdd3cb1bb 100644
--- a/src/gui/opengl/qopenglengineshadermanager.cpp
+++ b/src/gui/opengl/qopenglengineshadermanager.cpp
@@ -191,7 +191,7 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
#if defined(QT_DEBUG)
// Check that all the elements have been filled:
for (int i = 0; i < TotalSnippetCount; ++i) {
- if (qShaderSnippets[i] == 0) {
+ if (Q_UNLIKELY(!qShaderSnippets[i])) {
qFatal("Shader snippet for %s (#%d) is missing!",
snippetNameStr(SnippetName(i)).constData(), i);
}
@@ -240,11 +240,11 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
simpleShaderProg->link();
- if (simpleShaderProg->isLinked()) {
+ if (Q_UNLIKELY(!simpleShaderProg->isLinked())) {
+ qCritical("Errors linking simple shader: %s", qPrintable(simpleShaderProg->log()));
+ } else {
if (!inCache)
simpleShaderCache.store(simpleShaderProg, context);
- } else {
- qCritical("Errors linking simple shader: %s", qPrintable(simpleShaderProg->log()));
}
// Compile the blit shader:
@@ -281,11 +281,11 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
}
blitShaderProg->link();
- if (blitShaderProg->isLinked()) {
+ if (Q_UNLIKELY(!blitShaderProg->isLinked())) {
+ qCritical("Errors linking blit shader: %s", qPrintable(blitShaderProg->log()));
+ } else {
if (!inCache)
blitShaderCache.store(blitShaderProg, context);
- } else {
- qCritical("Errors linking blit shader: %s", qPrintable(blitShaderProg->log()));
}
#ifdef QT_GL_SHARED_SHADER_DEBUG
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index d614ad8401..bfd30735b2 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -5795,7 +5795,9 @@ QOpenGLES3Helper::QOpenGLES3Helper()
{
m_supportedVersion = qMakePair(2, 0);
- if (init()) {
+ if (Q_UNLIKELY(!init())) {
+ qFatal("Failed to load libGLESv2");
+ } else {
const QPair<int, int> contextVersion = QOpenGLContext::currentContext()->format().version();
qCDebug(lcGLES3, "Resolving OpenGL ES 3.0 entry points");
@@ -5993,8 +5995,6 @@ QOpenGLES3Helper::QOpenGLES3Helper()
}
m_supportedVersion = qMakePair(3, 1);
}
- } else {
- qFatal("Failed to load libGLESv2");
}
}
diff --git a/src/gui/opengl/qtriangulator_p.h b/src/gui/opengl/qtriangulator_p.h
index 0ab3f7496c..4e13e5bdd0 100644
--- a/src/gui/opengl/qtriangulator_p.h
+++ b/src/gui/opengl/qtriangulator_p.h
@@ -88,12 +88,13 @@ public:
inline QVertexIndexVector &operator = (const QVertexIndexVector &other)
{
- if (t == UnsignedInt)
- indices32 = other.indices32;
- else
- indices16 = other.indices16;
+ if (t == UnsignedInt)
+ indices32 = other.indices32;
+ else
+ indices16 = other.indices16;
- return *this;
+ t = other.t;
+ return *this;
}
private:
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 1e516e4581..283b6643b9 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -101,9 +101,10 @@ SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \
painting/qimagescale_sse4.cpp
AVX2_SOURCES += painting/qdrawhelper_avx2.cpp
-NEON_SOURCES += painting/qdrawhelper_neon.cpp
+NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
NEON_HEADERS += painting/qdrawhelper_neon_p.h
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
+!ios:contains(QT_ARCH, "arm"): CONFIG+=no_clang_integrated_as
!ios:!contains(QT_ARCH, "arm64"): DEFINES += ENABLE_PIXMAN_DRAWHELPERS
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index 8c3fd2ce4f..3112d551b2 100644
--- a/src/gui/painting/qcosmeticstroker.cpp
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -538,7 +538,7 @@ void QCosmeticStroker::drawPath(const QVectorPath &path)
QPointF p2 = QPointF(p[-2], p[-1]) * state->matrix;
calculateLastPoint(p1.x(), p1.y(), p2.x(), p2.y());
}
- int caps = (!closed & drawCaps) ? CapBegin : NoCaps;
+ int caps = (!closed && drawCaps) ? CapBegin : NoCaps;
// qDebug() << "closed =" << closed << capString(caps);
points += 2;
@@ -589,7 +589,7 @@ void QCosmeticStroker::drawPath(const QVectorPath &path)
const qreal *end = points + 2*path.elementCount();
// handle closed path case
bool closed = path.hasImplicitClose() || (points[0] == end[-2] && points[1] == end[-1]);
- int caps = (!closed & drawCaps) ? CapBegin : NoCaps;
+ int caps = (!closed && drawCaps) ? CapBegin : NoCaps;
if (closed) {
QPointF p2 = QPointF(end[-2], end[-1]) * state->matrix;
calculateLastPoint(p2.x(), p2.y(), p.x(), p.y());
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 87ceb9a89d..e7b81ebdd3 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -2337,8 +2337,8 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
uint bl = s2[x1];
uint br = s2[x2];
-#if defined(__SSE2__)
- // The SSE2 optimized interpolate_4_pixels is faster than interpolate_4_pixels_16.
+#if defined(__SSE2__) || defined(__ARM_NEON__)
+ // The optimized interpolate_4_pixels are faster than interpolate_4_pixels_16.
int distx = (fx & 0x0000ffff) >> 8;
int disty = (fy & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
@@ -2567,12 +2567,8 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
if ((fdx < 0 && fdx > -(fixed_scale / 8)) || std::abs(data->m22) < (1./8.)) { // scale up more than 8x
int disty = (fy & 0x0000ffff) >> 8;
for (int i = 0; i < len; ++i) {
- uint tl = buf1[i * 2 + 0];
- uint tr = buf1[i * 2 + 1];
- uint bl = buf2[i * 2 + 0];
- uint br = buf2[i * 2 + 1];
int distx = (fracX & 0x0000ffff) >> 8;
- b[i] = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
+ b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
fracX += fdx;
}
} else { //scale down
@@ -2633,15 +2629,10 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
if (std::abs(data->m11) > 8 || std::abs(data->m22) > 8) {
//if we are zooming more than 8 times, we use 8bit precision for the position.
for (int i = 0; i < len; ++i) {
- uint tl = buf1[i * 2 + 0];
- uint tr = buf1[i * 2 + 1];
- uint bl = buf2[i * 2 + 0];
- uint br = buf2[i * 2 + 1];
-
int distx = (fracX & 0x0000ffff) >> 8;
int disty = (fracY & 0x0000ffff) >> 8;
- b[i] = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
+ b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
fracX += fdx;
fracY += fdy;
}
@@ -2731,12 +2722,7 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
int distx = distxs[i];
int disty = distys[i];
- uint tl = buf1[i * 2 + 0];
- uint tr = buf1[i * 2 + 1];
- uint bl = buf2[i * 2 + 0];
- uint br = buf2[i * 2 + 1];
-
- b[i] = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
+ b[i] = interpolate_4_pixels(buf1 + i * 2, buf2 + i * 2, distx, disty);
}
length -= len;
b += len;
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 1ff19f4e04..fc24e22cac 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -629,31 +629,75 @@ static Q_ALWAYS_INLINE uint BYTE_MUL(uint x, uint a) {
}
#endif
-#ifdef __SSE2__
+#if defined(__SSE2__)
+static Q_ALWAYS_INLINE uint interpolate_4_pixels_sse2(__m128i vt, __m128i vb, uint distx, uint disty)
+{
+ // First interpolate top and bottom pixels in parallel.
+ vt = _mm_unpacklo_epi8(vt, _mm_setzero_si128());
+ vb = _mm_unpacklo_epi8(vb, _mm_setzero_si128());
+ vt = _mm_mullo_epi16(vt, _mm_set1_epi16(256 - disty));
+ vb = _mm_mullo_epi16(vb, _mm_set1_epi16(disty));
+ __m128i vlr = _mm_add_epi16(vt, vb);
+ vlr = _mm_srli_epi16(vlr, 8);
+ // vlr now contains the result of the first two interpolate calls vlr = unpacked((xright << 64) | xleft)
+
+ // Now the last interpolate between left and right..
+ const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(256 - distx), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vmulx = _mm_unpacklo_epi16(vidistx, vdistx);
+ vlr = _mm_unpacklo_epi16(vlr, _mm_srli_si128(vlr, 8));
+ // vlr now contains the colors of left and right interleaved { la, ra, lr, rr, lg, rg, lb, rb }
+ vlr = _mm_madd_epi16(vlr, vmulx); // Multiply and horizontal add.
+ vlr = _mm_srli_epi32(vlr, 8);
+ vlr = _mm_packs_epi32(vlr, vlr);
+ vlr = _mm_packus_epi16(vlr, vlr);
+ return _mm_cvtsi128_si32(vlr);
+}
+
+static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
+{
+ __m128i vt = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tl), _mm_cvtsi32_si128(tr));
+ __m128i vb = _mm_unpacklo_epi32(_mm_cvtsi32_si128(bl), _mm_cvtsi32_si128(br));
+ return interpolate_4_pixels_sse2(vt, vb, distx, disty);
+}
+
+static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint distx, uint disty)
+{
+ __m128i vt = _mm_loadl_epi64((const __m128i*)t);
+ __m128i vb = _mm_loadl_epi64((const __m128i*)b);
+ return interpolate_4_pixels_sse2(vt, vb, distx, disty);
+}
+#elif defined(__ARM_NEON__)
+static Q_ALWAYS_INLINE uint interpolate_4_pixels_neon(uint32x2_t vt32, uint32x2_t vb32, uint distx, uint disty)
+{
+ uint16x8_t vt16 = vmovl_u8(vreinterpret_u8_u32(vt32));
+ uint16x8_t vb16 = vmovl_u8(vreinterpret_u8_u32(vb32));
+ vt16 = vmulq_n_u16(vt16, 256 - disty);
+ vt16 = vmlaq_n_u16(vt16, vb16, disty);
+ vt16 = vshrq_n_u16(vt16, 8);
+ uint16x4_t vl16 = vget_low_u16(vt16);
+ uint16x4_t vr16 = vget_high_u16(vt16);
+ vl16 = vmul_n_u16(vl16, 256 - distx);
+ vl16 = vmla_n_u16(vl16, vr16, distx);
+ vl16 = vshr_n_u16(vl16, 8);
+ uint8x8_t vr = vmovn_u16(vcombine_u16(vl16, vl16));
+ return vget_lane_u32(vreinterpret_u32_u8(vr), 0);
+}
+
static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
{
- // First interpolate right and left pixels in parallel.
- __m128i vl = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tl), _mm_cvtsi32_si128(bl));
- __m128i vr = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tr), _mm_cvtsi32_si128(br));
- vl = _mm_unpacklo_epi8(vl, _mm_setzero_si128());
- vr = _mm_unpacklo_epi8(vr, _mm_setzero_si128());
- vl = _mm_mullo_epi16(vl, _mm_set1_epi16(256 - distx));
- vr = _mm_mullo_epi16(vr, _mm_set1_epi16(distx));
- __m128i vtb = _mm_add_epi16(vl, vr);
- vtb = _mm_srli_epi16(vtb, 8);
- // vtb now contains the result of the first two interpolate calls vtb = unpacked((xbot << 64) | xtop)
-
- // Now the last interpolate between top and bottom interpolations.
- const __m128i vidisty = _mm_shufflelo_epi16(_mm_cvtsi32_si128(256 - disty), _MM_SHUFFLE(0, 0, 0, 0));
- const __m128i vdisty = _mm_shufflelo_epi16(_mm_cvtsi32_si128(disty), _MM_SHUFFLE(0, 0, 0, 0));
- const __m128i vmuly = _mm_unpacklo_epi16(vidisty, vdisty);
- vtb = _mm_unpacklo_epi16(vtb, _mm_srli_si128(vtb, 8));
- // vtb now contains the colors of top and bottom interleaved { ta, ba, tr, br, tg, bg, tb, bb }
- vtb = _mm_madd_epi16(vtb, vmuly); // Multiply and horizontal add.
- vtb = _mm_srli_epi32(vtb, 8);
- vtb = _mm_packs_epi32(vtb, _mm_setzero_si128());
- vtb = _mm_packus_epi16(vtb, _mm_setzero_si128());
- return _mm_cvtsi128_si32(vtb);
+ uint32x2_t vt32 = vmov_n_u32(tl);
+ uint32x2_t vb32 = vmov_n_u32(bl);
+ vt32 = vset_lane_u32(tr, vt32, 1);
+ vb32 = vset_lane_u32(br, vb32, 1);
+ return interpolate_4_pixels_neon(vt32, vb32, distx, disty);
+}
+
+static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint distx, uint disty)
+{
+ uint32x2_t vt32 = vld1_u32(t);
+ uint32x2_t vb32 = vld1_u32(b);
+ return interpolate_4_pixels_neon(vt32, vb32, distx, disty);
}
#else
static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
@@ -664,6 +708,11 @@ static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint
uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
return INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
}
+
+static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint distx, uint disty)
+{
+ return interpolate_4_pixels(t[0], t[1], b[0], b[1], distx, disty);
+}
#endif
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp
index 33dccc5374..9381afa8e7 100644
--- a/src/gui/painting/qimagescale.cpp
+++ b/src/gui/painting/qimagescale.cpp
@@ -277,6 +277,18 @@ void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest,
int dw, int dh, int dow, int sow);
#endif
+#if defined(__ARM_NEON__)
+template<bool RGB>
+void qt_qimageScaleAARGBA_up_x_down_y_neon(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow);
+template<bool RGB>
+void qt_qimageScaleAARGBA_down_x_up_y_neon(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow);
+template<bool RGB>
+void qt_qimageScaleAARGBA_down_xy_neon(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow);
+#endif
+
static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest,
int dw, int dh, int dow, int sow)
{
@@ -296,7 +308,7 @@ static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest,
const unsigned int *pix = sptr + xpoints[x];
const int xap = xapoints[x];
if (xap > 0)
- *dptr = interpolate_4_pixels(pix[0], pix[1], pix[sow], pix[sow + 1], xap, yap);
+ *dptr = interpolate_4_pixels(pix, pix + sow, xap, yap);
else
*dptr = INTERPOLATE_PIXEL_256(pix[0], 256 - yap, pix[sow], yap);
dptr++;
@@ -329,6 +341,10 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
if (qCpuHasFeature(SSE4_1))
qt_qimageScaleAARGBA_up_x_down_y_sse4<false>(isi, dest, dw, dh, dow, sow);
else
+#elif defined(__ARM_NEON__)
+ if (qCpuHasFeature(NEON))
+ qt_qimageScaleAARGBA_up_x_down_y_neon<false>(isi, dest, dw, dh, dow, sow);
+ else
#endif
qt_qimageScaleAARGBA_up_x_down_y(isi, dest, dw, dh, dow, sow);
}
@@ -338,6 +354,10 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
if (qCpuHasFeature(SSE4_1))
qt_qimageScaleAARGBA_down_x_up_y_sse4<false>(isi, dest, dw, dh, dow, sow);
else
+#elif defined(__ARM_NEON__)
+ if (qCpuHasFeature(NEON))
+ qt_qimageScaleAARGBA_down_x_up_y_neon<false>(isi, dest, dw, dh, dow, sow);
+ else
#endif
qt_qimageScaleAARGBA_down_x_up_y(isi, dest, dw, dh, dow, sow);
}
@@ -347,6 +367,10 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest,
if (qCpuHasFeature(SSE4_1))
qt_qimageScaleAARGBA_down_xy_sse4<false>(isi, dest, dw, dh, dow, sow);
else
+#elif defined(__ARM_NEON__)
+ if (qCpuHasFeature(NEON))
+ qt_qimageScaleAARGBA_down_xy_neon<false>(isi, dest, dw, dh, dow, sow);
+ else
#endif
qt_qimageScaleAARGBA_down_xy(isi, dest, dw, dh, dow, sow);
}
@@ -522,6 +546,10 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
if (qCpuHasFeature(SSE4_1))
qt_qimageScaleAARGBA_up_x_down_y_sse4<true>(isi, dest, dw, dh, dow, sow);
else
+#elif defined(__ARM_NEON__)
+ if (qCpuHasFeature(NEON))
+ qt_qimageScaleAARGBA_up_x_down_y_neon<true>(isi, dest, dw, dh, dow, sow);
+ else
#endif
qt_qimageScaleAARGB_up_x_down_y(isi, dest, dw, dh, dow, sow);
}
@@ -531,6 +559,10 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
if (qCpuHasFeature(SSE4_1))
qt_qimageScaleAARGBA_down_x_up_y_sse4<true>(isi, dest, dw, dh, dow, sow);
else
+#elif defined(__ARM_NEON__)
+ if (qCpuHasFeature(NEON))
+ qt_qimageScaleAARGBA_down_x_up_y_neon<true>(isi, dest, dw, dh, dow, sow);
+ else
#endif
qt_qimageScaleAARGB_down_x_up_y(isi, dest, dw, dh, dow, sow);
}
@@ -540,6 +572,10 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest,
if (qCpuHasFeature(SSE4_1))
qt_qimageScaleAARGBA_down_xy_sse4<true>(isi, dest, dw, dh, dow, sow);
else
+#elif defined(__ARM_NEON__)
+ if (qCpuHasFeature(NEON))
+ qt_qimageScaleAARGBA_down_xy_neon<true>(isi, dest, dw, dh, dow, sow);
+ else
#endif
qt_qimageScaleAARGB_down_xy(isi, dest, dw, dh, dow, sow);
}
diff --git a/src/gui/painting/qimagescale_neon.cpp b/src/gui/painting/qimagescale_neon.cpp
new file mode 100644
index 0000000000..88389bebb9
--- /dev/null
+++ b/src/gui/painting/qimagescale_neon.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qimagescale_p.h"
+#include "qimage.h"
+#include <private/qsimd_p.h>
+
+#if defined(__ARM_NEON__)
+
+QT_BEGIN_NAMESPACE
+
+using namespace QImageScale;
+
+inline static uint32x4_t qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step)
+{
+ uint32x2_t vpix32 = vmov_n_u32(*pix);
+ uint16x4_t vpix16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(vpix32)));
+ uint32x4_t vx = vmull_n_u16(vpix16, xyap);
+ int i;
+ for (i = (1 << 14) - xyap; i > Cxy; i -= Cxy) {
+ pix += step;
+ vpix32 = vmov_n_u32(*pix);
+ vpix16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(vpix32)));
+ vx = vaddq_u32(vx, vmull_n_u16(vpix16, Cxy));
+ }
+ pix += step;
+ vpix32 = vmov_n_u32(*pix);
+ vpix16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(vpix32)));
+ vx = vaddq_u32(vx, vmull_n_u16(vpix16, i));
+ return vx;
+}
+
+template<bool RGB>
+void qt_qimageScaleAARGBA_up_x_down_y_neon(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const unsigned int **ypoints = isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ /* go through every scanline in the output buffer */
+ for (int y = 0; y < dh; y++) {
+ int Cy = yapoints[y] >> 16;
+ int yap = yapoints[y] & 0xffff;
+
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
+ uint32x4_t vx = qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow);
+
+ int xap = xapoints[x];
+ if (xap > 0) {
+ uint32x4_t vr = qt_qimageScaleAARGBA_helper(sptr + 1, yap, Cy, sow);
+
+ vx = vmulq_n_u32(vx, 256 - xap);
+ vr = vmulq_n_u32(vr, xap);
+ vx = vaddq_u32(vx, vr);
+ vx = vshrq_n_u32(vx, 8);
+ }
+ vx = vshrq_n_u32(vx, 14);
+ const uint16x4_t vx16 = vmovn_u32(vx);
+ const uint8x8_t vx8 = vmovn_u16(vcombine_u16(vx16, vx16));
+ *dptr = vget_lane_u32(vreinterpret_u32_u8(vx8), 0);
+ if (RGB)
+ *dptr |= 0xff000000;
+ dptr++;
+ }
+ }
+}
+
+template<bool RGB>
+void qt_qimageScaleAARGBA_down_x_up_y_neon(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const unsigned int **ypoints = isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ /* go through every scanline in the output buffer */
+ for (int y = 0; y < dh; y++) {
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ int Cx = xapoints[x] >> 16;
+ int xap = xapoints[x] & 0xffff;
+
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
+ uint32x4_t vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1);
+
+ int yap = yapoints[y];
+ if (yap > 0) {
+ uint32x4_t vr = qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1);
+
+ vx = vmulq_n_u32(vx, 256 - yap);
+ vr = vmulq_n_u32(vr, yap);
+ vx = vaddq_u32(vx, vr);
+ vx = vshrq_n_u32(vx, 8);
+ }
+ vx = vshrq_n_u32(vx, 14);
+ const uint16x4_t vx16 = vmovn_u32(vx);
+ const uint8x8_t vx8 = vmovn_u16(vcombine_u16(vx16, vx16));
+ *dptr = vget_lane_u32(vreinterpret_u32_u8(vx8), 0);
+ if (RGB)
+ *dptr |= 0xff000000;
+ dptr++;
+ }
+ }
+}
+
+template<bool RGB>
+void qt_qimageScaleAARGBA_down_xy_neon(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow)
+{
+ const unsigned int **ypoints = isi->ypoints;
+ int *xpoints = isi->xpoints;
+ int *xapoints = isi->xapoints;
+ int *yapoints = isi->yapoints;
+
+ for (int y = 0; y < dh; y++) {
+ int Cy = yapoints[y] >> 16;
+ int yap = yapoints[y] & 0xffff;
+
+ unsigned int *dptr = dest + (y * dow);
+ for (int x = 0; x < dw; x++) {
+ const int Cx = xapoints[x] >> 16;
+ const int xap = xapoints[x] & 0xffff;
+
+ const unsigned int *sptr = ypoints[y] + xpoints[x];
+ uint32x4_t vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1);
+ vx = vshrq_n_u32(vx, 4);
+ uint32x4_t vr = vmulq_n_u32(vx, yap);
+
+ int j;
+ for (j = (1 << 14) - yap; j > Cy; j -= Cy) {
+ sptr += sow;
+ vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1);
+ vx = vshrq_n_u32(vx, 4);
+ vx = vmulq_n_u32(vx, Cy);
+ vr = vaddq_u32(vr, vx);
+ }
+ sptr += sow;
+ vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1);
+ vx = vshrq_n_u32(vx, 4);
+ vx = vmulq_n_u32(vx, j);
+ vr = vaddq_u32(vr, vx);
+
+ vx = vshrq_n_u32(vr, 24);
+ const uint16x4_t vx16 = vmovn_u32(vx);
+ const uint8x8_t vx8 = vmovn_u16(vcombine_u16(vx16, vx16));
+ *dptr = vget_lane_u32(vreinterpret_u32_u8(vx8), 0);
+ if (RGB)
+ *dptr |= 0xff000000;
+ dptr++;
+ }
+ }
+}
+
+template void qt_qimageScaleAARGBA_up_x_down_y_neon<false>(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow);
+
+template void qt_qimageScaleAARGBA_up_x_down_y_neon<true>(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow);
+
+template void qt_qimageScaleAARGBA_down_x_up_y_neon<false>(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow);
+
+template void qt_qimageScaleAARGBA_down_x_up_y_neon<true>(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow);
+
+template void qt_qimageScaleAARGBA_down_xy_neon<false>(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow);
+
+template void qt_qimageScaleAARGBA_down_xy_neon<true>(QImageScaleInfo *isi, unsigned int *dest,
+ int dw, int dh, int dow, int sow);
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp
index a2bab58922..aa4a609d6c 100644
--- a/src/gui/painting/qpaintengine_blitter.cpp
+++ b/src/gui/painting/qpaintengine_blitter.cpp
@@ -190,7 +190,7 @@ private:
}
void setSourcePixmapMask() {
- updateStateBits(&drawPixmapMask, STATE_XFORM_SCALE, true);
+ updateStateBits(&drawPixmapMask, STATE_XFORM_SCALE, false);
updateStateBits(&drawPixmapMask, STATE_XFORM_COMPLEX, false);
updateStateBits(&drawPixmapMask, STATE_BRUSH_PATTERN, true);
@@ -212,7 +212,7 @@ private:
void setSourceOverScaledPixmapMask() {
setSourceOverPixmapMask();
- updateStateBits(&drawRectMask, STATE_XFORM_SCALE, true);
+ updateStateBits(&drawPixmapMask, STATE_XFORM_SCALE, true);
}
void setOpacityPixmapMask() {
diff --git a/src/gui/painting/qpaintengine_blitter_p.h b/src/gui/painting/qpaintengine_blitter_p.h
index ab44851ec7..17a648176c 100644
--- a/src/gui/painting/qpaintengine_blitter_p.h
+++ b/src/gui/painting/qpaintengine_blitter_p.h
@@ -60,46 +60,48 @@ class Q_GUI_EXPORT QBlitterPaintEngine : public QRasterPaintEngine
public:
QBlitterPaintEngine(QBlittablePlatformPixmap *p);
- virtual QPaintEngine::Type type() const { return Blitter; }
+ virtual QPaintEngine::Type type() const Q_DECL_OVERRIDE
+ { return Blitter; }
- virtual bool begin(QPaintDevice *pdev);
- virtual bool end();
+ virtual bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE;
+ virtual bool end() Q_DECL_OVERRIDE;
// Call down into QBlittable
- virtual void fill(const QVectorPath &path, const QBrush &brush);
- virtual void fillRect(const QRectF &rect, const QBrush &brush);
- virtual void fillRect(const QRectF &rect, const QColor &color);
- virtual void drawRects(const QRect *rects, int rectCount);
- virtual void drawRects(const QRectF *rects, int rectCount);
- void drawPixmap(const QPointF &p, const QPixmap &pm);
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE;
+ void fillRect(const QRectF &rect, const QBrush &brush) Q_DECL_OVERRIDE;
+ void fillRect(const QRectF &rect, const QColor &color) Q_DECL_OVERRIDE;
+ void drawRects(const QRect *rects, int rectCount) Q_DECL_OVERRIDE;
+ void drawRects(const QRectF *rects, int rectCount) Q_DECL_OVERRIDE;
+ void drawPixmap(const QPointF &p, const QPixmap &pm) Q_DECL_OVERRIDE;
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE;
// State tracking
- void setState(QPainterState *s);
- virtual void clipEnabledChanged();
- virtual void penChanged();
- virtual void brushChanged();
- virtual void opacityChanged();
- virtual void compositionModeChanged();
- virtual void renderHintsChanged();
- virtual void transformChanged();
+ void setState(QPainterState *s) Q_DECL_OVERRIDE;
+ virtual void clipEnabledChanged() Q_DECL_OVERRIDE;
+ virtual void penChanged() Q_DECL_OVERRIDE;
+ virtual void brushChanged() Q_DECL_OVERRIDE;
+ virtual void opacityChanged() Q_DECL_OVERRIDE;
+ virtual void compositionModeChanged() Q_DECL_OVERRIDE;
+ virtual void renderHintsChanged() Q_DECL_OVERRIDE;
+ virtual void transformChanged() Q_DECL_OVERRIDE;
// Override to lock the QBlittable before using raster
- void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
- void fillPath(const QPainterPath &path, QSpanData *fillData);
- void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- void drawEllipse(const QRectF &rect);
- void drawImage(const QPointF &p, const QImage &img);
+ void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE;
+ void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE;
+ void fillPath(const QPainterPath &path, QSpanData *fillData) Q_DECL_OVERRIDE;
+ void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE;
+ void drawEllipse(const QRectF &rect) Q_DECL_OVERRIDE;
+ void drawImage(const QPointF &p, const QImage &img) Q_DECL_OVERRIDE;
void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
- Qt::ImageConversionFlags flags = Qt::AutoColor);
- void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
- void drawTextItem(const QPointF &p, const QTextItem &textItem);
- void drawPoints(const QPointF *points, int pointCount);
- void drawPoints(const QPoint *points, int pointCount);
- void stroke(const QVectorPath &path, const QPen &pen);
- void drawStaticTextItem(QStaticTextItem *);
- bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions, QFontEngine *fontEngine);
+ Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
+ void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr) Q_DECL_OVERRIDE;
+ void drawTextItem(const QPointF &p, const QTextItem &textItem) Q_DECL_OVERRIDE;
+ void drawPoints(const QPointF *points, int pointCount) Q_DECL_OVERRIDE;
+ void drawPoints(const QPoint *points, int pointCount) Q_DECL_OVERRIDE;
+ void stroke(const QVectorPath &path, const QPen &pen) Q_DECL_OVERRIDE;
+ void drawStaticTextItem(QStaticTextItem *) Q_DECL_OVERRIDE;
+ bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
+ QFontEngine *fontEngine) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 05ccff5de0..b8ab98e290 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1338,9 +1338,9 @@ void QRasterPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
*/
-/*!
- \internal
-*/
+///*!
+// \internal
+//*/
void QRasterPaintEngine::fillPath(const QPainterPath &path, QSpanData *fillData)
{
#ifdef QT_DEBUG_DRAW
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 4e6e0b2f73..7ac1630692 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -128,20 +128,20 @@ public:
QRasterPaintEngine(QPaintDevice *device);
~QRasterPaintEngine();
- bool begin(QPaintDevice *device);
- bool end();
-
- void penChanged();
- void brushChanged();
- void brushOriginChanged();
- void opacityChanged();
- void compositionModeChanged();
- void renderHintsChanged();
- void transformChanged();
- void clipEnabledChanged();
-
- void setState(QPainterState *s);
- QPainterState *createState(QPainterState *orig) const;
+ bool begin(QPaintDevice *device) Q_DECL_OVERRIDE;
+ bool end() Q_DECL_OVERRIDE;
+
+ void penChanged() Q_DECL_OVERRIDE;
+ void brushChanged() Q_DECL_OVERRIDE;
+ void brushOriginChanged() Q_DECL_OVERRIDE;
+ void opacityChanged() Q_DECL_OVERRIDE;
+ void compositionModeChanged() Q_DECL_OVERRIDE;
+ void renderHintsChanged() Q_DECL_OVERRIDE;
+ void transformChanged() Q_DECL_OVERRIDE;
+ void clipEnabledChanged() Q_DECL_OVERRIDE;
+
+ void setState(QPainterState *s) Q_DECL_OVERRIDE;
+ QPainterState *createState(QPainterState *orig) const Q_DECL_OVERRIDE;
inline QRasterPaintEngineState *state() {
return static_cast<QRasterPaintEngineState *>(QPaintEngineEx::state());
}
@@ -154,42 +154,43 @@ public:
void updateMatrix(const QTransform &matrix);
- void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
- void fillPath(const QPainterPath &path, QSpanData *fillData);
- void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
+ virtual void fillPath(const QPainterPath &path, QSpanData *fillData);
+ virtual void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- void drawEllipse(const QRectF &rect);
+ void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE;
+ void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE;
- void fillRect(const QRectF &rect, const QBrush &brush);
- void fillRect(const QRectF &rect, const QColor &color);
+ void drawEllipse(const QRectF &rect) Q_DECL_OVERRIDE;
- void drawRects(const QRect *rects, int rectCount);
- void drawRects(const QRectF *rects, int rectCount);
+ void fillRect(const QRectF &rect, const QBrush &brush) Q_DECL_OVERRIDE;
+ void fillRect(const QRectF &rect, const QColor &color) Q_DECL_OVERRIDE;
- void drawPixmap(const QPointF &p, const QPixmap &pm);
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
- void drawImage(const QPointF &p, const QImage &img);
+ void drawRects(const QRect *rects, int rectCount) Q_DECL_OVERRIDE;
+ void drawRects(const QRectF *rects, int rectCount) Q_DECL_OVERRIDE;
+
+ void drawPixmap(const QPointF &p, const QPixmap &pm) Q_DECL_OVERRIDE;
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE;
+ void drawImage(const QPointF &p, const QImage &img) Q_DECL_OVERRIDE;
void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
- Qt::ImageConversionFlags flags = Qt::AutoColor);
- void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
- void drawTextItem(const QPointF &p, const QTextItem &textItem);
+ Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
+ void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr) Q_DECL_OVERRIDE;
+ void drawTextItem(const QPointF &p, const QTextItem &textItem) Q_DECL_OVERRIDE;
- void drawLines(const QLine *line, int lineCount);
- void drawLines(const QLineF *line, int lineCount);
+ void drawLines(const QLine *line, int lineCount) Q_DECL_OVERRIDE;
+ void drawLines(const QLineF *line, int lineCount) Q_DECL_OVERRIDE;
- void drawPoints(const QPointF *points, int pointCount);
- void drawPoints(const QPoint *points, int pointCount);
+ void drawPoints(const QPointF *points, int pointCount) Q_DECL_OVERRIDE;
+ void drawPoints(const QPoint *points, int pointCount) Q_DECL_OVERRIDE;
- void stroke(const QVectorPath &path, const QPen &pen);
- void fill(const QVectorPath &path, const QBrush &brush);
+ void stroke(const QVectorPath &path, const QPen &pen) Q_DECL_OVERRIDE;
+ void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE;
- void clip(const QVectorPath &path, Qt::ClipOperation op);
- void clip(const QRect &rect, Qt::ClipOperation op);
- void clip(const QRegion &region, Qt::ClipOperation op);
+ void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
+ void clip(const QRect &rect, Qt::ClipOperation op) Q_DECL_OVERRIDE;
+ void clip(const QRegion &region, Qt::ClipOperation op) Q_DECL_OVERRIDE;
inline const QClipData *clipData() const;
- void drawStaticTextItem(QStaticTextItem *textItem);
+ void drawStaticTextItem(QStaticTextItem *textItem) Q_DECL_OVERRIDE;
virtual bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
QFontEngine *fontEngine);
@@ -219,12 +220,12 @@ public:
QRasterBuffer *rasterBuffer();
void alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h);
- Type type() const { return Raster; }
+ Type type() const Q_DECL_OVERRIDE { return Raster; }
- QPoint coordinateOffset() const;
+ QPoint coordinateOffset() const Q_DECL_OVERRIDE;
- bool requiresPretransformedGlyphPositions(QFontEngine *fontEngine, const QTransform &m) const;
- bool shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const;
+ bool requiresPretransformedGlyphPositions(QFontEngine *fontEngine, const QTransform &m) const Q_DECL_OVERRIDE;
+ bool shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const Q_DECL_OVERRIDE;
protected:
QRasterPaintEngine(QRasterPaintEnginePrivate &d, QPaintDevice *);
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 48010c0a71..558ab81847 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1856,6 +1856,8 @@ bool QPainterPath::contains(const QPointF &pt) const
: ((winding_number % 2) != 0));
}
+enum PainterDirections { Left, Right, Top, Bottom };
+
static bool qt_painterpath_isect_line_rect(qreal x1, qreal y1, qreal x2, qreal y2,
const QRectF &rect)
{
@@ -1864,7 +1866,6 @@ static bool qt_painterpath_isect_line_rect(qreal x1, qreal y1, qreal x2, qreal y
qreal top = rect.top();
qreal bottom = rect.bottom();
- enum { Left, Right, Top, Bottom };
// clip the lines, after cohen-sutherland, see e.g. http://www.nondot.org/~sabre/graphpro/line6.html
int p1 = ((x1 < left) << Left)
| ((x1 > right) << Right)
diff --git a/src/gui/painting/qrgba64.h b/src/gui/painting/qrgba64.h
index fab9506ff2..51b37b2ef4 100644
--- a/src/gui/painting/qrgba64.h
+++ b/src/gui/painting/qrgba64.h
@@ -44,7 +44,7 @@ class QRgba64 {
// Make sure that the representation always has the order: red green blue alpha, independent
// of byte order. This way, vector operations that assume 4 16-bit values see the correct ones.
- enum {
+ enum Shifts {
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
RedShift = 48,
GreenShift = 32,
diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp
index 7735fd6b46..ea6c5d1984 100644
--- a/src/gui/text/qabstracttextdocumentlayout.cpp
+++ b/src/gui/text/qabstracttextdocumentlayout.cpp
@@ -447,8 +447,8 @@ void QAbstractTextDocumentLayout::unregisterHandler(int objectType, QObject *com
{
Q_D(QAbstractTextDocumentLayout);
- HandlerHash::iterator it = d->handlers.find(objectType);
- if (it != d->handlers.end() && (!component || component == it->component)) {
+ const auto it = d->handlers.constFind(objectType);
+ if (it != d->handlers.cend() && (!component || component == it->component)) {
if (component)
disconnect(component, SIGNAL(destroyed(QObject*)), this, SLOT(_q_handlerDestroyed(QObject*)));
d->handlers.erase(it);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 947c538234..ed4a932a32 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -549,7 +549,7 @@ QFont::QFont(const QFont &font, QPaintDevice *pd)
d->dpi = dpi;
d->screen = screen;
} else {
- d = font.d.data();
+ d = font.d;
}
}
@@ -654,7 +654,7 @@ QFont::QFont(const QString &family, int pointSize, int weight, bool italic)
Constructs a font that is a copy of \a font.
*/
QFont::QFont(const QFont &font)
- : d(font.d.data()), resolve_mask(font.resolve_mask)
+ : d(font.d), resolve_mask(font.resolve_mask)
{
}
@@ -670,7 +670,7 @@ QFont::~QFont()
*/
QFont &QFont::operator=(const QFont &font)
{
- d = font.d.data();
+ d = font.d;
resolve_mask = font.resolve_mask;
return *this;
}
@@ -1647,8 +1647,8 @@ bool QFont::operator<(const QFont &f) const
{
if (f.d == d) return false;
// the < operator for fontdefs ignores point sizes.
- QFontDef &r1 = f.d->request;
- QFontDef &r2 = d->request;
+ const QFontDef &r1 = f.d->request;
+ const QFontDef &r2 = d->request;
if (r1.pointSize != r2.pointSize) return r1.pointSize < r2.pointSize;
if (r1.pixelSize != r2.pixelSize) return r1.pixelSize < r2.pixelSize;
if (r1.weight != r2.weight) return r1.weight < r2.weight;
@@ -2388,7 +2388,7 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
that is not screen-compatible.
*/
QFontInfo::QFontInfo(const QFont &font)
- : d(font.d.data())
+ : d(font.d)
{
}
@@ -2396,7 +2396,7 @@ QFontInfo::QFontInfo(const QFont &font)
Constructs a copy of \a fi.
*/
QFontInfo::QFontInfo(const QFontInfo &fi)
- : d(fi.d.data())
+ : d(fi.d)
{
}
@@ -2412,7 +2412,7 @@ QFontInfo::~QFontInfo()
*/
QFontInfo &QFontInfo::operator=(const QFontInfo &fi)
{
- d = fi.d.data();
+ d = fi.d;
return *this;
}
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 1b9852c20c..2f8af2315d 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -1388,7 +1388,7 @@ QString QFontDatabase::styleString(const QFontInfo &fontInfo)
*/
QFontDatabase::QFontDatabase()
{
- if (!qApp || !QGuiApplicationPrivate::platformIntegration())
+ if (Q_UNLIKELY(!qApp || !QGuiApplicationPrivate::platformIntegration()))
qFatal("QFontDatabase: Must construct a QGuiApplication before accessing QFontDatabase");
QMutexLocker locker(fontDatabaseMutex());
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 5bc9fe3c7f..0fc7fc9242 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -145,7 +145,7 @@ extern void qt_format_text(const QFont& font, const QRectF &_r,
metrics that are compatible with a certain paint device.
*/
QFontMetrics::QFontMetrics(const QFont &font)
- : d(font.d.data())
+ : d(font.d)
{
}
@@ -171,7 +171,7 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
d->dpi = dpi;
d->screen = screen;
} else {
- d = font.d.data();
+ d = font.d;
}
}
@@ -180,7 +180,7 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
Constructs a copy of \a fm.
*/
QFontMetrics::QFontMetrics(const QFontMetrics &fm)
- : d(fm.d.data())
+ : d(fm.d)
{
}
@@ -197,7 +197,7 @@ QFontMetrics::~QFontMetrics()
*/
QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm)
{
- d = fm.d.data();
+ d = fm.d;
return *this;
}
@@ -995,7 +995,7 @@ int QFontMetrics::lineWidth() const
from the given \a fontMetrics object.
*/
QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics)
- : d(fontMetrics.d.data())
+ : d(fontMetrics.d)
{
}
@@ -1006,7 +1006,7 @@ QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics)
*/
QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other)
{
- d = other.d.data();
+ d = other.d;
return *this;
}
@@ -1034,7 +1034,7 @@ QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other)
metrics that are compatible with a certain paint device.
*/
QFontMetricsF::QFontMetricsF(const QFont &font)
- : d(font.d.data())
+ : d(font.d)
{
}
@@ -1060,7 +1060,7 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
d->dpi = dpi;
d->screen = screen;
} else {
- d = font.d.data();
+ d = font.d;
}
}
@@ -1069,7 +1069,7 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
Constructs a copy of \a fm.
*/
QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm)
- : d(fm.d.data())
+ : d(fm.d)
{
}
@@ -1086,7 +1086,7 @@ QFontMetricsF::~QFontMetricsF()
*/
QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm)
{
- d = fm.d.data();
+ d = fm.d;
return *this;
}
diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp
index 0695c2eff4..113e1d89d4 100644
--- a/src/gui/text/qplatformfontdatabase.cpp
+++ b/src/gui/text/qplatformfontdatabase.cpp
@@ -511,7 +511,7 @@ static const quint8 requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] =
{ 14, 127 }, // Nko
};
-enum {
+enum CsbBits {
Latin1CsbBit = 0,
CentralEuropeCsbBit = 1,
TurkishCsbBit = 4,
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 0fd5f510c7..b74ce23631 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -44,6 +44,7 @@
#include <qpa/qplatformfontdatabase.h>
#include <QtCore/qendian.h>
+#include <QtCore/qfile.h>
QT_BEGIN_NAMESPACE
@@ -687,7 +688,7 @@ extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSyst
QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writingSystem)
{
QRawFont rawFont;
- QFontPrivate *font_d = QFontPrivate::get(font);
+ const QFontPrivate *font_d = QFontPrivate::get(font);
int script = qt_script_for_writing_system(writingSystem);
QFontEngine *fe = font_d->engineForScript(script);
diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp
index f180a839b7..f300c18198 100644
--- a/src/gui/text/qsyntaxhighlighter.cpp
+++ b/src/gui/text/qsyntaxhighlighter.cpp
@@ -44,6 +44,8 @@
#include <qdebug.h>
#include <qtimer.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
class QSyntaxHighlighterPrivate : public QObjectPrivate
@@ -96,15 +98,15 @@ void QSyntaxHighlighterPrivate::applyFormatChanges()
const int preeditAreaLength = layout->preeditAreaText().length();
if (preeditAreaLength != 0) {
- QVector<QTextLayout::FormatRange>::Iterator it = ranges.begin();
- while (it != ranges.end()) {
- if (it->start >= preeditAreaStart
- && it->start + it->length <= preeditAreaStart + preeditAreaLength) {
- ++it;
- } else {
- it = ranges.erase(it);
- formatsChanged = true;
- }
+ auto isOutsidePreeditArea = [=](const QTextLayout::FormatRange &range) {
+ return range.start < preeditAreaStart
+ || range.start + range.length > preeditAreaStart + preeditAreaLength;
+ };
+ const auto it = std::remove_if(ranges.begin(), ranges.end(),
+ isOutsidePreeditArea);
+ if (it != ranges.end()) {
+ ranges.erase(it, ranges.end());
+ formatsChanged = true;
}
} else if (!ranges.isEmpty()) {
ranges.clear();
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 1c924175e2..2f755d0c25 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1548,7 +1548,7 @@ void QTextEngine::validate() const
if (block.docHandle()) {
layoutData->string = block.text();
if (option.flags() & QTextOption::ShowLineAndParagraphSeparators)
- layoutData->string += QLatin1Char(block.next().isValid() ? 0xb6 : 0x20);
+ layoutData->string += QLatin1Char(block.next().isValid() ? 0xb6 : 0xA7);
} else {
layoutData->string = text;
}
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index f8f41bb53d..a09ed2c040 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -1140,6 +1140,7 @@ void QTextHtmlParserNode::setListStyle(const QVector<QCss::Value> &cssValues)
for (int i = 0; i < cssValues.count(); ++i) {
if (cssValues.at(i).type == QCss::Value::KnownIdentifier) {
switch (static_cast<QCss::KnownValue>(cssValues.at(i).variant.toInt())) {
+ case QCss::Value_None: hasOwnListStyle = true; listStyle = QTextListFormat::ListStyleUndefined; break;
case QCss::Value_Disc: hasOwnListStyle = true; listStyle = QTextListFormat::ListDisc; break;
case QCss::Value_Square: hasOwnListStyle = true; listStyle = QTextListFormat::ListSquare; break;
case QCss::Value_Circle: hasOwnListStyle = true; listStyle = QTextListFormat::ListCircle; break;
@@ -1495,6 +1496,8 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
node->listStyle = QTextListFormat::ListDisc;
else if (value == QLatin1String("circle"))
node->listStyle = QTextListFormat::ListCircle;
+ else if (value == QLatin1String("none"))
+ node->listStyle = QTextListFormat::ListStyleUndefined;
}
}
break;
diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp
index 16d81a7d6d..d7a418e7c8 100644
--- a/src/gui/text/qtextimagehandler.cpp
+++ b/src/gui/text/qtextimagehandler.cpp
@@ -38,6 +38,7 @@
#include <qtextformat.h>
#include <qpainter.h>
#include <qdebug.h>
+#include <qfile.h>
#include <private/qtextengine_p.h>
#include <qpalette.h>
#include <qthread.h>
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index df7c8b9c71..6552309dcb 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -663,6 +663,8 @@ QTextFrame::iterator::iterator(QTextFrame *frame, int block, int begin, int end)
cb = block;
}
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+
/*!
Copy constructor. Constructs a copy of the \a other iterator.
*/
@@ -689,6 +691,8 @@ QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other)
return *this;
}
+#endif
+
/*!
Returns the current frame pointed to by the iterator, or 0 if the
iterator currently points to a block.
diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h
index fbb90e42b0..29eeddc414 100644
--- a/src/gui/text/qtextobject.h
+++ b/src/gui/text/qtextobject.h
@@ -143,8 +143,10 @@ public:
iterator(QTextFrame *frame, int block, int begin, int end);
public:
iterator();
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
iterator(const iterator &o);
iterator &operator=(const iterator &o);
+#endif
QTextFrame *parentFrame() const { return f; }
@@ -248,7 +250,9 @@ public:
iterator(const QTextDocumentPrivate *priv, int begin, int end, int f) : p(priv), b(begin), e(end), n(f) {}
public:
iterator() : p(Q_NULLPTR), b(0), e(0), n(0) {}
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
iterator(const iterator &o) : p(o.p), b(o.b), e(o.e), n(o.n) {}
+#endif
QTextFragment fragment() const;
diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp
index 31dfd20d1a..aceda62a2a 100644
--- a/src/gui/util/qvalidator.cpp
+++ b/src/gui/util/qvalidator.cpp
@@ -38,6 +38,7 @@
#ifndef QT_NO_VALIDATOR
#include "private/qobject_p.h"
#include "private/qlocale_p.h"
+#include "private/qnumeric_p.h"
#include <limits.h>
#include <cmath>
@@ -398,8 +399,8 @@ static qlonglong pow10(int exp)
QValidator::State QIntValidator::validate(QString & input, int&) const
{
QByteArray buff;
- if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff,
- -1, locale().numberOptions() & QLocale::RejectGroupSeparator)) {
+ if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff, -1,
+ locale().numberOptions())) {
return Invalid;
}
@@ -438,8 +439,8 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
void QIntValidator::fixup(QString &input) const
{
QByteArray buff;
- if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff,
- -1, locale().numberOptions() & QLocale::RejectGroupSeparator)) {
+ if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff, -1,
+ locale().numberOptions())) {
return;
}
bool ok, overflow;
@@ -662,8 +663,7 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL
{
Q_Q(const QDoubleValidator);
QByteArray buff;
- if (!locale.d->m_data->validateChars(input, numMode, &buff, q->dec,
- locale.numberOptions() & QLocale::RejectGroupSeparator)) {
+ if (!locale.d->m_data->validateChars(input, numMode, &buff, q->dec, locale.numberOptions())) {
return QValidator::Invalid;
}
@@ -676,9 +676,9 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL
if (q->t < 0 && buff.startsWith('+'))
return QValidator::Invalid;
- bool ok, overflow;
- double i = QLocaleData::bytearrayToDouble(buff.constData(), &ok, &overflow);
- if (overflow)
+ bool ok = false;
+ double i = buff.toDouble(&ok); // returns 0.0 if !ok
+ if (i == qt_qnan())
return QValidator::Invalid;
if (!ok)
return QValidator::Intermediate;
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index e829d52cbe..42c7c80f3b 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -78,6 +78,8 @@ ios {
OBJECTIVE_SOURCES += \
access/qnetworkreplynsurlconnectionimpl.mm
+
+ LIBS_PRIVATE += -framework Foundation
}
include($$PWD/../../3rdparty/zlib_dependency.pri)
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index c4cb8e65c0..bfe3eb9252 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -263,7 +263,7 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair)
request.setContentLength(uploadByteDevice->size());
} else if (request.contentLength() != -1 && uploadByteDevice->size() == -1) {
// everything OK, the user supplied us the contentLength
- } else if (request.contentLength() == -1 && uploadByteDevice->size() == -1) {
+ } else if (Q_UNLIKELY(request.contentLength() == -1 && uploadByteDevice->size() == -1)) {
qFatal("QHttpNetworkConnectionPrivate: Neither content-length nor upload device size were given");
}
}
@@ -1131,7 +1131,7 @@ void QHttpNetworkConnectionPrivate::startHostInfoLookup()
}
-void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(QHostInfo info)
+void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info)
{
bool bIpv4 = false;
bool bIpv6 = false;
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 9af39d416a..fe7f7c9b55 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -224,7 +224,7 @@ public:
// private slots
void _q_startNextRequest(); // send the next request from the queue
- void _q_hostLookupFinished(QHostInfo info);
+ void _q_hostLookupFinished(const QHostInfo &info);
void _q_connectDelayedChannel();
void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request);
diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h
index 784e9c14b8..eb22b40ba0 100644
--- a/src/network/access/qhttpthreaddelegate_p.h
+++ b/src/network/access/qhttpthreaddelegate_p.h
@@ -130,14 +130,14 @@ signals:
#ifndef QT_NO_SSL
void encrypted();
void sslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
- void sslConfigurationChanged(const QSslConfiguration);
+ void sslConfigurationChanged(const QSslConfiguration &);
void preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator *);
#endif
- void downloadMetaData(QList<QPair<QByteArray,QByteArray> >, int, QString, bool,
+ void downloadMetaData(const QList<QPair<QByteArray,QByteArray> > &, int, const QString &, bool,
QSharedPointer<char>, qint64, bool);
void downloadProgress(qint64, qint64);
- void downloadData(QByteArray);
- void error(QNetworkReply::NetworkError, const QString);
+ void downloadData(const QByteArray &);
+ void error(QNetworkReply::NetworkError, const QString &);
void downloadFinished();
void redirected(const QUrl &url, int httpStatus, int maxRedirectsRemainig);
@@ -285,7 +285,7 @@ public:
public slots:
// From user thread:
- void haveDataSlot(qint64 pos, QByteArray dataArray, bool dataAtEnd, qint64 dataSize)
+ void haveDataSlot(qint64 pos, const QByteArray &dataArray, bool dataAtEnd, qint64 dataSize)
{
if (pos != m_pos) {
// Sometimes when re-sending a request in the qhttpnetwork* layer there is a pending haveData from the
diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp
index 3f705450dd..5988c34433 100644
--- a/src/network/access/qnetworkdiskcache.cpp
+++ b/src/network/access/qnetworkdiskcache.cpp
@@ -231,8 +231,8 @@ void QNetworkDiskCache::insert(QIODevice *device)
qDebug() << "QNetworkDiskCache::insert()" << device;
#endif
Q_D(QNetworkDiskCache);
- QHash<QIODevice*, QCacheItem*>::iterator it = d->inserting.find(device);
- if (it == d->inserting.end()) {
+ const auto it = d->inserting.constFind(device);
+ if (Q_UNLIKELY(it == d->inserting.cend())) {
qWarning() << "QNetworkDiskCache::insert() called on a device we don't know about" << device;
return;
}
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 04d391a14c..9aa1d52d01 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -993,7 +993,7 @@ void QNetworkReplyHttpImplPrivate::initCacheSaveDevice()
q->connect(cacheSaveDevice, SIGNAL(aboutToClose()), SLOT(_q_cacheSaveDeviceAboutToClose()));
if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) {
- if (cacheSaveDevice && !cacheSaveDevice->isOpen())
+ if (Q_UNLIKELY(cacheSaveDevice && !cacheSaveDevice->isOpen()))
qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- "
"class %s probably needs to be fixed",
managerPrivate->networkCache->metaObject()->className());
@@ -1162,11 +1162,10 @@ void QNetworkReplyHttpImplPrivate::checkForRedirect(const int statusCode)
}
}
-void QNetworkReplyHttpImplPrivate::replyDownloadMetaData
- (QList<QPair<QByteArray,QByteArray> > hm,
- int sc,QString rp,bool pu,
- QSharedPointer<char> db,
- qint64 contentLength, bool spdyWasUsed)
+void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByteArray,QByteArray> > &hm,
+ int sc, const QString &rp, bool pu,
+ QSharedPointer<char> db,
+ qint64 contentLength, bool spdyWasUsed)
{
Q_Q(QNetworkReplyHttpImpl);
Q_UNUSED(contentLength);
@@ -1733,7 +1732,7 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation()
// ensure this function is only being called once
if (state == Working) {
- qDebug("QNetworkReplyImpl::_q_startOperation was called more than once");
+ qDebug() << "QNetworkReplyHttpImplPrivate::_q_startOperation was called more than once" << url;
return;
}
state = Working;
@@ -2216,7 +2215,7 @@ void QNetworkReplyHttpImplPrivate::setCachingEnabled(bool enable)
return; // nothing to do either!
if (enable) {
- if (bytesDownloaded) {
+ if (Q_UNLIKELY(bytesDownloaded)) {
qDebug() << "setCachingEnabled: " << bytesDownloaded << " bytesDownloaded";
// refuse to enable in this case
qCritical("QNetworkReplyImpl: backend error: caching was enabled after some bytes had been written");
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index 44d51d82a4..25762be5f9 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -147,7 +147,7 @@ signals:
void startHttpRequestSynchronously();
- void haveUploadData(const qint64 pos, QByteArray dataArray, bool dataAtEnd, qint64 dataSize);
+ void haveUploadData(const qint64 pos, const QByteArray &dataArray, bool dataAtEnd, qint64 dataSize);
};
class QNetworkReplyHttpImplPrivate: public QNetworkReplyPrivate
@@ -273,8 +273,8 @@ public:
// From HTTP thread:
void replyDownloadData(QByteArray);
void replyFinished();
- void replyDownloadMetaData(QList<QPair<QByteArray,QByteArray> >, int, QString, bool,
- QSharedPointer<char>, qint64, bool);
+ void replyDownloadMetaData(const QList<QPair<QByteArray,QByteArray> > &, int, const QString &,
+ bool, QSharedPointer<char>, qint64, bool);
void replyDownloadProgressSlot(qint64,qint64);
void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth);
void httpError(QNetworkReply::NetworkError error, const QString &errorString);
diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp
index 7961a1dbae..681c88e87b 100644
--- a/src/network/access/qnetworkreplyimpl.cpp
+++ b/src/network/access/qnetworkreplyimpl.cpp
@@ -67,7 +67,7 @@ void QNetworkReplyImplPrivate::_q_startOperation()
{
// ensure this function is only being called once
if (state == Working || state == Finished) {
- qDebug("QNetworkReplyImpl::_q_startOperation was called more than once");
+ qDebug() << "QNetworkReplyImpl::_q_startOperation was called more than once" << url;
return;
}
state = Working;
@@ -517,7 +517,7 @@ void QNetworkReplyImplPrivate::setCachingEnabled(bool enable)
return; // nothing to do either!
if (enable) {
- if (bytesDownloaded) {
+ if (Q_UNLIKELY(bytesDownloaded)) {
// refuse to enable in this case
qCritical("QNetworkReplyImpl: backend error: caching was enabled after some bytes had been written");
return;
@@ -606,7 +606,7 @@ void QNetworkReplyImplPrivate::initCacheSaveDevice()
cacheSaveDevice = networkCache()->prepare(metaData);
if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) {
- if (cacheSaveDevice && !cacheSaveDevice->isOpen())
+ if (Q_UNLIKELY(cacheSaveDevice && !cacheSaveDevice->isOpen()))
qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- "
"class %s probably needs to be fixed",
networkCache()->metaObject()->className());
@@ -680,7 +680,7 @@ void QNetworkReplyImplPrivate::appendDownstreamData(QIODevice *data)
return;
// read until EOF from data
- if (copyDevice) {
+ if (Q_UNLIKELY(copyDevice)) {
qCritical("QNetworkReplyImpl: copy from QIODevice already in progress -- "
"backend probly needs to be fixed");
return;
diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp
index 5f9697ab92..ea0f152eb0 100644
--- a/src/network/access/qspdyprotocolhandler.cpp
+++ b/src/network/access/qspdyprotocolhandler.cpp
@@ -601,7 +601,7 @@ void QSpdyProtocolHandler::sendControlFrame(FrameType type,
Q_UNUSED(written); // silence -Wunused-variable
}
-void QSpdyProtocolHandler::sendSYN_STREAM(HttpMessagePair messagePair,
+void QSpdyProtocolHandler::sendSYN_STREAM(const HttpMessagePair &messagePair,
qint32 streamID, qint32 associatedToStreamID)
{
QHttpNetworkRequest request = messagePair.first;
diff --git a/src/network/access/qspdyprotocolhandler_p.h b/src/network/access/qspdyprotocolhandler_p.h
index ed71878cd4..35f5b47360 100644
--- a/src/network/access/qspdyprotocolhandler_p.h
+++ b/src/network/access/qspdyprotocolhandler_p.h
@@ -166,7 +166,7 @@ private:
void sendControlFrame(FrameType type, ControlFrameFlags flags, const char *data, quint32 length);
- void sendSYN_STREAM(HttpMessagePair pair, qint32 streamID,
+ void sendSYN_STREAM(const HttpMessagePair &pair, qint32 streamID,
qint32 associatedToStreamID);
void sendRST_STREAM(qint32 streamID, RST_STREAM_STATUS_CODE statusCode);
void sendPING(quint32 pingID);
diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp
index 71e435b771..9c761f9479 100644
--- a/src/network/bearer/qnetworkconfigmanager_p.cpp
+++ b/src/network/bearer/qnetworkconfigmanager_p.cpp
@@ -380,7 +380,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations()
#ifndef QT_NO_LIBRARY
bool envOK = false;
- const int skipGeneric = qgetenv("QT_EXCLUDE_GENERIC_BEARER").toInt(&envOK);
+ const int skipGeneric = qEnvironmentVariableIntValue("QT_EXCLUDE_GENERIC_BEARER", &envOK);
QBearerEngine *generic = 0;
QFactoryLoader *l = loader();
const PluginKeyMap keyMap = l->keyMap();
@@ -477,7 +477,7 @@ void QNetworkConfigurationManagerPrivate::startPolling()
if (!pollTimer) {
pollTimer = new QTimer(this);
bool ok;
- int interval = qgetenv("QT_BEARER_POLL_TIMEOUT").toInt(&ok);
+ int interval = qEnvironmentVariableIntValue("QT_BEARER_POLL_TIMEOUT", &ok);
if (!ok)
interval = 10000;//default 10 seconds
pollTimer->setInterval(interval);
diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp
index 378245ce3e..b68abce380 100644
--- a/src/network/bearer/qnetworkconfiguration.cpp
+++ b/src/network/bearer/qnetworkconfiguration.cpp
@@ -35,11 +35,6 @@
#include "qnetworkconfiguration_p.h"
#include <QDebug>
-#ifdef Q_OS_BLACKBERRY
-#include "private/qcore_unix_p.h" // qt_safe_open
-#include <sys/pps.h>
-#endif // Q_OS_BLACKBERRY
-
QT_BEGIN_NAMESPACE
/*!
@@ -202,77 +197,6 @@ QT_BEGIN_NAMESPACE
\value BearerLTE The configuration is for a LTE (4G) interface.
*/
-#ifdef Q_OS_BLACKBERRY
-static const char cellularStatusFile[] = "/pps/services/radioctrl/modem0/status_public";
-
-static QNetworkConfiguration::BearerType cellularStatus()
-{
- QNetworkConfiguration::BearerType ret = QNetworkConfiguration::BearerUnknown;
-
- int cellularStatusFD;
- if ((cellularStatusFD = qt_safe_open(cellularStatusFile, O_RDONLY)) == -1) {
- qWarning() << "failed to open" << cellularStatusFile;
- return ret;
- }
- char buf[2048];
- if (qt_safe_read(cellularStatusFD, &buf, sizeof(buf)) == -1) {
- qWarning() << "read from PPS file failed:" << strerror(errno);
- qt_safe_close(cellularStatusFD);
- return ret;
- }
- pps_decoder_t ppsDecoder;
- if (pps_decoder_initialize(&ppsDecoder, buf) != PPS_DECODER_OK) {
- qWarning("failed to initialize PPS decoder");
- qt_safe_close(cellularStatusFD);
- return ret;
- }
- pps_decoder_error_t err;
- if ((err = pps_decoder_push(&ppsDecoder, 0)) != PPS_DECODER_OK) {
- qWarning() << "pps_decoder_push failed" << err;
- pps_decoder_cleanup(&ppsDecoder);
- qt_safe_close(cellularStatusFD);
- return ret;
- }
- if (!pps_decoder_is_integer(&ppsDecoder, "network_technology")) {
- qWarning("field has not the expected data type");
- pps_decoder_cleanup(&ppsDecoder);
- qt_safe_close(cellularStatusFD);
- return ret;
- }
- int type;
- if (!pps_decoder_get_int(&ppsDecoder, "network_technology", &type)
- == PPS_DECODER_OK) {
- qWarning("could not read bearer type from PPS");
- pps_decoder_cleanup(&ppsDecoder);
- qt_safe_close(cellularStatusFD);
- return ret;
- }
- switch (type) {
- case 0: // 0 == NONE
- break; // unhandled
- case 1: // fallthrough, 1 == GSM
- case 4: // 4 == CDMA_1X
- ret = QNetworkConfiguration::Bearer2G;
- break;
- case 2: // 2 == UMTS
- ret = QNetworkConfiguration::BearerWCDMA;
- break;
- case 8: // 8 == EVDO
- ret = QNetworkConfiguration::BearerEVDO;
- break;
- case 16: // 16 == LTE
- ret = QNetworkConfiguration::BearerLTE;
- break;
- default:
- qWarning() << "unhandled bearer type" << type;
- break;
- }
- pps_decoder_cleanup(&ppsDecoder);
- qt_safe_close(cellularStatusFD);
- return ret;
-}
-#endif // Q_OS_BLACKBERRY
-
/*!
Constructs an invalid configuration object.
@@ -494,19 +418,6 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerType() const
return BearerUnknown;
QMutexLocker locker(&d->mutex);
-
-#ifdef Q_OS_BLACKBERRY
- // for cellular configurations, we need to determine the exact
- // type right now, because it might have changed after the last scan
- if (d->bearerType == QNetworkConfiguration::Bearer2G) {
- QNetworkConfiguration::BearerType type = cellularStatus();
- // if reading the status failed for some reason, just
- // fall back to 2G
- return (type == QNetworkConfiguration::BearerUnknown)
- ? QNetworkConfiguration::Bearer2G : type;
- }
-#endif // Q_OS_BLACKBERRY
-
return d->bearerType;
}
@@ -639,20 +550,6 @@ QString QNetworkConfiguration::bearerTypeName() const
case BearerWLAN:
return QStringLiteral("WLAN");
case Bearer2G:
-#ifdef Q_OS_BLACKBERRY
- {
- // for cellular configurations, we need to determine the exact
- // type right now, because it might have changed after the last scan
- QNetworkConfiguration::BearerType type = cellularStatus();
- if (type == QNetworkConfiguration::BearerWCDMA) {
- return QStringLiteral("WCDMA");
- } else if (type == QNetworkConfiguration::BearerEVDO) {
- return QStringLiteral("EVDO");
- }else if (type == QNetworkConfiguration::BearerLTE) {
- return QStringLiteral("LTE");
- }
- }
-#endif // Q_OS_BLACKBERRY
return QStringLiteral("2G");
case Bearer3G:
return QStringLiteral("3G");
diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h
index 75df36fbd9..c8d926e32f 100644
--- a/src/network/bearer/qnetworkconfiguration_p.h
+++ b/src/network/bearer/qnetworkconfiguration_p.h
@@ -51,10 +51,6 @@
#include <QtCore/qmutex.h>
#include <QtCore/qmap.h>
-#ifdef Q_OS_BLACKBERRY
-#include <bps/netstatus.h>
-#endif
-
QT_BEGIN_NAMESPACE
typedef QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> QNetworkConfigurationPrivatePointer;
@@ -66,9 +62,6 @@ public:
type(QNetworkConfiguration::Invalid),
purpose(QNetworkConfiguration::UnknownPurpose),
bearerType(QNetworkConfiguration::BearerUnknown),
-#ifdef Q_OS_BLACKBERRY
- oldIpStatus(NETSTATUS_IP_STATUS_ERROR_UNKNOWN),
-#endif
isValid(false), roamingSupported(false)
{}
virtual ~QNetworkConfigurationPrivate()
@@ -89,10 +82,6 @@ public:
QNetworkConfiguration::Purpose purpose;
QNetworkConfiguration::BearerType bearerType;
-#ifdef Q_OS_BLACKBERRY
- netstatus_ip_status_t oldIpStatus;
-#endif
-
bool isValid;
bool roamingSupported;
diff --git a/src/network/bearer/qnetworksession_p.h b/src/network/bearer/qnetworksession_p.h
index f2ecf9902a..652687f07d 100644
--- a/src/network/bearer/qnetworksession_p.h
+++ b/src/network/bearer/qnetworksession_p.h
@@ -106,7 +106,7 @@ protected:
}
inline void setPrivateConfiguration(QNetworkConfiguration &config,
- QNetworkConfigurationPrivatePointer ptr) const
+ const QNetworkConfigurationPrivatePointer &ptr) const
{
config.d = ptr;
}
diff --git a/src/network/bearer/qsharednetworksession.cpp b/src/network/bearer/qsharednetworksession.cpp
index 0879bfbc2b..d2a3c78207 100644
--- a/src/network/bearer/qsharednetworksession.cpp
+++ b/src/network/bearer/qsharednetworksession.cpp
@@ -56,7 +56,7 @@ static void doDeleteLater(QObject* obj)
obj->deleteLater();
}
-QSharedPointer<QNetworkSession> QSharedNetworkSessionManager::getSession(QNetworkConfiguration config)
+QSharedPointer<QNetworkSession> QSharedNetworkSessionManager::getSession(const QNetworkConfiguration &config)
{
QSharedNetworkSessionManager *m(sharedNetworkSessionManager());
//if already have a session, return it
@@ -71,7 +71,7 @@ QSharedPointer<QNetworkSession> QSharedNetworkSessionManager::getSession(QNetwor
return session;
}
-void QSharedNetworkSessionManager::setSession(QNetworkConfiguration config, QSharedPointer<QNetworkSession> session)
+void QSharedNetworkSessionManager::setSession(const QNetworkConfiguration &config, QSharedPointer<QNetworkSession> session)
{
QSharedNetworkSessionManager *m(sharedNetworkSessionManager());
m->sessions[config] = session;
diff --git a/src/network/bearer/qsharednetworksession_p.h b/src/network/bearer/qsharednetworksession_p.h
index 3525c8359c..149e978e4f 100644
--- a/src/network/bearer/qsharednetworksession_p.h
+++ b/src/network/bearer/qsharednetworksession_p.h
@@ -61,8 +61,8 @@ uint qHash(const QNetworkConfiguration& config);
class QSharedNetworkSessionManager
{
public:
- static QSharedPointer<QNetworkSession> getSession(QNetworkConfiguration config);
- static void setSession(QNetworkConfiguration config, QSharedPointer<QNetworkSession> session);
+ static QSharedPointer<QNetworkSession> getSession(const QNetworkConfiguration &config);
+ static void setSession(const QNetworkConfiguration &config, QSharedPointer<QNetworkSession> session);
private:
QHash<QNetworkConfiguration, QWeakPointer<QNetworkSession> > sessions;
};
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index ddb30b7b6f..120a9650ac 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -55,10 +55,6 @@ mac {
mac:!ios:SOURCES += kernel/qnetworkproxy_mac.cpp
else:win32:SOURCES += kernel/qnetworkproxy_win.cpp
-else:blackberry {
- SOURCES += kernel/qnetworkproxy_blackberry.cpp
- LIBS_PRIVATE += -lbps
-}
else:contains(QT_CONFIG, libproxy) {
SOURCES += kernel/qnetworkproxy_libproxy.cpp
LIBS_PRIVATE += -lproxy
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index dc8ec5a300..b78db338ce 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -37,6 +37,7 @@
#include <qscopedpointer.h>
#include <qurl.h>
#include <private/qmutexpool_p.h>
+#include <private/qnativesocketengine_p.h>
#include <sys/types.h>
#include <netinet/in.h>
@@ -160,6 +161,7 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
state._u._ext.nscount6 = 1;
ns->sin6_family = AF_INET6;
ns->sin6_port = htons(53);
+ SetSALen::set(ns, sizeof(*ns));
Q_IPV6ADDR ipv6Address = nameserver.toIPv6Address();
for (int i=0; i<16; i++) {
diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp
index 4a527052d1..81906edc47 100644
--- a/src/network/kernel/qnetworkinterface.cpp
+++ b/src/network/kernel/qnetworkinterface.cpp
@@ -519,6 +519,31 @@ QList<QNetworkAddressEntry> QNetworkInterface::addressEntries() const
}
/*!
+ \since 5.7
+
+ Returns the index of the interface whose name is \a name or 0 if there is
+ no interface with that name. This function should produce the same result
+ as the following code, but will probably execute faster.
+
+ \code
+ QNetworkInterface::interfaceFromName(name).index()
+ \endcode
+
+ \sa interfaceFromName(), interfaceNameFromIndex(), QUdpDatagram::interfaceIndex()
+*/
+int QNetworkInterface::interfaceIndexFromName(const QString &name)
+{
+ if (name.isEmpty())
+ return 0;
+
+ bool ok;
+ uint id = name.toUInt(&ok);
+ if (!ok)
+ id = QNetworkInterfaceManager::interfaceIndexFromName(name);
+ return int(id);
+}
+
+/*!
Returns a QNetworkInterface object for the interface named \a
name. If no such interface exists, this function returns an
invalid QNetworkInterface object.
@@ -553,6 +578,27 @@ QNetworkInterface QNetworkInterface::interfaceFromIndex(int index)
}
/*!
+ \since 5.7
+
+ Returns the name of the interface whose index is \a index or an empty
+ string if there is no interface with that index. This function should
+ produce the same result as the following code, but will probably execute
+ faster.
+
+ \code
+ QNetworkInterface::interfaceFromIndex(index).name()
+ \endcode
+
+ \sa interfaceFromIndex(), interfaceIndexFromName(), QUdpDatagram::interfaceIndex()
+*/
+QString QNetworkInterface::interfaceNameFromIndex(int index)
+{
+ if (!index)
+ return QString();
+ return QNetworkInterfaceManager::interfaceNameFromIndex(index);
+}
+
+/*!
Returns a listing of all the network interfaces found on the host
machine. In case of failure it returns a list with zero elements.
*/
diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h
index b3daa3d4a0..bd57aea1cb 100644
--- a/src/network/kernel/qnetworkinterface.h
+++ b/src/network/kernel/qnetworkinterface.h
@@ -113,8 +113,10 @@ public:
QString hardwareAddress() const;
QList<QNetworkAddressEntry> addressEntries() const;
+ static int interfaceIndexFromName(const QString &name);
static QNetworkInterface interfaceFromName(const QString &name);
static QNetworkInterface interfaceFromIndex(int index);
+ static QString interfaceNameFromIndex(int index);
static QList<QNetworkInterface> allInterfaces();
static QList<QHostAddress> allAddresses();
diff --git a/src/network/kernel/qnetworkinterface_p.h b/src/network/kernel/qnetworkinterface_p.h
index 140a28c536..146ba7820c 100644
--- a/src/network/kernel/qnetworkinterface_p.h
+++ b/src/network/kernel/qnetworkinterface_p.h
@@ -100,6 +100,9 @@ public:
QSharedDataPointer<QNetworkInterfacePrivate> interfaceFromIndex(int index);
QList<QSharedDataPointer<QNetworkInterfacePrivate> > allInterfaces();
+ static uint interfaceIndexFromName(const QString &name);
+ static QString interfaceNameFromIndex(uint index);
+
// convenience:
QSharedDataPointer<QNetworkInterfacePrivate> empty;
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp
index 5e6d24dd44..e7b62effcb 100644
--- a/src/network/kernel/qnetworkinterface_unix.cpp
+++ b/src/network/kernel/qnetworkinterface_unix.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Intel Corporation.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -93,14 +94,8 @@ static QHostAddress addressFromSockaddr(sockaddr *sa, int ifindex = 0, const QSt
// this is the most likely scenario:
// a scope ID in a socket is that of the interface this address came from
address.setScopeId(ifname);
- } else if (scope) {
-#ifndef QT_NO_IPV6IFNAME
- char scopeid[IFNAMSIZ];
- if (::if_indextoname(scope, scopeid)) {
- address.setScopeId(QLatin1String(scopeid));
- } else
-#endif
- address.setScopeId(QString::number(uint(scope)));
+ } else if (scope) {
+ address.setScopeId(QNetworkInterfaceManager::interfaceNameFromIndex(scope));
}
}
return address;
@@ -124,6 +119,53 @@ static QNetworkInterface::InterfaceFlags convertFlags(uint rawFlags)
return flags;
}
+uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name)
+{
+#ifndef QT_NO_IPV6IFNAME
+ return ::if_nametoindex(name.toLatin1());
+#elif defined(SIOCGIFINDEX)
+ struct ifreq req;
+ int socket = qt_safe_socket(AF_INET, SOCK_STREAM, 0);
+ if (socket < 0)
+ return 0;
+
+ QByteArray name8bit = name.toLatin1();
+ memset(&req, 0, sizeof(ifreq));
+ memcpy(req.ifr_name, name8bit, qMin<int>(name8bit.length() + 1, sizeof(req.ifr_name) - 1));
+
+ uint id = 0;
+ if (qt_safe_ioctl(socket, SIOCGIFINDEX, &req) >= 0)
+ id = req.ifr_ifindex;
+ qt_safe_close(socket);
+ return id;
+#else
+ return 0;
+#endif
+}
+
+QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index)
+{
+#ifndef QT_NO_IPV6IFNAME
+ char buf[IF_NAMESIZE];
+ if (::if_indextoname(index, buf))
+ return QString::fromLatin1(buf);
+#elif defined(SIOCGIFNAME)
+ struct ifreq req;
+ int socket = qt_safe_socket(AF_INET, SOCK_STREAM, 0);
+ if (socket >= 0) {
+ memset(&req, 0, sizeof(ifreq));
+ req.ifr_ifindex = index;
+
+ if (qt_safe_ioctl(socket, SIOCGIFNAME, &req) >= 0) {
+ qt_safe_close(socket);
+ return QString::fromLatin1(req.ifr_name);
+ }
+ qt_safe_close(socket);
+ }
+#endif
+ return QString::number(uint(index));
+}
+
#ifdef QT_NO_GETIFADDRS
// getifaddrs not available
@@ -189,7 +231,11 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList<QNetworkInterfa
// Get the interface index
# ifdef SIOCGIFINDEX
if (qt_safe_ioctl(socket, SIOCGIFINDEX, &req) >= 0)
+# if defined(Q_OS_HAIKU)
+ ifindex = req.ifr_index;
+# else
ifindex = req.ifr_ifindex;
+# endif
# else
ifindex = if_nametoindex(req.ifr_name);
# endif
diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp
index 907638f73e..238f913846 100644
--- a/src/network/kernel/qnetworkinterface_win.cpp
+++ b/src/network/kernel/qnetworkinterface_win.cpp
@@ -57,8 +57,14 @@
QT_BEGIN_NAMESPACE
+typedef NETIO_STATUS (WINAPI *PtrConvertInterfaceIndexToLuid)(NET_IFINDEX, PNET_LUID);
typedef NETIO_STATUS (WINAPI *PtrConvertInterfaceLuidToName)(const NET_LUID *, PWSTR, SIZE_T);
+typedef NETIO_STATUS (WINAPI *PtrConvertInterfaceLuidToIndex)(const NET_LUID *, PNET_IFINDEX);
+typedef NETIO_STATUS (WINAPI *PtrConvertInterfaceNameToLuid)(const WCHAR *, PNET_LUID);
+static PtrConvertInterfaceIndexToLuid ptrConvertInterfaceIndexToLuid = 0;
static PtrConvertInterfaceLuidToName ptrConvertInterfaceLuidToName = 0;
+static PtrConvertInterfaceLuidToIndex ptrConvertInterfaceLuidToIndex = 0;
+static PtrConvertInterfaceNameToLuid ptrConvertInterfaceNameToLuid = 0;
static void resolveLibs()
{
@@ -71,10 +77,16 @@ static void resolveLibs()
#if defined(Q_OS_WINCE)
// since Windows Embedded Compact 7
+ ptrConvertInterfaceIndexToLuid = (PtrConvertInterfaceIndexToLuid)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceIndexToLuid");
ptrConvertInterfaceLuidToName = (PtrConvertInterfaceLuidToName)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceLuidToNameW");
+ ptrConvertInterfaceLuidToIndex = (PtrConvertInterfaceLuidToIndex)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceLuidToIndex");
+ ptrConvertInterfaceNameToLuid = (PtrConvertInterfaceNameToLuid)GetProcAddress(iphlpapiHnd, L"ConvertInterfaceNameToLuidW");
#else
// since Windows Vista
+ ptrConvertInterfaceIndexToLuid = (PtrConvertInterfaceIndexToLuid)GetProcAddress(iphlpapiHnd, "ConvertInterfaceIndexToLuid");
ptrConvertInterfaceLuidToName = (PtrConvertInterfaceLuidToName)GetProcAddress(iphlpapiHnd, "ConvertInterfaceLuidToNameW");
+ ptrConvertInterfaceLuidToIndex = (PtrConvertInterfaceLuidToIndex)GetProcAddress(iphlpapiHnd, "ConvertInterfaceLuidToIndex");
+ ptrConvertInterfaceNameToLuid = (PtrConvertInterfaceNameToLuid)GetProcAddress(iphlpapiHnd, "ConvertInterfaceNameToLuidW");
#endif
done = true;
}
@@ -92,13 +104,42 @@ static QHostAddress addressFromSockaddr(sockaddr *sa)
address.setAddress(((sockaddr_in6 *)sa)->sin6_addr.s6_addr);
int scope = ((sockaddr_in6 *)sa)->sin6_scope_id;
if (scope)
- address.setScopeId(QString::number(scope));
+ address.setScopeId(QNetworkInterfaceManager::interfaceNameFromIndex(scope));
} else
qWarning("Got unknown socket family %d", sa->sa_family);
return address;
}
+uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name)
+{
+ resolveLibs();
+ if (!ptrConvertInterfaceNameToLuid || !ptrConvertInterfaceLuidToIndex)
+ return 0;
+
+ NET_IFINDEX id;
+ NET_LUID luid;
+ if (ptrConvertInterfaceNameToLuid(reinterpret_cast<const wchar_t *>(name.constData()), &luid) == NO_ERROR
+ && ptrConvertInterfaceLuidToIndex(&luid, &id) == NO_ERROR)
+ return uint(id);
+ return 0;
+}
+
+QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index)
+{
+ resolveLibs();
+ if (ptrConvertInterfaceIndexToLuid && ptrConvertInterfaceLuidToName) {
+ NET_LUID luid;
+ if (ptrConvertInterfaceIndexToLuid(index, &luid) == NO_ERROR) {
+ WCHAR buf[IF_MAX_STRING_SIZE + 1];
+ if (ptrConvertInterfaceLuidToName(&luid, buf, sizeof(buf)/sizeof(buf[0])) == NO_ERROR)
+ return QString::fromWCharArray(buf);
+ }
+ }
+
+ return QString::number(index);
+}
+
static QHash<QHostAddress, QHostAddress> ipv4Netmasks()
{
//Retrieve all the IPV4 addresses & netmasks
diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp
index 1945b2427f..1e22ab15da 100644
--- a/src/network/kernel/qnetworkinterface_winrt.cpp
+++ b/src/network/kernel/qnetworkinterface_winrt.cpp
@@ -61,6 +61,19 @@ struct HostNameInfo {
QString address;
};
+uint QNetworkInterfaceManager::interfaceIndexFromName(const QString &name)
+{
+ // TBD - may not be possible
+ Q_UNUSED(name);
+ return 0;
+}
+
+QString QNetworkInterfaceManager::interfaceNameFromIndex(uint index)
+{
+ // TBD - may not be possible
+ return QString::number(index);
+}
+
static QNetworkInterfacePrivate *interfaceFromProfile(IConnectionProfile *profile, QList<HostNameInfo> *hostList)
{
if (!profile)
diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp
index 4c7c0c5442..4263938fdf 100644
--- a/src/network/kernel/qnetworkproxy.cpp
+++ b/src/network/kernel/qnetworkproxy.cpp
@@ -1530,12 +1530,6 @@ void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *fact
SOCKS server for all queries. If SOCKS isn't enabled, it will use
the HTTPS proxy for all TcpSocket and UrlRequest queries.
- On BlackBerry, this function obtains proxy settings for the default
- configuration using system configuration. The type will be set based on
- protocol tag "http", "https", "ftp", respectively. By default, it
- assumes http type. Proxy username and password are also set during
- the query using system configuration.
-
On other systems, this function will pick up proxy settings from
the "http_proxy" environment variable. This variable must be a URL
using one of the following schemes: "http", "socks5" or "socks5h".
@@ -1552,10 +1546,6 @@ void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *fact
\li On Windows platforms, this function may take several seconds to
execute depending on the configuration of the user's system.
-
- \li On BlackBerry, only UrlRequest and TcpSocket queries are supported. SOCKS is
- not supported. The proxy credentials are only retrieved for the
- default configuration.
\endlist
*/
diff --git a/src/network/kernel/qnetworkproxy_blackberry.cpp b/src/network/kernel/qnetworkproxy_blackberry.cpp
deleted file mode 100644
index ca30a65397..0000000000
--- a/src/network/kernel/qnetworkproxy_blackberry.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/**
- * Some notes about the code:
- *
- * ** It is assumed that the system proxies are for url based requests
- * ie. HTTP/HTTPS based.
- */
-
-#include <QtNetwork/qnetworkproxy.h>
-
-#ifndef QT_NO_NETWORKPROXY
-
-
-#include <QtCore/qflags.h>
-#include <QtCore/qurl.h>
-#include <QtNetwork/qnetworkconfiguration.h>
-
-#include <bps/netstatus.h>
-#include <errno.h>
-
-
-QT_BEGIN_NAMESPACE
-
-QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
-{
- if (query.url().scheme() == QLatin1String("file")
- || query.url().scheme() == QLatin1String("qrc"))
- return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
-
- if (query.queryType() != QNetworkProxyQuery::UrlRequest
- && query.queryType() != QNetworkProxyQuery::TcpSocket) {
- qWarning("Unsupported query type: %d", query.queryType());
- return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
- }
-
- QUrl url;
- if (query.queryType() == QNetworkProxyQuery::UrlRequest) {
- url = query.url();
- } else if (query.queryType() == QNetworkProxyQuery::TcpSocket
- && !query.peerHostName().isEmpty()) {
- url.setHost(query.peerHostName());
- switch (query.peerPort()) {
- case 443:
- url.setScheme(QStringLiteral("https"));
- break;
- case 21:
- url.setScheme(QStringLiteral("ftp"));
- break;
- default:
- // for unknown ports, we just pretend we are dealing
- // with a HTTP URL, otherwise we will not get a proxy
- // from the netstatus API
- url.setScheme(QStringLiteral("http"));
- }
- }
-
- if (!url.isValid()) {
- qWarning("Invalid URL: %s", qPrintable(url.toString()));
- return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
- }
-
- netstatus_proxy_details_t details;
- memset(&details, 0, sizeof(netstatus_proxy_details_t));
-
-#if BPS_VERSION >= 3001001
-
- QByteArray bUrl(url.toEncoded());
- QString sInterface(query.networkConfiguration().name());
- QByteArray bInterface;
- if (!sInterface.isEmpty()) {
- if (query.networkConfiguration().type() != QNetworkConfiguration::InternetAccessPoint) {
- qWarning("Unsupported configuration type: %d", query.networkConfiguration().type());
- return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
- }
- bInterface = sInterface.toUtf8();
- }
-
- if (netstatus_get_proxy_details_for_url(bUrl.constData(), (bInterface.isEmpty() ? NULL : bInterface.constData()), &details) != BPS_SUCCESS) {
- qWarning("netstatus_get_proxy_details_for_url failed! errno: %d", errno);
- return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
- }
-
-#else
-
- if (netstatus_get_proxy_details(&details) != BPS_SUCCESS) {
- qWarning("netstatus_get_proxy_details failed! errno: %d", errno);
- return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
- }
-
-#endif
-
- if (details.http_proxy_host == NULL) { // No proxy
- netstatus_free_proxy_details(&details);
- return QList<QNetworkProxy>() << QNetworkProxy(QNetworkProxy::NoProxy);
- }
-
- QNetworkProxy proxy;
-
- QString protocol = query.protocolTag();
- if (protocol.startsWith(QLatin1String("http"), Qt::CaseInsensitive)) { // http, https
- proxy.setType((QNetworkProxy::HttpProxy));
- } else if (protocol == QLatin1String("ftp")) {
- proxy.setType(QNetworkProxy::FtpCachingProxy);
- } else { // assume http proxy
- qDebug("Proxy type: %s assumed to be http proxy", qPrintable(protocol));
- proxy.setType((QNetworkProxy::HttpProxy));
- }
-
- // Set host
- // Note: ftp and https proxy type fields *are* obsolete.
- // The user interface allows only one host/port which gets duplicated
- // to all proxy type fields.
- proxy.setHostName(QString::fromUtf8(details.http_proxy_host));
-
- // Set port
- proxy.setPort(details.http_proxy_port);
-
- // Set username
- if (details.http_proxy_login_user)
- proxy.setUser(QString::fromUtf8(details.http_proxy_login_user));
-
- // Set password
- if (details.http_proxy_login_password)
- proxy.setPassword(QString::fromUtf8(details.http_proxy_login_password));
-
- netstatus_free_proxy_details(&details);
-
- return QList<QNetworkProxy>() << proxy;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 1c77d14b29..6110131484 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -561,7 +561,6 @@ QAbstractSocketPrivate::QAbstractSocketPrivate()
isBuffered(false),
connectTimer(0),
disconnectTimer(0),
- connectTimeElapsed(0),
hostLookupId(-1),
socketType(QAbstractSocket::UnknownSocketType),
state(QAbstractSocket::UnconnectedState),
@@ -722,19 +721,9 @@ bool QAbstractSocketPrivate::canReadNotification()
}
}
- // only emit readyRead() when not recursing, and only if there is data available
- bool hasData = newBytes > 0
-#ifndef QT_NO_UDPSOCKET
- || (!isBuffered && socketType != QAbstractSocket::TcpSocket && socketEngine && socketEngine->hasPendingDatagrams())
-#endif
- || (!isBuffered && socketType == QAbstractSocket::TcpSocket && socketEngine)
- ;
-
- if (!emittedReadyRead && hasData) {
- QScopedValueRollback<bool> r(emittedReadyRead);
- emittedReadyRead = true;
- emit q->readyRead();
- }
+ // Only emit readyRead() if there is data available.
+ if (newBytes > 0 || !isBuffered)
+ emitReadyRead();
// If we were closed as a result of the readyRead() signal,
// return.
@@ -792,12 +781,12 @@ void QAbstractSocketPrivate::canCloseNotification()
// then occur when we read from the socket again and fail
// in canReadNotification or by the manually created
// closeNotification below.
- emit q->readyRead();
+ emitReadyRead();
QMetaObject::invokeMethod(socketEngine, "closeNotification", Qt::QueuedConnection);
}
} else if (socketType == QAbstractSocket::TcpSocket && socketEngine) {
- emit q->readyRead();
+ emitReadyRead();
}
}
@@ -809,28 +798,15 @@ void QAbstractSocketPrivate::canCloseNotification()
*/
bool QAbstractSocketPrivate::canWriteNotification()
{
-#if defined (Q_OS_WIN)
- if (socketEngine && socketEngine->isWriteNotificationEnabled())
- socketEngine->setWriteNotificationEnabled(false);
-#endif
-
#if defined (QABSTRACTSOCKET_DEBUG)
qDebug("QAbstractSocketPrivate::canWriteNotification() flushing");
#endif
- qint64 tmp = writeBuffer.size();
- flush();
+ bool dataWasWritten = writeToSocket();
- if (socketEngine) {
-#if defined (Q_OS_WIN)
- if (!writeBuffer.isEmpty())
- socketEngine->setWriteNotificationEnabled(true);
-#else
- if (writeBuffer.isEmpty() && socketEngine->bytesToWrite() == 0)
- socketEngine->setWriteNotificationEnabled(false);
-#endif
- }
+ if (socketEngine && writeBuffer.isEmpty() && socketEngine->bytesToWrite() == 0)
+ socketEngine->setWriteNotificationEnabled(false);
- return (writeBuffer.size() < tmp);
+ return dataWasWritten;
}
/*! \internal
@@ -852,21 +828,20 @@ void QAbstractSocketPrivate::connectionNotification()
/*! \internal
- Writes pending data in the write buffers to the socket. The
- function writes as much as it can without blocking.
+ Writes one pending data block in the write buffer to the socket.
It is usually invoked by canWriteNotification after one or more
calls to write().
Emits bytesWritten().
*/
-bool QAbstractSocketPrivate::flush()
+bool QAbstractSocketPrivate::writeToSocket()
{
Q_Q(QAbstractSocket);
if (!socketEngine || !socketEngine->isValid() || (writeBuffer.isEmpty()
&& socketEngine->bytesToWrite() == 0)) {
#if defined (QABSTRACTSOCKET_DEBUG)
- qDebug("QAbstractSocketPrivate::flush() nothing to do: valid ? %s, writeBuffer.isEmpty() ? %s",
+ qDebug("QAbstractSocketPrivate::writeToSocket() nothing to do: valid ? %s, writeBuffer.isEmpty() ? %s",
(socketEngine && socketEngine->isValid()) ? "yes" : "no", writeBuffer.isEmpty() ? "yes" : "no");
#endif
@@ -884,7 +859,8 @@ bool QAbstractSocketPrivate::flush()
qint64 written = socketEngine->write(ptr, nextSize);
if (written < 0) {
#if defined (QABSTRACTSOCKET_DEBUG)
- qDebug() << "QAbstractSocketPrivate::flush() write error, aborting." << socketEngine->errorString();
+ qDebug() << "QAbstractSocketPrivate::writeToSocket() write error, aborting."
+ << socketEngine->errorString();
#endif
setErrorAndEmit(socketEngine->error(), socketEngine->errorString());
// an unexpected error so close the socket.
@@ -893,7 +869,7 @@ bool QAbstractSocketPrivate::flush()
}
#if defined (QABSTRACTSOCKET_DEBUG)
- qDebug("QAbstractSocketPrivate::flush() %lld bytes written to the network",
+ qDebug("QAbstractSocketPrivate::writeToSocket() %lld bytes written to the network",
written);
#endif
@@ -914,7 +890,23 @@ bool QAbstractSocketPrivate::flush()
if (state == QAbstractSocket::ClosingState)
q->disconnectFromHost();
- return true;
+ return written > 0;
+}
+
+/*! \internal
+
+ Writes pending data in the write buffers to the socket. The function
+ writes as much as it can without blocking. If any data was written,
+ this function returns true; otherwise false is returned.
+*/
+bool QAbstractSocketPrivate::flush()
+{
+ bool dataWasWritten = false;
+
+ while (!writeBuffer.isEmpty() && writeToSocket())
+ dataWasWritten = true;
+
+ return dataWasWritten;
}
#ifndef QT_NO_NETWORKPROXY
@@ -977,8 +969,6 @@ void QAbstractSocketPrivate::startConnectingByName(const QString &host)
state = QAbstractSocket::ConnectingState;
emit q->stateChanged(state);
- connectTimeElapsed = 0;
-
if (cachedSocketDescriptor != -1 || initSocketLayer(QAbstractSocket::UnknownNetworkLayerProtocol)) {
if (socketEngine->connectToHostByName(host, port) ||
socketEngine->state() == QAbstractSocket::ConnectingState) {
@@ -1061,9 +1051,6 @@ void QAbstractSocketPrivate::_q_startConnecting(const QHostInfo &hostInfo)
// Report the successful host lookup
emit q->hostFound();
- // Reset the total time spent connecting.
- connectTimeElapsed = 0;
-
// The addresses returned by the lookup will be tested one after
// another by _q_connectToNextAddress().
_q_connectToNextAddress();
@@ -1248,10 +1235,7 @@ void QAbstractSocketPrivate::_q_forceDisconnect()
*/
bool QAbstractSocketPrivate::readFromSocket()
{
-#ifdef QABSTRACTSOCKET_DEBUG
Q_Q(QAbstractSocket);
-#endif
-
// Find how many bytes we can read from the socket layer.
qint64 bytesToRead = socketEngine->bytesAvailable();
if (bytesToRead == 0) {
@@ -1280,7 +1264,7 @@ bool QAbstractSocketPrivate::readFromSocket()
buffer.chop(bytesToRead);
return true;
}
- buffer.chop(bytesToRead - (readBytes < 0 ? qint64(0) : readBytes));
+ buffer.chop(bytesToRead - ((readBytes < 0 || !q->isReadable()) ? qint64(0) : readBytes));
#if defined(QABSTRACTSOCKET_DEBUG)
qDebug("QAbstractSocketPrivate::readFromSocket() got %lld bytes, buffer size = %lld",
readBytes, buffer.size());
@@ -1301,6 +1285,21 @@ bool QAbstractSocketPrivate::readFromSocket()
/*! \internal
+ Prevents from the recursive readyRead() emission.
+*/
+void QAbstractSocketPrivate::emitReadyRead()
+{
+ Q_Q(QAbstractSocket);
+ // Only emit readyRead() when not recursing.
+ if (!emittedReadyRead) {
+ QScopedValueRollback<bool> r(emittedReadyRead);
+ emittedReadyRead = true;
+ emit q->readyRead();
+ }
+}
+
+/*! \internal
+
Sets up the internal state after the connection has succeeded.
*/
void QAbstractSocketPrivate::fetchConnectionParameters()
@@ -2378,7 +2377,7 @@ bool QAbstractSocket::isSequential() const
*/
bool QAbstractSocket::atEnd() const
{
- return QIODevice::atEnd() && (!isOpen() || d_func()->buffer.isEmpty());
+ return QIODevice::atEnd();
}
/*!
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index 23f0d26cbd..f8edc74a24 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -176,7 +176,7 @@ public:
// from QIODevice
void close() Q_DECL_OVERRIDE;
bool isSequential() const Q_DECL_OVERRIDE;
- bool atEnd() const Q_DECL_OVERRIDE;
+ bool atEnd() const Q_DECL_OVERRIDE; // ### Qt6: remove me
bool flush();
// for synchronous access
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index a905625b19..15f8344552 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -135,6 +135,8 @@ public:
void fetchConnectionParameters();
void setupSocketNotifiers();
bool readFromSocket();
+ bool writeToSocket();
+ void emitReadyRead();
void setError(QAbstractSocket::SocketError errorCode, const QString &errorString);
void setErrorAndEmit(QAbstractSocket::SocketError errorCode, const QString &errorString);
@@ -146,7 +148,6 @@ public:
QTimer *connectTimer;
QTimer *disconnectTimer;
- int connectTimeElapsed;
int hostLookupId;
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index 92ca76b560..3f20e5c046 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -768,7 +768,6 @@ void QHttpSocketEngine::emitPendingConnectionNotification()
void QHttpSocketEngine::emitReadNotification()
{
Q_D(QHttpSocketEngine);
- d->readNotificationActivated = true;
// if there is a connection notification pending we have to emit the readNotification
// incase there is connection error. This is only needed for Windows, but it does not
// hurt in other cases.
@@ -781,7 +780,6 @@ void QHttpSocketEngine::emitReadNotification()
void QHttpSocketEngine::emitWriteNotification()
{
Q_D(QHttpSocketEngine);
- d->writeNotificationActivated = true;
if (d->writeNotificationEnabled && !d->writeNotificationPending) {
d->writeNotificationPending = true;
QMetaObject::invokeMethod(this, "emitPendingWriteNotification", Qt::QueuedConnection);
@@ -801,8 +799,6 @@ QHttpSocketEnginePrivate::QHttpSocketEnginePrivate()
: readNotificationEnabled(false)
, writeNotificationEnabled(false)
, exceptNotificationEnabled(false)
- , readNotificationActivated(false)
- , writeNotificationActivated(false)
, readNotificationPending(false)
, writeNotificationPending(false)
, connectionNotificationPending(false)
diff --git a/src/network/socket/qhttpsocketengine_p.h b/src/network/socket/qhttpsocketengine_p.h
index 41c63fe11e..b34e5b0dc3 100644
--- a/src/network/socket/qhttpsocketengine_p.h
+++ b/src/network/socket/qhttpsocketengine_p.h
@@ -172,8 +172,6 @@ public:
bool readNotificationEnabled;
bool writeNotificationEnabled;
bool exceptNotificationEnabled;
- bool readNotificationActivated;
- bool writeNotificationActivated;
bool readNotificationPending;
bool writeNotificationPending;
bool connectionNotificationPending;
diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h
index 9a76e23013..2dc4bbaced 100644
--- a/src/network/socket/qnativesocketengine_p.h
+++ b/src/network/socket/qnativesocketengine_p.h
@@ -45,6 +45,7 @@
// We mean it.
//
#include "QtNetwork/qhostaddress.h"
+#include "QtNetwork/qnetworkinterface.h"
#include "private/qabstractsocketengine_p.h"
#ifndef Q_OS_WIN
# include "qplatformdefs.h"
@@ -98,6 +99,16 @@ union qt_sockaddr {
sockaddr_in6 a6;
};
+namespace {
+namespace SetSALen {
+ template <typename T> void set(T *sa, typename QtPrivate::QEnableIf<(&T::sa_len, true), QT_SOCKLEN_T>::Type len)
+ { sa->sa_len = len; }
+ template <typename T> void set(T *sin6, typename QtPrivate::QEnableIf<(&T::sin6_len, true), QT_SOCKLEN_T>::Type len)
+ { sin6->sin6_len = len; }
+ template <typename T> void set(T *, ...) {}
+}
+}
+
class QNativeSocketEnginePrivate;
#ifndef QT_NO_NETWORKINTERFACE
class QNetworkInterface;
@@ -266,7 +277,8 @@ public:
bool checkProxy(const QHostAddress &address);
bool fetchConnectionParameters();
- static uint scopeIdFromString(const QString &scopeid);
+ static uint scopeIdFromString(const QString &scopeid)
+ { return QNetworkInterface::interfaceIndexFromName(scopeid); }
/*! \internal
Sets \a address and \a port in the \a aa sockaddr structure and the size in \a sockAddrSize.
@@ -285,12 +297,14 @@ public:
Q_IPV6ADDR tmp = address.toIPv6Address();
memcpy(&aa->a6.sin6_addr, &tmp, sizeof(tmp));
*sockAddrSize = sizeof(sockaddr_in6);
+ SetSALen::set(&aa->a, sizeof(sockaddr_in6));
} else {
memset(&aa->a, 0, sizeof(sockaddr_in));
aa->a4.sin_family = AF_INET;
aa->a4.sin_port = htons(port);
aa->a4.sin_addr.s_addr = htonl(address.toIPv4Address());
*sockAddrSize = sizeof(sockaddr_in);
+ SetSALen::set(&aa->a, sizeof(sockaddr_in));
}
}
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 6a740f4c30..d672b8a12f 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -107,15 +107,8 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po
QHostAddress tmpAddress;
tmpAddress.setAddress(tmp);
*addr = tmpAddress;
- if (s->a6.sin6_scope_id) {
-#ifndef QT_NO_IPV6IFNAME
- char scopeid[IFNAMSIZ];
- if (::if_indextoname(s->a6.sin6_scope_id, scopeid)) {
- addr->setScopeId(QLatin1String(scopeid));
- } else
-#endif
- addr->setScopeId(QString::number(s->a6.sin6_scope_id));
- }
+ if (s->a6.sin6_scope_id)
+ addr->setScopeId(QNetworkInterface::interfaceNameFromIndex(s->a6.sin6_scope_id));
}
if (port)
*port = ntohs(s->a6.sin6_port);
@@ -131,21 +124,6 @@ static inline void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *po
}
}
-// inline on purpose
-inline uint QNativeSocketEnginePrivate::scopeIdFromString(const QString &scopeid)
-{
- if (scopeid.isEmpty())
- return 0;
-
- bool ok;
- uint id = scopeid.toUInt(&ok);
-#ifndef QT_NO_IPV6IFNAME
- if (!ok)
- id = ::if_nametoindex(scopeid.toLatin1());
-#endif
- return id;
-}
-
static void convertToLevelAndOption(QNativeSocketEngine::SocketOption opt,
QAbstractSocket::NetworkLayerProtocol socketProtocol, int &level, int &n)
{
@@ -1207,53 +1185,6 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize)
return qint64(r);
}
-#ifdef Q_OS_BLACKBERRY
-int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const
-{
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(socketDescriptor, &fds);
-
- int retval;
- QList<QSocketNotifier *> notifiers;
- if (selectForRead) {
- notifiers << readNotifier;
- retval = bb_select(notifiers, socketDescriptor + 1, &fds, 0, timeout);
- } else {
- notifiers << writeNotifier;
- retval = bb_select(notifiers, socketDescriptor + 1, 0, &fds, timeout);
- }
-
- return retval;
-}
-
-int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite,
- bool *selectForRead, bool *selectForWrite) const
-{
- fd_set fdread;
- FD_ZERO(&fdread);
- if (checkRead)
- FD_SET(socketDescriptor, &fdread);
-
- fd_set fdwrite;
- FD_ZERO(&fdwrite);
- if (checkWrite)
- FD_SET(socketDescriptor, &fdwrite);
-
- QList<QSocketNotifier *> notifiers;
- notifiers << readNotifier << writeNotifier;
- int ret = bb_select(notifiers, socketDescriptor + 1, &fdread, &fdwrite, timeout);
-
- if (ret <= 0)
- return ret;
- *selectForRead = FD_ISSET(socketDescriptor, &fdread);
- *selectForWrite = FD_ISSET(socketDescriptor, &fdwrite);
-
- return ret;
-}
-
-#else // not Q_OS_BLACKBERRY:
-
int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const
{
fd_set fds;
@@ -1300,6 +1231,5 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c
return ret;
}
-#endif // Q_OS_BLACKBERRY
QT_END_NAMESPACE
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 9aed0caa25..1379ed93ba 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -322,12 +322,6 @@ static inline int qt_socket_getMaxMsgSize(qintptr socketDescriptor)
# define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
#endif
-// inline on purpose
-inline uint QNativeSocketEnginePrivate::scopeIdFromString(const QString &scopeid)
-{
- return scopeid.toUInt();
-}
-
bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol)
{
@@ -657,6 +651,13 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin
int tries = 0;
do {
if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) {
+ if (value != NOERROR) {
+ // MSDN says getsockopt with SO_ERROR clears the error, but it's not actually cleared
+ // and this can affect all subsequent WSAConnect attempts, so clear it now.
+ const int val = NO_ERROR;
+ ::setsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, reinterpret_cast<const char*>(&val), sizeof val);
+ }
+
if (value == WSAECONNREFUSED) {
setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
socketState = QAbstractSocket::UnconnectedState;
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 4803e47224..1f9055b50c 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -731,6 +731,23 @@ int QSslConfiguration::sessionTicketLifeTimeHint() const
}
/*!
+ \since 5.7
+
+ Returns the ephemeral server key used for cipher algorithms
+ with forward secrecy, e.g. DHE-RSA-AES128-SHA.
+
+ The ephemeral key is only available when running in client mode, i.e.
+ QSslSocket::SslClientMode. When running in server mode or using a
+ cipher algorithm without forward secrecy a null key is returned.
+ The ephemeral server key will be set before emitting the encrypted()
+ signal.
+ */
+QSslKey QSslConfiguration::ephemeralServerKey() const
+{
+ return d->ephemeralServerKey;
+}
+
+/*!
\since 5.5
Returns this connection's current list of elliptic curves. This
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index 2cbc31b032..29ae95746e 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -128,6 +128,8 @@ public:
void setSessionTicket(const QByteArray &sessionTicket);
int sessionTicketLifeTimeHint() const;
+ QSslKey ephemeralServerKey() const;
+
// EC settings
QVector<QSslEllipticCurve> ellipticCurves() const;
void setEllipticCurves(const QVector<QSslEllipticCurve> &curves);
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index 3fd1252a7b..e636699854 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -113,6 +113,8 @@ public:
QByteArray sslSession;
int sslSessionTicketLifeTimeHint;
+ QSslKey ephemeralServerKey;
+
QList<QByteArray> nextAllowedProtocols;
QByteArray nextNegotiatedProtocol;
QSslConfiguration::NextProtocolNegotiationStatus nextProtocolNegotiationStatus;
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 805adc734f..1dfd87a0f8 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1507,6 +1507,10 @@ QList<QSslCertificate> QSslSocket::defaultCaCertificates()
returned by defaultCaCertificates(). You can replace that database
with your own with setDefaultCaCertificates().
+ \note: On OS X, only certificates that are either trusted for all
+ purposes or trusted for the purpose of SSL in the keychain will be
+ returned.
+
\sa caCertificates(), defaultCaCertificates(), setDefaultCaCertificates()
*/
QList<QSslCertificate> QSslSocket::systemCaCertificates()
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index 4e090f96cb..326686fad0 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -491,29 +491,6 @@ void QSslSocketPrivate::resetDefaultEllipticCurves()
Q_UNIMPLEMENTED();
}
-
-QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
-{
- QList<QSslCertificate> systemCerts;
-#ifdef Q_OS_OSX
- // SecTrustSettingsCopyCertificates is not defined on iOS.
- QCFType<CFArrayRef> cfCerts;
- OSStatus status = SecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts);
- if (status == noErr) {
- const CFIndex size = CFArrayGetCount(cfCerts);
- for (CFIndex i = 0; i < size; ++i) {
- SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i);
- QCFType<CFDataRef> derData = SecCertificateCopyData(cfCert);
- systemCerts << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
- }
- } else {
- // no detailed error handling here
- qCWarning(lcSsl) << "SecTrustSettingsCopyCertificates failed:" << status;
- }
-#endif
- return systemCerts;
-}
-
QSslSocketBackendPrivate::QSslSocketBackendPrivate()
: context(Q_NULLPTR)
{
@@ -867,6 +844,9 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSLCipherSuite(SSLCipherSui
case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
ciph.d->name = QLatin1String("ECDHE-RSA-AES256-SHA384");
break;
+ case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+ ciph.d->name = QLatin1String("ECDHE-RSA-AES256-GCM-SHA384");
+ break;
default:
return ciph;
}
@@ -914,6 +894,10 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSLCipherSuite(SSLCipherSui
ciph.d->encryptionMethod = QLatin1String("AES(128)");
ciph.d->bits = 128;
ciph.d->supportedBits = 128;
+ } else if (ciph.d->name.contains("AES256-GCM")) {
+ ciph.d->encryptionMethod = QLatin1String("AESGCM(256)");
+ ciph.d->bits = 256;
+ ciph.d->supportedBits = 256;
} else if (ciph.d->name.contains("AES256-")) {
ciph.d->encryptionMethod = QLatin1String("AES(256)");
ciph.d->bits = 256;
diff --git a/src/network/ssl/qsslsocket_mac_shared.cpp b/src/network/ssl/qsslsocket_mac_shared.cpp
new file mode 100644
index 0000000000..c662a694cd
--- /dev/null
+++ b/src/network/ssl/qsslsocket_mac_shared.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 ownCloud Inc
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//#define QSSLSOCKET_DEBUG
+//#define QT_DECRYPT_SSL_TRAFFIC
+
+#include "qssl_p.h"
+#include "qsslsocket.h"
+
+#ifndef QT_NO_OPENSSL
+# include "qsslsocket_openssl_p.h"
+# include "qsslsocket_openssl_symbols_p.h"
+#endif
+
+#include "qsslcertificate_p.h"
+
+#ifdef Q_OS_DARWIN
+# include <private/qcore_mac_p.h>
+#endif
+
+#include <QtCore/qdebug.h>
+
+#ifdef Q_OS_OSX
+# include <Security/Security.h>
+#endif
+
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_OSX
+namespace {
+
+bool hasTrustedSslServerPolicy(SecPolicyRef policy, CFDictionaryRef props) {
+ QCFType<CFDictionaryRef> policyProps = SecPolicyCopyProperties(policy);
+ // only accept certificates with policies for SSL server validation for now
+ if (CFEqual(CFDictionaryGetValue(policyProps, kSecPolicyOid), kSecPolicyAppleSSL)) {
+ CFBooleanRef policyClient;
+ if (CFDictionaryGetValueIfPresent(policyProps, kSecPolicyClient, reinterpret_cast<const void**>(&policyClient)) &&
+ CFEqual(policyClient, kCFBooleanTrue)) {
+ return false; // no client certs
+ }
+ if (!CFDictionaryContainsKey(props, kSecTrustSettingsResult)) {
+ // as per the docs, no trust settings result implies full trust
+ return true;
+ }
+ CFNumberRef number = static_cast<CFNumberRef>(CFDictionaryGetValue(props, kSecTrustSettingsResult));
+ SecTrustSettingsResult settingsResult;
+ CFNumberGetValue(number, kCFNumberSInt32Type, &settingsResult);
+ switch (settingsResult) {
+ case kSecTrustSettingsResultTrustRoot:
+ case kSecTrustSettingsResultTrustAsRoot:
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+bool isCaCertificateTrusted(SecCertificateRef cfCert, int domain)
+{
+ QCFType<CFArrayRef> cfTrustSettings;
+ OSStatus status = SecTrustSettingsCopyTrustSettings(cfCert, SecTrustSettingsDomain(domain), &cfTrustSettings);
+ if (status == noErr) {
+ CFIndex size = CFArrayGetCount(cfTrustSettings);
+ // if empty, trust for everything (as per the Security Framework documentation)
+ if (size == 0) {
+ return true;
+ } else {
+ for (CFIndex i = 0; i < size; ++i) {
+ CFDictionaryRef props = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(cfTrustSettings, i));
+ if (CFDictionaryContainsKey(props, kSecTrustSettingsPolicy)) {
+ if (hasTrustedSslServerPolicy((SecPolicyRef)CFDictionaryGetValue(props, kSecTrustSettingsPolicy), props))
+ return true;
+ }
+ }
+ }
+ } else {
+ qCWarning(lcSsl, "Error receiving trust for a CA certificate");
+ }
+ return false;
+}
+
+} // anon namespace
+#endif // Q_OS_OSX
+
+QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
+{
+ ensureInitialized();
+
+ QList<QSslCertificate> systemCerts;
+ // SecTrustSettingsCopyCertificates is not defined on iOS.
+#ifdef Q_OS_OSX
+ QCFType<CFArrayRef> cfCerts;
+ // iterate through all enum members, order:
+ // kSecTrustSettingsDomainUser, kSecTrustSettingsDomainAdmin, kSecTrustSettingsDomainSystem
+ for (int dom = kSecTrustSettingsDomainUser; dom <= int(kSecTrustSettingsDomainSystem); dom++) {
+ OSStatus status = SecTrustSettingsCopyCertificates(SecTrustSettingsDomain(dom), &cfCerts);
+ if (status == noErr) {
+ const CFIndex size = CFArrayGetCount(cfCerts);
+ for (CFIndex i = 0; i < size; ++i) {
+ SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i);
+ QCFType<CFDataRef> derData = SecCertificateCopyData(cfCert);
+ if (QT_PREPEND_NAMESPACE(isCaCertificateTrusted(cfCert, dom))) {
+ if (derData == NULL) {
+ qCWarning(lcSsl, "Error retrieving a CA certificate from the system store");
+ } else {
+ systemCerts << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
+ }
+ }
+ }
+ }
+ }
+#endif
+ return systemCerts;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index dd47dfc45f..a5ca844e88 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -78,12 +78,7 @@
QT_BEGIN_NAMESPACE
-#if defined(Q_OS_MACX)
-#define kSecTrustSettingsDomainSystem 2 // so we do not need to include the header file
- PtrSecCertificateCopyData QSslSocketPrivate::ptrSecCertificateCopyData = 0;
- PtrSecTrustSettingsCopyCertificates QSslSocketPrivate::ptrSecTrustSettingsCopyCertificates = 0;
- PtrSecTrustCopyAnchorCertificates QSslSocketPrivate::ptrSecTrustCopyAnchorCertificates = 0;
-#elif defined(Q_OS_WIN)
+#if defined(Q_OS_WIN)
PtrCertOpenSystemStoreW QSslSocketPrivate::ptrCertOpenSystemStoreW = 0;
PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = 0;
PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = 0;
@@ -506,23 +501,7 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
#ifndef QT_NO_LIBRARY
//load symbols needed to receive certificates from system store
-#if defined(Q_OS_MACX)
- QLibrary securityLib("/System/Library/Frameworks/Security.framework/Versions/Current/Security");
- if (securityLib.load()) {
- ptrSecCertificateCopyData = (PtrSecCertificateCopyData) securityLib.resolve("SecCertificateCopyData");
- if (!ptrSecCertificateCopyData)
- qCWarning(lcSsl, "could not resolve symbols in security library"); // should never happen
-
- ptrSecTrustSettingsCopyCertificates = (PtrSecTrustSettingsCopyCertificates) securityLib.resolve("SecTrustSettingsCopyCertificates");
- if (!ptrSecTrustSettingsCopyCertificates) { // method was introduced in Leopard, use legacy method if it's not there
- ptrSecTrustCopyAnchorCertificates = (PtrSecTrustCopyAnchorCertificates) securityLib.resolve("SecTrustCopyAnchorCertificates");
- if (!ptrSecTrustCopyAnchorCertificates)
- qCWarning(lcSsl, "could not resolve symbols in security library"); // should never happen
- }
- } else {
- qCWarning(lcSsl, "could not load security library");
- }
-#elif defined(Q_OS_WIN)
+#if defined(Q_OS_WIN)
HINSTANCE hLib = LoadLibraryW(L"Crypt32");
if (hLib) {
#if defined(Q_OS_WINCE)
@@ -680,6 +659,7 @@ void QSslSocketPrivate::resetDefaultEllipticCurves()
setDefaultSupportedEllipticCurves(curves);
}
+#ifndef Q_OS_DARWIN // Apple implementation in qsslsocket_mac_shared.cpp
QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
{
ensureInitialized();
@@ -688,43 +668,7 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
timer.start();
#endif
QList<QSslCertificate> systemCerts;
-#if defined(Q_OS_MACX)
- CFArrayRef cfCerts;
- OSStatus status = 1;
-
- CFDataRef SecCertificateCopyData (
- SecCertificateRef certificate
- );
-
- if (ptrSecCertificateCopyData) {
- if (ptrSecTrustSettingsCopyCertificates)
- status = ptrSecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &cfCerts);
- else if (ptrSecTrustCopyAnchorCertificates)
- status = ptrSecTrustCopyAnchorCertificates(&cfCerts);
- if (!status) {
- CFIndex size = CFArrayGetCount(cfCerts);
- for (CFIndex i = 0; i < size; ++i) {
- SecCertificateRef cfCert = (SecCertificateRef)CFArrayGetValueAtIndex(cfCerts, i);
- CFDataRef data;
-
- data = ptrSecCertificateCopyData(cfCert);
-
- if (data == NULL) {
- qCWarning(lcSsl, "error retrieving a CA certificate from the system store");
- } else {
- QByteArray rawCert = QByteArray::fromRawData((const char *)CFDataGetBytePtr(data), CFDataGetLength(data));
- systemCerts.append(QSslCertificate::fromData(rawCert, QSsl::Der));
- CFRelease(data);
- }
- }
- CFRelease(cfCerts);
- }
- else {
- // no detailed error handling here
- qCWarning(lcSsl, "could not retrieve system CA certificates");
- }
- }
-#elif defined(Q_OS_WIN)
+#if defined(Q_OS_WIN)
if (ptrCertOpenSystemStoreW && ptrCertFindCertificateInStore && ptrCertCloseStore) {
HCERTSTORE hSystemStore;
#if defined(Q_OS_WINCE)
@@ -801,6 +745,7 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
return systemCerts;
}
+#endif // Q_OS_DARWIN
void QSslSocketBackendPrivate::startClientEncryption()
{
@@ -1621,6 +1566,14 @@ void QSslSocketBackendPrivate::continueHandshake()
}
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+ if (q_SSLeay() >= 0x10002000L && mode == QSslSocket::SslClientMode) {
+ EVP_PKEY *key;
+ if (q_SSL_get_server_tmp_key(ssl, &key))
+ configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey);
+ }
+#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ...
+
connectionEncrypted = true;
emit q->encrypted();
if (autoStartHandshake && pendingClose) {
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 7f87f11b7c..08d84a440b 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -483,6 +483,9 @@ size_t q_EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
int q_EC_curve_nist2nid(const char *name);
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
#endif // OPENSSL_NO_EC
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+#define q_SSL_get_server_tmp_key(ssl, key) q_SSL_ctrl((ssl), SSL_CTRL_GET_SERVER_TMP_KEY, 0, (char *)key)
+#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
// PKCS#12 support
int q_PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index d6519718d9..17cc7b4259 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -151,11 +151,7 @@ public:
static bool isMatchingHostname(const QSslCertificate &cert, const QString &peerName);
Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname);
-#if defined(Q_OS_MACX)
- static PtrSecCertificateCopyData ptrSecCertificateCopyData;
- static PtrSecTrustSettingsCopyCertificates ptrSecTrustSettingsCopyCertificates;
- static PtrSecTrustCopyAnchorCertificates ptrSecTrustCopyAnchorCertificates;
-#elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
static PtrCertOpenSystemStoreW ptrCertOpenSystemStoreW;
static PtrCertFindCertificateInStore ptrCertFindCertificateInStore;
static PtrCertCloseStore ptrCertCloseStore;
diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri
index 29c47cd7c6..2173bf6ccc 100644
--- a/src/network/ssl/ssl.pri
+++ b/src/network/ssl/ssl.pri
@@ -46,6 +46,7 @@ contains(QT_CONFIG, ssl) | contains(QT_CONFIG, openssl) | contains(QT_CONFIG, op
SOURCES += ssl/qsslcertificate_qt.cpp \
ssl/qsslkey_qt.cpp \
ssl/qsslkey_mac.cpp \
+ ssl/qsslsocket_mac_shared.cpp \
ssl/qsslsocket_mac.cpp \
ssl/qsslellipticcurve_dummy.cpp
}
@@ -62,7 +63,9 @@ contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
ssl/qsslsocket_openssl.cpp \
ssl/qsslsocket_openssl_symbols.cpp
-android:!android-no-sdk: SOURCES += ssl/qsslsocket_openssl_android.cpp
+ darwin:SOURCES += ssl/qsslsocket_mac_shared.cpp
+
+ android:!android-no-sdk: SOURCES += ssl/qsslsocket_openssl_android.cpp
# Add optional SSL libs
# Static linking of OpenSSL with msvc:
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index 903f34f939..984590435d 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -188,7 +188,7 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
#if defined(QT_DEBUG)
// Check that all the elements have been filled:
for (int i = 0; i < TotalSnippetCount; ++i) {
- if (qShaderSnippets[i] == 0) {
+ if (Q_UNLIKELY(!qShaderSnippets[i])) {
qFatal("Shader snippet for %s (#%d) is missing!",
snippetNameStr(SnippetName(i)).constData(), i);
}
@@ -237,11 +237,11 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
simpleShaderProg->link();
- if (simpleShaderProg->isLinked()) {
+ if (Q_UNLIKELY(!simpleShaderProg->isLinked())) {
+ qCritical("Errors linking simple shader: %s", qPrintable(simpleShaderProg->log()));
+ } else {
if (!inCache)
simpleShaderCache.store(simpleShaderProg, context);
- } else {
- qCritical("Errors linking simple shader: %s", qPrintable(simpleShaderProg->log()));
}
// Compile the blit shader:
@@ -278,11 +278,11 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
}
blitShaderProg->link();
- if (blitShaderProg->isLinked()) {
+ if (Q_UNLIKELY(!blitShaderProg->isLinked())) {
+ qCritical("Errors linking blit shader: %s", qPrintable(blitShaderProg->log()));
+ } else {
if (!inCache)
blitShaderCache.store(blitShaderProg, context);
- } else {
- qCritical("Errors linking blit shader: %s", qPrintable(blitShaderProg->log()));
}
#ifdef QT_GL_SHARED_SHADER_DEBUG
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index 0617c36236..5c2cff8d8c 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -626,7 +626,7 @@ QGLShaderProgramPrivate::~QGLShaderProgramPrivate()
bool QGLShaderProgramPrivate::hasShader(QGLShader::ShaderType type) const
{
- foreach (QGLShader *shader, shaders) {
+ for (QGLShader *shader : shaders) {
if (shader->shaderType() == type)
return true;
}
@@ -874,17 +874,16 @@ void QGLShaderProgram::removeAllShaders()
{
Q_D(QGLShaderProgram);
d->removingShaders = true;
- foreach (QGLShader *shader, d->shaders) {
- if (d->programGuard && d->programGuard->id()
- && shader && shader->d_func()->shaderGuard)
- {
- d->glfuncs->glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
+ if (d->programGuard) {
+ if (const auto programGuardId = d->programGuard->id()) {
+ for (QGLShader *shader : qAsConst(d->shaders)) {
+ if (shader && shader->d_func()->shaderGuard)
+ d->glfuncs->glDetachShader(programGuardId, shader->d_func()->shaderGuard->id());
+ }
}
}
- foreach (QGLShader *shader, d->anonShaders) {
- // Delete shader objects that were created anonymously.
- delete shader;
- }
+ // Delete shader objects that were created anonymously.
+ qDeleteAll(d->anonShaders);
d->shaders.clear();
d->anonShaders.clear();
d->linked = false; // Program needs to be relinked.
@@ -929,7 +928,7 @@ bool QGLShaderProgram::link()
// Set up the geometry shader parameters
if (!QOpenGLContext::currentContext()->isOpenGLES()
&& d->glfuncs->glProgramParameteri) {
- foreach (QGLShader *shader, d->shaders) {
+ for (QGLShader *shader : qAsConst(d->shaders)) {
if (shader->shaderType() & QGLShader::Geometry) {
d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_INPUT_TYPE_EXT,
d->geometryInputType);
diff --git a/src/platformsupport/cglconvenience/cglconvenience.mm b/src/platformsupport/cglconvenience/cglconvenience.mm
index 6b0a91e13f..b20f324442 100644
--- a/src/platformsupport/cglconvenience/cglconvenience.mm
+++ b/src/platformsupport/cglconvenience/cglconvenience.mm
@@ -34,7 +34,7 @@
#include "cglconvenience_p.h"
#include <QtCore/qglobal.h>
#include <QtCore/private/qcore_mac_p.h>
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include <QVector>
void (*qcgl_getProcAddress(const QByteArray &procName))()
diff --git a/src/platformsupport/cglconvenience/cglconvenience.pri b/src/platformsupport/cglconvenience/cglconvenience.pri
index 0e86ddb208..1de38bbd08 100644
--- a/src/platformsupport/cglconvenience/cglconvenience.pri
+++ b/src/platformsupport/cglconvenience/cglconvenience.pri
@@ -1,4 +1,4 @@
-mac:!ios {
+osx {
INCLUDEPATH += $$PWD
HEADERS += \
@@ -7,5 +7,5 @@ mac:!ios {
OBJECTIVE_SOURCES += \
$$PWD/cglconvenience.mm
- LIBS_PRIVATE += -framework Cocoa -framework OpenGL
+ LIBS_PRIVATE += -framework AppKit -framework OpenGL
}
diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm
index ffa548bf83..5fec32c650 100644
--- a/src/platformsupport/clipboard/qmacmime.mm
+++ b/src/platformsupport/clipboard/qmacmime.mm
@@ -32,10 +32,13 @@
****************************************************************************/
#include <QtCore/qsystemdetection.h>
+
+#if defined(Q_OS_OSX)
+#import <AppKit/AppKit.h>
+#endif
+
#if defined(Q_OS_IOS)
#import <UIKit/UIKit.h>
-#elif defined(Q_OS_OSX)
-#import <Cocoa/Cocoa.h>
#endif
#include "qmacmime_p.h"
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp
index 3aab785b34..4bf7508b2f 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp
@@ -56,6 +56,12 @@
#ifndef ABS_CNT
#define ABS_CNT (ABS_MAX+1)
#endif
+#ifndef ABS_MT_POSITION_X
+#define ABS_MT_POSITION_X 0x35
+#endif
+#ifndef ABS_MT_POSITION_Y
+#define ABS_MT_POSITION_Y 0x36
+#endif
#define LONG_BITS (sizeof(long) * 8 )
#define LONG_FIELD_SIZE(bits) ((bits / LONG_BITS) + 1)
@@ -113,67 +119,73 @@ QStringList QDeviceDiscoveryStatic::scanConnectedDevices()
bool QDeviceDiscoveryStatic::checkDeviceType(const QString &device)
{
- bool ret = false;
int fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
- if (!fd) {
+ if (Q_UNLIKELY(fd == -1)) {
qWarning() << "Device discovery cannot open device" << device;
return false;
}
+ qCDebug(lcDD) << "doing static device discovery for " << device;
+
+ if ((m_types & Device_DRM) && device.contains(QString::fromLatin1(QT_DRM_DEVICE_PREFIX))) {
+ QT_CLOSE(fd);
+ return true;
+ }
+
+ long bitsAbs[LONG_FIELD_SIZE(ABS_CNT)];
long bitsKey[LONG_FIELD_SIZE(KEY_CNT)];
- if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitsKey)), bitsKey) >= 0 ) {
- if (!ret && (m_types & Device_Keyboard)) {
- if (testBit(KEY_Q, bitsKey)) {
- qCDebug(lcDD) << "Found keyboard at" << device;
- ret = true;
- }
- }
+ long bitsRel[LONG_FIELD_SIZE(REL_CNT)];
+ memset(bitsAbs, 0, sizeof(bitsAbs));
+ memset(bitsKey, 0, sizeof(bitsKey));
+ memset(bitsRel, 0, sizeof(bitsRel));
- if (!ret && (m_types & Device_Mouse)) {
- long bitsRel[LONG_FIELD_SIZE(REL_CNT)];
- if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(bitsRel)), bitsRel) >= 0 ) {
- if (testBit(REL_X, bitsRel) && testBit(REL_Y, bitsRel) && testBit(BTN_MOUSE, bitsKey)) {
- qCDebug(lcDD) << "Found mouse at" << device;
- ret = true;
- }
- }
+ ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs);
+ ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitsKey)), bitsKey);
+ ioctl(fd, EVIOCGBIT(EV_REL, sizeof(bitsRel)), bitsRel);
+
+ QT_CLOSE(fd);
+
+ if ((m_types & Device_Keyboard)) {
+ if (testBit(KEY_Q, bitsKey)) {
+ qCDebug(lcDD) << "Found keyboard at" << device;
+ return true;
}
+ }
- if (!ret && (m_types & (Device_Touchpad | Device_Touchscreen))) {
- long bitsAbs[LONG_FIELD_SIZE(ABS_CNT)];
- if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs) >= 0 ) {
- if (testBit(ABS_X, bitsAbs) && testBit(ABS_Y, bitsAbs)) {
- if ((m_types & Device_Touchpad) && testBit(BTN_TOOL_FINGER, bitsKey)) {
- qCDebug(lcDD) << "Found touchpad at" << device;
- ret = true;
- } else if ((m_types & Device_Touchscreen) && testBit(BTN_TOUCH, bitsKey)) {
- qCDebug(lcDD) << "Found touchscreen at" << device;
- ret = true;
- } else if ((m_types & Device_Tablet) && (testBit(BTN_STYLUS, bitsKey) || testBit(BTN_TOOL_PEN, bitsKey))) {
- qCDebug(lcDD) << "Found tablet at" << device;
- ret = true;
- }
- }
- }
+ if ((m_types & Device_Mouse)) {
+ if (testBit(REL_X, bitsRel) && testBit(REL_Y, bitsRel) && testBit(BTN_MOUSE, bitsKey)) {
+ qCDebug(lcDD) << "Found mouse at" << device;
+ return true;
}
+ }
- if (!ret && (m_types & Device_Joystick)) {
- long bitsAbs[LONG_FIELD_SIZE(ABS_CNT)];
- if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs) >= 0 ) {
- if ((m_types & Device_Joystick)
- && (testBit(BTN_A, bitsKey) || testBit(BTN_TRIGGER, bitsKey) || testBit(ABS_RX, bitsAbs))) {
- qCDebug(lcDD) << "Found joystick/gamepad at" << device;
- ret = true;
- }
+ if ((m_types & (Device_Touchpad | Device_Touchscreen))) {
+ if (testBit(ABS_X, bitsAbs) && testBit(ABS_Y, bitsAbs)) {
+ if ((m_types & Device_Touchpad) && testBit(BTN_TOOL_FINGER, bitsKey)) {
+ qCDebug(lcDD) << "Found touchpad at" << device;
+ return true;
+ } else if ((m_types & Device_Touchscreen) && testBit(BTN_TOUCH, bitsKey)) {
+ qCDebug(lcDD) << "Found touchscreen at" << device;
+ return true;
+ } else if ((m_types & Device_Tablet) && (testBit(BTN_STYLUS, bitsKey) || testBit(BTN_TOOL_PEN, bitsKey))) {
+ qCDebug(lcDD) << "Found tablet at" << device;
+ return true;
}
+ } else if (testBit(ABS_MT_POSITION_X, bitsAbs) &&
+ testBit(ABS_MT_POSITION_Y, bitsAbs)) {
+ qCDebug(lcDD) << "Found new-style touchscreen at" << device;
+ return true;
}
}
- if (!ret && (m_types & Device_DRM) && device.contains(QString::fromLatin1(QT_DRM_DEVICE_PREFIX)))
- ret = true;
+ if ((m_types & Device_Joystick)) {
+ if (testBit(BTN_A, bitsKey) || testBit(BTN_TRIGGER, bitsKey) || testBit(ABS_RX, bitsAbs)) {
+ qCDebug(lcDD) << "Found joystick/gamepad at" << device;
+ return true;
+ }
+ }
- QT_CLOSE(fd);
- return ret;
+ return false;
}
QT_END_NAMESPACE
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
index f285e61a9f..334eb51a86 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
@@ -185,11 +185,11 @@ void QDeviceDiscoveryUDev::handleUDevNotification()
// if we cannot determine a type, walk up the device tree
if (!checkDeviceType(dev)) {
// does not increase the refcount
- dev = udev_device_get_parent_with_subsystem_devtype(dev, subsystem, 0);
- if (!dev)
+ struct udev_device *parent_dev = udev_device_get_parent_with_subsystem_devtype(dev, subsystem, 0);
+ if (!parent_dev)
goto cleanup;
- if (!checkDeviceType(dev))
+ if (!checkDeviceType(parent_dev))
goto cleanup;
}
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index a5fe88871d..02217a7179 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -36,6 +36,7 @@
#include <QtCore/QList>
#include <QtCore/QElapsedTimer>
+#include <QtCore/QFile>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformscreen.h>
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 0af779097c..a87443cc85 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -35,8 +35,8 @@
#include <sys/param.h>
-#if defined(Q_OS_MACX)
-#import <Cocoa/Cocoa.h>
+#if defined(Q_OS_OSX)
+#import <AppKit/AppKit.h>
#import <IOKit/graphics/IOGraphicsLib.h>
#elif defined(Q_OS_IOS)
#import <UIKit/UIFont.h>
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 732aead62a..be1696dfe8 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -215,6 +215,8 @@ void QCoreTextFontEngine::init()
Q_ASSERT((void *)(&ctfont + 1) == (void *)&cgFont);
faceData.user_data = &ctfont;
faceData.get_font_table = ct_getSfntTable;
+
+ kerningPairsLoaded = false;
}
glyph_t QCoreTextFontEngine::glyphIndex(uint ucs4) const
@@ -788,4 +790,17 @@ QFontEngine::Properties QCoreTextFontEngine::properties() const
return result;
}
+void QCoreTextFontEngine::doKerning(QGlyphLayout *g, ShaperFlags flags) const
+{
+ if (!kerningPairsLoaded) {
+ kerningPairsLoaded = true;
+ qreal emSquare = CTFontGetUnitsPerEm(ctfont);
+ qreal scale = emSquare / CTFontGetSize(ctfont);
+
+ const_cast<QCoreTextFontEngine *>(this)->loadKerningPairs(QFixed::fromReal(scale));
+ }
+
+ QFontEngine::doKerning(g, flags);
+}
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
index 1c33ae7d84..c22d1ddc0a 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
@@ -97,6 +97,7 @@ public:
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) Q_DECL_OVERRIDE;
QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE;
QFixed emSquareSize() const Q_DECL_OVERRIDE;
+ void doKerning(QGlyphLayout *g, ShaperFlags flags) const Q_DECL_OVERRIDE;
bool supportsTransformation(const QTransform &transform) const Q_DECL_OVERRIDE;
@@ -134,6 +135,7 @@ private:
CGAffineTransform transform;
QFixed avgCharWidth;
QFontEngine::FaceId face_id;
+ mutable bool kerningPairsLoaded;
};
CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
diff --git a/src/platformsupport/graphics/graphics.pri b/src/platformsupport/graphics/graphics.pri
new file mode 100644
index 0000000000..43062682aa
--- /dev/null
+++ b/src/platformsupport/graphics/graphics.pri
@@ -0,0 +1,2 @@
+HEADERS += $$PWD/qrasterbackingstore_p.h
+SOURCES += $$PWD/qrasterbackingstore.cpp
diff --git a/src/platformsupport/graphics/qrasterbackingstore.cpp b/src/platformsupport/graphics/qrasterbackingstore.cpp
new file mode 100644
index 0000000000..a64a4cfa40
--- /dev/null
+++ b/src/platformsupport/graphics/qrasterbackingstore.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qrasterbackingstore_p.h"
+
+#include <QtGui/qpainter.h>
+
+QT_BEGIN_NAMESPACE
+
+QRasterBackingStore::QRasterBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+}
+
+QRasterBackingStore::~QRasterBackingStore()
+{
+}
+
+void QRasterBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents);
+
+ int windowDevicePixelRatio = window()->devicePixelRatio();
+ QSize effectiveBufferSize = size * windowDevicePixelRatio;
+
+ if (m_image.size() == effectiveBufferSize)
+ return;
+
+ QImage::Format format = window()->format().hasAlpha() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
+ m_image = QImage(effectiveBufferSize, format);
+ m_image.setDevicePixelRatio(windowDevicePixelRatio);
+ if (format == QImage::Format_ARGB32_Premultiplied)
+ m_image.fill(Qt::transparent);
+}
+
+QPaintDevice *QRasterBackingStore::paintDevice()
+{
+ return &m_image;
+}
+
+QImage QRasterBackingStore::toImage() const
+{
+ return m_image;
+}
+
+bool QRasterBackingStore::scroll(const QRegion &region, int dx, int dy)
+{
+ if (window()->surfaceType() != QSurface::RasterSurface)
+ return false;
+
+ extern void qt_scrollRectInImage(QImage &, const QRect &, const QPoint &);
+
+ const qreal devicePixelRatio = m_image.devicePixelRatio();
+ const QPoint delta(dx * devicePixelRatio, dy * devicePixelRatio);
+
+ foreach (const QRect &rect, region.rects())
+ qt_scrollRectInImage(m_image, QRect(rect.topLeft() * devicePixelRatio, rect.size() * devicePixelRatio), delta);
+
+ return true;
+}
+
+void QRasterBackingStore::beginPaint(const QRegion &region)
+{
+ if (!m_image.hasAlphaChannel())
+ return;
+
+ QPainter painter(&m_image);
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ const QColor blank = Qt::transparent;
+ foreach (const QRect &rect, region.rects())
+ painter.fillRect(rect, blank);
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/graphics/qrasterbackingstore_p.h b/src/platformsupport/graphics/qrasterbackingstore_p.h
new file mode 100644
index 0000000000..314a6e6e79
--- /dev/null
+++ b/src/platformsupport/graphics/qrasterbackingstore_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QRASTERBACKINGSTORE_P_H
+#define QRASTERBACKINGSTORE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qpa/qplatformbackingstore.h>
+
+
+QT_BEGIN_NAMESPACE
+
+class QRasterBackingStore : public QPlatformBackingStore
+{
+public:
+ QRasterBackingStore(QWindow *window);
+ ~QRasterBackingStore();
+
+ QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
+ QImage toImage() const Q_DECL_OVERRIDE;
+ void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
+ bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
+ void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;
+
+protected:
+ QImage m_image;
+};
+
+QT_END_NAMESPACE
+
+#endif // QRASTERBACKINGSTORE_P_H
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
index 06751de0ef..d467a62abd 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
@@ -35,6 +35,7 @@
#include <qplatformdefs.h>
+#include <QFile>
#include <QSocketNotifier>
#include <QStringList>
#include <QCoreApplication>
diff --git a/src/platformsupport/input/evdevtablet/evdevtablet.pri b/src/platformsupport/input/evdevtablet/evdevtablet.pri
index 5ace0df61d..fb9489353c 100644
--- a/src/platformsupport/input/evdevtablet/evdevtablet.pri
+++ b/src/platformsupport/input/evdevtablet/evdevtablet.pri
@@ -1,8 +1,10 @@
HEADERS += \
- $$PWD/qevdevtablet_p.h
+ $$PWD/qevdevtablethandler_p.h \
+ $$PWD/qevdevtabletmanager_p.h
SOURCES += \
- $$PWD/qevdevtablet.cpp
+ $$PWD/qevdevtablethandler.cpp \
+ $$PWD/qevdevtabletmanager.cpp
contains(QT_CONFIG, libudev) {
LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV
diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp b/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp
index c6f952c64d..aa87340112 100644
--- a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp
+++ b/src/platformsupport/input/evdevtablet/qevdevtablethandler.cpp
@@ -31,14 +31,14 @@
**
****************************************************************************/
-#include "qevdevtablet_p.h"
-#include <qpa/qwindowsysteminterface.h>
+#include "qevdevtablethandler_p.h"
+
#include <QStringList>
#include <QSocketNotifier>
#include <QGuiApplication>
#include <QLoggingCategory>
#include <QtCore/private/qcore_unix_p.h>
-#include <QtPlatformSupport/private/qdevicediscovery_p.h>
+#include <qpa/qwindowsysteminterface.h>
#include <linux/input.h>
QT_BEGIN_NAMESPACE
@@ -49,16 +49,11 @@ class QEvdevTabletData
{
public:
QEvdevTabletData(QEvdevTabletHandler *q_ptr);
- bool queryLimits();
- void testGrab();
+
void processInputEvent(input_event *ev);
- void reportProximityEnter();
- void reportProximityLeave();
void report();
QEvdevTabletHandler *q;
- QSocketNotifier *notifier;
- int fd;
int lastEventType;
QString devName;
struct {
@@ -73,57 +68,13 @@ public:
};
QEvdevTabletData::QEvdevTabletData(QEvdevTabletHandler *q_ptr)
- : q(q_ptr), notifier(0), fd(-1), lastEventType(0)
+ : q(q_ptr), lastEventType(0)
{
memset(&minValues, 0, sizeof(minValues));
memset(&maxValues, 0, sizeof(maxValues));
memset(&state, 0, sizeof(state));
}
-bool QEvdevTabletData::queryLimits()
-{
- bool ok = true;
- input_absinfo absInfo;
- memset(&absInfo, 0, sizeof(input_absinfo));
- ok &= ioctl(fd, EVIOCGABS(ABS_X), &absInfo) >= 0;
- if (ok) {
- minValues.x = absInfo.minimum;
- maxValues.x = absInfo.maximum;
- qCDebug(qLcEvdevTablet, "evdevtablet: min X: %d max X: %d", minValues.x, maxValues.x);
- }
- ok &= ioctl(fd, EVIOCGABS(ABS_Y), &absInfo) >= 0;
- if (ok) {
- minValues.y = absInfo.minimum;
- maxValues.y = absInfo.maximum;
- qCDebug(qLcEvdevTablet, "evdevtablet: min Y: %d max Y: %d", minValues.y, maxValues.y);
- }
- if (ioctl(fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) {
- minValues.p = absInfo.minimum;
- maxValues.p = absInfo.maximum;
- qCDebug(qLcEvdevTablet, "evdevtablet: min pressure: %d max pressure: %d", minValues.p, maxValues.p);
- }
- if (ioctl(fd, EVIOCGABS(ABS_DISTANCE), &absInfo) >= 0) {
- minValues.d = absInfo.minimum;
- maxValues.d = absInfo.maximum;
- qCDebug(qLcEvdevTablet, "evdevtablet: min distance: %d max distance: %d", minValues.d, maxValues.d);
- }
- char name[128];
- if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) {
- devName = QString::fromLocal8Bit(name);
- qCDebug(qLcEvdevTablet, "evdevtablet: device name: %s", name);
- }
- return ok;
-}
-
-void QEvdevTabletData::testGrab()
-{
- bool grabSuccess = !ioctl(fd, EVIOCGRAB, (void *) 1);
- if (grabSuccess)
- ioctl(fd, EVIOCGRAB, (void *) 0);
- else
- qWarning("evdevtablet: ERROR: The device is grabbed by another process. No events will be read.");
-}
-
void QEvdevTabletData::processInputEvent(input_event *ev)
{
if (ev->type == EV_ABS) {
@@ -167,20 +118,10 @@ void QEvdevTabletData::processInputEvent(input_event *ev)
lastEventType = ev->type;
}
-void QEvdevTabletData::reportProximityEnter()
-{
- QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus, state.tool, 1);
-}
-
-void QEvdevTabletData::reportProximityLeave()
-{
- QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus, state.tool, 1);
-}
-
void QEvdevTabletData::report()
{
if (!state.lastReportTool && state.tool)
- reportProximityEnter();
+ QWindowSystemInterface::handleTabletEnterProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId());
qreal nx = (state.x - minValues.x) / qreal(maxValues.x - minValues.x);
qreal ny = (state.y - minValues.y) / qreal(maxValues.y - minValues.y);
@@ -194,16 +135,17 @@ void QEvdevTabletData::report()
pointer = state.lastReportTool;
}
- qreal pressure = (state.p - minValues.p) / qreal(maxValues.p - minValues.p);
+ int pressureRange = maxValues.p - minValues.p;
+ qreal pressure = pressureRange ? (state.p - minValues.p) / qreal(pressureRange) : qreal(1);
if (state.down || state.lastReportDown) {
QWindowSystemInterface::handleTabletEvent(0, state.down, QPointF(), globalPos,
QTabletEvent::Stylus, pointer,
- pressure, 0, 0, 0, 0, 0, 1, qGuiApp->keyboardModifiers());
+ pressure, 0, 0, 0, 0, 0, q->deviceId(), qGuiApp->keyboardModifiers());
}
if (state.lastReportTool && !state.tool)
- reportProximityLeave();
+ QWindowSystemInterface::handleTabletLeaveProximityEvent(QTabletEvent::Stylus, state.tool, q->deviceId());
state.lastReportDown = state.down;
state.lastReportTool = state.tool;
@@ -211,69 +153,104 @@ void QEvdevTabletData::report()
}
-QEvdevTabletHandler::QEvdevTabletHandler(const QString &spec, QObject *parent)
- : QObject(parent), d(0)
+QEvdevTabletHandler::QEvdevTabletHandler(const QString &device, const QString &spec, QObject *parent)
+ : QObject(parent), m_fd(-1), m_device(device), m_notifier(0), d(0)
{
+ Q_UNUSED(spec)
+
setObjectName(QLatin1String("Evdev Tablet Handler"));
- d = new QEvdevTabletData(this);
- QString dev;
- QStringList args = spec.split(QLatin1Char(':'));
- for (int i = 0; i < args.count(); ++i) {
- if (args.at(i).startsWith(QLatin1String("/dev/"))) {
- dev = args.at(i);
- break;
- }
- }
- if (dev.isEmpty()) {
- QScopedPointer<QDeviceDiscovery> deviceDiscovery(
- QDeviceDiscovery::create(QDeviceDiscovery::Device_Tablet, this));
- if (deviceDiscovery) {
- QStringList devices = deviceDiscovery->scanConnectedDevices();
- if (!devices.isEmpty())
- dev = devices.at(0);
- }
- }
- if (!dev.isEmpty()) {
- qCDebug(qLcEvdevTablet, "evdevtablet: using %s", qPrintable(dev));
- d->fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
- if (d->fd >= 0) {
- d->testGrab();
- if (d->queryLimits()) {
- d->notifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, this);
- connect(d->notifier, SIGNAL(activated(int)), this, SLOT(readData()));
- }
- } else {
- qErrnoWarning(errno, "evdevtablet: Cannot open input device");
- }
+
+ qCDebug(qLcEvdevTablet, "evdevtablet: using %s", qPrintable(device));
+
+ m_fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
+ if (m_fd < 0) {
+ qErrnoWarning(errno, "evdevtablet: Cannot open input device %s", qPrintable(device));
+ return;
}
+
+ bool grabSuccess = !ioctl(m_fd, EVIOCGRAB, (void *) 1);
+ if (grabSuccess)
+ ioctl(m_fd, EVIOCGRAB, (void *) 0);
+ else
+ qWarning("evdevtablet: %s: The device is grabbed by another process. No events will be read.", qPrintable(device));
+
+ d = new QEvdevTabletData(this);
+ if (!queryLimits())
+ qWarning("evdevtablet: %s: Unset or invalid ABS limits. Behavior will be unspecified.", qPrintable(device));
+
+ m_notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
+ connect(m_notifier, &QSocketNotifier::activated, this, &QEvdevTabletHandler::readData);
}
QEvdevTabletHandler::~QEvdevTabletHandler()
{
- delete d->notifier;
- if (d->fd >= 0)
- QT_CLOSE(d->fd);
+ if (m_fd >= 0)
+ QT_CLOSE(m_fd);
delete d;
}
+qint64 QEvdevTabletHandler::deviceId() const
+{
+ return m_fd;
+}
+
+bool QEvdevTabletHandler::queryLimits()
+{
+ bool ok = true;
+ input_absinfo absInfo;
+ memset(&absInfo, 0, sizeof(input_absinfo));
+ ok &= ioctl(m_fd, EVIOCGABS(ABS_X), &absInfo) >= 0;
+ if (ok) {
+ d->minValues.x = absInfo.minimum;
+ d->maxValues.x = absInfo.maximum;
+ qCDebug(qLcEvdevTablet, "evdevtablet: %s: min X: %d max X: %d", qPrintable(m_device),
+ d->minValues.x, d->maxValues.x);
+ }
+ ok &= ioctl(m_fd, EVIOCGABS(ABS_Y), &absInfo) >= 0;
+ if (ok) {
+ d->minValues.y = absInfo.minimum;
+ d->maxValues.y = absInfo.maximum;
+ qCDebug(qLcEvdevTablet, "evdevtablet: %s: min Y: %d max Y: %d", qPrintable(m_device),
+ d->minValues.y, d->maxValues.y);
+ }
+ if (ioctl(m_fd, EVIOCGABS(ABS_PRESSURE), &absInfo) >= 0) {
+ d->minValues.p = absInfo.minimum;
+ d->maxValues.p = absInfo.maximum;
+ qCDebug(qLcEvdevTablet, "evdevtablet: %s: min pressure: %d max pressure: %d", qPrintable(m_device),
+ d->minValues.p, d->maxValues.p);
+ }
+ if (ioctl(m_fd, EVIOCGABS(ABS_DISTANCE), &absInfo) >= 0) {
+ d->minValues.d = absInfo.minimum;
+ d->maxValues.d = absInfo.maximum;
+ qCDebug(qLcEvdevTablet, "evdevtablet: %s: min distance: %d max distance: %d", qPrintable(m_device),
+ d->minValues.d, d->maxValues.d);
+ }
+ char name[128];
+ if (ioctl(m_fd, EVIOCGNAME(sizeof(name) - 1), name) >= 0) {
+ d->devName = QString::fromLocal8Bit(name);
+ qCDebug(qLcEvdevTablet, "evdevtablet: %s: device name: %s", qPrintable(m_device), name);
+ }
+ return ok;
+}
+
void QEvdevTabletHandler::readData()
{
static input_event buffer[32];
int n = 0;
for (; ;) {
- int result = QT_READ(d->fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n);
+ int result = QT_READ(m_fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n);
if (!result) {
- qWarning("evdevtablet: Got EOF from input device");
+ qWarning("evdevtablet: %s: Got EOF from input device", qPrintable(m_device));
return;
} else if (result < 0) {
if (errno != EINTR && errno != EAGAIN) {
- qErrnoWarning(errno, "evdevtablet: Could not read from input device");
+ qErrnoWarning(errno, "evdevtablet: %s: Could not read from input device", qPrintable(m_device));
if (errno == ENODEV) { // device got disconnected -> stop reading
- delete d->notifier;
- d->notifier = 0;
- QT_CLOSE(d->fd);
- d->fd = -1;
+ delete m_notifier;
+ m_notifier = 0;
+ QT_CLOSE(m_fd);
+ m_fd = -1;
}
return;
}
@@ -291,8 +268,8 @@ void QEvdevTabletHandler::readData()
}
-QEvdevTabletHandlerThread::QEvdevTabletHandlerThread(const QString &spec, QObject *parent)
- : QDaemonThread(parent), m_spec(spec), m_handler(0)
+QEvdevTabletHandlerThread::QEvdevTabletHandlerThread(const QString &device, const QString &spec, QObject *parent)
+ : QDaemonThread(parent), m_device(device), m_spec(spec), m_handler(0)
{
start();
}
@@ -305,7 +282,7 @@ QEvdevTabletHandlerThread::~QEvdevTabletHandlerThread()
void QEvdevTabletHandlerThread::run()
{
- m_handler = new QEvdevTabletHandler(m_spec);
+ m_handler = new QEvdevTabletHandler(m_device, m_spec);
exec();
delete m_handler;
m_handler = 0;
diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h b/src/platformsupport/input/evdevtablet/qevdevtablethandler_p.h
index f546f9a88a..4a9b2bab34 100644
--- a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h
+++ b/src/platformsupport/input/evdevtablet/qevdevtablethandler_p.h
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#ifndef QEVDEVTABLET_P_H
-#define QEVDEVTABLET_P_H
+#ifndef QEVDEVTABLETHANDLER_P_H
+#define QEVDEVTABLETHANDLER_P_H
//
// W A R N I N G
@@ -52,6 +52,7 @@
QT_BEGIN_NAMESPACE
+class QSocketNotifier;
class QEvdevTabletData;
class QEvdevTabletHandler : public QObject
@@ -59,29 +60,37 @@ class QEvdevTabletHandler : public QObject
Q_OBJECT
public:
- explicit QEvdevTabletHandler(const QString &spec = QString(), QObject *parent = 0);
+ explicit QEvdevTabletHandler(const QString &device, const QString &spec = QString(), QObject *parent = 0);
~QEvdevTabletHandler();
+ qint64 deviceId() const;
+
private slots:
void readData();
private:
+ bool queryLimits();
+
+ int m_fd;
+ QString m_device;
+ QSocketNotifier *m_notifier;
QEvdevTabletData *d;
};
class QEvdevTabletHandlerThread : public QDaemonThread
{
public:
- explicit QEvdevTabletHandlerThread(const QString &spec, QObject *parent = 0);
+ explicit QEvdevTabletHandlerThread(const QString &device, const QString &spec, QObject *parent = 0);
~QEvdevTabletHandlerThread();
void run() Q_DECL_OVERRIDE;
QEvdevTabletHandler *handler() { return m_handler; }
private:
+ QString m_device;
QString m_spec;
QEvdevTabletHandler *m_handler;
};
QT_END_NAMESPACE
-#endif // QEVDEVTABLET_P_H
+#endif // QEVDEVTABLETHANDLER_P_H
diff --git a/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp b/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp
new file mode 100644
index 0000000000..05fd6e655c
--- /dev/null
+++ b/src/platformsupport/input/evdevtablet/qevdevtabletmanager.cpp
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qevdevtabletmanager_p.h"
+#include "qevdevtablethandler_p.h"
+
+#include <QStringList>
+#include <QGuiApplication>
+#include <QLoggingCategory>
+#include <QtPlatformSupport/private/qdevicediscovery_p.h>
+#include <private/qguiapplication_p.h>
+#include <private/qinputdevicemanager_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(qLcEvdevTablet)
+
+QEvdevTabletManager::QEvdevTabletManager(const QString &key, const QString &specification, QObject *parent)
+ : QObject(parent)
+{
+ Q_UNUSED(key);
+
+ if (qEnvironmentVariableIsSet("QT_QPA_EVDEV_DEBUG"))
+ const_cast<QLoggingCategory &>(qLcEvdevTablet()).setEnabled(QtDebugMsg, true);
+
+ QString spec = QString::fromLocal8Bit(qgetenv("QT_QPA_EVDEV_TABLET_PARAMETERS"));
+
+ if (spec.isEmpty())
+ spec = specification;
+
+ QStringList args = spec.split(QLatin1Char(':'));
+ QStringList devices;
+
+ foreach (const QString &arg, args) {
+ if (arg.startsWith(QLatin1String("/dev/"))) {
+ devices.append(arg);
+ args.removeAll(arg);
+ }
+ }
+
+ // build new specification without /dev/ elements
+ m_spec = args.join(QLatin1Char(':'));
+
+ foreach (const QString &device, devices)
+ addDevice(device);
+
+ // when no devices specified, use device discovery to scan and monitor
+ if (devices.isEmpty()) {
+ qCDebug(qLcEvdevTablet) << "evdevtablet: Using device discovery";
+ m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_Tablet, this);
+ if (m_deviceDiscovery) {
+ QStringList devices = m_deviceDiscovery->scanConnectedDevices();
+ foreach (const QString &device, devices)
+ addDevice(device);
+ connect(m_deviceDiscovery, SIGNAL(deviceDetected(QString)), this, SLOT(addDevice(QString)));
+ connect(m_deviceDiscovery, SIGNAL(deviceRemoved(QString)), this, SLOT(removeDevice(QString)));
+ }
+ }
+}
+
+QEvdevTabletManager::~QEvdevTabletManager()
+{
+ qDeleteAll(m_activeDevices);
+}
+
+void QEvdevTabletManager::addDevice(const QString &deviceNode)
+{
+ qCDebug(qLcEvdevTablet) << "Adding device at" << deviceNode;
+ QEvdevTabletHandlerThread *handler;
+ handler = new QEvdevTabletHandlerThread(deviceNode, m_spec);
+ if (handler) {
+ m_activeDevices.insert(deviceNode, handler);
+ QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount(
+ QInputDeviceManager::DeviceTypeTablet, m_activeDevices.count());
+ } else {
+ qWarning("evdevtablet: Failed to open tablet device %s", qPrintable(deviceNode));
+ }
+}
+
+void QEvdevTabletManager::removeDevice(const QString &deviceNode)
+{
+ if (m_activeDevices.contains(deviceNode)) {
+ qCDebug(qLcEvdevTablet) << "Removing device at" << deviceNode;
+ QEvdevTabletHandlerThread *handler = m_activeDevices.value(deviceNode);
+ m_activeDevices.remove(deviceNode);
+ QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount(
+ QInputDeviceManager::DeviceTypeTablet, m_activeDevices.count());
+ delete handler;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/styles/qgtkglobal_p.h b/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h
index 7d729d7fc0..893ff03fa7 100644
--- a/src/widgets/styles/qgtkglobal_p.h
+++ b/src/platformsupport/input/evdevtablet/qevdevtabletmanager_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the QtWidgets module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#ifndef QGTKGLOBAL_P_H
-#define QGTKGLOBAL_P_H
+#ifndef QEVDEVTABLETMANAGER_P_H
+#define QEVDEVTABLETMANAGER_P_H
//
// W A R N I N G
@@ -45,38 +45,32 @@
// We mean it.
//
-#include <QtCore/qglobal.h>
-#if !defined(QT_NO_STYLE_GTK)
+#include <QObject>
+#include <QHash>
+#include <QSocketNotifier>
-#undef signals // Collides with GTK symbols
-#include <gtk/gtk.h>
-
-typedef unsigned long XID;
+QT_BEGIN_NAMESPACE
-#undef GTK_OBJECT_FLAGS
-#define GTK_OBJECT_FLAGS(obj)(((GtkObject*)(obj))->flags)
+class QDeviceDiscovery;
+class QEvdevTabletHandlerThread;
-#define QLS(x) QLatin1String(x)
+class QEvdevTabletManager : public QObject
+{
+ Q_OBJECT
+public:
+ QEvdevTabletManager(const QString &key, const QString &spec, QObject *parent = 0);
+ ~QEvdevTabletManager();
-QT_BEGIN_NAMESPACE
+private slots:
+ void addDevice(const QString &deviceNode);
+ void removeDevice(const QString &deviceNode);
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
-# define QT_RED 3
-# define QT_GREEN 2
-# define QT_BLUE 1
-# define QT_ALPHA 0
-#else
-# define QT_RED 0
-# define QT_GREEN 1
-# define QT_BLUE 2
-# define QT_ALPHA 3
-#endif
-# define GTK_RED 2
-# define GTK_GREEN 1
-# define GTK_BLUE 0
-# define GTK_ALPHA 3
+private:
+ QString m_spec;
+ QDeviceDiscovery *m_deviceDiscovery;
+ QHash<QString, QEvdevTabletHandlerThread *> m_activeDevices;
+};
QT_END_NAMESPACE
-#endif // !QT_NO_STYLE_GTK
-#endif // QGTKGLOBAL_P_H
+#endif // QEVDEVTABLETMANAGER_P_H
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
index ad348cc083..dc40f728e1 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
@@ -36,6 +36,7 @@
#include <QHash>
#include <QSocketNotifier>
#include <QGuiApplication>
+#include <QTouchDevice>
#include <QLoggingCategory>
#include <QtCore/private/qcore_unix_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>
diff --git a/src/platformsupport/input/libinput/qlibinputhandler.cpp b/src/platformsupport/input/libinput/qlibinputhandler.cpp
index 5aa66a4eaf..58fbaacd2b 100644
--- a/src/platformsupport/input/libinput/qlibinputhandler.cpp
+++ b/src/platformsupport/input/libinput/qlibinputhandler.cpp
@@ -85,18 +85,18 @@ QLibInputHandler::QLibInputHandler(const QString &key, const QString &spec)
Q_UNUSED(spec);
m_udev = udev_new();
- if (!m_udev)
+ if (Q_UNLIKELY(!m_udev))
qFatal("Failed to get udev context for libinput");
m_li = libinput_udev_create_context(&liInterface, Q_NULLPTR, m_udev);
- if (!m_li)
+ if (Q_UNLIKELY(!m_li))
qFatal("Failed to get libinput context");
libinput_log_set_handler(m_li, liLogHandler);
if (qLcLibInput().isDebugEnabled())
libinput_log_set_priority(m_li, LIBINPUT_LOG_PRIORITY_DEBUG);
- if (libinput_udev_assign_seat(m_li, "seat0"))
+ if (Q_UNLIKELY(libinput_udev_assign_seat(m_li, "seat0")))
qFatal("Failed to assign seat");
m_liFd = libinput_get_fd(m_li);
diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro
index 1ea6d0eb69..81c7faa389 100644
--- a/src/platformsupport/platformsupport.pro
+++ b/src/platformsupport/platformsupport.pro
@@ -25,5 +25,6 @@ contains(QT_CONFIG, dbus) {
include(dbusmenu/dbusmenu.pri)
include(dbustray/dbustray.pri)
}
+ios: include(graphics/graphics.pri)
load(qt_module)
diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
index 33cb4391f0..01efa1449f 100644
--- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
@@ -42,6 +42,8 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_MULTIPROCESS
+
enum { debug = 0 };
static inline QByteArray detectDesktopEnvironment()
@@ -149,4 +151,24 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
return launch(m_documentLauncher, url);
}
+#else
+QByteArray QGenericUnixServices::desktopEnvironment() const
+{
+ return QByteArrayLiteral("UNKNOWN");
+}
+
+bool QGenericUnixServices::openUrl(const QUrl &url)
+{
+ qWarning("openUrl() not supported on this platform");
+ return false;
+}
+
+bool QGenericUnixServices::openDocument(const QUrl &url)
+{
+ qWarning("openDocument() not supported on this platform");
+ return false;
+}
+
+#endif // QT_NO_MULTIPROCESS
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index 8f6171f217..ee62710913 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -616,7 +616,7 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
return QVariant(QGenericUnixTheme::xdgIconThemePaths());
case QPlatformTheme::StyleNames: {
QStringList styleNames;
- styleNames << QStringLiteral("GTK+") << QStringLiteral("fusion") << QStringLiteral("windows");
+ styleNames << QStringLiteral("fusion") << QStringLiteral("windows");
return QVariant(styleNames);
}
case QPlatformTheme::KeyboardScheme:
@@ -714,9 +714,9 @@ QStringList QGenericUnixTheme::themeNames()
result.push_back(QLatin1String(QKdeTheme::name));
#endif
} else if (gtkBasedEnvironments.contains(desktopName)) {
- // prefer the GTK2 theme implementation with native dialogs etc.
- result.push_back(QStringLiteral("gtk2"));
- // fallback to the generic Gnome theme if loading the GTK2 theme fails
+ // prefer the GTK3 theme implementation with native dialogs etc.
+ result.push_back(QStringLiteral("gtk3"));
+ // fallback to the generic Gnome theme if loading the GTK3 theme fails
result.push_back(QLatin1String(QGnomeTheme::name));
}
}
diff --git a/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp b/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp
index da5f042abd..d422353c90 100644
--- a/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp
+++ b/src/plugins/bearer/android/src/wrappers/androidconnectivitymanager.cpp
@@ -321,10 +321,6 @@ int AndroidConnectivityManager::getNetworkPreference() const
bool AndroidConnectivityManager::isActiveNetworkMetered() const
{
- // This function was added in JB
- if (QtAndroidPrivate::androidSdkVersion() < 16)
- return false;
-
return m_connectivityManager.callMethod<jboolean>("isActiveNetworkMetered");
}
diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro
index a1434fc2ea..61e6f46ebc 100644
--- a/src/plugins/bearer/bearer.pro
+++ b/src/plugins/bearer/bearer.pro
@@ -7,7 +7,6 @@ TEMPLATE = subdirs
#win32:SUBDIRS += nla
win32:SUBDIRS += generic
-blackberry:SUBDIRS += blackberry
win32:!wince:!winrt: SUBDIRS += nativewifi
mac:contains(QT_CONFIG, corewlan):SUBDIRS += corewlan
mac:SUBDIRS += generic
diff --git a/src/plugins/bearer/blackberry/blackberry.json b/src/plugins/bearer/blackberry/blackberry.json
deleted file mode 100644
index 233f05cf53..0000000000
--- a/src/plugins/bearer/blackberry/blackberry.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "Keys": [ "blackberry" ]
-}
diff --git a/src/plugins/bearer/blackberry/blackberry.pro b/src/plugins/bearer/blackberry/blackberry.pro
deleted file mode 100644
index c75de3aaad..0000000000
--- a/src/plugins/bearer/blackberry/blackberry.pro
+++ /dev/null
@@ -1,20 +0,0 @@
-TARGET = qbbbearer
-
-PLUGIN_TYPE = bearer
-PLUGIN_CLASS_NAME = QBBEnginePlugin
-load(qt_plugin)
-
-QT = core-private network-private
-
-# Uncomment this to enable debugging output for the plugin
-#DEFINES += QBBENGINE_DEBUG
-
-HEADERS += qbbengine.h \
- ../qnetworksession_impl.h \
- ../qbearerengine_impl.h
-
-SOURCES += qbbengine.cpp \
- ../qnetworksession_impl.cpp \
- main.cpp
-
-OTHER_FILES += blackberry.json
diff --git a/src/plugins/bearer/blackberry/qbbengine.cpp b/src/plugins/bearer/blackberry/qbbengine.cpp
deleted file mode 100644
index 5483c48eaa..0000000000
--- a/src/plugins/bearer/blackberry/qbbengine.cpp
+++ /dev/null
@@ -1,413 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qbbengine.h"
-#include "../qnetworksession_impl.h"
-
-#include <QDebug>
-#include <QThreadStorage>
-#include <QStringList>
-#include <QTimer>
-
-#include <bps/netstatus.h>
-
-#ifndef QT_NO_BEARERMANAGEMENT
-
-#ifdef QBBENGINE_DEBUG
-#define qBearerDebug qDebug
-#else
-#define qBearerDebug QT_NO_QDEBUG_MACRO
-#endif
-
-struct NetstatusInterfaceListCleanupHelper
-{
- static inline void cleanup(netstatus_interface_list_t *list)
- {
- netstatus_free_interfaces(list);
- }
-};
-
-struct NetstatusInterfaceCleanupHelper
-{
- static inline void cleanup(char *interface)
- {
- bps_free(interface);
- }
-};
-
-struct EngineInstanceHolder
-{
- EngineInstanceHolder(QBBEngine *engine) :
- instance(engine) {}
-
- QBBEngine *instance;
-};
-
-Q_GLOBAL_STATIC(QThreadStorage<EngineInstanceHolder *>, instanceStorage);
-
-static QNetworkConfiguration::BearerType
-interfaceType(netstatus_interface_type_t type)
-{
- switch (type) {
- case NETSTATUS_INTERFACE_TYPE_USB:
- case NETSTATUS_INTERFACE_TYPE_WIRED:
- return QNetworkConfiguration::BearerEthernet;
-
- case NETSTATUS_INTERFACE_TYPE_WIFI:
- return QNetworkConfiguration::BearerWLAN;
-
- case NETSTATUS_INTERFACE_TYPE_BLUETOOTH_DUN:
- return QNetworkConfiguration::BearerBluetooth;
-
- case NETSTATUS_INTERFACE_TYPE_CELLULAR:
- // The exact bearer type is determined in QNetworkConfiguration
- // at the time this info is queried, because opposed to the
- // information here the type might change quickly.
- return QNetworkConfiguration::Bearer2G;
-
- case NETSTATUS_INTERFACE_TYPE_VPN:
- case NETSTATUS_INTERFACE_TYPE_BB:
- case NETSTATUS_INTERFACE_TYPE_UNKNOWN:
- break;
- }
-
- return QNetworkConfiguration::BearerUnknown;
-}
-
-static QString idForName(const QString &name)
-{
- return QStringLiteral("bps:") + name;
-}
-
-QT_BEGIN_NAMESPACE
-
-
-QBBEngine::QBBEngine(QObject *parent) :
- QBearerEngineImpl(parent),
- pollingRequired(false),
- initialized(false)
-{
-}
-
-QBBEngine::~QBBEngine()
-{
-}
-
-
-QString QBBEngine::getInterfaceFromId(const QString &id)
-{
- const QMutexLocker locker(&mutex);
-
- return configurationInterface.value(id);
-}
-
-bool QBBEngine::hasIdentifier(const QString &id)
-{
- const QMutexLocker locker(&mutex);
-
- return configurationInterface.contains(id);
-}
-
-void QBBEngine::connectToId(const QString &id)
-{
- Q_EMIT connectionError(id, OperationNotSupported);
-}
-
-void QBBEngine::disconnectFromId(const QString &id)
-{
- Q_EMIT connectionError(id, OperationNotSupported);
-}
-
-void QBBEngine::initialize()
-{
- if (initialized) {
- qWarning("called, but instance already initialized.");
- return;
- }
-
- instanceStorage()->setLocalData(new EngineInstanceHolder(this));
-
- if (netstatus_request_events(0) != BPS_SUCCESS) {
- qWarning("cannot register for network events. Polling enabled.");
-
- const QMutexLocker locker(&pollingMutex);
- pollingRequired = true;
- } else {
- QAbstractEventDispatcher::instance()->installEventFilter(this);
- }
-
- doRequestUpdate();
-}
-
-void QBBEngine::requestUpdate()
-{
- doRequestUpdate();
-}
-
-void QBBEngine::doRequestUpdate()
-{
- qBearerDebug("entered method");
-
- netstatus_interface_list_t interfaceList;
-
- if ((netstatus_get_interfaces(&interfaceList)) != BPS_SUCCESS) {
- qBearerDebug("cannot retrieve interface list");
- return;
- }
-
- const QScopedPointer<netstatus_interface_list_t,
- NetstatusInterfaceListCleanupHelper> holder(&interfaceList);
-
- QSet<QString> currentConfigurations;
-
- for (int i = 0; i < interfaceList.num_interfaces; i++) {
- const char *interface = interfaceList.interfaces[i];
-
- qBearerDebug() << "discovered interface" << interface;
-
- updateConfiguration(interface);
-
- currentConfigurations << idForName(QString::fromLatin1(interface));
- }
-
- QMutexLocker locker(&mutex);
-
- const QStringList keys = accessPointConfigurations.uniqueKeys();
-
- locker.unlock();
-
- Q_FOREACH (const QString &id, keys) {
- if (!currentConfigurations.contains(id))
- removeConfiguration(id);
- }
-
- Q_EMIT updateCompleted();
-}
-
-QNetworkSession::State QBBEngine::sessionStateForId(const QString &id)
-{
- const QMutexLocker locker(&mutex);
-
- QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
-
- if (!ptr || !ptr->isValid)
- return QNetworkSession::Invalid;
-
- if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active)
- return QNetworkSession::Connected;
- else if ((ptr->state & QNetworkConfiguration::Discovered) == QNetworkConfiguration::Discovered)
- return QNetworkSession::Disconnected;
- else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined)
- return QNetworkSession::NotAvailable;
- else if ((ptr->state & QNetworkConfiguration::Undefined) == QNetworkConfiguration::Undefined)
- return QNetworkSession::NotAvailable;
-
- return QNetworkSession::Invalid;
-}
-
-QNetworkConfigurationManager::Capabilities QBBEngine::capabilities() const
-{
- return QNetworkConfigurationManager::ForcedRoaming;
-}
-
-QNetworkSessionPrivate *QBBEngine::createSessionBackend()
-{
- return new QNetworkSessionPrivateImpl;
-}
-
-QNetworkConfigurationPrivatePointer QBBEngine::defaultConfiguration()
-{
- char *interface = 0;
-
- if (netstatus_get_default_interface(&interface) != BPS_SUCCESS)
- return QNetworkConfigurationPrivatePointer();
-
- if (!interface)
- return QNetworkConfigurationPrivatePointer();
-
- const QScopedPointer<char, NetstatusInterfaceCleanupHelper> holder(interface);
-
- const QString id = idForName(QString::fromLatin1(interface));
-
- const QMutexLocker locker(&mutex);
-
- if (accessPointConfigurations.contains(id)) {
- qBearerDebug() << "found default interface:" << id;
-
- return accessPointConfigurations.value(id);
- }
-
- return QNetworkConfigurationPrivatePointer();
-}
-
-bool QBBEngine::requiresPolling() const
-{
- const QMutexLocker locker(&pollingMutex);
-
- return pollingRequired;
-}
-
-bool QBBEngine::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
-{
- Q_UNUSED(eventType);
- Q_UNUSED(result);
-
- bps_event_t * const event = static_cast<bps_event_t *>(message);
-
- Q_ASSERT(event);
-
- if (bps_event_get_domain(event) == netstatus_get_domain()) {
- qBearerDebug("got update request.");
- doRequestUpdate();
- }
-
- return false;
-}
-
-void QBBEngine::updateConfiguration(const char *interface)
-{
- netstatus_interface_details_t *details = 0;
-
- if (netstatus_get_interface_details(interface, &details) != BPS_SUCCESS) {
- qBearerDebug() << "cannot retrieve details for interface" << interface;
-
- return;
- }
-
- const QString name = QString::fromLatin1(netstatus_interface_get_name(details));
- const QString id = idForName(name);
-
-
- const netstatus_interface_type_t type = netstatus_interface_get_type(details);
- const netstatus_ip_status_t ipStatus = netstatus_interface_get_ip_status(details);
-
- netstatus_free_interface_details(&details);
-
- QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Defined;
-
- if (ipStatus == NETSTATUS_IP_STATUS_OK)
- state |= QNetworkConfiguration::Active;
-
- QMutexLocker locker(&mutex);
-
- if (accessPointConfigurations.contains(id)) {
- QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
-
- bool changed = false;
-
- QMutexLocker ptrLocker(&ptr->mutex);
-
- if (!ptr->isValid) {
- ptr->isValid = true;
- changed = true;
- }
-
- if (ptr->name != name) {
- ptr->name = name;
- changed = true;
- }
-
- if (ptr->id != id) {
- ptr->id = id;
- changed = true;
- }
-
- if (ptr->state != state) {
- ptr->state = state;
- changed = true;
- }
-
- const netstatus_ip_status_t oldIpStatus = ptr->oldIpStatus;
- ptr->oldIpStatus = ipStatus;
-
- ptrLocker.unlock();
-
- locker.unlock();
-
- if (changed) {
- qBearerDebug() << "configuration changed:" << interface;
-
- Q_EMIT configurationChanged(ptr);
- } else {
- // maybe Wifi has changed but gateway not yet ready etc.
- qBearerDebug("configuration has not changed.");
- if (oldIpStatus != ipStatus) { // if IP status changed
- if (ipStatus != NETSTATUS_IP_STATUS_OK
- && ipStatus != NETSTATUS_IP_STATUS_ERROR_NOT_UP
- && ipStatus != NETSTATUS_IP_STATUS_ERROR_NOT_CONFIGURED) {
- // work around race condition in netstatus API by just checking
- // again in 300 ms
- QTimer::singleShot(300, this, SLOT(doRequestUpdate()));
- }
- }
- }
-
- return;
- }
-
- QNetworkConfigurationPrivatePointer ptr(new QNetworkConfigurationPrivate);
-
- ptr->name = name;
- ptr->isValid = true;
- ptr->id = id;
- ptr->state = state;
- ptr->type = QNetworkConfiguration::InternetAccessPoint;
- ptr->bearerType = interfaceType(type);
-
- accessPointConfigurations.insert(id, ptr);
- configurationInterface.insert(id, name);
-
- locker.unlock();
-
- qBearerDebug() << "configuration added:" << interface;
-
- Q_EMIT configurationAdded(ptr);
-}
-
-void QBBEngine::removeConfiguration(const QString &id)
-{
- QMutexLocker locker(&mutex);
-
- QNetworkConfigurationPrivatePointer ptr =
- accessPointConfigurations.take(id);
-
- configurationInterface.remove(ptr->id);
-
- locker.unlock();
-
- Q_EMIT configurationRemoved(ptr);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/bearer/blackberry/qbbengine.h b/src/plugins/bearer/blackberry/qbbengine.h
deleted file mode 100644
index 08790797ea..0000000000
--- a/src/plugins/bearer/blackberry/qbbengine.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBBENGINE_H
-#define QBBENGINE_H
-
-#include "../qbearerengine_impl.h"
-
-#include <QAbstractEventDispatcher>
-#include <QAbstractNativeEventFilter>
-
-#ifndef QT_NO_BEARERMANAGEMENT
-
-struct bps_event_t;
-
-QT_BEGIN_NAMESPACE
-
-class QNetworkConfigurationPrivate;
-class QNetworkSessionPrivate;
-
-class QBBEngine : public QBearerEngineImpl, public QAbstractNativeEventFilter
-{
- Q_OBJECT
-
-public:
- explicit QBBEngine(QObject *parent = 0);
- ~QBBEngine();
-
- QString getInterfaceFromId(const QString &id) Q_DECL_OVERRIDE;
- bool hasIdentifier(const QString &id) Q_DECL_OVERRIDE;
-
- void connectToId(const QString &id) Q_DECL_OVERRIDE;
- void disconnectFromId(const QString &id) Q_DECL_OVERRIDE;
-
- Q_INVOKABLE void initialize() Q_DECL_OVERRIDE;
- Q_INVOKABLE void requestUpdate() Q_DECL_OVERRIDE;
-
- QNetworkSession::State sessionStateForId(const QString &id) Q_DECL_OVERRIDE;
-
- QNetworkConfigurationManager::Capabilities capabilities() const Q_DECL_OVERRIDE;
-
- QNetworkSessionPrivate *createSessionBackend() Q_DECL_OVERRIDE;
-
- QNetworkConfigurationPrivatePointer defaultConfiguration() Q_DECL_OVERRIDE;
-
- bool requiresPolling() const Q_DECL_OVERRIDE;
-
- bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
-
-protected:
- void updateConfiguration(const char *interface);
- void removeConfiguration(const QString &id);
-
-private Q_SLOTS:
- void doRequestUpdate();
-
-private:
- QHash<QString, QString> configurationInterface;
-
- mutable QMutex pollingMutex;
-
- bool pollingRequired;
- bool initialized;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_BEARERMANAGEMENT
-
-#endif // QBBENGINE_H
diff --git a/src/plugins/generic/evdevtablet/main.cpp b/src/plugins/generic/evdevtablet/main.cpp
index 62524e8f33..3a9fd4f1dd 100644
--- a/src/plugins/generic/evdevtablet/main.cpp
+++ b/src/plugins/generic/evdevtablet/main.cpp
@@ -32,7 +32,7 @@
****************************************************************************/
#include <QtGui/qgenericplugin.h>
-#include <QtPlatformSupport/private/qevdevtablet_p.h>
+#include <QtPlatformSupport/private/qevdevtabletmanager_p.h>
QT_BEGIN_NAMESPACE
@@ -44,7 +44,6 @@ class QEvdevTabletPlugin : public QGenericPlugin
public:
QEvdevTabletPlugin();
- QStringList keys() const;
QObject* create(const QString &key, const QString &specification) Q_DECL_OVERRIDE;
};
@@ -52,16 +51,11 @@ QEvdevTabletPlugin::QEvdevTabletPlugin()
{
}
-QStringList QEvdevTabletPlugin::keys() const
-{
- return QStringList() << "EvdevTablet";
-}
-
-QObject *QEvdevTabletPlugin::create(const QString &key,
+QObject* QEvdevTabletPlugin::create(const QString &key,
const QString &spec)
{
if (!key.compare(QLatin1String("EvdevTablet"), Qt::CaseInsensitive))
- return new QEvdevTabletHandlerThread(spec);
+ return new QEvdevTabletManager(key, spec);
return 0;
}
diff --git a/src/plugins/generic/tuiotouch/qtuiohandler.cpp b/src/plugins/generic/tuiotouch/qtuiohandler.cpp
index 2b42889cb1..2598bc5caf 100644
--- a/src/plugins/generic/tuiotouch/qtuiohandler.cpp
+++ b/src/plugins/generic/tuiotouch/qtuiohandler.cpp
@@ -36,6 +36,7 @@
#include <QRect>
#include <QWindow>
#include <QGuiApplication>
+#include <QTouchDevice>
#include <qpa/qwindowsysteminterface.h>
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
index d1bea9af23..58c91eca9f 100644
--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp
@@ -111,7 +111,7 @@ bool QComposeInputContext::filterEvent(const QEvent *event)
keysym = keyEvent->nativeVirtualKey();
int nCompose = 0;
- while (m_composeBuffer[nCompose] != 0 && nCompose < QT_KEYSEQUENCE_MAX_LEN)
+ while (nCompose < QT_KEYSEQUENCE_MAX_LEN && m_composeBuffer[nCompose] != 0)
nCompose++;
if (nCompose == QT_KEYSEQUENCE_MAX_LEN) {
diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
index bdf5a91335..898eafd786 100644
--- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
+++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h
@@ -68,7 +68,7 @@ protected:
private:
QObject *m_focusObject;
QVector<QComposeTableElement> m_composeTable;
- uint m_composeBuffer[QT_KEYSEQUENCE_MAX_LEN + 1];
+ uint m_composeBuffer[QT_KEYSEQUENCE_MAX_LEN];
TableGenerator::TableState m_tableState;
bool m_compositionTableInitialized;
};
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
index a952123576..ee67202093 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
@@ -112,7 +112,7 @@ QIBusPlatformInputContext::QIBusPlatformInputContext ()
m_eventFilterUseSynchronousMode = false;
if (qEnvironmentVariableIsSet("IBUS_ENABLE_SYNC_MODE")) {
bool ok;
- int enableSync = qgetenv("IBUS_ENABLE_SYNC_MODE").toInt(&ok);
+ int enableSync = qEnvironmentVariableIntValue("IBUS_ENABLE_SYNC_MODE", &ok);
if (ok && enableSync == 1)
m_eventFilterUseSynchronousMode = true;
}
@@ -397,6 +397,7 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal
bool retval = reply.value();
qCDebug(qtQpaInputMethods) << "filterEventFinished return" << code << sym << state << retval;
if (!retval) {
+#ifndef QT_NO_CONTEXTMENU
if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu
&& window != NULL) {
const QPoint globalPos = window->screen()->handle()->cursor()->pos();
@@ -404,6 +405,7 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal
QWindowSystemInterface::handleContextMenuEvent(window, false, pos,
globalPos, modifiers);
}
+#endif // QT_NO_CONTEXTMENU
QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
code, sym, state, string, isAutoRepeat);
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index 69f8bdbad7..385ad3b672 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -68,10 +68,6 @@ namespace QtAndroidAccessibility
void initialize()
{
- // API level > 16 is required.
- if (QtAndroidPrivate::androidSdkVersion() < 16)
- return;
-
QJNIObjectPrivate::callStaticMethod<void>(QtAndroid::applicationClass(),
"initializeAccessibility");
}
@@ -299,9 +295,6 @@ if (!clazz) { \
bool registerNatives(JNIEnv *env)
{
- if (QtAndroidPrivate::androidSdkVersion() < 16)
- return true; // We need API level 16 or higher
-
jclass clazz;
FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/accessibility/QtNativeAccessibility");
jclass appClass = static_cast<jclass>(env->NewGlobalRef(clazz));
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index dd9154f8d2..7045533fca 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -494,7 +494,7 @@ static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring para
// Obtain a handle to the main library (the library that contains the main() function).
// This library should already be loaded, and calling dlopen() will just return a reference to it.
m_mainLibraryHnd = dlopen(m_applicationParams.first().data(), 0);
- if (m_mainLibraryHnd == nullptr) {
+ if (Q_UNLIKELY(!m_mainLibraryHnd)) {
qCritical() << "dlopen failed:" << dlerror();
return false;
}
@@ -504,7 +504,7 @@ static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring para
m_main = (Main)dlsym(RTLD_DEFAULT, "main");
}
- if (!m_main) {
+ if (Q_UNLIKELY(!m_main)) {
qCritical() << "dlsym failed:" << dlerror() << endl
<< "Could not find main method";
return false;
diff --git a/src/plugins/platforms/android/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp
index 8018cef1dc..3f44a3c4b9 100644
--- a/src/plugins/platforms/android/androidjnimenu.cpp
+++ b/src/plugins/platforms/android/androidjnimenu.cpp
@@ -87,14 +87,7 @@ namespace QtAndroidMenu
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env)
{
QMutexLocker lock(&visibleMenuMutex);
- if (QtAndroidPrivate::androidSdkVersion() > 10 &&
- QtAndroidPrivate::androidSdkVersion() < 14 &&
- anchorRect.isValid()) {
- pendingContextMenus.clear();
- } else if (visibleMenu) {
- pendingContextMenus.append(visibleMenu);
- }
-
+ pendingContextMenus.append(visibleMenu);
visibleMenu = menu;
menu->aboutToShow();
env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
diff --git a/src/plugins/platforms/android/qandroideventdispatcher.cpp b/src/plugins/platforms/android/qandroideventdispatcher.cpp
index aecea0d4e1..3f1cfe18b9 100644
--- a/src/plugins/platforms/android/qandroideventdispatcher.cpp
+++ b/src/plugins/platforms/android/qandroideventdispatcher.cpp
@@ -77,8 +77,11 @@ void QAndroidEventDispatcher::goingToStop(bool stop)
wakeUp();
}
-int QAndroidEventDispatcher::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timespec *timeout)
+bool QAndroidEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
{
+ if (m_goingToStop.load())
+ flags |= QEventLoop::ExcludeSocketNotifiers | QEventLoop::X11ExcludeTimers;
+
{
AndroidDeadlockProtector protector;
if (protector.acquire() && m_stopRequest.testAndSetAcquire(StopRequest, Stopping)) {
@@ -86,21 +89,10 @@ int QAndroidEventDispatcher::select(int nfds, fd_set *readfds, fd_set *writefds,
wakeUp();
}
}
- return QUnixEventDispatcherQPA::select(nfds, readfds, writefds, exceptfds, timeout);
-}
-bool QAndroidEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
-{
- if (m_goingToStop.load()) {
- return QUnixEventDispatcherQPA::processEvents(flags /*| QEventLoop::ExcludeUserInputEvents*/
- | QEventLoop::ExcludeSocketNotifiers
- | QEventLoop::X11ExcludeTimers);
- } else {
- return QUnixEventDispatcherQPA::processEvents(flags);
- }
+ return QUnixEventDispatcherQPA::processEvents(flags);
}
-
QAndroidEventDispatcherStopper *QAndroidEventDispatcherStopper::instance()
{
static QAndroidEventDispatcherStopper androidEventDispatcherStopper;
diff --git a/src/plugins/platforms/android/qandroideventdispatcher.h b/src/plugins/platforms/android/qandroideventdispatcher.h
index 946bae5b20..e2c4770467 100644
--- a/src/plugins/platforms/android/qandroideventdispatcher.h
+++ b/src/plugins/platforms/android/qandroideventdispatcher.h
@@ -50,9 +50,6 @@ public:
void goingToStop(bool stop);
protected:
- int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- timespec *timeout);
-
bool processEvents(QEventLoop::ProcessEventsFlags flags);
private:
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 0eddb26959..2e4c3d71ab 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -339,7 +339,7 @@ QAndroidInputContext::QAndroidInputContext()
: QPlatformInputContext(), m_composingTextStart(-1), m_blockUpdateSelection(false), m_batchEditNestingLevel(0), m_focusObject(0)
{
jclass clazz = QJNIEnvironmentPrivate::findClass(QtNativeInputConnectionClassName);
- if (clazz == NULL) {
+ if (Q_UNLIKELY(!clazz)) {
qCritical() << "Native registration unable to find class '"
<< QtNativeInputConnectionClassName
<< '\'';
@@ -347,7 +347,7 @@ QAndroidInputContext::QAndroidInputContext()
}
QJNIEnvironmentPrivate env;
- if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
+ if (Q_UNLIKELY(env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0)) {
qCritical() << "RegisterNatives failed for '"
<< QtNativeInputConnectionClassName
<< '\'';
@@ -355,7 +355,7 @@ QAndroidInputContext::QAndroidInputContext()
}
clazz = QJNIEnvironmentPrivate::findClass(QtExtractedTextClassName);
- if (clazz == NULL) {
+ if (Q_UNLIKELY(!clazz)) {
qCritical() << "Native registration unable to find class '"
<< QtExtractedTextClassName
<< '\'';
@@ -364,43 +364,43 @@ QAndroidInputContext::QAndroidInputContext()
m_extractedTextClass = static_cast<jclass>(env->NewGlobalRef(clazz));
m_classConstructorMethodID = env->GetMethodID(m_extractedTextClass, "<init>", "()V");
- if (m_classConstructorMethodID == NULL) {
+ if (Q_UNLIKELY(!m_classConstructorMethodID)) {
qCritical() << "GetMethodID failed";
return;
}
m_partialEndOffsetFieldID = env->GetFieldID(m_extractedTextClass, "partialEndOffset", "I");
- if (m_partialEndOffsetFieldID == NULL) {
+ if (Q_UNLIKELY(!m_partialEndOffsetFieldID)) {
qCritical() << "Can't find field partialEndOffset";
return;
}
m_partialStartOffsetFieldID = env->GetFieldID(m_extractedTextClass, "partialStartOffset", "I");
- if (m_partialStartOffsetFieldID == NULL) {
+ if (Q_UNLIKELY(!m_partialStartOffsetFieldID)) {
qCritical() << "Can't find field partialStartOffset";
return;
}
m_selectionEndFieldID = env->GetFieldID(m_extractedTextClass, "selectionEnd", "I");
- if (m_selectionEndFieldID == NULL) {
+ if (Q_UNLIKELY(!m_selectionEndFieldID)) {
qCritical() << "Can't find field selectionEnd";
return;
}
m_selectionStartFieldID = env->GetFieldID(m_extractedTextClass, "selectionStart", "I");
- if (m_selectionStartFieldID == NULL) {
+ if (Q_UNLIKELY(!m_selectionStartFieldID)) {
qCritical() << "Can't find field selectionStart";
return;
}
m_startOffsetFieldID = env->GetFieldID(m_extractedTextClass, "startOffset", "I");
- if (m_startOffsetFieldID == NULL) {
+ if (Q_UNLIKELY(!m_startOffsetFieldID)) {
qCritical() << "Can't find field startOffset";
return;
}
m_textFieldID = env->GetFieldID(m_extractedTextClass, "text", "Ljava/lang/String;");
- if (m_textFieldID == NULL) {
+ if (Q_UNLIKELY(!m_textFieldID)) {
qCritical() << "Can't find field text";
return;
}
diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
index 5725f5793e..a21aac51b4 100644
--- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
@@ -47,7 +47,7 @@ void QAndroidPlatformFontDatabase::populateFontDatabase()
QString fontpath = fontDir();
QDir dir(fontpath);
- if (!dir.exists()) {
+ if (Q_UNLIKELY(!dir.exists())) {
qFatal("QFontDatabase: Cannot find font directory %s - is Qt installed correctly?",
qPrintable(fontpath));
}
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 2a127f5c3c..23d242a95f 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -120,14 +120,14 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface();
m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (m_eglDisplay == EGL_NO_DISPLAY)
+ if (Q_UNLIKELY(m_eglDisplay == EGL_NO_DISPLAY))
qFatal("Could not open egl display");
EGLint major, minor;
- if (!eglInitialize(m_eglDisplay, &major, &minor))
+ if (Q_UNLIKELY(!eglInitialize(m_eglDisplay, &major, &minor)))
qFatal("Could not initialize egl display");
- if (!eglBindAPI(EGL_OPENGL_ES_API))
+ if (Q_UNLIKELY(!eglBindAPI(EGL_OPENGL_ES_API)))
qFatal("Could not bind GL_ES API");
m_primaryScreen = new QAndroidPlatformScreen();
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
index 57d3bfaf22..85f51d7d29 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
@@ -175,7 +175,7 @@ void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
m_androidSurfaceObject = QJNIObjectPrivate();
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL);
m_format = q_glFormatFromConfig(m_eglDisplay, config, window()->requestedFormat());
- if (m_eglSurface == EGL_NO_SURFACE) {
+ if (Q_UNLIKELY(m_eglSurface == EGL_NO_SURFACE)) {
EGLint error = eglGetError();
eglTerminate(m_eglDisplay);
qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error);
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index 5531910555..94e132fc9a 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -204,12 +204,12 @@ QJsonObject AndroidStyle::loadStyleData()
QJsonParseError error;
QJsonDocument document = QJsonDocument::fromJson(f.readAll(), &error);
- if (document.isNull()) {
+ if (Q_UNLIKELY(document.isNull())) {
qCritical() << error.errorString();
return QJsonObject();
}
- if (!document.isObject()) {
+ if (Q_UNLIKELY(!document.isObject())) {
qCritical() << "Style.json does not contain a valid style.";
return QJsonObject();
}
@@ -219,7 +219,7 @@ QJsonObject AndroidStyle::loadStyleData()
static std::shared_ptr<AndroidStyle> loadAndroidStyle(QPalette *defaultPalette)
{
double pixelDensity = QHighDpiScaling::isActive() ? QtAndroid::pixelDensity() : 1.0;
- std::shared_ptr<AndroidStyle> style(new AndroidStyle);
+ std::shared_ptr<AndroidStyle> style = std::make_shared<AndroidStyle>();
style->m_styleData = AndroidStyle::loadStyleData();
if (style->m_styleData.isEmpty())
return std::shared_ptr<AndroidStyle>();
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index ba0e6b001a..fec1da334f 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -84,7 +84,7 @@ contains(QT_CONFIG, opengl.*) {
RESOURCES += qcocoaresources.qrc
-LIBS += -framework Cocoa -framework Carbon -framework IOKit -lcups
+LIBS += -framework AppKit -framework Carbon -framework IOKit -lcups
QT += core-private gui-private platformsupport-private
diff --git a/src/plugins/platforms/cocoa/main.mm b/src/plugins/platforms/cocoa/main.mm
index 43ff715161..4ec2b4ffc4 100644
--- a/src/plugins/platforms/cocoa/main.mm
+++ b/src/plugins/platforms/cocoa/main.mm
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include <qpa/qplatformintegrationplugin.h>
#include <qpa/qplatformthemeplugin.h>
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
index 228643ab26..2d1aa41a9a 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
@@ -33,7 +33,7 @@
#ifndef QCOCOAACCESIBILITY_H
#define QCOCOAACCESIBILITY_H
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include <QtGui>
#include <qpa/qplatformaccessibility.h>
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 723c341e59..e8d69e9dbb 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -336,6 +336,7 @@ bool hasValueAttribute(QAccessibleInterface *interface)
Q_ASSERT(interface);
const QAccessible::Role qtrole = interface->role();
if (qtrole == QAccessible::EditableText
+ || qtrole == QAccessible::StaticText
|| interface->valueInterface()
|| interface->state().checkable) {
return true;
@@ -347,6 +348,9 @@ bool hasValueAttribute(QAccessibleInterface *interface)
id getValueAttribute(QAccessibleInterface *interface)
{
const QAccessible::Role qtrole = interface->role();
+ if (qtrole == QAccessible::StaticText) {
+ return QCFString::toNSString(interface->text(QAccessible::Name));
+ }
if (qtrole == QAccessible::EditableText) {
if (QAccessibleTextInterface *textInterface = interface->textInterface()) {
// VoiceOver will read out the entire text string at once when returning
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index b55393c7dc..5b2ee1c284 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -292,6 +292,8 @@ static void convertLineOffset(QAccessibleTextInterface *text, int &line, int &of
QSize qtSize = iface->rect().size();
return [NSValue valueWithSize: NSMakeSize(qtSize.width(), qtSize.height())];
} else if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) {
+ if (iface->role() == QAccessible::StaticText)
+ return nil;
return QCFString::toNSString(iface->text(QAccessible::Name));
} else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) {
return QCFString::toNSString(iface->text(QAccessible::Description));
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm
index d9919f1120..7d0018a595 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm
@@ -181,7 +181,7 @@ QT_BEGIN_NAMESPACE
void qt_redirectNSApplicationSendEvent()
{
- if (QCoreApplication::testAttribute(Qt::AA_MacPluginApplication))
+ if (QCoreApplication::testAttribute(Qt::AA_PluginApplication))
// In a plugin we cannot chain sendEvent hooks: a second plugin could
// store the implementation of the first, which during the program flow
// can be unloaded.
@@ -207,7 +207,7 @@ void qt_redirectNSApplicationSendEvent()
void qt_resetNSApplicationSendEvent()
{
- if (QCoreApplication::testAttribute(Qt::AA_MacPluginApplication))
+ if (QCoreApplication::testAttribute(Qt::AA_PluginApplication))
return;
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
index abaaba91a5..a0eb8cc6fd 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.h
@@ -79,7 +79,7 @@
//
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
#include <qglobal.h>
#include <private/qcore_mac_p.h>
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 5a199de4a5..839b536863 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -34,7 +34,7 @@
#ifndef QBACKINGSTORE_COCOA_H
#define QBACKINGSTORE_COCOA_H
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include "qcocoawindow.h"
#include "qnsview.h"
diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
index 8843e009a2..ddc2938855 100644
--- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
@@ -31,13 +31,13 @@
**
****************************************************************************/
-#include "qcocoacolordialoghelper.h"
-
#ifndef QT_NO_COLORDIALOG
#include <QtCore/qdebug.h>
#include <QtCore/qtimer.h>
+#include <qpa/qplatformtheme.h>
+#include "qcocoacolordialoghelper.h"
#include "qcocoahelpers.h"
#import <AppKit/AppKit.h>
@@ -52,7 +52,7 @@ static NSButton *macCreateButton(const char *text, NSView *superview)
[button setButtonType:NSMomentaryLightButton];
[button setBezelStyle:NSRoundedBezelStyle];
[button setTitle:(NSString*)(CFStringRef)QCFString(
- qt_mac_removeMnemonics(QCoreApplication::translate("QDialogButtonBox", text)))];
+ QPlatformTheme::removeMnemonics(QCoreApplication::translate("QDialogButtonBox", text)))];
[[button cell] setFont:[NSFont systemFontOfSize:
[NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
[superview addSubview:button];
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.h b/src/plugins/platforms/cocoa/qcocoacursor.h
index d104939f0c..58be5414f1 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.h
+++ b/src/plugins/platforms/cocoa/qcocoacursor.h
@@ -34,7 +34,7 @@
#ifndef QWINDOWSCURSOR_H
#define QWINDOWSCURSOR_H
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include <QtCore>
#include <qpa/qplatformcursor.h>
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.h b/src/plugins/platforms/cocoa/qcocoadrag.h
index c1eeb34679..51de5dd5ed 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.h
+++ b/src/plugins/platforms/cocoa/qcocoadrag.h
@@ -34,7 +34,7 @@
#ifndef QCOCOADRAG_H
#define QCOCOADRAG_H
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include <QtGui>
#include <qpa/qplatformdrag.h>
#include <private/qsimpledrag_p.h>
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 1865624d57..117eba1b2a 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -80,7 +80,7 @@
#include <qdebug.h>
#undef slots
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include <Carbon/Carbon.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 9dc013ba4d..0bfb105a5d 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -31,6 +31,8 @@
**
****************************************************************************/
+#include <qpa/qplatformtheme.h>
+
#include "qcocoafiledialoghelper.h"
#ifndef QT_NO_FILEDIALOG
@@ -180,7 +182,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
static QString strippedText(QString s)
{
s.remove( QString::fromLatin1("...") );
- return qt_mac_removeMnemonics(s).trimmed();
+ return QPlatformTheme::removeMnemonics(s).trimmed();
}
- (NSString *)strip:(const QString &)label
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
index d1802fe4f9..c1c871f02b 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
@@ -31,17 +31,17 @@
**
****************************************************************************/
-#include "qcocoafontdialoghelper.h"
-
#ifndef QT_NO_FONTDIALOG
#include <QtCore/qtimer.h>
#include <QtGui/qfontdatabase.h>
+#include <qpa/qplatformtheme.h>
#include <private/qfont_p.h>
#include <private/qfontengine_p.h>
#include <private/qfontengine_coretext_p.h>
+#include "qcocoafontdialoghelper.h"
#include "qcocoahelpers.h"
#import <AppKit/AppKit.h>
@@ -72,7 +72,7 @@ static NSButton *macCreateButton(const char *text, NSView *superview)
[button setButtonType:NSMomentaryLightButton];
[button setBezelStyle:NSRoundedBezelStyle];
[button setTitle:(NSString*)(CFStringRef)QCFString(
- qt_mac_removeMnemonics(QCoreApplication::translate("QDialogButtonBox", text)))];
+ QPlatformTheme::removeMnemonics(QCoreApplication::translate("QDialogButtonBox", text)))];
[[button cell] setFont:[NSFont systemFontOfSize:
[NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
[superview addSubview:button];
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h
index fa6db018a7..cac53b14f9 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.h
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h
@@ -40,7 +40,7 @@
#include <QtGui/QWindow>
#undef slots
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 0f9b8b900d..d43c8e5ee9 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -39,7 +39,7 @@
#include <QtPlatformSupport/private/cglconvenience_p.h>
#include <QtPlatformHeaders/qcocoanativecontext.h>
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index b86a17ca12..b83977c7d8 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -46,6 +46,7 @@
//
#include "qt_mac_p.h"
#include <private/qguiapplication_p.h>
+#include <QtGui/qpalette.h>
#include <QtGui/qscreen.h>
QT_BEGIN_NAMESPACE
@@ -66,6 +67,7 @@ NSImage *qt_mac_create_nsimage(const QIcon &icon);
CGImageRef qt_mac_toCGImage(const QImage &qImage);
CGImageRef qt_mac_toCGImageMask(const QImage &qImage);
QImage qt_mac_toQImage(CGImageRef image);
+QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size);
NSSize qt_mac_toNSSize(const QSize &qtSize);
NSRect qt_mac_toNSRect(const QRect &rect);
@@ -74,6 +76,8 @@ QRect qt_mac_toQRect(const NSRect &rect);
QColor qt_mac_toQColor(const NSColor *color);
QColor qt_mac_toQColor(CGColorRef color);
+QBrush qt_mac_toQBrush(CGColorRef color);
+QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup = QPalette::Normal);
// Creates a mutable shape, it's the caller's responsibility to release.
HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion &region);
@@ -90,7 +94,6 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions);
// Misc
void qt_mac_transformProccessToForegroundApplication();
-QString qt_mac_removeMnemonics(const QString &original);
CGColorSpaceRef qt_mac_genericColorSpace();
CGColorSpaceRef qt_mac_displayColorSpace(const QWidget *widget);
CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice);
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 7bc8d6585b..de27175bbd 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -31,6 +31,8 @@
**
****************************************************************************/
+#include <qpa/qplatformtheme.h>
+
#include "qcocoahelpers.h"
@@ -46,6 +48,27 @@
#include <algorithm>
+#include <Carbon/Carbon.h>
+
+@interface NSGraphicsContext (QtAdditions)
+
++ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState;
+
+@end
+
+@implementation NSGraphicsContext (QtAdditions)
+
++ (NSGraphicsContext *)qt_graphicsContextWithCGContext:(CGContextRef)graphicsPort flipped:(BOOL)initialFlippedState
+{
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_NA)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_10)
+ return [self graphicsContextWithCGContext:graphicsPort flipped:initialFlippedState];
+#endif
+ return [self graphicsContextWithGraphicsPort:graphicsPort flipped:initialFlippedState];
+}
+
+@end
+
QT_BEGIN_NAMESPACE
//
@@ -236,6 +259,125 @@ QColor qt_mac_toQColor(CGColorRef color)
return qtColor;
}
+QBrush qt_mac_toQBrush(CGColorRef color)
+{
+ QBrush qtBrush;
+ CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(color));
+ if (model == kCGColorSpaceModelPattern) {
+ // Colorspace we can't deal with; the color is drawn directly using a callback.
+ qWarning("Qt: qt_mac_toQBrush: cannot convert from colorspace model: %d", model);
+ Q_ASSERT(false);
+ } else {
+ qtBrush.setStyle(Qt::SolidPattern);
+ qtBrush.setColor(qt_mac_toQColor(color));
+ }
+ return qtBrush;
+}
+
+static bool qt_mac_isSystemColorOrInstance(const NSColor *color, NSString *colorNameComponent, NSString *className)
+{
+ // We specifically do not want isKindOfClass: here
+ if ([color.className isEqualToString:className]) // NSPatternColorSpace
+ return true;
+ if ([color.catalogNameComponent isEqualToString:@"System"] &&
+ [color.colorNameComponent isEqualToString:colorNameComponent] &&
+ [color.colorSpaceName isEqualToString:NSNamedColorSpace])
+ return true;
+ return false;
+}
+
+QBrush qt_mac_toQBrush(const NSColor *color, QPalette::ColorGroup colorGroup)
+{
+ QBrush qtBrush;
+
+ // QTBUG-49773: This calls NSDrawMenuItemBackground to render a 1 by n gradient; could use HITheme
+ if ([color.className isEqualToString:@"NSMenuItemHighlightColor"]) {
+ qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMenuItemHighlightColor");
+ return qtBrush;
+ }
+
+ // Not a catalog color or a manifestation of System.windowBackgroundColor;
+ // only retrieved from NSWindow.backgroundColor directly
+ if ([color.className isEqualToString:@"NSMetalPatternColor"]) {
+ // NSTexturedBackgroundWindowMask, could theoretically handle this without private API by
+ // creating a window with the appropriate properties and then calling NSWindow.backgroundColor.patternImage,
+ // which returns a texture sized 1 by (window height, including frame), backed by a CGPattern
+ // which follows the window key state... probably need to allow QBrush to store a function pointer
+ // like CGPattern does
+ qWarning("Qt: qt_mac_toQBrush: cannot convert from NSMetalPatternColor");
+ return qtBrush;
+ }
+
+ // No public API to get these colors/stops;
+ // both accurately obtained through runtime object inspection on OS X 10.11
+ // (the NSColor object has NSGradient i-vars for both color groups)
+ if (qt_mac_isSystemColorOrInstance(color, @"_sourceListBackgroundColor", @"NSSourceListBackgroundColor")) {
+ QLinearGradient gradient;
+ if (colorGroup == QPalette::Active) {
+ gradient.setColorAt(0, QColor(233, 237, 242));
+ gradient.setColorAt(0.5, QColor(225, 229, 235));
+ gradient.setColorAt(1, QColor(209, 216, 224));
+ } else {
+ gradient.setColorAt(0, QColor(248, 248, 248));
+ gradient.setColorAt(0.5, QColor(240, 240, 240));
+ gradient.setColorAt(1, QColor(235, 235, 235));
+ }
+ return QBrush(gradient);
+ }
+
+ // A couple colors are special... they are actually instances of NSGradientPatternColor, which
+ // override set/setFill/setStroke to instead initialize an internal color
+ // ([NSColor colorWithCalibratedWhite:0.909804 alpha:1.000000]) while still returning the
+ // ruled lines pattern image (from OS X 10.4) to the user from -[NSColor patternImage]
+ // (and providing no public API to get the underlying color without this insanity)
+ if (qt_mac_isSystemColorOrInstance(color, @"controlColor", @"NSGradientPatternColor") ||
+ qt_mac_isSystemColorOrInstance(color, @"windowBackgroundColor", @"NSGradientPatternColor")) {
+ static QColor newColor;
+ if (!newColor.isValid()) {
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_NA)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ newColor = qt_mac_toQColor(color.CGColor);
+ } else
+#endif
+ {
+ NSBitmapImageRep *offscreenRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil
+ pixelsWide:1
+ pixelsHigh:1
+ bitsPerSample:8
+ samplesPerPixel:4
+ hasAlpha:YES
+ isPlanar:NO
+ colorSpaceName:NSDeviceRGBColorSpace
+ bytesPerRow:4
+ bitsPerPixel:32];
+ [NSGraphicsContext saveGraphicsState];
+ [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:offscreenRep]];
+ NSEraseRect(NSMakeRect(0, 0, 1, 1));
+ [color drawSwatchInRect:NSMakeRect(0, 0, 1, 1)];
+ [NSGraphicsContext restoreGraphicsState];
+ NSUInteger pixel[4];
+ [offscreenRep getPixel:pixel atX:0 y:0];
+ [offscreenRep release];
+ newColor = QColor(pixel[0], pixel[1], pixel[2], pixel[3]);
+ }
+ }
+
+ qtBrush.setStyle(Qt::SolidPattern);
+ qtBrush.setColor(newColor);
+ return qtBrush;
+ }
+
+ if (NSColor *patternColor = [color colorUsingColorSpaceName:NSPatternColorSpace]) {
+ NSImage *patternImage = patternColor.patternImage;
+ const QSizeF sz(patternImage.size.width, patternImage.size.height);
+ qtBrush.setTexture(qt_mac_toQPixmap(patternImage, sz)); // QTBUG-49774
+ } else {
+ qtBrush.setStyle(Qt::SolidPattern);
+ qtBrush.setColor(qt_mac_toQColor(color));
+ }
+ return qtBrush;
+}
+
// Use this method to keep all the information in the TextSegment. As long as it is ordered
// we are in OK shape, and we can influence that ourselves.
struct KeyPair
@@ -439,88 +581,49 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
// Misc
//
-// Changes the process type for this process to kProcessTransformToForegroundApplication,
+// Sets the activation policy for this process to NSApplicationActivationPolicyRegular,
// unless either LSUIElement or LSBackgroundOnly is set in the Info.plist.
void qt_mac_transformProccessToForegroundApplication()
{
- ProcessSerialNumber psn;
- if (GetCurrentProcess(&psn) == noErr) {
- bool forceTransform = true;
- CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
- CFSTR("LSUIElement"));
+ bool forceTransform = true;
+ CFTypeRef value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
+ CFSTR("LSUIElement"));
+ if (value) {
+ CFTypeID valueType = CFGetTypeID(value);
+ // Officially it's supposed to be a string, a boolean makes sense, so we'll check.
+ // A number less so, but OK.
+ if (valueType == CFStringGetTypeID())
+ forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
+ else if (valueType == CFBooleanGetTypeID())
+ forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
+ else if (valueType == CFNumberGetTypeID()) {
+ int valueAsInt;
+ CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
+ forceTransform = !valueAsInt;
+ }
+ }
+
+ if (forceTransform) {
+ value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
+ CFSTR("LSBackgroundOnly"));
if (value) {
CFTypeID valueType = CFGetTypeID(value);
- // Officially it's supposed to be a string, a boolean makes sense, so we'll check.
- // A number less so, but OK.
- if (valueType == CFStringGetTypeID())
- forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
- else if (valueType == CFBooleanGetTypeID())
+ if (valueType == CFBooleanGetTypeID())
forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
+ else if (valueType == CFStringGetTypeID())
+ forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
else if (valueType == CFNumberGetTypeID()) {
int valueAsInt;
CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
forceTransform = !valueAsInt;
}
}
-
- if (forceTransform) {
- value = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
- CFSTR("LSBackgroundOnly"));
- if (value) {
- CFTypeID valueType = CFGetTypeID(value);
- if (valueType == CFBooleanGetTypeID())
- forceTransform = !CFBooleanGetValue(static_cast<CFBooleanRef>(value));
- else if (valueType == CFStringGetTypeID())
- forceTransform = !(QCFString::toQString(static_cast<CFStringRef>(value)).toInt());
- else if (valueType == CFNumberGetTypeID()) {
- int valueAsInt;
- CFNumberGetValue(static_cast<CFNumberRef>(value), kCFNumberIntType, &valueAsInt);
- forceTransform = !valueAsInt;
- }
- }
- }
-
- if (forceTransform) {
- TransformProcessType(&psn, kProcessTransformToForegroundApplication);
- }
}
-}
-QString qt_mac_removeMnemonics(const QString &original)
-{
- QString returnText(original.size(), 0);
- int finalDest = 0;
- int currPos = 0;
- int l = original.length();
- while (l) {
- if (original.at(currPos) == QLatin1Char('&')
- && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) {
- ++currPos;
- --l;
- if (l == 0)
- break;
- } else if (original.at(currPos) == QLatin1Char('(') && l >= 4 &&
- original.at(currPos + 1) == QLatin1Char('&') &&
- original.at(currPos + 2) != QLatin1Char('&') &&
- original.at(currPos + 3) == QLatin1Char(')')) {
- /* remove mnemonics its format is "\s*(&X)" */
- int n = 0;
- while (finalDest > n && returnText.at(finalDest - n - 1).isSpace())
- ++n;
- finalDest -= n;
- currPos += 4;
- l -= 4;
- continue;
- }
- returnText[finalDest] = original.at(currPos);
- ++currPos;
- ++finalDest;
- --l;
+ if (forceTransform) {
+ [[NSApplication sharedApplication] setActivationPolicy:NSApplicationActivationPolicyRegular];
}
- returnText.truncate(finalDest);
- return returnText;
}
-
static CGColorSpaceRef m_genericColorSpace = 0;
static QHash<CGDirectDisplayID, CGColorSpaceRef> m_displayColorSpaceHash;
static bool m_postRoutineRegistered = false;
@@ -775,7 +878,7 @@ bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret)
QString qt_mac_removeAmpersandEscapes(QString s)
{
- return qt_mac_removeMnemonics(s).trimmed();
+ return QPlatformTheme::removeMnemonics(s).trimmed();
}
/*! \internal
@@ -821,6 +924,26 @@ CGContextRef qt_mac_cg_context(QPaintDevice *pdev)
return ret;
}
+QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size)
+{
+ const NSSize pixmapSize = NSMakeSize(size.width(), size.height());
+ QPixmap pixmap(pixmapSize.width, pixmapSize.height);
+ pixmap.fill(Qt::transparent);
+ [image setSize:pixmapSize];
+ const NSRect iconRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height);
+ QMacCGContext ctx(&pixmap);
+ if (!ctx)
+ return QPixmap();
+ NSGraphicsContext *gc = [NSGraphicsContext qt_graphicsContextWithCGContext:ctx flipped:YES];
+ if (!gc)
+ return QPixmap();
+ [NSGraphicsContext saveGraphicsState];
+ [NSGraphicsContext setCurrentContext:gc];
+ [image drawInRect:iconRect fromRect:iconRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
+ [NSGraphicsContext restoreGraphicsState];
+ return pixmap;
+}
+
QImage qt_mac_toQImage(CGImageRef image)
{
const size_t w = CGImageGetWidth(image),
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index e7e21c356a..7943926ba3 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -34,7 +34,7 @@
#ifndef QPLATFORMINTEGRATION_COCOA_H
#define QPLATFORMINTEGRATION_COCOA_H
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include "qcocoacursor.h"
#include "qcocoawindow.h"
@@ -148,6 +148,9 @@ public:
QList<QCocoaWindow *> *popupWindowStack();
void setApplicationIcon(const QIcon &icon) const Q_DECL_OVERRIDE;
+
+ void beep() const Q_DECL_OVERRIDE;
+
private:
static QCocoaIntegration *mInstance;
Options mOptions;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 6bec6b191d..245cfe33be 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -317,7 +317,7 @@ QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
// ### For AA_MacPluginApplication we don't want to load the menu nib.
// Qt 4 also does not set the application delegate, so that behavior
// is matched here.
- if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
+ if (!QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
// Set app delegate, link to the current delegate (if any)
QCocoaApplicationDelegate *newDelegate = [QCocoaApplicationDelegate sharedDelegate];
@@ -344,7 +344,7 @@ QCocoaIntegration::~QCocoaIntegration()
qt_resetNSApplicationSendEvent();
QMacAutoReleasePool pool;
- if (!QCoreApplication::testAttribute(Qt::AA_MacPluginApplication)) {
+ if (!QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
// remove the apple event handlers installed by QCocoaApplicationDelegate
QCocoaApplicationDelegate *delegate = [QCocoaApplicationDelegate sharedDelegate];
[delegate removeAppleEventHandlers];
@@ -614,4 +614,9 @@ void QCocoaIntegration::setApplicationIcon(const QIcon &icon) const
[image release];
}
+void QCocoaIntegration::beep() const
+{
+ NSBeep();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.h b/src/plugins/platforms/cocoa/qcocoakeymapper.h
index 11bbdc5426..9e79d634ab 100644
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.h
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.h
@@ -36,7 +36,7 @@
#include <qcocoahelpers.h>
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include <Carbon/Carbon.h>
#include <QtCore/QList>
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index 1a516f874b..d404438db6 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include "qcocoamenubar.h"
#include "qcocoawindow.h"
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 0f551bcd7d..968d1a2a4d 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -31,6 +31,8 @@
**
****************************************************************************/
+#include <qpa/qplatformtheme.h>
+
#include "qcocoamenuitem.h"
#include "qcocoamenu.h"
@@ -318,7 +320,7 @@ NSMenuItem *QCocoaMenuItem::sync()
if (accel.count() > 1)
text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")");
- QString finalString = qt_mac_removeMnemonics(text);
+ QString finalString = QPlatformTheme::removeMnemonics(text);
bool useAttributedTitle = false;
// Cocoa Font and title
if (m_font.resolve()) {
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.h b/src/plugins/platforms/cocoa/qcocoamenuloader.h
index bdc943f78a..a3eea8bc15 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.h
@@ -45,7 +45,7 @@
// We mean it.
//
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
#include <QtCore/private/qcore_mac_p.h>
@interface QT_MANGLE_NAMESPACE(QCocoaMenuLoader) : NSResponder
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index d018c05635..e46a622d3a 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -60,8 +60,6 @@ public:
NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
- Q_INVOKABLE void beep();
-
#ifndef QT_NO_OPENGL
static void *cglContextForContext(QOpenGLContext *context);
static void *nsOpenGLContextForContext(QOpenGLContext* context);
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index baee451903..542a26d409 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -60,7 +60,7 @@
#include <QtPlatformHeaders/qcocoawindowfunctions.h>
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
QT_BEGIN_NAMESPACE
@@ -139,11 +139,6 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return 0;
}
-void QCocoaNativeInterface::beep()
-{
- NSBeep();
-}
-
QPlatformPrinterSupport *QCocoaNativeInterface::createPlatformPrinterSupport()
{
#if !defined(QT_NO_WIDGETS) && !defined(QT_NO_PRINTER)
diff --git a/src/plugins/platforms/cocoa/qcocoaservices.mm b/src/plugins/platforms/cocoa/qcocoaservices.mm
index 6f3f6c4e1d..75fc32f338 100644
--- a/src/plugins/platforms/cocoa/qcocoaservices.mm
+++ b/src/plugins/platforms/cocoa/qcocoaservices.mm
@@ -33,8 +33,6 @@
#include "qcocoaservices.h"
-#include "qt_mac_p.h"
-
#include <AppKit/NSWorkspace.h>
#include <Foundation/NSURL.h>
@@ -47,7 +45,7 @@ bool QCocoaServices::openUrl(const QUrl &url)
const QString scheme = url.scheme();
if (scheme.isEmpty())
return openDocument(url);
- return [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:QCFString::toNSString(url.toString(QUrl::FullyEncoded))]];
+ return [[NSWorkspace sharedWorkspace] openURL:url.toNSURL()];
}
bool QCocoaServices::openDocument(const QUrl &url)
@@ -55,7 +53,7 @@ bool QCocoaServices::openDocument(const QUrl &url)
if (!url.isValid())
return false;
- return [[NSWorkspace sharedWorkspace] openFile:QCFString::toNSString(url.toLocalFile())];
+ return [[NSWorkspace sharedWorkspace] openFile:url.toLocalFile().toNSString()];
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index 93f8b2ba6f..91a3214da3 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -42,13 +42,13 @@
QT_BEGIN_NAMESPACE
-QColor qt_mac_colorForTheme(ThemeBrush brush)
+QBrush qt_mac_brushForTheme(ThemeBrush brush)
{
QMacAutoReleasePool pool;
QCFType<CGColorRef> cgClr = 0;
HIThemeBrushCreateCGColor(brush, &cgClr);
- return qt_mac_toQColor(cgClr);
+ return qt_mac_toQBrush(cgClr);
}
QColor qt_mac_colorForThemeTextColor(ThemeTextColor themeColor)
@@ -86,25 +86,29 @@ QPalette * qt_mac_createSystemPalette()
QColor qc;
// Standard palette initialization (copied from Qt 4 styles)
- QColor background = QColor(237, 237, 237);
+ QBrush backgroundBrush = qt_mac_toQBrush([NSColor windowBackgroundColor]);
+ QColor background = backgroundBrush.color();
QColor light(background.lighter(110));
QColor dark(background.darker(160));
QColor mid(background.darker(140));
QPalette *palette = new QPalette(Qt::black, background, light, dark, mid, Qt::black, Qt::white);
+ palette->setBrush(QPalette::Window, backgroundBrush);
+
palette->setBrush(QPalette::Disabled, QPalette::WindowText, dark);
palette->setBrush(QPalette::Disabled, QPalette::Text, dark);
palette->setBrush(QPalette::Disabled, QPalette::ButtonText, dark);
- palette->setBrush(QPalette::Disabled, QPalette::Base, background);
+ palette->setBrush(QPalette::Disabled, QPalette::Base, backgroundBrush);
palette->setColor(QPalette::Disabled, QPalette::Dark, QColor(191, 191, 191));
palette->setColor(QPalette::Active, QPalette::Dark, QColor(191, 191, 191));
palette->setColor(QPalette::Inactive, QPalette::Dark, QColor(191, 191, 191));
// System palette initialization:
- palette->setBrush(QPalette::Active, QPalette::Highlight, qt_mac_colorForTheme(kThemeBrushPrimaryHighlightColor));
- qc = qt_mac_colorForTheme(kThemeBrushSecondaryHighlightColor);
- palette->setBrush(QPalette::Inactive, QPalette::Highlight, qc);
- palette->setBrush(QPalette::Disabled, QPalette::Highlight, qc);
+ palette->setBrush(QPalette::Active, QPalette::Highlight,
+ qt_mac_toQBrush([NSColor selectedControlColor]));
+ QBrush br = qt_mac_toQBrush([NSColor secondarySelectedControlColor]);
+ palette->setBrush(QPalette::Inactive, QPalette::Highlight, br);
+ palette->setBrush(QPalette::Disabled, QPalette::Highlight, br);
palette->setBrush(QPalette::Shadow, background.darker(170));
@@ -168,8 +172,7 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
}
if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette) {
- qc = qt_mac_colorForTheme(kThemeBrushMenuBackground);
- pal.setBrush(QPalette::Background, qc);
+ pal.setBrush(QPalette::Background, qt_mac_brushForTheme(kThemeBrushMenuBackground));
qc = qt_mac_colorForThemeTextColor(kThemeTextColorMenuItemActive);
pal.setBrush(QPalette::ButtonText, qc);
qc = qt_mac_colorForThemeTextColor(kThemeTextColorMenuItemSelected);
@@ -186,9 +189,9 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
pal.color(QPalette::Active, QPalette::Text));
} else if (mac_widget_colors[i].paletteRole == QPlatformTheme::ItemViewPalette) {
pal.setBrush(QPalette::Active, QPalette::Highlight,
- qt_mac_colorForTheme(kThemeBrushAlternatePrimaryHighlightColor));
- qc = qt_mac_colorForThemeTextColor(kThemeTextColorMenuItemSelected);
- pal.setBrush(QPalette::Active, QPalette::HighlightedText, qc);
+ qt_mac_toQBrush([NSColor alternateSelectedControlColor]));
+ pal.setBrush(QPalette::Active, QPalette::HighlightedText,
+ qt_mac_toQBrush([NSColor alternateSelectedControlTextColor]));
pal.setBrush(QPalette::Inactive, QPalette::Text,
pal.brush(QPalette::Active, QPalette::Text));
pal.setBrush(QPalette::Inactive, QPalette::HighlightedText,
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index 0cd7b7d4c8..31340c7781 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -37,6 +37,8 @@
#include <QtCore/QHash>
#include <qpa/qplatformtheme.h>
+Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver));
+
QT_BEGIN_NAMESPACE
class QPalette;
@@ -46,6 +48,8 @@ public:
QCocoaTheme();
~QCocoaTheme();
+ void reset();
+
QPlatformMenuItem* createPlatformMenuItem() const Q_DECL_OVERRIDE;
QPlatformMenu* createPlatformMenu() const Q_DECL_OVERRIDE;
QPlatformMenuBar* createPlatformMenuBar() const Q_DECL_OVERRIDE;
@@ -73,6 +77,7 @@ private:
mutable QPalette *m_systemPalette;
mutable QHash<QPlatformTheme::Palette, QPalette*> m_palettes;
mutable QHash<QPlatformTheme::Font, QFont*> m_fonts;
+ mutable QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver) *m_notificationReceiver;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index 4b73d0af08..1fd40c49f1 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
#include "qcocoatheme.h"
#include "messages.h"
@@ -55,6 +55,33 @@
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformnativeinterface.h>
+#include <Carbon/Carbon.h>
+
+@interface QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver) : NSObject {
+QCocoaTheme *mPrivate;
+}
+- (id)initWithPrivate:(QCocoaTheme *)priv;
+- (void)systemColorsDidChange:(NSNotification *)notification;
+@end
+
+QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaThemeNotificationReceiver);
+
+@implementation QCocoaThemeNotificationReceiver
+- (id)initWithPrivate:(QCocoaTheme *)priv
+{
+ self = [super init];
+ mPrivate = priv;
+ return self;
+}
+
+- (void)systemColorsDidChange:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ mPrivate->reset();
+ QWindowSystemInterface::handleThemeChange(Q_NULLPTR);
+}
+@end
+
QT_BEGIN_NAMESPACE
const char *QCocoaTheme::name = "cocoa";
@@ -62,14 +89,27 @@ const char *QCocoaTheme::name = "cocoa";
QCocoaTheme::QCocoaTheme()
:m_systemPalette(0)
{
-
+ m_notificationReceiver = [[QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver) alloc] initWithPrivate:this];
+ [[NSNotificationCenter defaultCenter] addObserver:m_notificationReceiver
+ selector:@selector(systemColorsDidChange:)
+ name:NSSystemColorsDidChangeNotification
+ object:nil];
}
QCocoaTheme::~QCocoaTheme()
{
+ [[NSNotificationCenter defaultCenter] removeObserver:m_notificationReceiver];
+ [m_notificationReceiver release];
+ reset();
+ qDeleteAll(m_fonts);
+}
+
+void QCocoaTheme::reset()
+{
delete m_systemPalette;
+ m_systemPalette = Q_NULLPTR;
qDeleteAll(m_palettes);
- qDeleteAll(m_fonts);
+ m_palettes.clear();
}
bool QCocoaTheme::usePlatformNativeDialog(DialogType dialogType) const
@@ -257,18 +297,7 @@ QPixmap QCocoaTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &siz
NSImage *iconImage = [[NSWorkspace sharedWorkspace] iconForFile:QCFString::toNSString(fileInfo.canonicalFilePath())];
if (!iconImage)
return QPixmap();
- NSSize pixmapSize = NSMakeSize(size.width(), size.height());
- QPixmap pixmap(pixmapSize.width, pixmapSize.height);
- pixmap.fill(Qt::transparent);
- [iconImage setSize:pixmapSize];
- NSRect iconRect = NSMakeRect(0, 0, pixmapSize.width, pixmapSize.height);
- CGContextRef ctx = qt_mac_cg_context(&pixmap);
- NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:YES];
- [NSGraphicsContext saveGraphicsState];
- [NSGraphicsContext setCurrentContext:gc];
- [iconImage drawInRect:iconRect fromRect:iconRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil];
- [NSGraphicsContext restoreGraphicsState];
- return pixmap;
+ return qt_mac_toQPixmap(iconImage, size);
}
QVariant QCocoaTheme::themeHint(ThemeHint hint) const
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 05e6cf3c9e..e830be212a 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -34,7 +34,7 @@
#ifndef QCOCOAWINDOW_H
#define QCOCOAWINDOW_H
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include <qpa/qplatformwindow.h>
#include <QRect>
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 3b5909a37e..2d8abba189 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -47,8 +47,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformscreen.h>
-#include <Cocoa/Cocoa.h>
-#include <Carbon/Carbon.h>
+#include <AppKit/AppKit.h>
#include <QDebug>
@@ -689,7 +688,16 @@ void QCocoaWindow::setVisible(bool visible)
cocoaEventDispatcherPrivate->beginModalSession(window());
m_hasModalSession = true;
} else if ([m_nsWindow canBecomeKeyWindow]) {
- [m_nsWindow makeKeyAndOrderFront:nil];
+ QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
+ QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = 0;
+ if (cocoaEventDispatcher)
+ cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
+
+ if (!(cocoaEventDispatcherPrivate && cocoaEventDispatcherPrivate->currentModalSession()))
+ [m_nsWindow makeKeyAndOrderFront:nil];
+ else
+ [m_nsWindow orderFront:nil];
+
foreach (QCocoaWindow *childWindow, m_childWindows)
childWindow->show(true);
} else {
@@ -1345,6 +1353,9 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
}
} else {
// Child windows have no NSWindow, link the NSViews instead.
+ if ([m_contentView superview])
+ [m_contentView removeFromSuperview];
+
[m_parentCocoaWindow->m_contentView addSubview : m_contentView];
QRect rect = windowGeometry();
// Prevent setting a (0,0) window size; causes opengl context
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.h b/src/plugins/platforms/cocoa/qmacclipboard.h
index 0d1f195f48..8b290866c6 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.h
+++ b/src/plugins/platforms/cocoa/qmacclipboard.h
@@ -39,7 +39,7 @@
#undef slots
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qmacdefines_mac.h b/src/plugins/platforms/cocoa/qmacdefines_mac.h
index b2773a2b9f..fd540e7c34 100644
--- a/src/plugins/platforms/cocoa/qmacdefines_mac.h
+++ b/src/plugins/platforms/cocoa/qmacdefines_mac.h
@@ -92,7 +92,7 @@ typedef signed long OSStatus;
# define old_slots slots
# undef slots
# endif
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
# ifdef old_slots
# undef slots
# define slots
diff --git a/src/plugins/platforms/cocoa/qmultitouch_mac_p.h b/src/plugins/platforms/cocoa/qmultitouch_mac_p.h
index e4eec41295..0af0505a47 100644
--- a/src/plugins/platforms/cocoa/qmultitouch_mac_p.h
+++ b/src/plugins/platforms/cocoa/qmultitouch_mac_p.h
@@ -47,7 +47,7 @@
#include <QtCore/qglobal.h>
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
#include <qpa/qwindowsysteminterface.h>
#include <qhash.h>
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 50b456cab7..a3541829c6 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -34,7 +34,7 @@
#ifndef QNSVIEW_H
#define QNSVIEW_H
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include <QtCore/QPointer>
#include <QtGui/QImage>
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 0d80333e65..7f13961897 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -33,7 +33,6 @@
#include <QtCore/qglobal.h>
-#include <Carbon/Carbon.h>
#include <dlfcn.h>
#include "qnsview.h"
diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
index 1f15da5b3b..d44b02549d 100644
--- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
@@ -31,8 +31,6 @@
**
****************************************************************************/
-#include <Carbon/Carbon.h>
-
#include "qnsview.h"
#include "qcocoahelpers.h"
#include "qcocoaaccessibility.h"
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h
index b8d344aa0e..794059bc68 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.h
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h
@@ -34,7 +34,7 @@
#ifndef QNSWINDOWDELEGATE_H
#define QNSWINDOWDELEGATE_H
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include "qcocoawindow.h"
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index edd1d656f0..6edfd75a14 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -251,7 +251,7 @@ void QMacPrintEnginePrivate::initialize()
setPageSize(m_pageLayout.pageSize());
QHash<QMacPrintEngine::PrintEnginePropertyKey, QVariant>::const_iterator propC;
- for (propC = valueCache.constBegin(); propC != valueCache.constEnd(); propC++) {
+ for (propC = valueCache.constBegin(); propC != valueCache.constEnd(); ++propC) {
q->setProperty(propC.key(), propC.value());
}
}
diff --git a/src/plugins/platforms/cocoa/qt_mac_p.h b/src/plugins/platforms/cocoa/qt_mac_p.h
index 576e0f9729..9a20c31720 100644
--- a/src/plugins/platforms/cocoa/qt_mac_p.h
+++ b/src/plugins/platforms/cocoa/qt_mac_p.h
@@ -48,7 +48,7 @@
#include "qmacdefines_mac.h"
#ifdef __OBJC__
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include <objc/runtime.h>
#endif
@@ -63,30 +63,10 @@
#include "QtGui/qpainter.h"
-#include <Carbon/Carbon.h>
-
QT_BEGIN_NAMESPACE
class QWidget;
class QDragMoveEvent;
-/* Event masks */
-// internal Qt types
-
-enum {
- //AE types
- typeAEClipboardChanged = 1,
- //types
- typeQWidget = 1, /* QWidget * */
- //params
- kEventParamQWidget = 'qwid', /* typeQWidget */
- //events
- kEventQtRequestContext = 13,
- kEventQtRequestMenubarUpdate = 14,
- kEventQtRequestShowSheet = 17,
- kEventQtRequestActivate = 18,
- kEventQtRequestWindowChange = 20
-};
-
// Simple class to manage short-lived regions
class QMacSmartQuickDrawRegion
{
@@ -103,8 +83,6 @@ public:
}
};
-QString qt_mac_removeMnemonics(const QString &original); //implemented in qmacstyle_mac.cpp
-
class Q_WIDGETS_EXPORT QMacWindowChangeEvent
{
private:
@@ -127,8 +105,8 @@ class QMacCGContext
public:
QMacCGContext(QPainter *p); //qpaintengine_mac.mm
inline QMacCGContext() { context = 0; }
- inline QMacCGContext(const QPaintDevice *pdev) {
- extern CGContextRef qt_mac_cg_context(const QPaintDevice *);
+ inline QMacCGContext(QPaintDevice *pdev) {
+ extern CGContextRef qt_mac_cg_context(QPaintDevice *);
context = qt_mac_cg_context(pdev);
}
inline QMacCGContext(CGContextRef cg, bool takeOwnership=false) {
@@ -173,10 +151,6 @@ extern QPoint qt_mac_nativeMapFromParent(const QWidget *child, const QPoint &pt)
# undef check
#endif
-QFont qfontForThemeFont(ThemeFontID themeID);
-
-QColor qcolorForThemeTextColor(ThemeTextColor themeColor);
-
struct QMacDndAnswerRecord {
QRect rect;
Qt::KeyboardModifiers modifiers;
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
index 154023fb11..418c2e3745 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
@@ -51,7 +51,7 @@ public:
HRESULT hr = QWindowsDirect2DContext::instance()->d2dDevice()->CreateDeviceContext(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
&deviceContext);
- if (FAILED(hr))
+ if (Q_UNLIKELY(FAILED(hr)))
qFatal("%s: Couldn't create Direct2D Device Context: %#x", __FUNCTION__, hr);
}
diff --git a/src/plugins/platforms/directfb/qdirectfbblitter.cpp b/src/plugins/platforms/directfb/qdirectfbblitter.cpp
index b87310ed76..3d8ffa9bf7 100644
--- a/src/plugins/platforms/directfb/qdirectfbblitter.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbblitter.cpp
@@ -65,7 +65,7 @@ QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, IDirectFBSurface *surface)
DFBSurfaceCapabilities surfaceCaps;
m_surface->GetCapabilities(m_surface.data(), &surfaceCaps);
m_premult = (surfaceCaps & DSCAPS_PREMULTIPLIED);
- if (qgetenv("QT_DIRECTFB_BLITTER_DEBUGPAINT").toInt())
+ if (qEnvironmentVariableIntValue("QT_DIRECTFB_BLITTER_DEBUGPAINT"))
m_debugPaint = true;
}
@@ -92,7 +92,7 @@ QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, bool alpha)
surfaceDesc.pixelformat = QDirectFbBlitter::pixmapFormat();
}
- if (qgetenv("QT_DIRECTFB_BLITTER_DEBUGPAINT").toInt())
+ if (qEnvironmentVariableIntValue("QT_DIRECTFB_BLITTER_DEBUGPAINT"))
m_debugPaint = true;
IDirectFB *dfb = QDirectFbConvenience::dfbInterface();
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp
index c29d64c06d..38b61f8f8b 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp
@@ -280,12 +280,18 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr
qCDebug(qLcEglfsKmsDebug) << "Selected mode" << selected_mode << ":" << width << "x" << height
<< '@' << refresh << "hz for output" << connectorName;
}
-
+ static const int width = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH");
+ static const int height = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT");
+ QSizeF size(width, height);
+ if (size.isEmpty()) {
+ size.setWidth(connector->mmWidth);
+ size.setHeight(connector->mmHeight);
+ }
QEglFSKmsOutput output = {
QString::fromUtf8(connectorName),
connector->connector_id,
crtc_id,
- QSizeF(connector->mmWidth, connector->mmHeight),
+ size,
selected_mode,
false,
drmModeGetCrtc(m_dri_fd, crtc_id),
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp
index d1814fb85d..789f2fa86f 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsintegration.cpp
@@ -77,7 +77,7 @@ void QEglFSKmsIntegration::platformInit()
qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:" << devices;
d->deleteLater();
- if (devices.isEmpty())
+ if (Q_UNLIKELY(devices.isEmpty()))
qFatal("Could not find DRM device!");
m_devicePath = devices.first();
@@ -85,7 +85,7 @@ void QEglFSKmsIntegration::platformInit()
}
m_device = new QEglFSKmsDevice(this, m_devicePath);
- if (!m_device->open())
+ if (Q_UNLIKELY(!m_device->open()))
qFatal("Could not open device %s - aborting!", qPrintable(m_devicePath));
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
index f7450708ab..03cfea72b8 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
@@ -53,20 +53,20 @@ QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration()
void QEglFSKmsEglDeviceIntegration::platformInit()
{
- if (!query_egl_device())
+ if (Q_UNLIKELY(!query_egl_device()))
qFatal("Could not set up EGL device!");
const char *deviceName = m_funcs->query_device_string(m_egl_device, EGL_DRM_DEVICE_FILE_EXT);
- if (!deviceName)
+ if (Q_UNLIKELY(!deviceName))
qFatal("Failed to query device name from EGLDevice");
qCDebug(qLcEglfsKmsDebug, "Opening %s", deviceName);
m_dri_fd = drmOpen(deviceName, Q_NULLPTR);
- if (m_dri_fd < 0)
+ if (Q_UNLIKELY(m_dri_fd < 0))
qFatal("Could not open DRM device");
- if (!setup_kms())
+ if (Q_UNLIKELY(!setup_kms()))
qFatal("Could not set up KMS on device %s!", m_device.constData());
qCDebug(qLcEglfsKmsDebug, "DRM/KMS initialized");
@@ -101,14 +101,14 @@ EGLDisplay QEglFSKmsEglDeviceIntegration::createDisplay(EGLNativeDisplayType nat
display = eglGetDisplay(nativeDisplay);
}
- if (display == EGL_NO_DISPLAY)
+ if (Q_UNLIKELY(display == EGL_NO_DISPLAY))
qFatal("Could not get EGL display");
EGLint major, minor;
- if (!eglInitialize(display, &major, &minor))
+ if (Q_UNLIKELY(!eglInitialize(display, &major, &minor)))
qFatal("Could not initialize egl display");
- if (!eglBindAPI(EGL_OPENGL_ES_API))
+ if (Q_UNLIKELY(!eglBindAPI(EGL_OPENGL_ES_API)))
qFatal("Failed to bind EGL_OPENGL_ES_API\n");
return display;
@@ -267,8 +267,8 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const
QEglJetsonTK1Window *eglWindow = new QEglJetsonTK1Window(window, this);
m_funcs->initialize(eglWindow->screen()->display());
- if (!(m_funcs->has_egl_output_base && m_funcs->has_egl_output_drm && m_funcs->has_egl_stream
- && m_funcs->has_egl_stream_producer_eglsurface && m_funcs->has_egl_stream_consumer_egloutput))
+ if (Q_UNLIKELY(!(m_funcs->has_egl_output_base && m_funcs->has_egl_output_drm && m_funcs->has_egl_stream &&
+ m_funcs->has_egl_stream_producer_eglsurface && m_funcs->has_egl_stream_consumer_egloutput)))
qFatal("Required extensions missing!");
return eglWindow;
@@ -310,7 +310,7 @@ void QEglFSKmsEglDeviceIntegration::waitForVSync(QPlatformSurface *) const
-1, 0, 0,
&m_drm_connector->connector_id, 1,
const_cast<const drmModeModeInfoPtr>(&m_drm_mode));
- if (ret)
+ if (Q_UNLIKELY(ret))
qFatal("drmModeSetCrtc failed");
}
}
@@ -379,7 +379,7 @@ bool QEglFSKmsEglDeviceIntegration::setup_kms()
}
}
- if (crtc == 0)
+ if (Q_UNLIKELY(crtc == 0))
qFatal("No suitable CRTC available");
m_drm_connector = connector;
@@ -399,7 +399,7 @@ bool QEglFSKmsEglDeviceIntegration::setup_kms()
bool QEglFSKmsEglDeviceIntegration::query_egl_device()
{
m_funcs = new QEGLStreamConvenience;
- if (!m_funcs->has_egl_device_base)
+ if (Q_UNLIKELY(!m_funcs->has_egl_device_base))
qFatal("EGL_EXT_device_base missing");
EGLint num_devices = 0;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
index 4d29b96608..ef586622e2 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
@@ -172,7 +172,7 @@ void QEglFSX11Integration::sendConnectionEvent(xcb_atom_t a)
void QEglFSX11Integration::platformInit()
{
m_display = XOpenDisplay(0);
- if (!m_display)
+ if (Q_UNLIKELY(!m_display))
qFatal("Could not open display");
XSetEventQueueOwner(DISPLAY, XCBOwnsEventQueue);
diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/plugins/platforms/eglfs/qeglfscursor.cpp
index eea130a754..bfb69d3e8f 100644
--- a/src/plugins/platforms/eglfs/qeglfscursor.cpp
+++ b/src/plugins/platforms/eglfs/qeglfscursor.cpp
@@ -38,6 +38,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLShaderProgram>
+#include <QtCore/QFile>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonObject>
diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
index 8af48a893b..963c1604fc 100644
--- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
@@ -65,19 +65,6 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader,
(QEGLDeviceIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive))
-static inline QEGLDeviceIntegration *loadIntegration(QFactoryLoader *loader, const QString &key)
-{
- const int index = loader->indexOf(key);
- if (index != -1) {
- QObject *plugin = loader->instance(index);
- if (QEGLDeviceIntegrationPlugin *factory = qobject_cast<QEGLDeviceIntegrationPlugin *>(plugin)) {
- if (QEGLDeviceIntegration *result = factory->create())
- return result;
- }
- }
- return Q_NULLPTR;
-}
-
#endif // QT_NO_LIBRARY
QStringList QEGLDeviceIntegrationFactory::keys(const QString &pluginPath)
@@ -111,10 +98,10 @@ QEGLDeviceIntegration *QEGLDeviceIntegrationFactory::create(const QString &key,
#ifndef QT_NO_LIBRARY
if (!pluginPath.isEmpty()) {
QCoreApplication::addLibraryPath(pluginPath);
- integration = loadIntegration(directLoader(), key);
+ integration = qLoadPlugin<QEGLDeviceIntegration, QEGLDeviceIntegrationPlugin>(directLoader(), key);
}
if (!integration)
- integration = loadIntegration(loader(), key);
+ integration = qLoadPlugin<QEGLDeviceIntegration, QEGLDeviceIntegrationPlugin>(loader(), key);
if (integration)
qCDebug(qLcEglDevDebug) << "Using EGL device integration" << key;
else
@@ -155,7 +142,7 @@ void QEGLDeviceIntegration::platformInit()
framebuffer = qt_safe_open(fbDev, O_RDONLY);
- if (framebuffer == -1) {
+ if (Q_UNLIKELY(framebuffer == -1)) {
qWarning("EGLFS: Failed to open %s", fbDev.constData());
qFatal("EGLFS: Can't continue without a display");
}
diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h
index 5ec98b37d1..ba47b3693e 100644
--- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h
@@ -108,6 +108,10 @@ class Q_EGLFS_EXPORT QEGLDeviceIntegrationPlugin : public QObject
public:
virtual QEGLDeviceIntegration *create() = 0;
+
+ // the pattern expected by qLoadPlugin calls for a QString argument.
+ // we don't need it, so don't bother subclasses with it:
+ QEGLDeviceIntegration *create(const QString &) { return create(); }
};
class Q_EGLFS_EXPORT QEGLDeviceIntegrationFactory
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index 2086ce56e2..001dd76803 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -118,11 +118,11 @@ void QEglFSIntegration::initialize()
qt_egl_device_integration()->platformInit();
m_display = qt_egl_device_integration()->createDisplay(nativeDisplay());
- if (m_display == EGL_NO_DISPLAY)
+ if (Q_UNLIKELY(m_display == EGL_NO_DISPLAY))
qFatal("Could not open egl display");
EGLint major, minor;
- if (!eglInitialize(m_display, &major, &minor))
+ if (Q_UNLIKELY(!eglInitialize(m_display, &major, &minor)))
qFatal("Could not initialize egl display");
m_inputContext = QPlatformInputContextFactory::create();
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index 8301be8c17..b29981bc98 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -102,17 +102,15 @@ void QEglFSWindow::create()
QEglFSScreen *screen = this->screen();
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
if (screen->primarySurface() != EGL_NO_SURFACE) {
- if (isRaster() && compositor->targetWindow()) {
- m_format = compositor->targetWindow()->format();
- return;
- }
-
+ if (Q_UNLIKELY(!isRaster() || !compositor->targetWindow())) {
#if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)
- // We can have either a single OpenGL window or multiple raster windows.
- // Other combinations cannot work.
- qFatal("EGLFS: OpenGL windows cannot be mixed with others.");
+ // We can have either a single OpenGL window or multiple raster windows.
+ // Other combinations cannot work.
+ qFatal("EGLFS: OpenGL windows cannot be mixed with others.");
#endif
-
+ return;
+ }
+ m_format = compositor->targetWindow()->format();
return;
}
@@ -122,7 +120,7 @@ void QEglFSWindow::create()
resetSurface();
- if (m_surface == EGL_NO_SURFACE) {
+ if (Q_UNLIKELY(m_surface == EGL_NO_SURFACE)) {
EGLint error = eglGetError();
eglTerminate(screen->display());
qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error);
@@ -135,7 +133,7 @@ void QEglFSWindow::create()
context->setShareContext(qt_gl_global_share_context());
context->setFormat(m_format);
context->setScreen(window()->screen());
- if (!context->create())
+ if (Q_UNLIKELY(!context->create()))
qFatal("EGLFS: Failed to create compositing context");
compositor->setTarget(context, window());
}
diff --git a/src/plugins/platforms/haiku/qhaikuwindow.cpp b/src/plugins/platforms/haiku/qhaikuwindow.cpp
index 9622d12111..1576e7c04e 100644
--- a/src/plugins/platforms/haiku/qhaikuwindow.cpp
+++ b/src/plugins/platforms/haiku/qhaikuwindow.cpp
@@ -127,7 +127,7 @@ QHaikuWindow::QHaikuWindow(QWindow *window)
m_window = haikuWindow;
- if (!m_window)
+ if (Q_UNLIKELY(!m_window))
qFatal("QHaikuWindow: failed to create window");
setGeometry(rect);
diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro
index bf7849b740..b1075d3c0f 100644
--- a/src/plugins/platforms/ios/ios.pro
+++ b/src/plugins/platforms/ios/ios.pro
@@ -6,7 +6,7 @@ PLUGIN_CLASS_NAME = QIOSIntegrationPlugin
load(qt_plugin)
QT += core-private gui-private platformsupport-private
-LIBS += -framework Foundation -framework UIKit -framework QuartzCore -framework AssetsLibrary
+LIBS += -framework Foundation -framework UIKit -framework QuartzCore -framework AssetsLibrary -framework AudioToolbox
OBJECTIVE_SOURCES = \
plugin.mm \
@@ -30,7 +30,8 @@ OBJECTIVE_SOURCES = \
qiostextresponder.mm \
qiosmenu.mm \
qiosfileengineassetslibrary.mm \
- qiosfiledialog.mm
+ qiosfiledialog.mm \
+ qiosmessagedialog.mm
HEADERS = \
qiosintegration.h \
@@ -54,7 +55,8 @@ HEADERS = \
qiosmenu.h \
qiosfileenginefactory.h \
qiosfileengineassetslibrary.h \
- qiosfiledialog.h
+ qiosfiledialog.h \
+ qiosmessagedialog.h
OTHER_FILES = \
quiview_textinput.mm \
diff --git a/src/plugins/platforms/ios/qiosbackingstore.h b/src/plugins/platforms/ios/qiosbackingstore.h
index 5d2ae429f1..387a286447 100644
--- a/src/plugins/platforms/ios/qiosbackingstore.h
+++ b/src/plugins/platforms/ios/qiosbackingstore.h
@@ -36,34 +36,31 @@
#include <qpa/qplatformbackingstore.h>
+#include <QtPlatformSupport/private/qrasterbackingstore_p.h>
+
QT_BEGIN_NAMESPACE
class QOpenGLPaintDevice;
-class QOpenGLFramebufferObject;
-class QOffscreenSurface;
-class QIOSBackingStore : public QPlatformBackingStore
+class QIOSBackingStore : public QRasterBackingStore
{
public:
QIOSBackingStore(QWindow *window);
~QIOSBackingStore();
- QPaintDevice *paintDevice();
+ QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
- void beginPaint(const QRegion &);
- void endPaint();
+ void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
+ void endPaint() Q_DECL_OVERRIDE;
- void flush(QWindow *window, const QRegion &region, const QPoint &offset);
- void resize(const QSize &size, const QRegion &staticContents);
- GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const;
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+ void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
void makeCurrent();
private:
QOpenGLContext *m_context;
- QOpenGLPaintDevice *m_device;
- QOpenGLFramebufferObject *m_fbo;
- QOffscreenSurface *m_surface;
+ QOpenGLPaintDevice *m_glDevice;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm
index 875d06dc80..f408c13af3 100644
--- a/src/plugins/platforms/ios/qiosbackingstore.mm
+++ b/src/plugins/platforms/ios/qiosbackingstore.mm
@@ -38,6 +38,7 @@
#include <QtGui/QOpenGLPaintDevice>
#include <QtGui/QOpenGLFramebufferObject>
#include <QtGui/QOffscreenSurface>
+#include <QtGui/qpainter.h>
#include <QtGui/private/qwindow_p.h>
#include <QtDebug>
@@ -58,13 +59,12 @@ void QIOSPaintDevice::ensureActiveTarget()
}
QIOSBackingStore::QIOSBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
+ : QRasterBackingStore(window)
, m_context(new QOpenGLContext)
- , m_device(0)
- , m_fbo(0)
- , m_surface(0)
+ , m_glDevice(nullptr)
{
QSurfaceFormat fmt = window->requestedFormat();
+
// Due to sharing QIOSContext redirects our makeCurrent on window() attempts to
// the global share context. Hence it is essential to have a compatible format.
fmt.setDepthBufferSize(QSurfaceFormat::defaultFormat().depthBufferSize());
@@ -73,8 +73,10 @@ QIOSBackingStore::QIOSBackingStore(QWindow *window)
if (fmt.depthBufferSize() == 0)
qWarning("No depth in default format, expect rendering errors");
+ // We use the surface both for raster operations and for GL drawing (when
+ // we blit the raster image), so the type needs to cover both use cases.
if (window->surfaceType() == QSurface::RasterSurface)
- window->setSurfaceType(QSurface::OpenGLSurface);
+ window->setSurfaceType(QSurface::RasterGLSurface);
m_context->setFormat(fmt);
m_context->setScreen(window->screen());
@@ -85,75 +87,44 @@ QIOSBackingStore::QIOSBackingStore(QWindow *window)
QIOSBackingStore::~QIOSBackingStore()
{
- delete m_fbo;
- delete m_surface;
delete m_context;
- delete m_device;
+ delete m_glDevice;
}
void QIOSBackingStore::makeCurrent()
{
- QSurface *surface = m_surface ? m_surface : static_cast<QSurface *>(window());
- if (!m_context->makeCurrent(surface))
+ if (!m_context->makeCurrent(window()))
qWarning("QIOSBackingStore: makeCurrent() failed");
- if (m_fbo)
- m_fbo->bind();
}
-void QIOSBackingStore::beginPaint(const QRegion &)
+void QIOSBackingStore::beginPaint(const QRegion &region)
{
- if (qt_window_private(window())->compositing) {
- if (!m_fbo) {
- delete m_device;
- m_device = 0;
- }
- if (!m_surface) {
- m_surface = new QOffscreenSurface;
- m_surface->setFormat(m_context->format());
- m_surface->create();
- }
- if (!m_context->makeCurrent(m_surface))
- qWarning("QIOSBackingStore: Failed to make offscreen surface current");
- const QSize size = window()->size() * window()->devicePixelRatio();
- if (m_fbo && m_fbo->size() != size) {
- delete m_fbo;
- m_fbo = 0;
- }
- if (!m_fbo)
- m_fbo = new QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::CombinedDepthStencil);
- } else if (m_fbo) {
- delete m_fbo;
- m_fbo = 0;
- delete m_surface;
- m_surface = 0;
- delete m_device;
- m_device = 0;
- }
-
makeCurrent();
- if (!m_device)
- m_device = new QIOSPaintDevice(this);
+ if (!m_glDevice)
+ m_glDevice = new QIOSPaintDevice(this);
+
+ if (window()->surfaceType() == QSurface::RasterGLSurface)
+ QRasterBackingStore::beginPaint(region);
}
void QIOSBackingStore::endPaint()
{
- if (m_fbo) {
- m_fbo->release();
- glFlush();
- }
}
QPaintDevice *QIOSBackingStore::paintDevice()
{
- Q_ASSERT(m_device);
+ Q_ASSERT(m_glDevice);
// Keep paint device size and device pixel ratio in sync with window
qreal devicePixelRatio = window()->devicePixelRatio();
- m_device->setSize(window()->size() * devicePixelRatio);
- m_device->setDevicePixelRatio(devicePixelRatio);
+ m_glDevice->setSize(window()->size() * devicePixelRatio);
+ m_glDevice->setDevicePixelRatio(devicePixelRatio);
- return m_device;
+ if (window()->surfaceType() == QSurface::RasterGLSurface)
+ return QRasterBackingStore::paintDevice();
+ else
+ return m_glDevice;
}
void QIOSBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
@@ -171,6 +142,11 @@ void QIOSBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
return;
}
+ if (window->surfaceType() == QSurface::RasterGLSurface) {
+ QPainter painter(m_glDevice);
+ painter.drawImage(QPoint(), m_image);
+ }
+
m_context->makeCurrent(window);
m_context->swapBuffers(window);
}
@@ -179,31 +155,20 @@ void QIOSBackingStore::resize(const QSize &size, const QRegion &staticContents)
{
Q_UNUSED(staticContents);
- // Resizing the backing store would in our case mean resizing the QWindow,
- // as we cheat and use an QOpenGLPaintDevice that we target at the window.
- // That's probably not what the user intended, so we ignore resizes of the
- // backing store and always keep the paint device's size in sync with the
- // window size in beginPaint().
+ if (window()->surfaceType() == QSurface::OpenGLSurface) {
+ // Resizing the backing store would in this case mean resizing the QWindow,
+ // as we use an QOpenGLPaintDevice that we target at the window. That's
+ // probably not what the user intended, so we ignore resizes of the backing
+ // store and always keep the paint device's size in sync with the window
+ // size in beginPaint().
- if (size != window()->size() && !window()->inherits("QWidgetWindow"))
- qWarning() << "QIOSBackingStore needs to have the same size as its window";
-}
-
-GLuint QIOSBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const
-{
- Q_ASSERT(qt_window_private(window())->compositing);
- Q_UNUSED(dirtyRegion);
-
- if (flags)
- *flags = TextureFlip;
+ if (size != window()->size() && !window()->inherits("QWidgetWindow"))
+ qWarning() << "QIOSBackingStore needs to have the same size as its window";
- if (!m_fbo)
- return 0;
-
- if (textureSize)
- *textureSize = m_fbo->size();
+ return;
+ }
- return m_fbo->texture();
+ QRasterBackingStore::resize(size, staticContents);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qioseventdispatcher.mm b/src/plugins/platforms/ios/qioseventdispatcher.mm
index 0e9f176487..e1c6071c38 100644
--- a/src/plugins/platforms/ios/qioseventdispatcher.mm
+++ b/src/plugins/platforms/ios/qioseventdispatcher.mm
@@ -129,7 +129,7 @@ namespace
// Which we verify, just in case
struct rlimit stackLimit = {0, 0};
- if (getrlimit(RLIMIT_STACK, &stackLimit) == 0 && stackSize > stackLimit.rlim_cur)
+ if (Q_UNLIKELY(getrlimit(RLIMIT_STACK, &stackLimit) == 0 && stackSize > stackLimit.rlim_cur))
qFatal("Unexpectedly exceeded stack limit");
return stackSize;
@@ -250,7 +250,7 @@ static void __attribute__((noinline, noreturn)) user_main_trampoline()
unsigned int bufferSize = [arg lengthOfBytesUsingEncoding:cStringEncoding] + 1;
argv[i] = reinterpret_cast<char *>(malloc(bufferSize));
- if (![arg getCString:argv[i] maxLength:bufferSize encoding:cStringEncoding])
+ if (Q_UNLIKELY(![arg getCString:argv[i] maxLength:bufferSize encoding:cStringEncoding]))
qFatal("Could not convert argv[%d] to C string", i);
}
diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h
index 7d23fe1d62..e670d83a8d 100644
--- a/src/plugins/platforms/ios/qiosintegration.h
+++ b/src/plugins/platforms/ios/qiosintegration.h
@@ -82,6 +82,8 @@ public:
void addScreen(QPlatformScreen *screen) { screenAdded(screen); }
void destroyScreen(QPlatformScreen *screen) { QPlatformIntegration::destroyScreen(screen); }
+ void beep() const Q_DECL_OVERRIDE;
+
static QIOSIntegration *instance();
// -- QPlatformNativeInterface --
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 85b5c477cc..21248ddb86 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -53,6 +53,8 @@
#include <QtPlatformSupport/private/qmacmime_p.h>
#include <QDir>
+#import <AudioToolbox/AudioServices.h>
+
#include <QtDebug>
QT_BEGIN_NAMESPACE
@@ -70,7 +72,7 @@ QIOSIntegration::QIOSIntegration()
, m_accessibility(0)
, m_debugWindowManagement(false)
{
- if (![UIApplication sharedApplication]) {
+ if (Q_UNLIKELY(![UIApplication sharedApplication])) {
qFatal("Error: You are creating QApplication before calling UIApplicationMain.\n" \
"If you are writing a native iOS application, and only want to use Qt for\n" \
"parts of the application, a good place to create QApplication is from within\n" \
@@ -268,6 +270,13 @@ QPlatformNativeInterface *QIOSIntegration::nativeInterface() const
return const_cast<QIOSIntegration *>(this);
}
+void QIOSIntegration::beep() const
+{
+#if !TARGET_IPHONE_SIMULATOR
+ AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
+#endif
+}
+
// ---------------------------------------------------------
void *QIOSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
diff --git a/src/plugins/platforms/ios/qiosmenu.h b/src/plugins/platforms/ios/qiosmenu.h
index ec23b55507..3beb58b503 100644
--- a/src/plugins/platforms/ios/qiosmenu.h
+++ b/src/plugins/platforms/ios/qiosmenu.h
@@ -74,9 +74,6 @@ public:
bool m_separator;
QIOSMenu *m_menu;
QKeySequence m_shortcut;
-
-private:
- QString removeMnemonics(const QString &original);
};
typedef QList<QIOSMenuItem *> QIOSMenuItemList;
diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm
index 612f8c43a2..5f9346816a 100644
--- a/src/plugins/platforms/ios/qiosmenu.mm
+++ b/src/plugins/platforms/ios/qiosmenu.mm
@@ -33,6 +33,7 @@
#include <qglobal.h>
#include <qguiapplication.h>
+#include <qpa/qplatformtheme.h>
#include "qiosglobal.h"
#include "qiosmenu.h"
@@ -271,7 +272,7 @@ quintptr QIOSMenuItem::tag() const
void QIOSMenuItem::setText(const QString &text)
{
- m_text = removeMnemonics(text);
+ m_text = QPlatformTheme::removeMnemonics(text);
}
void QIOSMenuItem::setMenu(QPlatformMenu *menu)
@@ -304,41 +305,6 @@ void QIOSMenuItem::setEnabled(bool enabled)
m_enabled = enabled;
}
-QString QIOSMenuItem::removeMnemonics(const QString &original)
-{
- // Copied from qcocoahelpers
- QString returnText(original.size(), 0);
- int finalDest = 0;
- int currPos = 0;
- int l = original.length();
- while (l) {
- if (original.at(currPos) == QLatin1Char('&')
- && (l == 1 || original.at(currPos + 1) != QLatin1Char('&'))) {
- ++currPos;
- --l;
- if (l == 0)
- break;
- } else if (original.at(currPos) == QLatin1Char('(') && l >= 4 &&
- original.at(currPos + 1) == QLatin1Char('&') &&
- original.at(currPos + 2) != QLatin1Char('&') &&
- original.at(currPos + 3) == QLatin1Char(')')) {
- /* remove mnemonics its format is "\s*(&X)" */
- int n = 0;
- while (finalDest > n && returnText.at(finalDest - n - 1).isSpace())
- ++n;
- finalDest -= n;
- currPos += 4;
- l -= 4;
- continue;
- }
- returnText[finalDest] = original.at(currPos);
- ++currPos;
- ++finalDest;
- --l;
- }
- returnText.truncate(finalDest);
- return returnText;
-}
QIOSMenu::QIOSMenu()
: QPlatformMenu()
diff --git a/src/plugins/bearer/blackberry/main.cpp b/src/plugins/platforms/ios/qiosmessagedialog.h
index ddeaefa75c..a9bd42324e 100644
--- a/src/plugins/bearer/blackberry/main.cpp
+++ b/src/plugins/platforms/ios/qiosmessagedialog.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Research In Motion
+** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -31,33 +31,35 @@
**
****************************************************************************/
-#include "qbbengine.h"
+#ifndef QIOSMESSAGEDIALOG_H
+#define QIOSMESSAGEDIALOG_H
-#include <QtNetwork/private/qbearerplugin_p.h>
-
-#ifndef QT_NO_BEARERMANAGEMENT
+#include <QtCore/qeventloop.h>
+#include <qpa/qplatformdialoghelper.h>
QT_BEGIN_NAMESPACE
-class QBBEnginePlugin : public QBearerEnginePlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QBearerEngineFactoryInterface" FILE "blackberry.json")
+Q_FORWARD_DECLARE_OBJC_CLASS(UIAlertController);
+Q_FORWARD_DECLARE_OBJC_CLASS(UIAlertAction);
+class QIOSMessageDialog : public QPlatformMessageDialogHelper
+{
public:
- QBearerEngine *create(const QString &key) const;
-};
+ QIOSMessageDialog();
+ ~QIOSMessageDialog();
-QBearerEngine *QBBEnginePlugin::create(const QString &key) const
-{
- if (key == QLatin1String("blackberry"))
- return new QBBEngine;
+ void exec() Q_DECL_OVERRIDE;
+ bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) Q_DECL_OVERRIDE;
+ void hide() Q_DECL_OVERRIDE;
- return 0;
-}
+private:
+ QEventLoop m_eventLoop;
+ UIAlertController *m_alertController;
+ QString messageTextPlain();
+ UIAlertAction *createAction(StandardButton button);
+};
QT_END_NAMESPACE
-#include "main.moc"
+#endif // QIOSMESSAGEDIALOG_H
-#endif // QT_NO_BEARERMANAGEMENT
diff --git a/src/plugins/platforms/ios/qiosmessagedialog.mm b/src/plugins/platforms/ios/qiosmessagedialog.mm
new file mode 100644
index 0000000000..39f7d4b1cd
--- /dev/null
+++ b/src/plugins/platforms/ios/qiosmessagedialog.mm
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#import <UIKit/UIKit.h>
+
+#include <QtGui/qwindow.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <qpa/qplatformtheme.h>
+
+#include "qiosglobal.h"
+#include "quiview.h"
+#include "qiosmessagedialog.h"
+
+QIOSMessageDialog::QIOSMessageDialog()
+ : m_alertController(Q_NULLPTR)
+{
+}
+
+QIOSMessageDialog::~QIOSMessageDialog()
+{
+ hide();
+}
+
+inline QString QIOSMessageDialog::messageTextPlain()
+{
+ // Concatenate text fragments, and remove HTML tags
+ const QSharedPointer<QMessageDialogOptions> &opt = options();
+ const QString &lineShift = QStringLiteral("\n\n");
+ const QString &informativeText = opt->informativeText();
+ const QString &detailedText = opt->detailedText();
+
+ QString text = opt->text();
+ if (!informativeText.isEmpty())
+ text += lineShift + informativeText;
+ if (!detailedText.isEmpty())
+ text += lineShift + detailedText;
+
+ text.replace(QLatin1String("<p>"), QStringLiteral("\n"), Qt::CaseInsensitive);
+ text.remove(QRegularExpression(QStringLiteral("<[^>]*>")));
+
+ return text;
+}
+
+inline UIAlertAction *QIOSMessageDialog::createAction(StandardButton button)
+{
+ const StandardButton labelButton = button == NoButton ? Ok : button;
+ const QString &standardLabel = QGuiApplicationPrivate::platformTheme()->standardButtonText(labelButton);
+ const QString &label = QPlatformTheme::removeMnemonics(standardLabel);
+
+ UIAlertActionStyle style = UIAlertActionStyleDefault;
+ if (button == Cancel)
+ style = UIAlertActionStyleCancel;
+ else if (button == Discard)
+ style = UIAlertActionStyleDestructive;
+
+ return [UIAlertAction actionWithTitle:label.toNSString() style:style handler:^(UIAlertAction *) {
+ hide();
+ if (button == NoButton)
+ emit reject();
+ else
+ emit clicked(button, buttonRole(button));
+ }];
+}
+
+void QIOSMessageDialog::exec()
+{
+ m_eventLoop.exec(QEventLoop::DialogExec);
+}
+
+bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+{
+ Q_UNUSED(windowFlags);
+ if (m_alertController // Ensure that the dialog is not showing already
+ || !options() // Some message dialogs don't have options (QErrorMessage)
+ || windowModality != Qt::ApplicationModal // We can only do app modal dialogs
+ || QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_8_0) // API limitation
+ return false;
+
+ m_alertController = [[UIAlertController
+ alertControllerWithTitle:options()->windowTitle().toNSString()
+ message:messageTextPlain().toNSString()
+ preferredStyle:UIAlertControllerStyleAlert] retain];
+
+ if (StandardButtons buttons = options()->standardButtons()) {
+ for (int i = FirstButton; i < LastButton; i<<=1) {
+ if (i & buttons)
+ [m_alertController addAction:createAction(StandardButton(i))];
+ }
+ } else {
+ // We need at least one button to allow the user close the dialog
+ [m_alertController addAction:createAction(NoButton)];
+ }
+
+ UIWindow *window = parent ? reinterpret_cast<UIView *>(parent->winId()).window : [UIApplication sharedApplication].keyWindow;
+ [window.rootViewController presentViewController:m_alertController animated:YES completion:nil];
+ return true;
+}
+
+void QIOSMessageDialog::hide()
+{
+ m_eventLoop.exit();
+ [m_alertController dismissViewControllerAnimated:YES completion:nil];
+ [m_alertController release];
+ m_alertController = Q_NULLPTR;
+}
diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm
index bc40069670..dccacb2c0e 100644
--- a/src/plugins/platforms/ios/qiostheme.mm
+++ b/src/plugins/platforms/ios/qiostheme.mm
@@ -47,6 +47,7 @@
#include "qiosmenu.h"
#include "qiosfiledialog.h"
+#include "qiosmessagedialog.h"
QT_BEGIN_NAMESPACE
@@ -85,6 +86,7 @@ bool QIOSTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const
{
switch (type) {
case FileDialog:
+ case MessageDialog:
return true;
default:
return false;
@@ -97,6 +99,9 @@ QPlatformDialogHelper *QIOSTheme::createPlatformDialogHelper(QPlatformTheme::Dia
case FileDialog:
return new QIOSFileDialog();
break;
+ case MessageDialog:
+ return new QIOSMessageDialog();
+ break;
default:
return 0;
}
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index 91708c0a47..b4481ce5a2 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -34,6 +34,7 @@
#include "qlinuxfbscreen.h"
#include <QtPlatformSupport/private/qfbcursor_p.h>
#include <QtPlatformSupport/private/qfbwindow_p.h>
+#include <QtCore/QFile>
#include <QtCore/QRegularExpression>
#include <QtGui/QPainter>
@@ -291,10 +292,8 @@ QLinuxFbScreen::~QLinuxFbScreen()
close(mFbFd);
}
- if (mTtyFd != -1) {
+ if (mTtyFd != -1)
resetTty(mTtyFd, mOldTtyMode);
- close(mTtyFd);
- }
delete mBlitter;
}
diff --git a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
index 59062338cb..093a1c689c 100644
--- a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
+++ b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
@@ -74,19 +74,19 @@ QMinimalEglScreen::QMinimalEglScreen(EGLNativeDisplayType display)
EGLint major, minor;
- if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+ if (Q_UNLIKELY(!eglBindAPI(EGL_OPENGL_ES_API))) {
qWarning("Could not bind GL_ES API\n");
qFatal("EGL error");
}
m_dpy = eglGetDisplay(display);
- if (m_dpy == EGL_NO_DISPLAY) {
+ if (Q_UNLIKELY(m_dpy == EGL_NO_DISPLAY)) {
qWarning("Could not open egl display\n");
qFatal("EGL error");
}
qWarning("Opened display %p\n", m_dpy);
- if (!eglInitialize(m_dpy, &major, &minor)) {
+ if (Q_UNLIKELY(!eglInitialize(m_dpy, &major, &minor))) {
qWarning("Could not initialize egl display\n");
qFatal("EGL error");
}
@@ -135,9 +135,9 @@ void QMinimalEglScreen::createAndSetPlatformContext()
EGLNativeWindowType eglWindow = 0;
#ifdef Q_OPENKODE
- if (kdInitializeNV() == KD_ENOTINITIALIZED) {
+ if (Q_UNLIKELY(kdInitializeNV() == KD_ENOTINITIALIZED))
qFatal("Did not manage to initialize openkode");
- }
+
KDWindow *window = kdCreateWindow(m_dpy,config,0);
kdRealizeWindow(window,&eglWindow);
@@ -148,7 +148,7 @@ void QMinimalEglScreen::createAndSetPlatformContext()
#endif
m_surface = eglCreateWindowSurface(m_dpy, config, eglWindow, NULL);
- if (m_surface == EGL_NO_SURFACE) {
+ if (Q_UNLIKELY(m_surface == EGL_NO_SURFACE)) {
qWarning("Could not create the egl surface: error = 0x%x\n", eglGetError());
eglTerminate(m_dpy);
qFatal("EGL error");
diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp b/src/plugins/platforms/mirclient/qmirclientclipboard.cpp
index aa2ddf2103..4494847b54 100644
--- a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientclipboard.cpp
@@ -100,7 +100,7 @@ void QMirClientClipboard::onDBusClipboardGetContentsFinished(QDBusPendingCallWat
Q_ASSERT(call == mPendingGetContentsCall.data());
QDBusPendingReply<QByteArray> reply = *call;
- if (reply.isError()) {
+ if (Q_UNLIKELY(reply.isError())) {
qCritical("QMirClientClipboard - Failed to get system clipboard contents via D-Bus. %s, %s",
qPrintable(reply.error().name()), qPrintable(reply.error().message()));
// TODO: Might try again later a number of times...
@@ -114,7 +114,7 @@ void QMirClientClipboard::onDBusClipboardGetContentsFinished(QDBusPendingCallWat
void QMirClientClipboard::onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher *call)
{
QDBusPendingReply<void> reply = *call;
- if (reply.isError()) {
+ if (Q_UNLIKELY(reply.isError())) {
qCritical("QMirClientClipboard - Failed to set the system clipboard contents via D-Bus. %s, %s",
qPrintable(reply.error().name()), qPrintable(reply.error().message()));
// TODO: Might try again later a number of times...
@@ -148,9 +148,8 @@ void QMirClientClipboard::setupDBus()
"com.canonical.QtMir.Clipboard",
"ContentsChanged",
this, SLOT(updateMimeData(QByteArray)));
- if (!ok) {
+ if (Q_UNLIKELY(!ok))
qCritical("QMirClientClipboard - Failed to connect to ContentsChanged signal form the D-Bus system clipboard.");
- }
mDBusClipboard = new QDBusInterface("com.canonical.QtMir",
"/com/canonical/QtMir/Clipboard",
diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp b/src/plugins/platforms/mirclient/qmirclientglcontext.cpp
index bfba5051e5..bbd7f5ee75 100644
--- a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientglcontext.cpp
@@ -39,6 +39,7 @@
#include "qmirclientwindow.h"
#include "qmirclientlogging.h"
#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtGui/private/qopenglcontext_p.h>
#if !defined(QT_NO_DEBUG)
static void printOpenGLESConfig() {
@@ -103,6 +104,15 @@ bool QMirClientOpenGLContext::makeCurrent(QPlatformSurface* surface)
ASSERT(eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext) == EGL_TRUE);
printOpenGLESConfig();
#endif
+
+ // When running on the emulator, shaders will be compiled using a thin wrapper around the desktop drivers.
+ // These wrappers might not support the precision qualifiers, so set the workaround flag to true.
+ const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
+ if (rendererString != 0 && qstrncmp(rendererString, "Android Emulator", 16) == 0) {
+ QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
+ ctx_d->workaround_missingPrecisionQualifiers = true;
+ }
+
return true;
}
diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.cpp b/src/plugins/platforms/mirclient/qmirclientintegration.cpp
index a234f4eac6..87d2002c56 100644
--- a/src/plugins/platforms/mirclient/qmirclientintegration.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientintegration.cpp
@@ -95,7 +95,7 @@ QMirClientClientIntegration::QMirClientClientIntegration()
// Create new application instance
mInstance = u_application_instance_new_from_description_with_options(mDesc, mOptions);
- if (mInstance == nullptr)
+ if (Q_UNLIKELY(!mInstance))
qFatal("QMirClientClientIntegration: connection to Mir server failed. Check that a Mir server is\n"
"running, and the correct socket is being used and is accessible. The shell may have\n"
"rejected the incoming connection, so check its log file");
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp
index eb704f2dfa..dfaaa43c1d 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp
@@ -143,7 +143,7 @@ static Window createDummyWindow(QOffscreenX11Info *x11, XVisualInfo *visualInfo)
static Window createDummyWindow(QOffscreenX11Info *x11, GLXFBConfig config)
{
XVisualInfo *visualInfo = glXGetVisualFromFBConfig(x11->display(), config);
- if (!visualInfo)
+ if (Q_UNLIKELY(!visualInfo))
qFatal("Could not initialize GLX");
Window window = createDummyWindow(x11, visualInfo);
XFree(visualInfo);
@@ -177,7 +177,7 @@ QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGL
d->window = createDummyWindow(x11, config);
} else {
XVisualInfo *visualInfo = qglx_findVisualInfo(x11->display(), 0, &d->format);
- if (!visualInfo)
+ if (Q_UNLIKELY(!visualInfo))
qFatal("Could not initialize GLX");
d->context = glXCreateContext(x11->display(), visualInfo, d->shareContext, true);
if (!d->context && d->shareContext) {
diff --git a/src/plugins/platforms/openwfd/qopenwfdport.cpp b/src/plugins/platforms/openwfd/qopenwfdport.cpp
index 8da1e9bd34..c1646fbdf9 100644
--- a/src/plugins/platforms/openwfd/qopenwfdport.cpp
+++ b/src/plugins/platforms/openwfd/qopenwfdport.cpp
@@ -96,9 +96,8 @@ void QOpenWFDPort::attach()
mPhysicalSize = QSizeF(physicalWFDSize[0],physicalWFDSize[1]);
WFDint numAvailablePipelines = wfdGetPortAttribi(mDevice->handle(),mPort,WFD_PORT_PIPELINE_ID_COUNT);
- if (!numAvailablePipelines) {
+ if (Q_UNLIKELY(!numAvailablePipelines))
qFatal("Not possible to make screen that is not possible to create WFPort with no pipline");
- }
WFDint pipeIds[numAvailablePipelines];
wfdGetPortAttribiv(mDevice->handle(),mPort,WFD_PORT_BINDABLE_PIPELINE_IDS,numAvailablePipelines,pipeIds);
@@ -109,9 +108,9 @@ void QOpenWFDPort::attach()
mDevice-> addToUsedPipelineSet(mPipelineId,this);
mPipeline = wfdCreatePipeline(mDevice->handle(),mPipelineId,WFD_NONE);
- if (mPipeline == WFD_INVALID_HANDLE) {
+ if (Q_UNLIKELY(mPipeline == WFD_INVALID_HANDLE))
qFatal("Failed to create pipeline for port %p", this);
- }
+
break;
}
}
diff --git a/src/plugins/platforms/qnx/qblackberrytheme.cpp b/src/plugins/platforms/qnx/qblackberrytheme.cpp
deleted file mode 100644
index f75e8f3766..0000000000
--- a/src/plugins/platforms/qnx/qblackberrytheme.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qblackberrytheme.h"
-
-#include "qqnxfiledialoghelper.h"
-#include "qqnxsystemsettings.h"
-#include "qqnxintegration.h"
-
-QT_BEGIN_NAMESPACE
-
-QBlackberryTheme::QBlackberryTheme(const QQnxIntegration *integration) : m_integration(integration)
-{
- // Set the dark theme as default palette
- QColor color = QColor(211, 211, 211);
- m_defaultPalette.setBrush(QPalette::ButtonText, color);
- m_defaultPalette.setBrush(QPalette::WindowText, color);
- m_defaultPalette.setBrush(QPalette::Text, color);
-
- color.setAlpha(179);
- m_defaultPalette.setBrush(QPalette::Disabled, QPalette::ButtonText, color);
- m_defaultPalette.setBrush(QPalette::Disabled, QPalette::WindowText, color);
- m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Text, color);
-
- color.setRgb(18, 18, 18);
- m_defaultPalette.setColor(QPalette::Window, color);
- m_defaultPalette.setColor(QPalette::Base, color);
- m_defaultPalette.setColor(QPalette::AlternateBase, QColor(50, 50, 50));
- m_defaultPalette.setColor(QPalette::Button, color);
-
- m_defaultPalette.setBrush(QPalette::Highlight, QColor(0, 168, 223));
- m_defaultPalette.setBrush(QPalette::HighlightedText, QColor(250, 250,250));
-}
-
-QBlackberryTheme::~QBlackberryTheme()
-{
- qDeleteAll(m_fonts);
-}
-
-bool QBlackberryTheme::usePlatformNativeDialog(DialogType type) const
-{
- if (type == QPlatformTheme::FileDialog)
- return true;
-#if !defined(QT_NO_COLORDIALOG)
- if (type == QPlatformTheme::ColorDialog)
- return false;
-#endif
-#if !defined(QT_NO_FONTDIALOG)
- if (type == QPlatformTheme::FontDialog)
- return false;
-#endif
- return false;
-}
-
-QPlatformDialogHelper *QBlackberryTheme::createPlatformDialogHelper(DialogType type) const
-{
- switch (type) {
- case QPlatformTheme::FileDialog:
- return new QQnxFileDialogHelper(m_integration);
-#if !defined(QT_NO_COLORDIALOG)
- case QPlatformTheme::ColorDialog:
-#endif
-#if !defined(QT_NO_FONTDIALOG)
- case QPlatformTheme::FontDialog:
-#endif
- default:
- return 0;
- }
-}
-
-const QFont *QBlackberryTheme::font(Font type) const
-{
- QPlatformFontDatabase *fontDatabase = m_integration->fontDatabase();
-
- if (fontDatabase && m_fonts.isEmpty())
- m_fonts = qt_qnx_createRoleFonts(fontDatabase);
- return m_fonts.value(type, 0);
-}
-
-const QPalette *QBlackberryTheme::palette(Palette type) const
-{
- // Return the default palette
- if (type == SystemPalette)
- return &m_defaultPalette;
-
- return QPlatformTheme::palette(type);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qblackberrytheme.h b/src/plugins/platforms/qnx/qblackberrytheme.h
deleted file mode 100644
index bcef4e5ef4..0000000000
--- a/src/plugins/platforms/qnx/qblackberrytheme.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBLACKBERRYTHEME_H
-#define QBLACKBERRYTHEME_H
-
-#include <qpa/qplatformtheme.h>
-
-#include <QtGui/qfont.h>
-
-#include <QtCore/qhash.h>
-#include <QtCore/qstring.h>
-
-#include <QtGui/QPalette>
-
-QT_BEGIN_NAMESPACE
-
-class QQnxIntegration;
-
-class QBlackberryTheme : public QPlatformTheme
-{
-public:
- explicit QBlackberryTheme(const QQnxIntegration *);
- ~QBlackberryTheme();
-
- static QString name() { return QStringLiteral("blackberry"); }
-
- bool usePlatformNativeDialog(DialogType type) const;
- QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
-
- const QFont *font(Font type = SystemFont) const;
-
- const QPalette *palette(Palette type = SystemPalette) const;
-
-private:
- mutable QHash<QPlatformTheme::Font, QFont*> m_fonts;
- const QQnxIntegration *m_integration;
- QPalette m_defaultPalette;
-};
-
-QT_END_NAMESPACE
-
-#endif // QBLACKBERRYTHEME_H
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index 95a8e44cb8..5a0f4f5c98 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -5,10 +5,9 @@ QT += platformsupport-private core-private gui-private
# Uncomment this to build with support for IMF once it becomes available in the BBNDK
#CONFIG += qqnx_imf
-!blackberry:CONFIG += qqnx_screeneventthread
+CONFIG += qqnx_screeneventthread
# Uncomment these to enable debugging output for various aspects of the plugin
-#DEFINES += QQNXBPSEVENTFILTER_DEBUG
#DEFINES += QQNXBUFFER_DEBUG
#DEFINES += QQNXBUTTON_DEBUG
#DEFINES += QQNXCLIPBOARD_DEBUG
@@ -86,52 +85,20 @@ contains(QT_CONFIG, opengles2) {
LIBS += -lEGL
}
-CONFIG(blackberry) {
- SOURCES += qqnxnavigatorbps.cpp \
- qqnxeventdispatcher_blackberry.cpp \
- qqnxbpseventfilter.cpp \
- qqnxvirtualkeyboardbps.cpp \
- qblackberrytheme.cpp \
- qqnxsystemsettings.cpp
-
- HEADERS += qqnxnavigatorbps.h \
- qqnxeventdispatcher_blackberry.h \
- qqnxbpseventfilter.h \
- qqnxvirtualkeyboardbps.h \
- qblackberrytheme.h \
- qqnxsystemsettings.h \
- qqnxfiledialoghelper.h
-
- LIBS += -lbps
-}
-
-CONFIG(blackberry) {
- SOURCES += qqnxfiledialoghelper_bb10.cpp \
- qqnxfilepicker.cpp \
- qqnxnavigatorcover.cpp
-
- HEADERS += qqnxfilepicker.h \
- qqnxnavigatorcover.h
-}
-
CONFIG(qqnx_pps) {
DEFINES += QQNX_PPS
SOURCES += qqnxclipboard.cpp \
- qqnxbuttoneventnotifier.cpp
+ qqnxbuttoneventnotifier.cpp \
+ qqnxnavigatorpps.cpp \
+ qqnxnavigatoreventnotifier.cpp \
+ qqnxvirtualkeyboardpps.cpp
HEADERS += qqnxclipboard.h \
- qqnxbuttoneventnotifier.h
-
- !blackberry {
- SOURCES += qqnxnavigatorpps.cpp \
- qqnxnavigatoreventnotifier.cpp \
- qqnxvirtualkeyboardpps.cpp
-
- HEADERS += qqnxnavigatorpps.h \
- qqnxnavigatoreventnotifier.h \
- qqnxvirtualkeyboardpps.h
- }
+ qqnxbuttoneventnotifier.h \
+ qqnxnavigatorpps.h \
+ qqnxnavigatoreventnotifier.h \
+ qqnxvirtualkeyboardpps.h
LIBS += -lpps
!contains(DEFINES, QT_NO_CLIPBOARD): LIBS += -lclipboard
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp b/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
deleted file mode 100644
index 66843283b6..0000000000
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqnxbpseventfilter.h"
-#include "qqnxnavigatoreventhandler.h"
-#include "qqnxscreen.h"
-#include "qqnxscreeneventhandler.h"
-#include "qqnxvirtualkeyboardbps.h"
-#include "qqnxfiledialoghelper.h"
-
-#include <QCoreApplication>
-#include <QAbstractEventDispatcher>
-#include <QDebug>
-
-#include <bps/event.h>
-#include <bps/navigator.h>
-#include <bps/screen.h>
-
-#if defined(QQNXBPSEVENTFILTER_DEBUG)
-#define qBpsEventFilterDebug qDebug
-#else
-#define qBpsEventFilterDebug QT_NO_QDEBUG_MACRO
-#endif
-
-QT_BEGIN_NAMESPACE
-
-static QQnxBpsEventFilter *s_instance = 0;
-
-QQnxBpsEventFilter::QQnxBpsEventFilter(QQnxNavigatorEventHandler *navigatorEventHandler,
- QQnxScreenEventHandler *screenEventHandler,
- QQnxVirtualKeyboardBps *virtualKeyboard, QObject *parent)
- : QObject(parent)
- , m_navigatorEventHandler(navigatorEventHandler)
- , m_screenEventHandler(screenEventHandler)
- , m_virtualKeyboard(virtualKeyboard)
-{
- Q_ASSERT(s_instance == 0);
-
- s_instance = this;
-}
-
-QQnxBpsEventFilter::~QQnxBpsEventFilter()
-{
- Q_ASSERT(s_instance == this);
-
- s_instance = 0;
-}
-
-void QQnxBpsEventFilter::installOnEventDispatcher(QAbstractEventDispatcher *dispatcher)
-{
- qBpsEventFilterDebug() << "dispatcher=" << dispatcher;
-
- if (navigator_request_events(NAVIGATOR_EXTENDED_DATA) != BPS_SUCCESS)
- qWarning("QQNX: failed to register for navigator events");
-
- dispatcher->installNativeEventFilter(this);
-}
-
-void QQnxBpsEventFilter::registerForScreenEvents(QQnxScreen *screen)
-{
- if (!m_screenEventHandler) {
- qWarning("QQNX: trying to register for screen events, but no handler provided.");
- return;
- }
-
- int attached;
- if (screen_get_display_property_iv(screen->nativeDisplay(), SCREEN_PROPERTY_ATTACHED, &attached) != BPS_SUCCESS) {
- qWarning() << "QQNX: unable to query display attachment";
- return;
- }
-
- if (!attached) {
- qBpsEventFilterDebug() << "skipping event registration for non-attached screen";
- return;
- }
-
- if (screen_request_events(screen->nativeContext()) != BPS_SUCCESS)
- qWarning("QQNX: failed to register for screen events on screen %p", screen->nativeContext());
-}
-
-void QQnxBpsEventFilter::unregisterForScreenEvents(QQnxScreen *screen)
-{
- if (!m_screenEventHandler) {
- qWarning("QQNX: trying to unregister for screen events, but no handler provided.");
- return;
- }
-
- if (screen_stop_events(screen->nativeContext()) != BPS_SUCCESS)
- qWarning("QQNX: failed to unregister for screen events on screen %p", screen->nativeContext());
-}
-
-bool QQnxBpsEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
-{
- Q_UNUSED(eventType);
- Q_UNUSED(result);
- bps_event_t *event = static_cast<bps_event_t *>(message);
- const int eventDomain = bps_event_get_domain(event);
- qBpsEventFilterDebug() << "event=" << event << "domain=" << eventDomain;
-
- if (eventDomain == screen_get_domain()) {
- if (!m_screenEventHandler) {
- qWarning("QQNX: registered for screen events, but no handler provided.");
- return false;
- }
-
- screen_event_t screenEvent = screen_event_get_event(event);
- return m_screenEventHandler->handleEvent(screenEvent);
- }
-
- if (eventDomain == navigator_get_domain())
- return handleNavigatorEvent(event);
-
- if (m_virtualKeyboard->handleEvent(event))
- return true;
-
- return false;
-}
-
-bool QQnxBpsEventFilter::handleNavigatorEvent(bps_event_t *event)
-{
- switch (bps_event_get_code(event)) {
- case NAVIGATOR_ORIENTATION_CHECK: {
- const int angle = navigator_event_get_orientation_angle(event);
- qBpsEventFilterDebug() << "ORIENTATION CHECK event. angle=" << angle;
-
- const bool result = m_navigatorEventHandler->handleOrientationCheck(angle);
- qBpsEventFilterDebug() << "ORIENTATION CHECK event. result=" << result;
-
- // reply to navigator whether orientation is acceptable
- navigator_orientation_check_response(event, result);
- break;
- }
-
- case NAVIGATOR_ORIENTATION: {
- const int angle = navigator_event_get_orientation_angle(event);
- qBpsEventFilterDebug() << "ORIENTATION event. angle=" << angle;
- m_navigatorEventHandler->handleOrientationChange(angle);
-
- navigator_done_orientation(event);
- break;
- }
-
- case NAVIGATOR_SWIPE_DOWN:
- qBpsEventFilterDebug("SWIPE DOWN event");
- m_navigatorEventHandler->handleSwipeDown();
- break;
-
- case NAVIGATOR_EXIT:
- qBpsEventFilterDebug("EXIT event");
- m_navigatorEventHandler->handleExit();
- break;
-
- case NAVIGATOR_WINDOW_STATE: {
- qBpsEventFilterDebug("WINDOW STATE event");
- const navigator_window_state_t state = navigator_event_get_window_state(event);
- const QByteArray id(navigator_event_get_groupid(event));
-
- switch (state) {
- case NAVIGATOR_WINDOW_FULLSCREEN:
- m_navigatorEventHandler->handleWindowGroupStateChanged(id, Qt::WindowFullScreen);
- break;
- case NAVIGATOR_WINDOW_THUMBNAIL:
- m_navigatorEventHandler->handleWindowGroupStateChanged(id, Qt::WindowMinimized);
- break;
- case NAVIGATOR_WINDOW_INVISIBLE:
- break;
- }
-
- break;
- }
-
- case NAVIGATOR_WINDOW_ACTIVE: {
- qBpsEventFilterDebug("WINDOW ACTIVE event");
- const QByteArray id(navigator_event_get_groupid(event));
- m_navigatorEventHandler->handleWindowGroupActivated(id);
- break;
- }
-
- case NAVIGATOR_WINDOW_INACTIVE: {
- qBpsEventFilterDebug("WINDOW INACTIVE event");
- const QByteArray id(navigator_event_get_groupid(event));
- m_navigatorEventHandler->handleWindowGroupDeactivated(id);
- break;
- }
-
- case NAVIGATOR_LOW_MEMORY:
- qWarning() << "QGuiApplication based process" << QCoreApplication::applicationPid()
- << "received \"NAVIGATOR_LOW_MEMORY\" event";
- return false;
-
- default:
- qBpsEventFilterDebug() << "Unhandled navigator event. code=" << bps_event_get_code(event);
- return false;
- }
-
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxbpseventfilter.h b/src/plugins/platforms/qnx/qqnxbpseventfilter.h
deleted file mode 100644
index f1d67848e8..0000000000
--- a/src/plugins/platforms/qnx/qqnxbpseventfilter.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQNXBPSEVENTFILTER_H
-#define QQNXBPSEVENTFILTER_H
-
-#include <QObject>
-#include <QHash>
-#include <QAbstractNativeEventFilter>
-
-#include <bps/dialog.h>
-
-struct bps_event_t;
-
-QT_BEGIN_NAMESPACE
-
-class QAbstractEventDispatcher;
-class QQnxNavigatorEventHandler;
-class QQnxFileDialogHelper;
-class QQnxScreen;
-class QQnxScreenEventHandler;
-class QQnxVirtualKeyboardBps;
-
-class QQnxBpsEventFilter : public QObject, public QAbstractNativeEventFilter
-{
- Q_OBJECT
-public:
- QQnxBpsEventFilter(QQnxNavigatorEventHandler *navigatorEventHandler,
- QQnxScreenEventHandler *screenEventHandler,
- QQnxVirtualKeyboardBps *virtualKeyboard, QObject *parent = 0);
- ~QQnxBpsEventFilter();
-
- void installOnEventDispatcher(QAbstractEventDispatcher *dispatcher);
-
- void registerForScreenEvents(QQnxScreen *screen);
- void unregisterForScreenEvents(QQnxScreen *screen);
-
-private:
- bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
-
- bool handleNavigatorEvent(bps_event_t *event);
-
-private:
- QQnxNavigatorEventHandler *m_navigatorEventHandler;
- QQnxScreenEventHandler *m_screenEventHandler;
- QQnxVirtualKeyboardBps *m_virtualKeyboard;
- QHash<dialog_instance_t, QQnxFileDialogHelper*> m_dialogMapper;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQNXBPSEVENTFILTER_H
diff --git a/src/plugins/platforms/qnx/qqnxbuffer.cpp b/src/plugins/platforms/qnx/qqnxbuffer.cpp
index 7ee6664676..5d838ac189 100644
--- a/src/plugins/platforms/qnx/qqnxbuffer.cpp
+++ b/src/plugins/platforms/qnx/qqnxbuffer.cpp
@@ -76,7 +76,7 @@ QQnxBuffer::QQnxBuffer(screen_buffer_t buffer)
screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, (void **)&dataPtr),
"Failed to query buffer pointer");
- if (dataPtr == 0)
+ if (Q_UNLIKELY(!dataPtr))
qFatal("QQNX: buffer pointer is NULL, errno=%d", errno);
// Get format of buffer
@@ -131,13 +131,13 @@ void QQnxBuffer::invalidateInCache()
qBufferDebug();
// Verify native buffer exists
- if (m_buffer == 0)
+ if (Q_UNLIKELY(!m_buffer))
qFatal("QQNX: can't invalidate cache for null buffer");
// Evict buffer's data from cache
errno = 0;
int result = msync(m_image.bits(), m_image.height() * m_image.bytesPerLine(), MS_INVALIDATE | MS_CACHE_ONLY);
- if (result != 0)
+ if (Q_UNLIKELY(result != 0))
qFatal("QQNX: failed to invalidate cache, errno=%d", errno);
}
diff --git a/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp b/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
index 614bfc381f..ec30e79ab5 100644
--- a/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
+++ b/src/plugins/platforms/qnx/qqnxbuttoneventnotifier.cpp
@@ -82,7 +82,7 @@ void QQnxButtonEventNotifier::start()
errno = 0;
m_fd = qt_safe_open(ppsPath, O_RDONLY);
if (m_fd == -1) {
-#if defined(Q_OS_BLACKBERRY) || defined (QQNXBUTTON_DEBUG)
+#if defined (QQNXBUTTON_DEBUG)
qWarning("QQNX: failed to open buttons pps, errno=%d", errno);
#endif
return;
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
index 00eaf2bf03..5f80b39fe6 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
@@ -59,7 +59,7 @@ QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool nee
// Set window usage
const int val = SCREEN_USAGE_OPENGL_ES2;
const int result = screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_USAGE, &val);
- if (result != 0)
+ if (Q_UNLIKELY(result != 0))
qFatal("QQnxEglWindow: failed to set window alpha usage, errno=%d", errno);
m_requestedBufferSize = shouldMakeFullScreen() ? screen()->geometry().size() : window->geometry().size();
@@ -106,7 +106,7 @@ void QQnxEglWindow::destroyEGLSurface()
// Destroy EGL surface if it exists
if (m_eglSurface != EGL_NO_SURFACE) {
EGLBoolean eglResult = eglDestroySurface(platformOpenGLContext()->getEglDisplay(), m_eglSurface);
- if (eglResult != EGL_TRUE)
+ if (Q_UNLIKELY(eglResult != EGL_TRUE))
qFatal("QQNX: failed to destroy EGL surface, err=%d", eglGetError());
}
@@ -118,12 +118,12 @@ void QQnxEglWindow::swapEGLBuffers()
qEglWindowDebug();
// Set current rendering API
EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (eglResult != EGL_TRUE)
+ if (Q_UNLIKELY(eglResult != EGL_TRUE))
qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
// Post EGL surface to window
eglResult = eglSwapBuffers(m_platformOpenGLContext->getEglDisplay(), m_eglSurface);
- if (eglResult != EGL_TRUE)
+ if (Q_UNLIKELY(eglResult != EGL_TRUE))
qFatal("QQNX: failed to swap EGL buffers, err=%d", eglGetError());
windowPosted();
@@ -178,15 +178,15 @@ int QQnxEglWindow::pixelFormat() const
const QSurfaceFormat format = m_platformOpenGLContext->format();
// Extract size of color channels from window format
const int redSize = format.redBufferSize();
- if (redSize == -1)
+ if (Q_UNLIKELY(redSize == -1))
qFatal("QQnxWindow: red size not defined");
const int greenSize = format.greenBufferSize();
- if (greenSize == -1)
+ if (Q_UNLIKELY(greenSize == -1))
qFatal("QQnxWindow: green size not defined");
const int blueSize = format.blueBufferSize();
- if (blueSize == -1)
+ if (Q_UNLIKELY(blueSize == -1))
qFatal("QQnxWindow: blue size not defined");
// select matching native format
diff --git a/src/plugins/platforms/qnx/qqnxeventdispatcher_blackberry.cpp b/src/plugins/platforms/qnx/qqnxeventdispatcher_blackberry.cpp
deleted file mode 100644
index 30596fe08f..0000000000
--- a/src/plugins/platforms/qnx/qqnxeventdispatcher_blackberry.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqnxeventdispatcher_blackberry.h"
-
-#include <qpa/qwindowsysteminterface.h>
-#include <private/qguiapplication_p.h>
-
-QT_BEGIN_NAMESPACE
-
-
-QQnxEventDispatcherBlackberry::QQnxEventDispatcherBlackberry(QObject *parent)
- : QEventDispatcherBlackberry(parent)
-{
-}
-
-QQnxEventDispatcherBlackberry::~QQnxEventDispatcherBlackberry()
-{
-}
-
-bool QQnxEventDispatcherBlackberry::processEvents(QEventLoop::ProcessEventsFlags flags)
-{
- const bool didSendEvents = QEventDispatcherBlackberry::processEvents(flags);
- return QWindowSystemInterface::sendWindowSystemEvents(flags) || didSendEvents;
-}
-
-bool QQnxEventDispatcherBlackberry::hasPendingEvents()
-{
- return QEventDispatcherBlackberry::hasPendingEvents() || QWindowSystemInterface::windowSystemEventsQueued();
-}
-
-void QQnxEventDispatcherBlackberry::flush()
-{
- if (qApp)
- qApp->sendPostedEvents();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxeventdispatcher_blackberry.h b/src/plugins/platforms/qnx/qqnxeventdispatcher_blackberry.h
deleted file mode 100644
index 036bf126ab..0000000000
--- a/src/plugins/platforms/qnx/qqnxeventdispatcher_blackberry.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQNXEVENTDISPATCHER_BLACKBERRY_H
-#define QQNXEVENTDISPATCHER_BLACKBERRY_H
-
-#include <qglobal.h>
-#include <private/qeventdispatcher_blackberry_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQnxEventDispatcherBlackberry : public QEventDispatcherBlackberry
-{
- Q_OBJECT
-
-public:
- explicit QQnxEventDispatcherBlackberry(QObject *parent = 0);
- ~QQnxEventDispatcherBlackberry();
-
- bool processEvents(QEventLoop::ProcessEventsFlags flags);
- bool hasPendingEvents();
-
- void flush();
-};
-
-QT_END_NAMESPACE
-
-#endif // QQNXEVENTDISPATCHER_BLACKBERRY_H
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h b/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
deleted file mode 100644
index 76cceafcfe..0000000000
--- a/src/plugins/platforms/qnx/qqnxfiledialoghelper.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQNXFILEDIALOGHELPER_H
-#define QQNXFILEDIALOGHELPER_H
-
-#include <qpa/qplatformdialoghelper.h>
-
-
-QT_BEGIN_NAMESPACE
-
-class QQnxIntegration;
-
-class QQnxFilePicker;
-
-class QQnxFileDialogHelper : public QPlatformFileDialogHelper
-{
- Q_OBJECT
-public:
- explicit QQnxFileDialogHelper(const QQnxIntegration *);
- ~QQnxFileDialogHelper();
-
- void exec();
-
- bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent);
- void hide();
-
- bool defaultNameFilterDisables() const;
- void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
- QUrl directory() const Q_DECL_OVERRIDE;
- void selectFile(const QUrl &fileName) Q_DECL_OVERRIDE;
- QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
- void setFilter();
- void selectNameFilter(const QString &filter);
- QString selectedNameFilter() const;
-
- QQnxFilePicker *nativeDialog() const { return m_dialog; }
-
-Q_SIGNALS:
- void dialogClosed();
-
-private Q_SLOTS:
- void emitSignals();
-
-private:
- void setNameFilter(const QString &filter);
- void setNameFilters(const QStringList &filters);
-
- const QQnxIntegration *m_integration;
- QQnxFilePicker *m_dialog;
- QFileDialogOptions::AcceptMode m_acceptMode;
- QString m_selectedFilter;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQNXFILEDIALOGHELPER_H
diff --git a/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp b/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp
deleted file mode 100644
index 3bc84686e0..0000000000
--- a/src/plugins/platforms/qnx/qqnxfiledialoghelper_bb10.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2013 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqnxfiledialoghelper.h"
-
-#include "qqnxfilepicker.h"
-#include "qqnxbpseventfilter.h"
-#include "qqnxscreen.h"
-#include "qqnxintegration.h"
-
-#include <QDebug>
-#include <QEventLoop>
-#include <QScreen>
-#include <QTimer>
-#include <QWindow>
-
-#ifdef QQNXFILEDIALOGHELPER_DEBUG
-#define qFileDialogHelperDebug qDebug
-#else
-#define qFileDialogHelperDebug QT_NO_QDEBUG_MACRO
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QQnxFileDialogHelper::QQnxFileDialogHelper(const QQnxIntegration *integration)
- : QPlatformFileDialogHelper(),
- m_integration(integration),
- m_dialog(new QQnxFilePicker),
- m_acceptMode(QFileDialogOptions::AcceptOpen),
- m_selectedFilter()
-{
- connect(m_dialog, &QQnxFilePicker::closed, this, &QQnxFileDialogHelper::emitSignals);
-}
-
-QQnxFileDialogHelper::~QQnxFileDialogHelper()
-{
- delete m_dialog;
-}
-
-void QQnxFileDialogHelper::exec()
-{
- qFileDialogHelperDebug();
-
- // Clear any previous results
- m_dialog->setDirectories(QStringList());
-
- QEventLoop loop;
- connect(m_dialog, SIGNAL(closed()), &loop, SLOT(quit()));
- loop.exec();
-}
-
-bool QQnxFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
-{
- Q_UNUSED(flags);
- Q_UNUSED(parent);
- Q_UNUSED(modality);
-
- qFileDialogHelperDebug();
-
- // Create dialog
- const QSharedPointer<QFileDialogOptions> &opts = options();
- if (opts->acceptMode() == QFileDialogOptions::AcceptOpen) {
- // Select one or many files?
- const QQnxFilePicker::Mode mode = (opts->fileMode() == QFileDialogOptions::ExistingFiles)
- ? QQnxFilePicker::PickerMultiple : QQnxFilePicker::Picker;
-
- m_dialog->setMode(mode);
-
- // Set the actual list of extensions
- if (!opts->nameFilters().isEmpty())
- setNameFilters(opts->nameFilters());
- else
- setNameFilter(tr("All files (*.*)"));
- } else {
- const QQnxFilePicker::Mode mode = (opts->initiallySelectedFiles().count() >= 2)
- ? QQnxFilePicker::SaverMultiple : QQnxFilePicker::Saver;
-
- m_dialog->setMode(mode);
-
- if (!opts->initiallySelectedFiles().isEmpty()) {
- QStringList files;
- Q_FOREACH ( const QUrl &url, opts->initiallySelectedFiles() )
- files.append(url.toLocalFile());
- m_dialog->setDefaultSaveFileNames(files);
- }
- }
-
- // Cache the accept mode so we know which functions to use to get the results back
- m_acceptMode = opts->acceptMode();
- m_dialog->setTitle(opts->windowTitle());
- m_dialog->open();
-
- return true;
-}
-
-void QQnxFileDialogHelper::hide()
-{
- qFileDialogHelperDebug();
- m_dialog->close();
-}
-
-bool QQnxFileDialogHelper::defaultNameFilterDisables() const
-{
- qFileDialogHelperDebug();
- return false;
-}
-
-void QQnxFileDialogHelper::setDirectory(const QUrl &directory)
-{
- m_dialog->addDirectory(directory.toLocalFile());
-}
-
-QUrl QQnxFileDialogHelper::directory() const
-{
- qFileDialogHelperDebug();
- if (!m_dialog->directories().isEmpty())
- return QUrl::fromLocalFile(m_dialog->directories().first());
-
- return QUrl();
-}
-
-void QQnxFileDialogHelper::selectFile(const QUrl &fileName)
-{
- m_dialog->addDefaultSaveFileName(fileName.toLocalFile());
-}
-
-QList<QUrl> QQnxFileDialogHelper::selectedFiles() const
-{
- qFileDialogHelperDebug();
- QList<QUrl> urls;
- QStringList files = m_dialog->selectedFiles();
- Q_FOREACH (const QString &file, files)
- urls.append(QUrl::fromLocalFile(file));
- return urls;
-}
-
-void QQnxFileDialogHelper::setFilter()
-{
- // No native api to support setting a filter from QDir::Filters
- qFileDialogHelperDebug();
-}
-
-void QQnxFileDialogHelper::selectNameFilter(const QString &filter)
-{
- qFileDialogHelperDebug() << "filter =" << filter;
- setNameFilter(filter);
-}
-
-QString QQnxFileDialogHelper::selectedNameFilter() const
-{
- // For now there is no way for the user to change the selected filter
- // so this just reflects what the developer has set programmatically.
- qFileDialogHelperDebug();
- return m_selectedFilter;
-}
-
-void QQnxFileDialogHelper::emitSignals()
-{
- if (m_dialog->selectedFiles().isEmpty())
- Q_EMIT reject();
- else
- Q_EMIT accept();
-}
-
-void QQnxFileDialogHelper::setNameFilter(const QString &filter)
-{
- qFileDialogHelperDebug() << "filter =" << filter;
-
- setNameFilters(QPlatformFileDialogHelper::cleanFilterList(filter));
-}
-
-void QQnxFileDialogHelper::setNameFilters(const QStringList &filters)
-{
- qFileDialogHelperDebug() << "filters =" << filters;
-
- Q_ASSERT(!filters.isEmpty());
-
- m_dialog->setFilters(filters);
- m_selectedFilter = filters.first();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.cpp b/src/plugins/platforms/qnx/qqnxfilepicker.cpp
deleted file mode 100644
index ca8d731e66..0000000000
--- a/src/plugins/platforms/qnx/qqnxfilepicker.cpp
+++ /dev/null
@@ -1,322 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2013 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqnxfilepicker.h"
-
-#include <QAbstractEventDispatcher>
-#include <QCoreApplication>
-#include <QDebug>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QJsonParseError>
-#include <QMimeDatabase>
-#include <QUrl>
-#include <private/qppsobject_p.h>
-
-#include <bps/navigator.h>
-#include <bps/navigator_invoke.h>
-
-#include <errno.h>
-
-#ifdef QQNXFILEPICKER_DEBUG
-#define qFilePickerDebug qDebug
-#else
-#define qFilePickerDebug QT_NO_QDEBUG_MACRO
-#endif
-
-QT_BEGIN_NAMESPACE
-
-static const char s_filePickerTarget[] = "sys.filepicker.target";
-
-QQnxFilePicker::QQnxFilePicker(QObject *parent)
- : QObject(parent)
- , m_invocationHandle(0)
- , m_mode(QQnxFilePicker::Picker)
- , m_title(tr("Pick a file"))
-{
- QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
-}
-
-QQnxFilePicker::~QQnxFilePicker()
-{
- cleanup();
-
- QCoreApplication::eventDispatcher()->removeNativeEventFilter(this);
-}
-
-void QQnxFilePicker::open()
-{
- if (m_invocationHandle)
- return;
-
- // Clear any previous results
- m_selectedFiles.clear();
-
- int errorCode = BPS_SUCCESS;
-
- errorCode = navigator_invoke_invocation_create(&m_invocationHandle);
- if (errorCode != BPS_SUCCESS) {
- qWarning() << "QQnxFilePicker: unable to create invocation:" << strerror(errno);
- return;
- }
-
- errorCode = navigator_invoke_invocation_set_target(m_invocationHandle, s_filePickerTarget);
-
- if (errorCode != BPS_SUCCESS) {
- cleanup();
- qWarning() << "QQnxFilePicker: unable to set target:" << strerror(errno);
- return;
- }
-
- errorCode = navigator_invoke_invocation_set_action(m_invocationHandle, "bb.action.OPEN");
- if (errorCode != BPS_SUCCESS) {
- cleanup();
- qWarning() << "QQnxFilePicker: unable to set action:" << strerror(errno);
- return;
- }
-
- errorCode = navigator_invoke_invocation_set_type(m_invocationHandle, "application/vnd.blackberry.file_picker");
- if (errorCode != BPS_SUCCESS) {
- cleanup();
- qWarning() << "QQnxFilePicker: unable to set mime type:" << strerror(errno);
- return;
- }
-
- QVariantMap map;
- map[QStringLiteral("Type")] = filePickerType();
- map[QStringLiteral("Mode")] = modeToString(m_mode);
- map[QStringLiteral("Title")] = m_title;
- map[QStringLiteral("ViewMode")] = QStringLiteral("Default");
- map[QStringLiteral("SortBy")] = QStringLiteral("Default");
- map[QStringLiteral("SortOrder")] = QStringLiteral("Default");
- map[QStringLiteral("ImageCrop")] = false;
- map[QStringLiteral("AllowOverwrite")] = false;
-
- if (!m_defaultSaveFileNames.isEmpty())
- map[QStringLiteral("DefaultFileNames")] = m_defaultSaveFileNames.join(QLatin1Char(','));
- if (!m_filters.isEmpty())
- map[QStringLiteral("Filter")] = m_filters.join(QLatin1Char(';'));
-
- QByteArray ppsData;
- ppsData = QPpsObject::encode(map);
-
- errorCode = navigator_invoke_invocation_set_data(m_invocationHandle, ppsData.constData(), ppsData.size());
- if (errorCode != BPS_SUCCESS) {
- cleanup();
- qWarning() << "QQnxFilePicker: unable to set data:" << strerror(errno);
- return;
- }
-
- navigator_invoke_invocation_send(m_invocationHandle);
-}
-
-void QQnxFilePicker::close()
-{
- navigator_card_close_child();
- cleanup();
-}
-
-bool QQnxFilePicker::nativeEventFilter(const QByteArray&, void *message, long*)
-{
- bps_event_t * const event = static_cast<bps_event_t*>(message);
- if (!event)
- return false;
-
- if (bps_event_get_code(event) == NAVIGATOR_INVOKE_TARGET_RESULT) {
- const char *id = navigator_event_get_id(event);
- const char *err = navigator_event_get_err(event);
- qFilePickerDebug("received invocation response: id=%s err=%s", id, err);
- } else if (bps_event_get_code(event) == NAVIGATOR_CHILD_CARD_CLOSED) {
- const char *data = navigator_event_get_card_closed_data(event);
- qFilePickerDebug("received data: data='%s'", data);
- handleFilePickerResponse(data);
- }
-
- return false; // do not drop the event
-}
-
-void QQnxFilePicker::setMode(QQnxFilePicker::Mode mode)
-{
- m_mode = mode;
-}
-
-void QQnxFilePicker::setDefaultSaveFileNames(const QStringList &fileNames)
-{
- m_defaultSaveFileNames = fileNames;
-}
-
-void QQnxFilePicker::addDefaultSaveFileName(const QString &fileName)
-{
- m_defaultSaveFileNames.append(fileName);
-}
-
-void QQnxFilePicker::setDirectories(const QStringList &directories)
-{
- m_directories = directories;
-}
-
-void QQnxFilePicker::addDirectory(const QString &directory)
-{
- m_directories.append(directory);
-}
-
-void QQnxFilePicker::setFilters(const QStringList &filters)
-{
- m_filters = filters;
-}
-
-void QQnxFilePicker::setTitle(const QString &title)
-{
- m_title = title;
-}
-
-QQnxFilePicker::Mode QQnxFilePicker::mode() const
-{
- return m_mode;
-}
-
-QStringList QQnxFilePicker::defaultSaveFileNames() const
-{
- return m_defaultSaveFileNames;
-}
-
-QStringList QQnxFilePicker::directories() const
-{
- return m_directories;
-}
-
-QStringList QQnxFilePicker::filters() const
-{
- return m_filters;
-}
-
-QStringList QQnxFilePicker::selectedFiles() const
-{
- return m_selectedFiles;
-}
-
-QString QQnxFilePicker::title() const
-{
- return m_title;
-}
-
-void QQnxFilePicker::cleanup()
-{
- if (m_invocationHandle) {
- navigator_invoke_invocation_destroy(m_invocationHandle);
- m_invocationHandle = 0;
- }
-}
-
-void QQnxFilePicker::handleFilePickerResponse(const char *data)
-{
- QJsonParseError jsonError;
- QJsonDocument document = QJsonDocument::fromJson(data, &jsonError);
-
- if (jsonError.error != QJsonParseError::NoError) {
- qFilePickerDebug() << "Error parsing FilePicker response: "
- << jsonError.errorString();
- Q_EMIT closed();
- cleanup();
- return;
- }
-
- // The response is a list of Json objects.
- const QVariantList array = document.array().toVariantList();
-
- foreach (const QVariant &variant, array) {
- const QJsonObject object = QJsonObject::fromVariantMap(variant.toMap());
- const QUrl url(object.value(QStringLiteral("uri")).toString());
- const QString localFile = url.toLocalFile(); // strip "file://"
-
- if (!localFile.isEmpty())
- m_selectedFiles << localFile;
-
- qFilePickerDebug() << "FilePicker uri response:" << localFile;
- }
-
- Q_EMIT closed();
- cleanup();
-}
-
-QString QQnxFilePicker::filePickerType() const
-{
- bool images = false;
- bool video = false;
- bool music = false;
- QMimeDatabase mimeDb;
- for (int i = 0; i < m_filters.count(); i++) {
- QList<QMimeType> mimeTypes = mimeDb.mimeTypesForFileName(m_filters.at(i));
- if (mimeTypes.isEmpty())
- return QStringLiteral("Other");
-
- if (mimeTypes.first().name().startsWith(QLatin1String("image")))
- images = true;
- else if (mimeTypes.first().name().startsWith(QLatin1String("audio")))
- music = true;
- else if (mimeTypes.first().name().startsWith(QLatin1String("video")))
- video = true;
- else
- return QStringLiteral("Other");
- }
-
- if (!video && !music)
- return QStringLiteral("Picture");
-
- if (!images && !music)
- return QStringLiteral("Video");
-
- if (!images && !video)
- return QStringLiteral("Music");
-
- return QStringLiteral("Other");
-}
-
-QString QQnxFilePicker::modeToString(QQnxFilePicker::Mode mode) const
-{
- switch (mode) {
- case Picker:
- return QStringLiteral("Picker");
- case Saver:
- return QStringLiteral("Saver");
- case PickerMultiple:
- return QStringLiteral("PickerMultiple");
- case SaverMultiple:
- return QStringLiteral("SaverMultiple");
- }
-
- return QStringLiteral("Picker");
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.h b/src/plugins/platforms/qnx/qqnxfilepicker.h
deleted file mode 100644
index 7e4f9010cc..0000000000
--- a/src/plugins/platforms/qnx/qqnxfilepicker.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2013 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQNXFILEPICKER_H
-#define QQNXFILEPICKER_H
-
-#include <QAbstractNativeEventFilter>
-#include <QObject>
-#include <QStringList>
-
-QT_BEGIN_NAMESPACE
-
-struct navigator_invoke_invocation_t;
-
-class QQnxFilePicker : public QObject, public QAbstractNativeEventFilter
-{
- Q_OBJECT
-
-public:
- explicit QQnxFilePicker(QObject *parent = 0);
- ~QQnxFilePicker();
-
- enum Mode {
- Picker,
- Saver,
- PickerMultiple,
- SaverMultiple
- };
-
- bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
-
- void setMode(Mode mode);
- void setDefaultSaveFileNames(const QStringList &fileNames);
- void addDefaultSaveFileName(const QString &fileName);
- void setDirectories(const QStringList &directories);
- void addDirectory(const QString &directory);
- void setFilters(const QStringList &filters);
- void setTitle(const QString &title);
-
- Mode mode() const;
-
- QStringList defaultSaveFileNames() const;
- QStringList directories() const;
- QStringList filters() const;
- QStringList selectedFiles() const;
-
- QString title() const;
-
-Q_SIGNALS:
- void closed();
-
-public Q_SLOTS:
- void open();
- void close();
-
-private:
- void cleanup();
- void handleFilePickerResponse(const char *data);
- QString filePickerType() const;
-
- QString modeToString(Mode mode) const;
-
- navigator_invoke_invocation_t *m_invocationHandle;
-
- Mode m_mode;
-
- QStringList m_defaultSaveFileNames;
- QStringList m_directories;
- QStringList m_filters;
- QStringList m_selectedFiles;
-
- QString m_title;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQNXFILEPICKER_H
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index 5ef8d72926..20930af524 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -61,7 +61,7 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
// Set current rendering API
EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (eglResult != EGL_TRUE)
+ if (Q_UNLIKELY(eglResult != EGL_TRUE))
qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
// Get colour channel sizes from window format
@@ -113,7 +113,7 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
// Select EGL config based on requested window format
m_eglConfig = q_configFromGLFormat(ms_eglDisplay, format);
- if (m_eglConfig == 0)
+ if (Q_UNLIKELY(m_eglConfig == 0))
qFatal("QQnxGLContext: failed to find EGL config");
QQnxGLContext *glShareContext = static_cast<QQnxGLContext*>(m_glContext->shareHandle());
@@ -121,7 +121,7 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, m_eglShareContext,
contextAttrs(format));
- if (m_eglContext == EGL_NO_CONTEXT) {
+ if (Q_UNLIKELY(m_eglContext == EGL_NO_CONTEXT)) {
checkEGLError("eglCreateContext");
qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError());
}
@@ -170,13 +170,13 @@ void QQnxGLContext::initializeContext()
// Initialize connection to EGL
ms_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (ms_eglDisplay == EGL_NO_DISPLAY) {
+ if (Q_UNLIKELY(ms_eglDisplay == EGL_NO_DISPLAY)) {
checkEGLError("eglGetDisplay");
qFatal("QQnxGLContext: failed to obtain EGL display");
}
EGLBoolean eglResult = eglInitialize(ms_eglDisplay, 0, 0);
- if (eglResult != EGL_TRUE) {
+ if (Q_UNLIKELY(eglResult != EGL_TRUE)) {
checkEGLError("eglInitialize");
qFatal("QQnxGLContext: failed to initialize EGL display, err=%d", eglGetError());
}
@@ -198,7 +198,7 @@ bool QQnxGLContext::makeCurrent(QPlatformSurface *surface)
// Set current rendering API
EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (eglResult != EGL_TRUE)
+ if (Q_UNLIKELY(eglResult != EGL_TRUE))
qFatal("QQnxGLContext: failed to set EGL API, err=%d", eglGetError());
QQnxEglWindow *platformWindow = dynamic_cast<QQnxEglWindow*>(surface);
@@ -227,12 +227,12 @@ void QQnxGLContext::doneCurrent()
// set current rendering API
EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (eglResult != EGL_TRUE)
+ if (Q_UNLIKELY(eglResult != EGL_TRUE))
qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
// clear curent EGL context and unbind EGL surface
eglResult = eglMakeCurrent(ms_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (eglResult != EGL_TRUE)
+ if (Q_UNLIKELY(eglResult != EGL_TRUE))
qFatal("QQNX: failed to clear current EGL context, err=%d", eglGetError());
}
@@ -252,7 +252,7 @@ QFunctionPointer QQnxGLContext::getProcAddress(const QByteArray &procName)
// Set current rendering API
EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (eglResult != EGL_TRUE)
+ if (Q_UNLIKELY(eglResult != EGL_TRUE))
qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
// Lookup EGL extension function pointer
diff --git a/src/plugins/platforms/qnx/qqnxglobal.cpp b/src/plugins/platforms/qnx/qqnxglobal.cpp
index 01e7675839..4d2599746e 100644
--- a/src/plugins/platforms/qnx/qqnxglobal.cpp
+++ b/src/plugins/platforms/qnx/qqnxglobal.cpp
@@ -44,8 +44,8 @@ void qScreenCheckError(int rc, const char *funcInfo, const char *message, bool c
rc = screen_flush_context(QQnxIntegration::screenContext(), 0);
}
- if (rc) {
- if (critical)
+ if (Q_UNLIKELY(rc)) {
+ if (Q_UNLIKELY(critical))
qCritical("%s - Screen: %s - Error: %s (%i)", funcInfo, message, strerror(errno), errno);
else
qWarning("%s - Screen: %s - Error: %s (%i)", funcInfo, message, strerror(errno), errno);
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
index 3af481b991..5aa8b9bfee 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
@@ -530,29 +530,28 @@ static bool imfAvailable()
if ( p_imf_client_init == 0 ) {
void *handle = dlopen("libinput_client.so.1", 0);
- if ( handle ) {
- p_imf_client_init = (int32_t (*)()) dlsym(handle, "imf_client_init");
- p_imf_client_disconnect = (void (*)()) dlsym(handle, "imf_client_disconnect");
- p_ictrl_open_session = (const input_session_t *(*)(connection_interface_t *))dlsym(handle, "ictrl_open_session");
- p_ictrl_close_session = (void (*)(input_session_t *))dlsym(handle, "ictrl_close_session");
- p_ictrl_dispatch_event = (int32_t (*)(event_t *))dlsym(handle, "ictrl_dispatch_event");
- p_vkb_init_selection_service = (int32_t (*)())dlsym(handle, "vkb_init_selection_service");
- p_ictrl_get_num_active_sessions = (int32_t (*)())dlsym(handle, "ictrl_get_num_active_sessions");
- } else {
+ if (Q_UNLIKELY(!handle)) {
qCritical("libinput_client.so.1 is not present - IMF services are disabled.");
s_imfDisabled = true;
return false;
}
-
- if ( p_imf_client_init && p_ictrl_open_session && p_ictrl_dispatch_event ) {
- s_imfReady = true;
- } else {
+ p_imf_client_init = (int32_t (*)()) dlsym(handle, "imf_client_init");
+ p_imf_client_disconnect = (void (*)()) dlsym(handle, "imf_client_disconnect");
+ p_ictrl_open_session = (const input_session_t *(*)(connection_interface_t *))dlsym(handle, "ictrl_open_session");
+ p_ictrl_close_session = (void (*)(input_session_t *))dlsym(handle, "ictrl_close_session");
+ p_ictrl_dispatch_event = (int32_t (*)(event_t *))dlsym(handle, "ictrl_dispatch_event");
+ p_vkb_init_selection_service = (int32_t (*)())dlsym(handle, "vkb_init_selection_service");
+ p_ictrl_get_num_active_sessions = (int32_t (*)())dlsym(handle, "ictrl_get_num_active_sessions");
+
+ if (Q_UNLIKELY(!p_imf_client_init || !p_ictrl_open_session || !p_ictrl_dispatch_event)) {
p_ictrl_open_session = 0;
p_ictrl_dispatch_event = 0;
s_imfDisabled = true;
qCritical("libinput_client.so.1 did not contain the correct symbols, library mismatch? IMF services are disabled.");
return false;
}
+
+ s_imfReady = true;
}
return s_imfReady;
@@ -581,7 +580,7 @@ QQnxInputContext::QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVir
Q_ASSERT(sInputContextInstance == 0);
sInputContextInstance = this;
- if (p_imf_client_init() != 0) {
+ if (Q_UNLIKELY(p_imf_client_init() != 0)) {
s_imfInitFailed = true;
qCritical("imf_client_init failed - IMF services will be unavailable");
}
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 6548c82310..0616ac626f 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -52,12 +52,7 @@
#include "qqnxeglwindow.h"
#endif
-#if defined(Q_OS_BLACKBERRY)
-#include "qqnxbpseventfilter.h"
-#include "qqnxnavigatorbps.h"
-#include "qblackberrytheme.h"
-#include "qqnxvirtualkeyboardbps.h"
-#elif defined(QQNX_PPS)
+#if defined(QQNX_PPS)
#include "qqnxnavigatorpps.h"
#include "qqnxnavigatoreventnotifier.h"
#include "qqnxvirtualkeyboardpps.h"
@@ -75,12 +70,7 @@
#endif
#include "private/qgenericunixfontdatabase_p.h"
-
-#if defined(Q_OS_BLACKBERRY)
-#include "qqnxeventdispatcher_blackberry.h"
-#else
#include "private/qgenericunixeventdispatcher_p.h"
-#endif
#include <qpa/qplatformwindow.h>
#include <qpa/qwindowsysteminterface.h>
@@ -120,16 +110,10 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
options |= QQnxIntegration::AlwaysFlushScreenContext;
}
-// On Blackberry the first window is treated as a root window
-#ifdef Q_OS_BLACKBERRY
- if (!paramList.contains(QLatin1String("no-rootwindow"))) {
- options |= QQnxIntegration::RootWindow;
- }
-#else
if (paramList.contains(QLatin1String("rootwindow"))) {
options |= QQnxIntegration::RootWindow;
}
-#endif
+
return options;
}
@@ -147,12 +131,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
#endif
, m_services(0)
, m_fontDatabase(new QGenericUnixFontDatabase())
-#if defined(Q_OS_BLACKBERRY)
- , m_eventDispatcher(new QQnxEventDispatcherBlackberry())
- , m_bpsEventFilter(0)
-#else
, m_eventDispatcher(createUnixEventDispatcher())
-#endif
, m_nativeInterface(new QQnxNativeInterface(this))
, m_screenEventHandler(new QQnxScreenEventHandler(this))
#if !defined(QT_NO_CLIPBOARD)
@@ -169,8 +148,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
Q_SCREEN_CRITICALERROR(screen_create_context(&ms_screenContext, SCREEN_APPLICATION_CONTEXT),
"Failed to create screen context");
- // Not on BlackBerry, it has specialized event dispatcher which also handles navigator events
-#if !defined(Q_OS_BLACKBERRY) && defined(QQNX_PPS)
+#if defined(QQNX_PPS)
// Create/start navigator event notifier
m_navigatorEventNotifier = new QQnxNavigatorEventNotifier(m_navigatorEventHandler);
@@ -190,8 +168,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
m_screenEventThread->start();
#endif
- // Not on BlackBerry, it has specialized event dispatcher which also handles virtual keyboard events
-#if !defined(Q_OS_BLACKBERRY) && defined(QQNX_PPS)
+#if defined(QQNX_PPS)
// Create/start the keyboard class.
m_virtualKeyboard = new QQnxVirtualKeyboardPps();
@@ -200,9 +177,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection);
#endif
-#if defined(Q_OS_BLACKBERRY)
- m_navigator = new QQnxNavigatorBps();
-#elif defined(QQNX_PPS)
+#if defined(QQNX_PPS)
m_navigator = new QQnxNavigatorPps();
#endif
@@ -210,34 +185,8 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
if (m_navigator)
m_services = new QQnxServices(m_navigator);
-#if defined(Q_OS_BLACKBERRY)
- QQnxVirtualKeyboardBps* virtualKeyboardBps = new QQnxVirtualKeyboardBps;
-
-#if defined(QQNX_SCREENEVENTTHREAD)
- m_bpsEventFilter = new QQnxBpsEventFilter(m_navigatorEventHandler, 0, virtualKeyboardBps);
-#else
- m_bpsEventFilter = new QQnxBpsEventFilter(m_navigatorEventHandler, m_screenEventHandler, virtualKeyboardBps);
-#endif
-
- m_bpsEventFilter->installOnEventDispatcher(m_eventDispatcher);
-
- m_virtualKeyboard = virtualKeyboardBps;
-#endif
-
- // Create displays for all possible screens (which may not be attached). We have to do this
- // *after* the call to m_bpsEventFilter->installOnEventDispatcher(m_eventDispatcher). The
- // reason for this is that we have to be registered for NAVIGATOR events before we create the
- // QQnxScreen objects, and hence the QQnxRootWindow's. It is when the NAVIGATOR service sees
- // the window creation that it starts sending us messages which results in a race if we
- // create the displays first.
createDisplays();
-#if !defined(QQNX_SCREENEVENTTHREAD) && defined(Q_OS_BLACKBERRY)
- // Register for screen domain events with bps
- Q_FOREACH (QQnxScreen *screen, m_screens)
- m_bpsEventFilter->registerForScreenEvents(screen);
-#endif
-
if (m_virtualKeyboard) {
// TODO check if we need to do this for all screens or only the primary one
QObject::connect(m_virtualKeyboard, SIGNAL(heightChanged(int)),
@@ -275,7 +224,7 @@ QQnxIntegration::~QQnxIntegration()
#endif
// Stop/destroy navigator event notifier
-#if !defined(Q_OS_BLACKBERRY) && defined(QQNX_PPS)
+#if defined(QQNX_PPS)
delete m_navigatorEventNotifier;
#endif
delete m_navigatorEventHandler;
@@ -283,13 +232,6 @@ QQnxIntegration::~QQnxIntegration()
#if defined(QQNX_SCREENEVENTTHREAD)
// Stop/destroy screen event thread
delete m_screenEventThread;
-#elif defined(Q_OS_BLACKBERRY)
- Q_FOREACH (QQnxScreen *screen, m_screens)
- m_bpsEventFilter->unregisterForScreenEvents(screen);
-#endif
-
-#if defined(Q_OS_BLACKBERRY)
- delete m_bpsEventFilter;
#endif
// In case the event-dispatcher was never transferred to QCoreApplication
@@ -450,21 +392,6 @@ QPlatformServices * QQnxIntegration::services() const
return m_services;
}
-#if defined(Q_OS_BLACKBERRY)
-QStringList QQnxIntegration::themeNames() const
-{
- return QStringList(QBlackberryTheme::name());
-}
-
-QPlatformTheme *QQnxIntegration::createPlatformTheme(const QString &name) const
-{
- qIntegrationDebug() << "name =" << name;
- if (name == QBlackberryTheme::name())
- return new QBlackberryTheme(this);
- return 0;
-}
-#endif
-
QWindow *QQnxIntegration::window(screen_window_t qnxWindow)
{
qIntegrationDebug();
@@ -498,7 +425,7 @@ void QQnxIntegration::createDisplays()
&displayCount);
Q_SCREEN_CRITICALERROR(result, "Failed to query display count");
- if (displayCount < 1) {
+ if (Q_UNLIKELY(displayCount < 1)) {
// Never happens, even if there's no display, libscreen returns 1
qFatal("QQnxIntegration: displayCount=%d", displayCount);
}
@@ -601,7 +528,7 @@ QQnxIntegration::Options QQnxIntegration::ms_options = 0;
bool QQnxIntegration::supportsNavigatorEvents() const
{
- // If QQNX_PPS or Q_OS_BLACKBERRY is defined then we have navigator
+ // If QQNX_PPS is defined then we have navigator
return m_navigator != 0;
}
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index 04250cdba0..3a4a1380ab 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -42,7 +42,6 @@
QT_BEGIN_NAMESPACE
-class QQnxBpsEventFilter;
#if defined(QQNX_SCREENEVENTTHREAD)
class QQnxScreenEventThread;
#endif
@@ -117,12 +116,6 @@ public:
QPlatformServices *services() const;
-#if defined(Q_OS_BLACKBERRY)
- QStringList themeNames() const;
- QPlatformTheme *createPlatformTheme(const QString &name) const;
- QQnxBpsEventFilter *bpsEventFilter() const { return m_bpsEventFilter; }
-#endif
-
static QWindow *window(screen_window_t qnxWindow);
QQnxScreen *screenForNative(screen_display_t qnxScreen) const;
@@ -156,9 +149,6 @@ private:
QQnxServices *m_services;
QPlatformFontDatabase *m_fontDatabase;
mutable QAbstractEventDispatcher *m_eventDispatcher;
-#if defined(Q_OS_BLACKBERRY)
- QQnxBpsEventFilter *m_bpsEventFilter;
-#endif
QQnxNativeInterface *m_nativeInterface;
QList<QQnxScreen*> m_screens;
QQnxScreenEventHandler *m_screenEventHandler;
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
index 549e0209bf..8c22f7cea0 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
@@ -85,11 +85,6 @@ void *QQnxNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q
void *QQnxNativeInterface::nativeResourceForIntegration(const QByteArray &resource)
{
-#ifdef Q_OS_BLACKBERRY
- if (resource == "navigatorEventHandler")
- return m_integration->navigatorEventHandler();
-#endif
-
return 0;
}
diff --git a/src/plugins/platforms/qnx/qqnxnavigatorbps.cpp b/src/plugins/platforms/qnx/qqnxnavigatorbps.cpp
deleted file mode 100644
index 0d730d6f57..0000000000
--- a/src/plugins/platforms/qnx/qqnxnavigatorbps.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqnxnavigatorbps.h"
-
-#include <QDebug>
-
-#include <bps/navigator.h>
-
-QT_BEGIN_NAMESPACE
-
-QQnxNavigatorBps::QQnxNavigatorBps(QObject *parent)
- : QQnxAbstractNavigator(parent)
-{
- bps_initialize();
-}
-
-QQnxNavigatorBps::~QQnxNavigatorBps()
-{
- bps_shutdown();
-}
-
-bool QQnxNavigatorBps::requestInvokeUrl(const QByteArray &encodedUrl)
-{
- char *error = 0;
-
- int ret = navigator_invoke(encodedUrl, &error);
- if (error) {
- qWarning() << "error=" << error;
- bps_free(error);
- }
-
- return (ret == BPS_SUCCESS);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxnavigatorbps.h b/src/plugins/platforms/qnx/qqnxnavigatorbps.h
deleted file mode 100644
index b006695de6..0000000000
--- a/src/plugins/platforms/qnx/qqnxnavigatorbps.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQNXNAVIGATORBPS_H
-#define QQNXNAVIGATORBPS_H
-
-#include "qqnxabstractnavigator.h"
-
-QT_BEGIN_NAMESPACE
-
-class QQnxNavigatorBps : public QQnxAbstractNavigator
-{
- Q_OBJECT
-public:
- explicit QQnxNavigatorBps(QObject *parent = 0);
- ~QQnxNavigatorBps();
-
-protected:
- bool requestInvokeUrl(const QByteArray &encodedUrl);
-};
-
-QT_END_NAMESPACE
-
-#endif // QQNXNAVIGATORBPS_H
diff --git a/src/plugins/platforms/qnx/qqnxnavigatorcover.cpp b/src/plugins/platforms/qnx/qqnxnavigatorcover.cpp
deleted file mode 100644
index 6d30677b30..0000000000
--- a/src/plugins/platforms/qnx/qqnxnavigatorcover.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqnxnavigatorcover.h"
-
-QQnxNavigatorCover::QQnxNavigatorCover()
-{
- navigator_window_cover_attribute_create(&m_coverAttribute);
-}
-
-QQnxNavigatorCover::~QQnxNavigatorCover()
-{
- if (m_coverAttribute)
- navigator_window_cover_attribute_destroy(m_coverAttribute);
-
- navigator_window_cover_reset();
-}
-
-void QQnxNavigatorCover::updateCover()
-{
- if (m_coverAttribute) {
- navigator_window_cover_attribute_set_transition(m_coverAttribute,
- NAVIGATOR_WINDOW_COVER_TRANSITION_NONE);
- navigator_window_cover_attribute_set_alternate_window(m_coverAttribute);
- navigator_window_cover_update(m_coverAttribute);
- }
-}
diff --git a/src/plugins/platforms/qnx/qqnxnavigatorcover.h b/src/plugins/platforms/qnx/qqnxnavigatorcover.h
deleted file mode 100644
index 5e9ed9f7bd..0000000000
--- a/src/plugins/platforms/qnx/qqnxnavigatorcover.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQNXNAVIGATORCOVER_H
-#define QQNXNAVIGATORCOVER_H
-
-#include "qqnxabstractcover.h"
-#include <bps/navigator.h>
-
-class QQnxNavigatorCover : public QQnxAbstractCover
-{
-public:
- QQnxNavigatorCover();
- ~QQnxNavigatorCover();
-
- void updateCover();
-
-private:
- navigator_window_cover_attribute_t *m_coverAttribute;
-};
-
-#endif // QQNXNAVIGATORCOVER_H
diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp b/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp
index 6199eb8e11..8098c9970e 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp
+++ b/src/plugins/platforms/qnx/qqnxnavigatoreventnotifier.cpp
@@ -102,7 +102,7 @@ void QQnxNavigatorEventNotifier::parsePPS(const QByteArray &ppsData, QByteArray
QList<QByteArray> lines = ppsData.split('\n');
// validate pps object
- if (lines.size() == 0 || lines.at(0) != "@control")
+ if (Q_UNLIKELY(lines.empty() || lines.at(0) != "@control"))
qFatal("QQNX: unrecognized pps object, data=%s", ppsData.constData());
// parse pps object attributes and extract values
@@ -160,7 +160,7 @@ void QQnxNavigatorEventNotifier::replyPPS(const QByteArray &res, const QByteArra
// send pps message to navigator
errno = 0;
int bytes = write(m_fd, ppsData.constData(), ppsData.size());
- if (bytes == -1)
+ if (Q_UNLIKELY(bytes == -1))
qFatal("QQNX: failed to write navigator pps, errno=%d", errno);
}
@@ -198,7 +198,7 @@ void QQnxNavigatorEventNotifier::readData()
// attempt to read pps data
errno = 0;
int bytes = qt_safe_read(m_fd, buffer, ppsBufferSize - 1);
- if (bytes == -1)
+ if (Q_UNLIKELY(bytes == -1))
qFatal("QQNX: failed to read navigator pps, errno=%d", errno);
// check if pps data was received
diff --git a/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp b/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp
index b139471669..ca8e2bd3ab 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp
+++ b/src/plugins/platforms/qnx/qqnxnavigatorpps.cpp
@@ -100,7 +100,7 @@ bool QQnxNavigatorPps::sendPpsMessage(const QByteArray &message, const QByteArra
// send pps message to navigator
errno = 0;
int bytes = qt_safe_write(m_fd, ppsMessage.constData(), ppsMessage.size());
- if (bytes == -1)
+ if (Q_UNLIKELY(bytes == -1))
qFatal("QQNX: failed to write navigator pps, errno=%d", errno);
// allocate buffer for pps data
@@ -110,7 +110,7 @@ bool QQnxNavigatorPps::sendPpsMessage(const QByteArray &message, const QByteArra
do {
errno = 0;
bytes = qt_safe_read(m_fd, buffer, ppsBufferSize - 1);
- if (bytes == -1)
+ if (Q_UNLIKELY(bytes == -1))
qFatal("QQNX: failed to read navigator pps, errno=%d", errno);
} while (bytes == 0);
@@ -125,7 +125,7 @@ bool QQnxNavigatorPps::sendPpsMessage(const QByteArray &message, const QByteArra
parsePPS(ppsData, responseFields);
if (responseFields.contains("res") && responseFields.value("res") == message) {
- if (responseFields.contains("err")) {
+ if (Q_UNLIKELY(responseFields.contains("err"))) {
qCritical() << "navigator responded with error: " << responseFields.value("err");
return false;
}
@@ -142,7 +142,7 @@ void QQnxNavigatorPps::parsePPS(const QByteArray &ppsData, QHash<QByteArray, QBy
QList<QByteArray> lines = ppsData.split('\n');
// validate pps object
- if (lines.size() == 0 || lines.at(0) != "@control")
+ if (Q_UNLIKELY(lines.empty() || lines.at(0) != "@control"))
qFatal("QQNX: unrecognized pps object, data=%s", ppsData.constData());
// parse pps object attributes and extract values
diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
index 933fce0e33..771986d763 100644
--- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
@@ -61,7 +61,7 @@ QQnxRasterWindow::QQnxRasterWindow(QWindow *window, screen_context_t context, bo
const int val = SCREEN_USAGE_NATIVE | SCREEN_USAGE_READ | SCREEN_USAGE_WRITE;
const int result = screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_USAGE, &val);
- if (result != 0)
+ if (Q_UNLIKELY(result != 0))
qFatal("QQnxRasterWindow: failed to set window alpha usage, errno=%d", errno);
}
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index c4125ef177..7eaf50318c 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -584,10 +584,6 @@ void QQnxScreen::addWindow(QQnxWindow *window)
else
m_childWindows.push_back(window);
updateHierarchy();
- } else {
-#if defined(Q_OS_BLACKBERRY)
- m_coverWindow = window;
-#endif
}
}
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index 6c9532c428..781c6f28af 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -254,13 +254,8 @@ void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event)
"Failed to query event cap");
int sequenceId = 0;
-#if defined(Q_OS_BLACKBERRY)
- Q_SCREEN_CHECKERROR(
- screen_get_event_property_iv(event, SCREEN_PROPERTY_SEQUENCE_ID, &sequenceId),
- "Failed to query event seqId");
-#endif
-
bool inject = true;
+
Q_FOREACH (QQnxScreenEventFilter *filter, m_eventFilters) {
if (filter->handleKeyboardEvent(flags, sym, modifiers, scan, cap, sequenceId)) {
inject = false;
@@ -584,12 +579,12 @@ void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event)
errno = 0;
screen_window_t window = 0;
- if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0)
+ if (Q_UNLIKELY(screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0))
qFatal("QQnx: failed to query window property, errno=%d", errno);
errno = 0;
int property;
- if (screen_get_event_property_iv(event, SCREEN_PROPERTY_NAME, &property) != 0)
+ if (Q_UNLIKELY(screen_get_event_property_iv(event, SCREEN_PROPERTY_NAME, &property) != 0))
qFatal("QQnx: failed to query window property, errno=%d", errno);
switch (property) {
@@ -606,7 +601,7 @@ void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t wi
{
errno = 0;
int focus = 0;
- if (window && screen_get_window_property_iv(window, SCREEN_PROPERTY_KEYBOARD_FOCUS, &focus) != 0)
+ if (Q_UNLIKELY(window && screen_get_window_property_iv(window, SCREEN_PROPERTY_KEYBOARD_FOCUS, &focus) != 0))
qFatal("QQnx: failed to query keyboard focus property, errno=%d", errno);
QWindow *focusWindow = QQnxIntegration::window(window);
diff --git a/src/plugins/platforms/qnx/qqnxsystemsettings.cpp b/src/plugins/platforms/qnx/qqnxsystemsettings.cpp
deleted file mode 100644
index 243630ec85..0000000000
--- a/src/plugins/platforms/qnx/qqnxsystemsettings.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqnxsystemsettings.h"
-
-#include <QFont>
-#include <qpa/qplatformfontdatabase.h>
-
-QT_BEGIN_NAMESPACE
-
-QHash<QPlatformTheme::Font, QFont *> qt_qnx_createRoleFonts(QPlatformFontDatabase *fontDatabase)
-{
- // See http://docs.blackberry.com/en/developers/deliverables/41577/typography.jsp
- // which recommends using
- // - small font size of 6 points
- // - normal font size of 8 points
- // - 11 points for titles (not covered by the theme system).
- QFont baseFont = fontDatabase->defaultFont();
- baseFont.setPointSize(8);
-
- QHash<QPlatformTheme::Font, QFont *> fonts;
- fonts.insert(QPlatformTheme::SystemFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::PushButtonFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::ListViewFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::ListBoxFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::TitleBarFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::MenuFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::ComboMenuItemFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::HeaderViewFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::TipLabelFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::LabelFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::ToolButtonFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::MenuItemFont, new QFont(baseFont));
- fonts.insert(QPlatformTheme::ComboLineEditFont, new QFont(baseFont));
-
- QFont smallFont(baseFont);
- smallFont.setPointSize(6);
- fonts.insert(QPlatformTheme::SmallFont, new QFont(smallFont));
- fonts.insert(QPlatformTheme::MiniFont, new QFont(smallFont));
-
- return fonts;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxsystemsettings.h b/src/plugins/platforms/qnx/qqnxsystemsettings.h
deleted file mode 100644
index 6a99d5a70c..0000000000
--- a/src/plugins/platforms/qnx/qqnxsystemsettings.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQNXSYSTEMSETTINGS_H
-#define QQNXSYSTEMSETTINGS_H
-
-#include <QtCore/qhash.h>
-#include <qpa/qplatformtheme.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPlatformFontDatabase;
-
-QHash<QPlatformTheme::Font, QFont *> qt_qnx_createRoleFonts(QPlatformFontDatabase *fontDatabase);
-
-QT_END_NAMESPACE
-
-#endif // QQNXSYSTEMSETTINGS_H
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
deleted file mode 100644
index b55ae842ed..0000000000
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqnxvirtualkeyboardbps.h"
-
-#include <QDebug>
-
-#include <bps/event.h>
-#include <bps/locale.h>
-#include <bps/virtualkeyboard.h>
-#if defined(Q_OS_BLACKBERRY)
-#include <bbndk.h>
-#endif
-
-#if defined(QQNXVIRTUALKEYBOARD_DEBUG)
-#define qVirtualKeyboardDebug qDebug
-#else
-#define qVirtualKeyboardDebug QT_NO_QDEBUG_MACRO
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QQnxVirtualKeyboardBps::QQnxVirtualKeyboardBps(QObject *parent)
- : QQnxAbstractVirtualKeyboard(parent)
-{
- if (locale_request_events(0) != BPS_SUCCESS)
- qWarning("QQNX: Failed to register for locale events");
-
- if (virtualkeyboard_request_events(0) != BPS_SUCCESS)
- qWarning("QQNX: Failed to register for virtual keyboard events");
-
- int height = 0;
- if (virtualkeyboard_get_height(&height) != BPS_SUCCESS)
- qWarning("QQNX: Failed to get virtual keyboard height");
-
- setHeight(height);
-}
-
-bool QQnxVirtualKeyboardBps::handleEvent(bps_event_t *event)
-{
- const int eventDomain = bps_event_get_domain(event);
- if (eventDomain == locale_get_domain())
- return handleLocaleEvent(event);
-
- if (eventDomain == virtualkeyboard_get_domain())
- return handleVirtualKeyboardEvent(event);
-
- return false;
-}
-
-bool QQnxVirtualKeyboardBps::showKeyboard()
-{
- qVirtualKeyboardDebug() << "current visibility=" << isVisible();
-
- // They keyboard's mode is global between applications, we have to set it each time
- if ( !isVisible() )
- applyKeyboardOptions();
-
- virtualkeyboard_show();
- return true;
-}
-
-bool QQnxVirtualKeyboardBps::hideKeyboard()
-{
- qVirtualKeyboardDebug() << "current visibility=" << isVisible();
- virtualkeyboard_hide();
- return true;
-}
-
-void QQnxVirtualKeyboardBps::applyKeyboardOptions()
-{
- virtualkeyboard_layout_t layout = keyboardLayout();
- virtualkeyboard_enter_t enter = enterKey();
-
- qVirtualKeyboardDebug() << "mode=" << keyboardMode() << "enterKey=" << enterKeyType();
-
- virtualkeyboard_change_options(layout, enter);
-}
-
-virtualkeyboard_layout_t QQnxVirtualKeyboardBps::keyboardLayout() const
-{
- switch (keyboardMode()) {
- case Url:
- return VIRTUALKEYBOARD_LAYOUT_URL;
- case Email:
- return VIRTUALKEYBOARD_LAYOUT_EMAIL;
- case Web:
- return VIRTUALKEYBOARD_LAYOUT_WEB;
- case NumPunc:
- return VIRTUALKEYBOARD_LAYOUT_NUM_PUNC;
- case Number:
- return VIRTUALKEYBOARD_LAYOUT_NUMBER;
- case Symbol:
- return VIRTUALKEYBOARD_LAYOUT_SYMBOL;
- case Phone:
- return VIRTUALKEYBOARD_LAYOUT_PHONE;
- case Pin:
- return VIRTUALKEYBOARD_LAYOUT_PIN;
- case Password:
- return VIRTUALKEYBOARD_LAYOUT_PASSWORD;
-#if defined(Q_OS_BLACKBERRY)
-#if BBNDK_VERSION_AT_LEAST(10, 2, 1)
- case Alphanumeric:
- return VIRTUALKEYBOARD_LAYOUT_ALPHANUMERIC;
-#endif
-#endif
- case Default: // fall through
- default:
- return VIRTUALKEYBOARD_LAYOUT_DEFAULT;
- }
-
- return VIRTUALKEYBOARD_LAYOUT_DEFAULT;
-}
-
-virtualkeyboard_enter_t QQnxVirtualKeyboardBps::enterKey() const
-{
- switch (enterKeyType()) {
- case Connect:
- return VIRTUALKEYBOARD_ENTER_CONNECT;
- case Done:
- return VIRTUALKEYBOARD_ENTER_DONE;
- case Go:
- return VIRTUALKEYBOARD_ENTER_GO;
- case Join:
- return VIRTUALKEYBOARD_ENTER_JOIN;
- case Next:
- return VIRTUALKEYBOARD_ENTER_NEXT;
- case Search:
- return VIRTUALKEYBOARD_ENTER_SEARCH;
- case Send:
- return VIRTUALKEYBOARD_ENTER_SEND;
- case Submit:
- return VIRTUALKEYBOARD_ENTER_SUBMIT;
- case Default: // fall through
- default:
- return VIRTUALKEYBOARD_ENTER_DEFAULT;
- }
-
- return VIRTUALKEYBOARD_ENTER_DEFAULT;
-}
-
-bool QQnxVirtualKeyboardBps::handleLocaleEvent(bps_event_t *event)
-{
- if (bps_event_get_code(event) == LOCALE_INFO) {
- const QString language = QString::fromLatin1(locale_event_get_language(event));
- const QString country = QString::fromLatin1(locale_event_get_country(event));
- const QLocale newLocale(language + QLatin1Char('_') + country);
-
- qVirtualKeyboardDebug() << "current locale" << locale() << "new locale=" << newLocale;
- setLocale(newLocale);
- return true;
- }
-
- qVirtualKeyboardDebug() << "Unhandled locale event. code=" << bps_event_get_code(event);
-
- return false;
-}
-
-bool QQnxVirtualKeyboardBps::handleVirtualKeyboardEvent(bps_event_t *event)
-{
- switch (bps_event_get_code(event)) {
- case VIRTUALKEYBOARD_EVENT_VISIBLE:
- qVirtualKeyboardDebug() << "EVENT VISIBLE: current visibility=" << isVisible();
- setVisible(true);
- break;
-
- case VIRTUALKEYBOARD_EVENT_HIDDEN:
- qVirtualKeyboardDebug() << "EVENT HIDDEN: current visibility=" << isVisible();
- setVisible(false);
- break;
-
- case VIRTUALKEYBOARD_EVENT_INFO: {
- const int newHeight = virtualkeyboard_event_get_height(event);
- qVirtualKeyboardDebug() << "EVENT INFO: current height=" << height() << "new height=" << newHeight;
- setHeight(newHeight);
- break;
- }
-
- default:
- qVirtualKeyboardDebug() << "Unhandled virtual keyboard event. code=" << bps_event_get_code(event);
- return false;
- }
-
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h
deleted file mode 100644
index a720c5d894..0000000000
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2012 Research In Motion
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQNXVIRTUALKEYBOARDBPS_H
-#define QQNXVIRTUALKEYBOARDBPS_H
-
-#include "qqnxabstractvirtualkeyboard.h"
-#include <bps/virtualkeyboard.h>
-
-struct bps_event_t;
-
-QT_BEGIN_NAMESPACE
-
-class QQnxVirtualKeyboardBps : public QQnxAbstractVirtualKeyboard
-{
- Q_OBJECT
-public:
- explicit QQnxVirtualKeyboardBps(QObject *parent = 0);
-
- bool handleEvent(bps_event_t *event);
-
- bool showKeyboard();
- bool hideKeyboard();
-
-protected:
- void applyKeyboardOptions();
-
-private:
- bool handleLocaleEvent(bps_event_t *event);
- bool handleVirtualKeyboardEvent(bps_event_t *event);
-
- virtualkeyboard_layout_t keyboardLayout() const;
- virtualkeyboard_enter_t enterKey() const;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQNXVIRTUALKEYBOARDBPS_H
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
index d5a9a49ac6..880a914c84 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
@@ -127,7 +127,7 @@ bool QQnxVirtualKeyboardPps::connect()
}
m_buffer = new char[ms_bufferSize];
- if (!m_buffer) {
+ if (Q_UNLIKELY(!m_buffer)) {
qCritical("QQnxVirtualKeyboard: Unable to allocate buffer of %d bytes. "
"Size is unavailable.", ms_bufferSize);
return false;
@@ -170,7 +170,7 @@ void QQnxVirtualKeyboardPps::ppsDataReady()
return;
// nread is the real space necessary, not the amount read.
- if (static_cast<size_t>(nread) > ms_bufferSize - 1) {
+ if (Q_UNLIKELY(static_cast<size_t>(nread) > ms_bufferSize - 1)) {
qCritical("QQnxVirtualKeyboard: Keyboard buffer size too short; need %u.", nread + 1);
connect(); // reconnect
return;
@@ -184,7 +184,7 @@ void QQnxVirtualKeyboardPps::ppsDataReady()
#endif
const char *value;
- if (pps_decoder_get_string(m_decoder, "error", &value) == PPS_DECODER_OK) {
+ if (Q_UNLIKELY(pps_decoder_get_string(m_decoder, "error", &value) == PPS_DECODER_OK)) {
qCritical("QQnxVirtualKeyboard: Keyboard PPS decoder error: %s", value ? value : "[null]");
return;
}
@@ -214,11 +214,11 @@ void QQnxVirtualKeyboardPps::handleKeyboardInfoMessage()
{
int newHeight = 0;
- if (pps_decoder_push(m_decoder, "dat") != PPS_DECODER_OK) {
+ if (Q_UNLIKELY(pps_decoder_push(m_decoder, "dat") != PPS_DECODER_OK)) {
qCritical("QQnxVirtualKeyboard: Keyboard PPS dat object not found");
return;
}
- if (pps_decoder_get_int(m_decoder, "size", &newHeight) != PPS_DECODER_OK) {
+ if (Q_UNLIKELY(pps_decoder_get_int(m_decoder, "size", &newHeight) != PPS_DECODER_OK)) {
qCritical("QQnxVirtualKeyboard: Keyboard PPS size field not found");
return;
}
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 4dc1248bd1..47888178c4 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -47,12 +47,6 @@
#include <QtCore/QDebug>
-#if defined(Q_OS_BLACKBERRY)
-#include "qqnxnavigatorcover.h"
-#include <sys/pps.h>
-#include <bps/navigator.h>
-#endif
-
#include <errno.h>
#if defined(QQNXWINDOW_DEBUG)
@@ -378,7 +372,7 @@ void QQnxWindow::setBufferSize(const QSize &size)
screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
"Failed to query render buffer count");
- if (bufferCount != MAX_BUFFER_COUNT) {
+ if (Q_UNLIKELY(bufferCount != MAX_BUFFER_COUNT)) {
qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d.",
MAX_BUFFER_COUNT, bufferCount);
}
@@ -456,10 +450,10 @@ void QQnxWindow::removeFromParent()
qWindowDebug() << "window =" << window();
// Remove from old Hierarchy position
if (m_parentWindow) {
- if (m_parentWindow->m_childWindows.removeAll(this))
- m_parentWindow = 0;
- else
+ if (Q_UNLIKELY(!m_parentWindow->m_childWindows.removeAll(this)))
qFatal("QQnxWindow: Window Hierarchy broken; window has parent, but parent hasn't got child.");
+ else
+ m_parentWindow = 0;
} else if (m_screen) {
m_screen->removeWindow(this);
}
@@ -633,23 +627,7 @@ QQnxWindow *QQnxWindow::findWindow(screen_window_t windowHandle)
void QQnxWindow::minimize()
{
-#if defined(Q_OS_BLACKBERRY)
- qWindowDebug();
-
- pps_encoder_t encoder;
-
- pps_encoder_initialize(&encoder, false);
- pps_encoder_add_string(&encoder, "msg", "minimizeWindow");
-
- if (navigator_raw_write(pps_encoder_buffer(&encoder),
- pps_encoder_length(&encoder)) != BPS_SUCCESS) {
- qWindowDebug() << "navigator_raw_write failed:" << strerror(errno);
- }
-
- pps_encoder_cleanup(&encoder);
-#else
qWarning("Qt::WindowMinimized is not supported by this OS version");
-#endif
}
void QQnxWindow::setRotation(int rotation)
@@ -686,18 +664,8 @@ void QQnxWindow::initWindow()
QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window()->screen()->handle());
setScreen(platformScreen);
- if (window()->type() == Qt::CoverWindow) {
-#if defined(Q_OS_BLACKBERRY)
- if (platformScreen->rootWindow()) {
- screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(),
- SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window);
- m_cover.reset(new QQnxNavigatorCover);
- } else {
- qWarning("No root window for cover window");
- }
-#endif
+ if (window()->type() == Qt::CoverWindow)
m_exposed = false;
- }
// Add window to plugin's window mapper
QQnxIntegration::addWindow(m_window, window());
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 4934b6c6e4..c954e0a96d 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -188,7 +188,7 @@ void QWindowsUser32DLL::init()
// MinGW (g++ 3.4.5) accepts only C casts.
setLayeredWindowAttributes = (SetLayeredWindowAttributes)(library.resolve("SetLayeredWindowAttributes"));
updateLayeredWindow = (UpdateLayeredWindow)(library.resolve("UpdateLayeredWindow"));
- if (!setLayeredWindowAttributes || !updateLayeredWindow)
+ if (Q_UNLIKELY(!setLayeredWindowAttributes || !updateLayeredWindow))
qFatal("This version of Windows is not supported (User32.dll is missing the symbols 'SetLayeredWindowAttributes', 'UpdateLayeredWindow').");
updateLayeredWindowIndirect = (UpdateLayeredWindowIndirect)(library.resolve("UpdateLayeredWindowIndirect"));
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index c769eb04a4..b946c34a2b 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -780,6 +780,21 @@ QPixmap QWindowsCursor::dragDefaultCursor(Qt::DropAction action) const
return m_ignoreDragCursor;
}
+HCURSOR QWindowsCursor::hCursor(const QCursor &c) const
+{
+ const Qt::CursorShape shape = c.shape();
+ if (shape == Qt::BitmapCursor) {
+ const auto pit = m_pixmapCursorCache.constFind(QWindowsPixmapCursorCacheKey(c));
+ if (pit != m_pixmapCursorCache.constEnd())
+ return pit.value()->handle();
+ } else {
+ const auto sit = m_standardCursorCache.constFind(shape);
+ if (sit != m_standardCursorCache.constEnd())
+ return sit.value()->handle();
+ }
+ return HCURSOR(0);
+}
+
/*!
\class QWindowsWindowCursor
\brief Per-Window cursor. Contains a QCursor and manages its associated system
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index e93f779f94..0e080f725a 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -115,6 +115,8 @@ public:
QPixmap dragDefaultCursor(Qt::DropAction action) const;
+ HCURSOR hCursor(const QCursor &c) const;
+
private:
typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index 021058fa33..c68f05b5bb 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -230,8 +230,6 @@ private:
};
typedef QMap<Qt::DropAction, CursorEntry> ActionCursorMap;
- typedef ActionCursorMap::Iterator ActionCursorMapIt;
- typedef ActionCursorMap::ConstIterator ActionCursorMapConstIt;
const Mode m_mode;
QWindowsDrag *m_drag;
@@ -312,7 +310,7 @@ void QWindowsOleDropSource::createCursors()
if (cursorPixmap.isNull() && platformCursor)
cursorPixmap = static_cast<QWindowsCursor *>(platformCursor)->dragDefaultCursor(action);
const qint64 cacheKey = cursorPixmap.cacheKey();
- const ActionCursorMapIt it = m_cursors.find(action);
+ const auto it = m_cursors.find(action);
if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
continue;
if (cursorPixmap.isNull()) {
@@ -393,7 +391,7 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
{
HRESULT hr = S_OK;
do {
- if (fEscapePressed) {
+ if (fEscapePressed || QWindowsDrag::isCanceled()) {
hr = ResultFromScode(DRAGDROP_S_CANCEL);
break;
}
@@ -441,7 +439,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
m_drag->updateAction(action);
const qint64 currentCacheKey = m_drag->currentDrag()->dragCursor(action).cacheKey();
- ActionCursorMapConstIt it = m_cursors.constFind(action);
+ auto it = m_cursors.constFind(action);
// If a custom drag cursor is set, check its cache key to detect changes.
if (it == m_cursors.constEnd() || (currentCacheKey && currentCacheKey != it.value().cacheKey)) {
createCursors();
@@ -673,6 +671,8 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
\ingroup qt-lighthouse-win
*/
+bool QWindowsDrag::m_canceled = false;
+
QWindowsDrag::QWindowsDrag() :
m_dropDataObject(0), m_cachedDropTargetHelper(0)
{
@@ -714,6 +714,7 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag)
Qt::DropAction dragResult = Qt::IgnoreAction;
DWORD resultEffect;
+ QWindowsDrag::m_canceled = false;
QWindowsOleDropSource *windowDropSource = new QWindowsOleDropSource(this);
windowDropSource->createCursors();
QWindowsOleDataObject *dropDataObject = new QWindowsOleDataObject(dropData);
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
index 890ad6c142..ebe949a6af 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.h
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -90,6 +90,8 @@ public:
Qt::DropAction drag(QDrag *drag) Q_DECL_OVERRIDE;
static QWindowsDrag *instance();
+ void cancelDrag() Q_DECL_OVERRIDE { QWindowsDrag::m_canceled = true; }
+ static bool isCanceled() { return QWindowsDrag::m_canceled; }
IDataObject *dropDataObject() const { return m_dropDataObject; }
void setDropDataObject(IDataObject *dataObject) { m_dropDataObject = dataObject; }
@@ -99,6 +101,8 @@ public:
IDropTargetHelper* dropHelper();
private:
+ static bool m_canceled;
+
QWindowsDropMimeData m_dropData;
IDataObject *m_dropDataObject;
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 8a2fbe1f6d..8d1bbc75a6 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -44,6 +44,7 @@
#include <QtCore/qmath.h>
#include <QtCore/QDebug>
+#include <QtCore/QFile>
#include <QtCore/QtEndian>
#include <QtCore/QThreadStorage>
#include <QtCore/private/qsystemlibrary_p.h>
@@ -1062,7 +1063,7 @@ QSharedPointer<QWindowsFontEngineData> sharedFontData()
{
FontEngineThreadLocalData *data = fontEngineThreadLocalData();
if (!data->hasLocalData())
- data->setLocalData(QSharedPointer<QWindowsFontEngineData>(new QWindowsFontEngineData));
+ data->setLocalData(QSharedPointer<QWindowsFontEngineData>::create());
return data->localData();
}
#else // !QT_NO_THREAD
@@ -1072,7 +1073,7 @@ QWindowsFontEngineDataPtr sharedFontData()
{
QWindowsFontEngineDataPtr *data = fontEngineData();
if (data->isNull())
- *data = QWindowsFontEngineDataPtr(new QWindowsFontEngineData);
+ *data = QWindowsFontEngineDataPtr::create();
return *data;
}
#endif // QT_NO_THREAD
@@ -1605,7 +1606,7 @@ LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request)
lf.lfPitchAndFamily = DEFAULT_PITCH | hint;
QString fam = request.family;
- if (fam.size() >= LF_FACESIZE) {
+ if (Q_UNLIKELY(fam.size() >= LF_FACESIZE)) {
qCritical("%s: Family name '%s' is too long.", __FUNCTION__, qPrintable(fam));
fam.truncate(LF_FACESIZE - 1);
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
index 684c44acf2..08ef555441 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -145,10 +145,8 @@ static FontKeys &fontKeys()
static const FontKey *findFontKey(const QString &name, int *indexIn = Q_NULLPTR)
{
- typedef FontKeys::ConstIterator ConstIt;
-
const FontKeys &keys = fontKeys();
- for (ConstIt it = keys.constBegin(), cend = keys.constEnd(); it != cend; ++it) {
+ for (auto it = keys.constBegin(), cend = keys.constEnd(); it != cend; ++it) {
const int index = it->fontNames.indexOf(name);
if (index >= 0) {
if (indexIn)
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 30417f7cee..41fa8c015d 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -54,6 +54,7 @@
#include <QtGui/private/qpaintengine_raster_p.h>
#include <QtCore/QtEndian>
+#include <QtCore/QFile>
#include <QtCore/qmath.h>
#include <QtCore/QThreadStorage>
#include <QtCore/private/qsystemlibrary_p.h>
@@ -196,7 +197,7 @@ void QWindowsFontEngine::getCMap()
designToDevice = QFixed((int)otm->otmEMSquare)/QFixed::fromReal(fontDef.pixelSize);
unitsPerEm = otm->otmEMSquare;
x_height = (int)otm->otmsXHeight;
- loadKerningPairs(QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight));
+ loadKerningPairs(designToDevice);
_faceId.filename = QFile::encodeName(QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFullName)));
lineWidth = otm->otmsUnderscoreSize;
fsType = otm->otmfsType;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index bd2014b8f2..b2781c8212 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -61,6 +61,7 @@
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
# include "qwindowssessionmanager.h"
#endif
+#include <QtGui/qtouchdevice.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/qpa/qplatforminputcontextfactory_p.h>
@@ -220,12 +221,14 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
if (tabletAbsoluteRange >= 0)
m_context.setTabletAbsoluteRange(tabletAbsoluteRange);
if (!dpiAwarenessSet) { // Set only once in case of repeated instantiations of QGuiApplication.
- m_context.setProcessDpiAwareness(dpiAwareness);
+ if (!QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
+ m_context.setProcessDpiAwareness(dpiAwareness);
+ qCDebug(lcQpaWindows)
+ << __FUNCTION__ << "DpiAwareness=" << dpiAwareness
+ << "effective process DPI awareness=" << QWindowsContext::processDpiAwareness();
+ }
dpiAwarenessSet = true;
}
- qCDebug(lcQpaWindows)
- << __FUNCTION__ << "DpiAwareness=" << dpiAwareness
- << "effective process DPI awareness=" << QWindowsContext::processDpiAwareness();
m_context.initTouch(m_options);
}
@@ -594,4 +597,9 @@ QPlatformServices *QWindowsIntegration::services() const
return &d->m_services;
}
+void QWindowsIntegration::beep() const
+{
+ MessageBeep(MB_OK); // For QApplication
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index cb10bf08f5..a93e2c9856 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -96,6 +96,8 @@ public:
unsigned options() const;
+ void beep() const Q_DECL_OVERRIDE;
+
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const Q_DECL_OVERRIDE;
#endif
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index e26010b5c4..80f3d3e2b8 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -41,6 +41,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
+#include <QtGui/QTouchDevice>
#include <QtGui/QWindow>
#include <QtGui/QCursor>
diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.cpp b/src/plugins/platforms/windows/qwindowsnativeimage.cpp
index 66e64e64b4..56e18e20d7 100644
--- a/src/plugins/platforms/windows/qwindowsnativeimage.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeimage.cpp
@@ -96,7 +96,7 @@ static inline HBITMAP createDIB(HDC hdc, int width, int height,
void *bits = 0;
HBITMAP bitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO *>(&bmi),
DIB_RGB_COLORS, &bits, 0, 0);
- if (!bitmap || !bits)
+ if (Q_UNLIKELY(!bitmap || !bits))
qFatal("%s: CreateDIBSection failed.", __FUNCTION__);
*bitsIn = (uchar*)bits;
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index 659ef79c18..c5c60aa882 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -34,6 +34,7 @@
#include "qwindowsnativeinterface.h"
#include "qwindowswindow.h"
#include "qwindowscontext.h"
+#include "qwindowscursor.h"
#include "qwindowsfontdatabase.h"
#include "qwindowsopenglcontext.h"
#include "qwindowsopengltester.h"
@@ -42,6 +43,8 @@
#include <QtGui/QWindow>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QScreen>
+#include <qpa/qplatformscreen.h>
QT_BEGIN_NAMESPACE
@@ -102,6 +105,19 @@ void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resourc
return 0;
}
+#ifndef QT_NO_CURSOR
+void *QWindowsNativeInterface::nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor)
+{
+ if (resource == QByteArrayLiteral("hcursor")) {
+ if (const QScreen *primaryScreen = QGuiApplication::primaryScreen()) {
+ if (const QPlatformCursor *pCursor= primaryScreen->handle()->cursor())
+ return static_cast<const QWindowsCursor *>(pCursor)->hCursor(cursor);
+ }
+ }
+ return Q_NULLPTR;
+}
+#endif // !QT_NO_CURSOR
+
static const char customMarginPropertyC[] = "WindowsCustomMargins";
QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const
@@ -195,11 +211,6 @@ QString QWindowsNativeInterface::registerWindowClass(const QString &classNameIn,
return QWindowsContext::instance()->registerWindowClass(classNameIn, (WNDPROC)eventProc);
}
-void QWindowsNativeInterface::beep()
-{
- MessageBeep(MB_OK); // For QApplication
-}
-
bool QWindowsNativeInterface::asyncExpose() const
{
return QWindowsContext::instance()->asyncExpose();
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h
index 97839ae1ae..48de0f514d 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.h
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h
@@ -66,15 +66,15 @@ public:
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
#endif
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
-
+#ifndef QT_NO_CURSOR
+ void *nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor) Q_DECL_OVERRIDE;
+#endif
Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
const QString &windowName,
void *eventProc) const;
Q_INVOKABLE QString registerWindowClass(const QString &classNameIn, void *eventProc) const;
- Q_INVOKABLE void beep();
-
Q_INVOKABLE void registerWindowsMime(void *mimeIn);
Q_INVOKABLE void unregisterWindowsMime(void *mime);
Q_INVOKABLE int registerMimeType(const QString &mimeType);
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index b27811df9e..d5aae9746d 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -391,6 +391,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
const int currentDevice = m_devices.at(m_currentDevice).currentDevice;
const int currentPointer = m_devices.at(m_currentDevice).currentPointerType;
+ const qint64 uniqueId = m_devices.at(m_currentDevice).uniqueId;
// The tablet can be used in 2 different modes, depending on it settings:
// 1) Absolute (pen) mode:
@@ -407,7 +408,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
qCDebug(lcQpaTablet) << __FUNCTION__ << "processing " << packetCount
- << "target:" << QGuiApplicationPrivate::tabletPressTarget;
+ << "target:" << QGuiApplicationPrivate::tabletDevicePoint(uniqueId).target;
const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
@@ -420,7 +421,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
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.
+ QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(uniqueId).target; // Pass to window that grabbed it.
QPoint globalPos = globalPosF.toPoint();
// Get Mouse Position and compare to tablet info
@@ -484,7 +485,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
static_cast<Qt::MouseButtons>(packet.pkButtons),
pressureNew, tiltX, tiltY,
tangentialPressure, rotation, z,
- m_devices.at(m_currentDevice).uniqueId,
+ uniqueId,
keyboardModifiers);
}
return true;
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index cc367ff801..08eb5c02e2 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -501,28 +501,43 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
const int scaleFactor = primaryScreen ? qRound(QHighDpiScaling::factor(primaryScreen)) : 1;
const QSizeF pixmapSize = size * scaleFactor;
int resourceId = -1;
+ int stockId = SIID_INVALID;
+ UINT stockFlags = 0;
LPCTSTR iconName = 0;
switch (sp) {
case DriveCDIcon:
+ stockId = SIID_DRIVECD;
+ resourceId = 12;
+ break;
case DriveDVDIcon:
+ stockId = SIID_DRIVEDVD;
resourceId = 12;
break;
case DriveNetIcon:
+ stockId = SIID_DRIVENET;
resourceId = 10;
break;
case DriveHDIcon:
+ stockId = SIID_DRIVEFIXED;
resourceId = 9;
break;
case DriveFDIcon:
+ stockId = SIID_DRIVE35;
resourceId = 7;
break;
- case FileIcon:
case FileLinkIcon:
+ stockFlags = SHGSI_LINKOVERLAY;
+ // Fall through
+ case FileIcon:
+ stockId = SIID_DOCNOASSOC;
resourceId = 1;
break;
- case DirIcon:
case DirLinkIcon:
+ stockFlags = SHGSI_LINKOVERLAY;
+ // Fall through
case DirClosedIcon:
+ case DirIcon:
+ stockId = SIID_FOLDER;
resourceId = 4;
break;
case DesktopIcon:
@@ -531,54 +546,68 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) con
case ComputerIcon:
resourceId = 16;
break;
- case DirOpenIcon:
case DirLinkOpenIcon:
+ stockFlags = SHGSI_LINKOVERLAY;
+ // Fall through
+ case DirOpenIcon:
+ stockId = SIID_FOLDEROPEN;
resourceId = 5;
break;
case FileDialogNewFolder:
+ stockId = SIID_FOLDER;
resourceId = 319;
break;
case DirHomeIcon:
resourceId = 235;
break;
case TrashIcon:
+ stockId = SIID_RECYCLER;
resourceId = 191;
break;
#ifndef Q_OS_WINCE
case MessageBoxInformation:
+ stockId = SIID_INFO;
iconName = IDI_INFORMATION;
break;
case MessageBoxWarning:
+ stockId = SIID_WARNING;
iconName = IDI_WARNING;
break;
case MessageBoxCritical:
+ stockId = SIID_ERROR;
iconName = IDI_ERROR;
break;
case MessageBoxQuestion:
+ stockId = SIID_HELP;
iconName = IDI_QUESTION;
break;
case VistaShield:
+ stockId = SIID_SHIELD;
+ break;
+#endif
+ default:
+ break;
+ }
+
+#ifndef Q_OS_WINCE
+ if (stockId != SIID_INVALID) {
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
- && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) {
- if (!QWindowsContext::shell32dll.sHGetStockIconInfo)
- return QPixmap();
+ && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
+ && QWindowsContext::shell32dll.sHGetStockIconInfo) {
QPixmap pixmap;
SHSTOCKICONINFO iconInfo;
memset(&iconInfo, 0, sizeof(iconInfo));
iconInfo.cbSize = sizeof(iconInfo);
- const int iconSize = pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON;
- if (QWindowsContext::shell32dll.sHGetStockIconInfo(SIID_SHIELD, SHGFI_ICON | iconSize, &iconInfo) == S_OK) {
+ stockFlags |= (pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON);
+ if (QWindowsContext::shell32dll.sHGetStockIconInfo(stockId, SHGFI_ICON | stockFlags, &iconInfo) == S_OK) {
pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon);
pixmap.setDevicePixelRatio(scaleFactor);
DestroyIcon(iconInfo.hIcon);
return pixmap;
}
}
- break;
-#endif
- default:
- break;
}
+#endif
if (resourceId != -1) {
QPixmap pixmap = loadIconFromShell32(resourceId, pixmapSize);
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
index bc77df566e..8ca669141e 100644
--- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
@@ -112,7 +112,7 @@ void QWinRTEGLContext::initialize()
EGL_NONE,
};
g->eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes);
- if (g->eglDisplay == EGL_NO_DISPLAY)
+ if (Q_UNLIKELY(g->eglDisplay == EGL_NO_DISPLAY))
qCritical("Failed to initialize EGL display: 0x%x", eglGetError());
// eglInitialize checks for EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index bec94c1e51..8a53047d1e 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -180,7 +180,7 @@ QWinRTWindow::~QWinRTWindow()
EGLBoolean value = eglDestroySurface(d->display, d->surface);
d->surface = EGL_NO_SURFACE;
- if (value == EGL_FALSE)
+ if (Q_UNLIKELY(value == EGL_FALSE))
qCritical("Failed to destroy EGL window surface: 0x%x", eglGetError());
}
@@ -321,7 +321,7 @@ void QWinRTWindow::createEglSurface(EGLDisplay display, EGLConfig config)
d->surface = eglCreateWindowSurface(display, config,
reinterpret_cast<EGLNativeWindowType>(winId()),
nullptr);
- if (d->surface == EGL_NO_SURFACE)
+ if (Q_UNLIKELY(d->surface == EGL_NO_SURFACE))
qCritical("Failed to create EGL window surface: 0x%x", eglGetError());
return S_OK;
});
diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp
index 508f5e82e6..4e63e1ef66 100644
--- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationfactory.cpp
@@ -46,17 +46,6 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QXcbGlIntegrationFactoryInterface_iid, QLatin1String("/xcbglintegrations"), Qt::CaseInsensitive))
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader,
(QXcbGlIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive))
-
-static inline QXcbGlIntegration *loadIntegration(QFactoryLoader *loader, const QString &key)
-{
- const int index = loader->indexOf(key);
- if (index != -1) {
- if (QXcbGlIntegrationPlugin *factory = qobject_cast<QXcbGlIntegrationPlugin *>(loader->instance(index)))
- if (QXcbGlIntegration *result = factory->create())
- return result;
- }
- return Q_NULLPTR;
-}
#endif // !QT_NO_LIBRARY
QStringList QXcbGlIntegrationFactory::keys(const QString &pluginPath)
@@ -86,13 +75,13 @@ QStringList QXcbGlIntegrationFactory::keys(const QString &pluginPath)
QXcbGlIntegration *QXcbGlIntegrationFactory::create(const QString &platform, const QString &pluginPath)
{
#ifndef QT_NO_LIBRARY
- // Try loading the plugin from platformPluginPath first:
+ // Try loading the plugin from pluginPath first:
if (!pluginPath.isEmpty()) {
QCoreApplication::addLibraryPath(pluginPath);
- if (QXcbGlIntegration *ret = loadIntegration(directLoader(), platform))
+ if (QXcbGlIntegration *ret = qLoadPlugin<QXcbGlIntegration, QXcbGlIntegrationPlugin>(directLoader(), platform))
return ret;
}
- if (QXcbGlIntegration *ret = loadIntegration(loader(), platform))
+ if (QXcbGlIntegration *ret = qLoadPlugin<QXcbGlIntegration, QXcbGlIntegrationPlugin>(loader(), platform))
return ret;
#else
Q_UNUSED(platform);
diff --git a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationplugin.h b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationplugin.h
index f9a25cc12a..a61a7036a8 100644
--- a/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationplugin.h
+++ b/src/plugins/platforms/xcb/gl_integrations/qxcbglintegrationplugin.h
@@ -53,6 +53,9 @@ public:
{ }
virtual QXcbGlIntegration *create() = 0;
+ // the pattern expected by qLoadPlugin calls for a QString argument.
+ // we don't need it, so don't bother subclasses with it:
+ QXcbGlIntegration *create(const QString &) { return create(); }
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index 4cb220a02f..208170de37 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -99,7 +99,7 @@ static Window createDummyWindow(Display *dpy, XVisualInfo *visualInfo, int scree
static Window createDummyWindow(Display *dpy, GLXFBConfig config, int screenNumber, Window rootWin)
{
XVisualInfo *visualInfo = glXGetVisualFromFBConfig(dpy, config);
- if (!visualInfo)
+ if (Q_UNLIKELY(!visualInfo))
qFatal("Could not initialize GLX");
Window window = createDummyWindow(dpy, visualInfo, screenNumber, rootWin);
XFree(visualInfo);
@@ -305,7 +305,7 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
// Note that m_format gets updated with the used surface format
visualInfo = qglx_findVisualInfo(m_display, screen->screenNumber(), &m_format);
- if (!visualInfo)
+ if (Q_UNLIKELY(!visualInfo))
qFatal("Could not initialize GLX");
m_context = glXCreateContext(m_display, visualInfo, m_shareContext, true);
if (!m_context && m_shareContext) {
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index abb48034cd..7348eaac20 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -577,7 +577,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber);
#endif //XCB_USE_XLIB
- if (!m_connection || xcb_connection_has_error(m_connection))
+ if (Q_UNLIKELY(!m_connection || xcb_connection_has_error(m_connection)))
qFatal("QXcbConnection: Could not connect to display %s", m_displayName.constData());
@@ -990,17 +990,20 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
int i = 0;
for (; i < m_callLog.size(); ++i) {
if (m_callLog.at(i).sequence == error->sequence) {
- qDebug("Caused by: %s:%d", qPrintable(m_callLog.at(i).file), m_callLog.at(i).line);
+ qDebug("Caused by: %s:%d", m_callLog.at(i).file.constData(), m_callLog.at(i).line);
break;
} else if (m_callLog.at(i).sequence > error->sequence) {
- qDebug("Caused some time before: %s:%d", qPrintable(m_callLog.at(i).file), m_callLog.at(i).line);
+ qDebug("Caused some time before: %s:%d", m_callLog.at(i).file.constData(),
+ m_callLog.at(i).line);
if (i > 0)
- qDebug("and after: %s:%d", qPrintable(m_callLog.at(i-1).file), m_callLog.at(i-1).line);
+ qDebug("and after: %s:%d", m_callLog.at(i-1).file.constData(),
+ m_callLog.at(i-1).line);
break;
}
}
if (i == m_callLog.size() && !m_callLog.isEmpty())
- qDebug("Caused some time after: %s:%d", qPrintable(m_callLog.first().file), m_callLog.first().line);
+ qDebug("Caused some time after: %s:%d", m_callLog.first().file.constData(),
+ m_callLog.first().line);
#endif
}
@@ -1688,15 +1691,14 @@ void QXcbConnection::processXcbEvents()
if (accepted)
continue;
- QVector<PeekFunc>::iterator it = m_peekFuncs.begin();
- while (it != m_peekFuncs.end()) {
+ auto isWaitingFor = [=](PeekFunc peekFunc) {
// These callbacks return true if the event is what they were
// waiting for, remove them from the list in that case.
- if ((*it)(this, event))
- it = m_peekFuncs.erase(it);
- else
- ++it;
- }
+ return peekFunc(this, event);
+ };
+ m_peekFuncs.erase(std::remove_if(m_peekFuncs.begin(), m_peekFuncs.end(),
+ isWaitingFor),
+ m_peekFuncs.end());
m_reader->unlock();
handleXcbEvent(event);
m_reader->lock();
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index a6a7b9e7ca..6fa7532555 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -631,7 +631,11 @@ private:
QMutex m_callLogMutex;
void log(const char *file, int line, int sequence);
template <typename cookie_t>
- friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line);
+ friend cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection,
+ const char *file, int line);
+ template <typename reply_t>
+ friend reply_t *q_xcb_call_template(reply_t *reply, QXcbConnection *connection,
+ const char *file, int line);
#endif
WindowMapper m_mapper;
@@ -696,11 +700,19 @@ private:
#ifdef Q_XCB_DEBUG
template <typename cookie_t>
-cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file, int line)
+cookie_t q_xcb_call_template(const cookie_t &cookie, QXcbConnection *connection, const char *file,
+ int line)
{
connection->log(file, line, cookie.sequence);
return cookie;
}
+
+template <typename reply_t>
+reply_t *q_xcb_call_template(reply_t *reply, QXcbConnection *connection, const char *file, int line)
+{
+ connection->log(file, line, reply->sequence);
+ return reply;
+}
#define Q_XCB_CALL(x) q_xcb_call_template(x, connection(), __FILE__, __LINE__)
#define Q_XCB_CALL2(x, connection) q_xcb_call_template(x, connection, __FILE__, __LINE__)
#define Q_XCB_NOOP(c) q_xcb_call_template(xcb_no_operation(c->xcb_connection()), c, __FILE__, __LINE__);
diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h
index 3c6dece1f2..f6c1d9db90 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.h
+++ b/src/plugins/platforms/xcb/qxcbcursor.h
@@ -77,6 +77,11 @@ public:
static void queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDesktop, QPoint *pos, int *keybMask = 0);
+#ifndef QT_NO_CURSOR
+ xcb_cursor_t xcbCursor(const QCursor &c) const
+ { return m_cursorHash.value(QXcbCursorCacheKey(c), xcb_cursor_t(0)); }
+#endif
+
private:
#ifndef QT_NO_CURSOR
typedef QHash<QXcbCursorCacheKey, xcb_cursor_t> CursorHash;
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 19e8b1de7d..c42ea627a8 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -454,4 +454,17 @@ void QXcbIntegration::sync()
}
}
+// For QApplication::beep()
+void QXcbIntegration::beep() const
+{
+ QScreen *priScreen = QGuiApplication::primaryScreen();
+ if (!priScreen)
+ return;
+ QPlatformScreen *screen = priScreen->handle();
+ if (!screen)
+ return;
+ xcb_connection_t *connection = static_cast<QXcbScreen *>(screen)->xcb_connection();
+ xcb_bell(connection, 0);
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 4e2a3c2bbd..f833015596 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -104,6 +104,8 @@ public:
void sync() Q_DECL_OVERRIDE;
+ void beep() const Q_DECL_OVERRIDE;
+
static QXcbIntegration *instance() { return m_instance; }
private:
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 2e088d3ca5..0bfefc962e 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -1511,11 +1511,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type,
QWindow *window = targetWindow->window();
if (!filtered) {
+#ifndef QT_NO_CONTEXTMENU
if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu) {
const QPoint globalPos = window->screen()->handle()->cursor()->pos();
const QPoint pos = window->mapFromGlobal(globalPos);
QWindowSystemInterface::handleContextMenuEvent(window, false, pos, globalPos, modifiers);
}
+#endif // QT_NO_CONTEXTMENU
QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers,
code, sym, state, string, isAutoRepeat);
}
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index dfb0a125e2..1403cee622 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -33,6 +33,7 @@
#include "qxcbnativeinterface.h"
+#include "qxcbcursor.h"
#include "qxcbscreen.h"
#include "qxcbwindow.h"
#include "qxcbintegration.h"
@@ -91,18 +92,6 @@ QXcbNativeInterface::QXcbNativeInterface() :
{
}
-void QXcbNativeInterface::beep() // For QApplication::beep()
-{
- QScreen *priScreen = QGuiApplication::primaryScreen();
- if (!priScreen)
- return;
- QPlatformScreen *screen = priScreen->handle();
- if (!screen)
- return;
- xcb_connection_t *connection = static_cast<QXcbScreen *>(screen)->xcb_connection();
- xcb_bell(connection, 0);
-}
-
static inline QXcbSystemTrayTracker *systemTrayTracker(const QScreen *s)
{
if (!s)
@@ -288,6 +277,20 @@ void *QXcbNativeInterface::nativeResourceForBackingStore(const QByteArray &resou
return result;
}
+#ifndef QT_NO_CURSOR
+void *QXcbNativeInterface::nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor)
+{
+ if (resource == QByteArrayLiteral("xcbcursor")) {
+ if (const QScreen *primaryScreen = QGuiApplication::primaryScreen()) {
+ if (const QPlatformCursor *pCursor= primaryScreen->handle()->cursor()) {
+ xcb_cursor_t xcbCursor = static_cast<const QXcbCursor *>(pCursor)->xcbCursor(cursor);
+ return reinterpret_cast<void *>(quintptr(xcbCursor));
+ }
+ }
+ }
+ return Q_NULLPTR;
+}
+#endif // !QT_NO_CURSOR
QPlatformNativeInterface::NativeResourceForIntegrationFunction QXcbNativeInterface::nativeResourceFunctionForIntegration(const QByteArray &resource)
{
@@ -444,11 +447,15 @@ void *QXcbNativeInterface::atspiBus()
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection) {
xcb_atom_t atspiBusAtom = defaultConnection->internAtom("AT_SPI_BUS");
- xcb_get_property_cookie_t cookie = Q_XCB_CALL(xcb_get_property(defaultConnection->xcb_connection(), false,
- defaultConnection->rootWindow(),
- atspiBusAtom,
- XCB_ATOM_STRING, 0, 128));
- xcb_get_property_reply_t *reply = Q_XCB_CALL(xcb_get_property_reply(defaultConnection->xcb_connection(), cookie, 0));
+ xcb_get_property_cookie_t cookie = Q_XCB_CALL2(xcb_get_property(
+ defaultConnection->xcb_connection(),
+ false, defaultConnection->rootWindow(),
+ atspiBusAtom, XCB_ATOM_STRING, 0, 128),
+ defaultConnection);
+ xcb_get_property_reply_t *reply = Q_XCB_CALL2(xcb_get_property_reply(
+ defaultConnection->xcb_connection(),
+ cookie, 0),
+ defaultConnection);
Q_ASSERT(!reply->bytes_after);
char *data = (char *)xcb_get_property_value(reply);
int length = xcb_get_property_value_length(reply);
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index f88b710864..fdda10e307 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -78,6 +78,9 @@ public:
void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) Q_DECL_OVERRIDE;
void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) Q_DECL_OVERRIDE;
void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *backingStore) Q_DECL_OVERRIDE;
+#ifndef QT_NO_CURSOR
+ void *nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor) Q_DECL_OVERRIDE;
+#endif
NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
@@ -105,7 +108,6 @@ public:
static void setAppTime(QScreen *screen, xcb_timestamp_t time);
static void setAppUserTime(QScreen *screen, xcb_timestamp_t time);
- Q_INVOKABLE void beep();
Q_INVOKABLE bool systemTrayAvailable(const QScreen *screen) const;
Q_INVOKABLE void setParentRelativeBackPixmap(QWindow *window);
Q_INVOKABLE bool systrayVisualHasAlphaChannel();
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 4e4a0cdaef..f030252865 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -393,7 +393,7 @@ void QXcbWindow::create()
if (!visualInfo)
visualInfo = static_cast<XVisualInfo *>(createVisual());
- if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)
+ if (Q_UNLIKELY(!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface))
qFatal("Could not initialize OpenGL");
if (!visualInfo && window()->surfaceType() == QSurface::RasterGLSurface) {
@@ -1090,6 +1090,7 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
}
setWmWindowType(wmWindowTypes, flags);
+ setNetWmStateWindowFlags(flags);
setMotifWindowFlags(flags);
setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput);
@@ -1323,6 +1324,15 @@ void QXcbWindow::updateNetWmStateBeforeMap()
setNetWmStates(states);
}
+void QXcbWindow::setNetWmStateWindowFlags(Qt::WindowFlags flags)
+{
+ changeNetWmState(flags & Qt::WindowStaysOnTopHint,
+ atom(QXcbAtom::_NET_WM_STATE_ABOVE),
+ atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP));
+ changeNetWmState(flags & Qt::WindowStaysOnBottomHint,
+ atom(QXcbAtom::_NET_WM_STATE_BELOW));
+}
+
void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
{
xcb_window_t wid = m_window;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 3cfa71c9e0..8d3aef8e07 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -182,6 +182,7 @@ protected:
void setNetWmStates(NetWmStates);
void setMotifWindowFlags(Qt::WindowFlags flags);
+ void setNetWmStateWindowFlags(Qt::WindowFlags flags);
void updateMotifWmHintsBeforeMap();
void updateNetWmStateBeforeMap();
diff --git a/src/plugins/platformthemes/gtk2/gtk2.json b/src/plugins/platformthemes/gtk2/gtk2.json
deleted file mode 100644
index 86dd8e58fa..0000000000
--- a/src/plugins/platformthemes/gtk2/gtk2.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "Keys": [ "gtk2" ]
-}
diff --git a/src/plugins/platformthemes/gtk2/gtk2.pro b/src/plugins/platformthemes/gtk2/gtk2.pro
deleted file mode 100644
index 73c156f82b..0000000000
--- a/src/plugins/platformthemes/gtk2/gtk2.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-TARGET = qgtk2
-
-PLUGIN_TYPE = platformthemes
-PLUGIN_EXTENDS = -
-PLUGIN_CLASS_NAME = QGtk2ThemePlugin
-load(qt_plugin)
-
-QT += core-private gui-private platformsupport-private
-
-CONFIG += X11
-QMAKE_CXXFLAGS += $$QT_CFLAGS_QGTK2
-LIBS += $$QT_LIBS_QGTK2
-
-HEADERS += \
- qgtk2dialoghelpers.h \
- qgtk2theme.h
-
-SOURCES += \
- main.cpp \
- qgtk2dialoghelpers.cpp \
- qgtk2theme.cpp \
diff --git a/src/plugins/platformthemes/gtk3/gtk3.json b/src/plugins/platformthemes/gtk3/gtk3.json
new file mode 100644
index 0000000000..3887248353
--- /dev/null
+++ b/src/plugins/platformthemes/gtk3/gtk3.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "gtk3" ]
+}
diff --git a/src/plugins/platformthemes/gtk3/gtk3.pro b/src/plugins/platformthemes/gtk3/gtk3.pro
new file mode 100644
index 0000000000..cd19e73ed8
--- /dev/null
+++ b/src/plugins/platformthemes/gtk3/gtk3.pro
@@ -0,0 +1,21 @@
+TARGET = qgtk3
+
+PLUGIN_TYPE = platformthemes
+PLUGIN_EXTENDS = -
+PLUGIN_CLASS_NAME = QGtk3ThemePlugin
+load(qt_plugin)
+
+QT += core-private gui-private platformsupport-private
+
+CONFIG += X11
+QMAKE_CXXFLAGS += $$QT_CFLAGS_QGTK3
+LIBS += $$QT_LIBS_QGTK3
+
+HEADERS += \
+ qgtk3dialoghelpers.h \
+ qgtk3theme.h
+
+SOURCES += \
+ main.cpp \
+ qgtk3dialoghelpers.cpp \
+ qgtk3theme.cpp
diff --git a/src/plugins/platformthemes/gtk2/main.cpp b/src/plugins/platformthemes/gtk3/main.cpp
index 34ac3ffc07..c3e81b18e3 100644
--- a/src/plugins/platformthemes/gtk2/main.cpp
+++ b/src/plugins/platformthemes/gtk3/main.cpp
@@ -32,24 +32,24 @@
****************************************************************************/
#include <qpa/qplatformthemeplugin.h>
-#include "qgtk2theme.h"
+#include "qgtk3theme.h"
QT_BEGIN_NAMESPACE
-class QGtk2ThemePlugin : public QPlatformThemePlugin
+class QGtk3ThemePlugin : public QPlatformThemePlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QPlatformThemeFactoryInterface_iid FILE "gtk2.json")
+ Q_PLUGIN_METADATA(IID QPlatformThemeFactoryInterface_iid FILE "gtk3.json")
public:
QPlatformTheme *create(const QString &key, const QStringList &params) Q_DECL_OVERRIDE;
};
-QPlatformTheme *QGtk2ThemePlugin::create(const QString &key, const QStringList &params)
+QPlatformTheme *QGtk3ThemePlugin::create(const QString &key, const QStringList &params)
{
Q_UNUSED(params);
- if (!key.compare(QLatin1String(QGtk2Theme::name), Qt::CaseInsensitive))
- return new QGtk2Theme;
+ if (!key.compare(QLatin1String(QGtk3Theme::name), Qt::CaseInsensitive))
+ return new QGtk3Theme;
return 0;
}
diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp
index 857f373759..4af91ded27 100644
--- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include "qgtk2dialoghelpers.h"
+#include "qgtk3dialoghelpers.h"
#include <qeventloop.h>
#include <qwindow.h>
@@ -50,13 +50,13 @@
QT_BEGIN_NAMESPACE
-class QGtk2Dialog : public QWindow
+class QGtk3Dialog : public QWindow
{
Q_OBJECT
public:
- QGtk2Dialog(GtkWidget *gtkWidget);
- ~QGtk2Dialog();
+ QGtk3Dialog(GtkWidget *gtkWidget);
+ ~QGtk3Dialog();
GtkDialog *gtkDialog() const;
@@ -69,7 +69,7 @@ Q_SIGNALS:
void reject();
protected:
- static void onResponse(QGtk2Dialog *dialog, int response);
+ static void onResponse(QGtk3Dialog *dialog, int response);
private slots:
void onParentWindowDestroyed();
@@ -78,24 +78,24 @@ private:
GtkWidget *gtkWidget;
};
-QGtk2Dialog::QGtk2Dialog(GtkWidget *gtkWidget) : gtkWidget(gtkWidget)
+QGtk3Dialog::QGtk3Dialog(GtkWidget *gtkWidget) : gtkWidget(gtkWidget)
{
g_signal_connect_swapped(G_OBJECT(gtkWidget), "response", G_CALLBACK(onResponse), this);
g_signal_connect(G_OBJECT(gtkWidget), "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
}
-QGtk2Dialog::~QGtk2Dialog()
+QGtk3Dialog::~QGtk3Dialog()
{
gtk_clipboard_store(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
gtk_widget_destroy(gtkWidget);
}
-GtkDialog *QGtk2Dialog::gtkDialog() const
+GtkDialog *QGtk3Dialog::gtkDialog() const
{
return GTK_DIALOG(gtkWidget);
}
-void QGtk2Dialog::exec()
+void QGtk3Dialog::exec()
{
if (modality() == Qt::ApplicationModal) {
// block input to the whole app, including other GTK dialogs
@@ -109,9 +109,9 @@ void QGtk2Dialog::exec()
}
}
-bool QGtk2Dialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
+bool QGtk3Dialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
{
- connect(parent, &QWindow::destroyed, this, &QGtk2Dialog::onParentWindowDestroyed,
+ connect(parent, &QWindow::destroyed, this, &QGtk3Dialog::onParentWindowDestroyed,
Qt::UniqueConnection);
setParent(parent);
setFlags(flags);
@@ -119,29 +119,31 @@ bool QGtk2Dialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWind
gtk_widget_realize(gtkWidget); // creates X window
+ GdkWindow *gdkWindow = gtk_widget_get_window(gtkWidget);
if (parent) {
- XSetTransientForHint(gdk_x11_drawable_get_xdisplay(gtkWidget->window),
- gdk_x11_drawable_get_xid(gtkWidget->window),
+ GdkDisplay *gdkDisplay = gdk_window_get_display(gdkWindow);
+ XSetTransientForHint(gdk_x11_display_get_xdisplay(gdkDisplay),
+ gdk_x11_window_get_xid(gdkWindow),
parent->winId());
}
if (modality != Qt::NonModal) {
- gdk_window_set_modal_hint(gtkWidget->window, true);
+ gdk_window_set_modal_hint(gdkWindow, true);
QGuiApplicationPrivate::showModalWindow(this);
}
gtk_widget_show(gtkWidget);
- gdk_window_focus(gtkWidget->window, 0);
+ gdk_window_focus(gdkWindow, GDK_CURRENT_TIME);
return true;
}
-void QGtk2Dialog::hide()
+void QGtk3Dialog::hide()
{
QGuiApplicationPrivate::hideModalWindow(this);
gtk_widget_hide(gtkWidget);
}
-void QGtk2Dialog::onResponse(QGtk2Dialog *dialog, int response)
+void QGtk3Dialog::onResponse(QGtk3Dialog *dialog, int response)
{
if (response == GTK_RESPONSE_OK)
emit dialog->accept();
@@ -149,101 +151,84 @@ void QGtk2Dialog::onResponse(QGtk2Dialog *dialog, int response)
emit dialog->reject();
}
-void QGtk2Dialog::onParentWindowDestroyed()
+void QGtk3Dialog::onParentWindowDestroyed()
{
- // The QGtk2*DialogHelper classes own this object. Make sure the parent doesn't delete it.
+ // The QGtk3*DialogHelper classes own this object. Make sure the parent doesn't delete it.
setParent(0);
}
-QGtk2ColorDialogHelper::QGtk2ColorDialogHelper()
+QGtk3ColorDialogHelper::QGtk3ColorDialogHelper()
{
- d.reset(new QGtk2Dialog(gtk_color_selection_dialog_new("")));
+ d.reset(new QGtk3Dialog(gtk_color_chooser_dialog_new("", 0)));
connect(d.data(), SIGNAL(accept()), this, SLOT(onAccepted()));
connect(d.data(), SIGNAL(reject()), this, SIGNAL(reject()));
- GtkWidget *gtkColorSelection = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(d->gtkDialog()));
- g_signal_connect_swapped(gtkColorSelection, "color-changed", G_CALLBACK(onColorChanged), this);
+ g_signal_connect_swapped(d->gtkDialog(), "color-activated", G_CALLBACK(onColorChanged), this);
}
-QGtk2ColorDialogHelper::~QGtk2ColorDialogHelper()
+QGtk3ColorDialogHelper::~QGtk3ColorDialogHelper()
{
}
-bool QGtk2ColorDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
+bool QGtk3ColorDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
{
applyOptions();
return d->show(flags, modality, parent);
}
-void QGtk2ColorDialogHelper::exec()
+void QGtk3ColorDialogHelper::exec()
{
d->exec();
}
-void QGtk2ColorDialogHelper::hide()
+void QGtk3ColorDialogHelper::hide()
{
d->hide();
}
-void QGtk2ColorDialogHelper::setCurrentColor(const QColor &color)
+void QGtk3ColorDialogHelper::setCurrentColor(const QColor &color)
{
GtkDialog *gtkDialog = d->gtkDialog();
- GtkWidget *gtkColorSelection = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(gtkDialog));
- GdkColor gdkColor;
- gdkColor.red = color.red() << 8;
- gdkColor.green = color.green() << 8;
- gdkColor.blue = color.blue() << 8;
- gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(gtkColorSelection), &gdkColor);
- if (color.alpha() < 255) {
- gtk_color_selection_set_has_opacity_control(GTK_COLOR_SELECTION(gtkColorSelection), true);
- gtk_color_selection_set_current_alpha(GTK_COLOR_SELECTION(gtkColorSelection), color.alpha() << 8);
- }
+ if (color.alpha() < 255)
+ gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(gtkDialog), true);
+ GdkRGBA gdkColor;
+ gdkColor.red = color.redF();
+ gdkColor.green = color.greenF();
+ gdkColor.blue = color.blueF();
+ gdkColor.alpha = color.alphaF();
+ gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(gtkDialog), &gdkColor);
}
-QColor QGtk2ColorDialogHelper::currentColor() const
+QColor QGtk3ColorDialogHelper::currentColor() const
{
GtkDialog *gtkDialog = d->gtkDialog();
- GtkWidget *gtkColorSelection = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(gtkDialog));
- GdkColor gdkColor;
- gtk_color_selection_get_current_color(GTK_COLOR_SELECTION(gtkColorSelection), &gdkColor);
- guint16 alpha = gtk_color_selection_get_current_alpha(GTK_COLOR_SELECTION(gtkColorSelection));
- return QColor(gdkColor.red >> 8, gdkColor.green >> 8, gdkColor.blue >> 8, alpha >> 8);
+ GdkRGBA gdkColor;
+ gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(gtkDialog), &gdkColor);
+ return QColor::fromRgbF(gdkColor.red, gdkColor.green, gdkColor.blue, gdkColor.alpha);
}
-void QGtk2ColorDialogHelper::onAccepted()
+void QGtk3ColorDialogHelper::onAccepted()
{
emit accept();
emit colorSelected(currentColor());
}
-void QGtk2ColorDialogHelper::onColorChanged(QGtk2ColorDialogHelper *dialog)
+void QGtk3ColorDialogHelper::onColorChanged(QGtk3ColorDialogHelper *dialog)
{
emit dialog->currentColorChanged(dialog->currentColor());
}
-void QGtk2ColorDialogHelper::applyOptions()
+void QGtk3ColorDialogHelper::applyOptions()
{
GtkDialog *gtkDialog = d->gtkDialog();
gtk_window_set_title(GTK_WINDOW(gtkDialog), options()->windowTitle().toUtf8());
- GtkWidget *gtkColorSelection = gtk_color_selection_dialog_get_color_selection(GTK_COLOR_SELECTION_DIALOG(gtkDialog));
- gtk_color_selection_set_has_opacity_control(GTK_COLOR_SELECTION(gtkColorSelection), options()->testOption(QColorDialogOptions::ShowAlphaChannel));
-
- GtkWidget *okButton = 0;
- GtkWidget *cancelButton = 0;
- GtkWidget *helpButton = 0;
- g_object_get(G_OBJECT(gtkDialog), "ok-button", &okButton, "cancel-button", &cancelButton, "help-button", &helpButton, NULL);
- if (okButton)
- g_object_set(G_OBJECT(okButton), "visible", !options()->testOption(QColorDialogOptions::NoButtons), NULL);
- if (cancelButton)
- g_object_set(G_OBJECT(cancelButton), "visible", !options()->testOption(QColorDialogOptions::NoButtons), NULL);
- if (helpButton)
- gtk_widget_hide(helpButton);
+ gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(gtkDialog), options()->testOption(QColorDialogOptions::ShowAlphaChannel));
}
-QGtk2FileDialogHelper::QGtk2FileDialogHelper()
+QGtk3FileDialogHelper::QGtk3FileDialogHelper()
{
- d.reset(new QGtk2Dialog(gtk_file_chooser_dialog_new("", 0,
+ d.reset(new QGtk3Dialog(gtk_file_chooser_dialog_new("", 0,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK, NULL)));
@@ -254,11 +239,11 @@ QGtk2FileDialogHelper::QGtk2FileDialogHelper()
g_signal_connect_swapped(GTK_FILE_CHOOSER(d->gtkDialog()), "current-folder-changed", G_CALLBACK(onCurrentFolderChanged), this);
}
-QGtk2FileDialogHelper::~QGtk2FileDialogHelper()
+QGtk3FileDialogHelper::~QGtk3FileDialogHelper()
{
}
-bool QGtk2FileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
+bool QGtk3FileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
{
_dir.clear();
_selection.clear();
@@ -267,12 +252,12 @@ bool QGtk2FileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modal
return d->show(flags, modality, parent);
}
-void QGtk2FileDialogHelper::exec()
+void QGtk3FileDialogHelper::exec()
{
d->exec();
}
-void QGtk2FileDialogHelper::hide()
+void QGtk3FileDialogHelper::hide()
{
// After GtkFileChooserDialog has been hidden, gtk_file_chooser_get_current_folder()
// & gtk_file_chooser_get_filenames() will return bogus values -> cache the actual
@@ -283,18 +268,18 @@ void QGtk2FileDialogHelper::hide()
d->hide();
}
-bool QGtk2FileDialogHelper::defaultNameFilterDisables() const
+bool QGtk3FileDialogHelper::defaultNameFilterDisables() const
{
return false;
}
-void QGtk2FileDialogHelper::setDirectory(const QUrl &directory)
+void QGtk3FileDialogHelper::setDirectory(const QUrl &directory)
{
GtkDialog *gtkDialog = d->gtkDialog();
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(gtkDialog), directory.toLocalFile().toUtf8());
}
-QUrl QGtk2FileDialogHelper::directory() const
+QUrl QGtk3FileDialogHelper::directory() const
{
// While GtkFileChooserDialog is hidden, gtk_file_chooser_get_current_folder()
// returns a bogus value -> return the cached value before hiding
@@ -311,7 +296,7 @@ QUrl QGtk2FileDialogHelper::directory() const
return QUrl::fromLocalFile(ret);
}
-void QGtk2FileDialogHelper::selectFile(const QUrl &filename)
+void QGtk3FileDialogHelper::selectFile(const QUrl &filename)
{
GtkDialog *gtkDialog = d->gtkDialog();
if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
@@ -323,7 +308,7 @@ void QGtk2FileDialogHelper::selectFile(const QUrl &filename)
}
}
-QList<QUrl> QGtk2FileDialogHelper::selectedFiles() const
+QList<QUrl> QGtk3FileDialogHelper::selectedFiles() const
{
// While GtkFileChooserDialog is hidden, gtk_file_chooser_get_filenames()
// returns a bogus value -> return the cached value before hiding
@@ -339,12 +324,12 @@ QList<QUrl> QGtk2FileDialogHelper::selectedFiles() const
return selection;
}
-void QGtk2FileDialogHelper::setFilter()
+void QGtk3FileDialogHelper::setFilter()
{
applyOptions();
}
-void QGtk2FileDialogHelper::selectNameFilter(const QString &filter)
+void QGtk3FileDialogHelper::selectNameFilter(const QString &filter)
{
GtkFileFilter *gtkFilter = _filters.value(filter);
if (gtkFilter) {
@@ -353,14 +338,14 @@ void QGtk2FileDialogHelper::selectNameFilter(const QString &filter)
}
}
-QString QGtk2FileDialogHelper::selectedNameFilter() const
+QString QGtk3FileDialogHelper::selectedNameFilter() const
{
GtkDialog *gtkDialog = d->gtkDialog();
GtkFileFilter *gtkFilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(gtkDialog));
return _filterNames.value(gtkFilter);
}
-void QGtk2FileDialogHelper::onAccepted()
+void QGtk3FileDialogHelper::onAccepted()
{
emit accept();
@@ -374,7 +359,7 @@ void QGtk2FileDialogHelper::onAccepted()
emit fileSelected(files.first());
}
-void QGtk2FileDialogHelper::onSelectionChanged(GtkDialog *gtkDialog, QGtk2FileDialogHelper *helper)
+void QGtk3FileDialogHelper::onSelectionChanged(GtkDialog *gtkDialog, QGtk3FileDialogHelper *helper)
{
QString selection;
gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(gtkDialog));
@@ -385,7 +370,7 @@ void QGtk2FileDialogHelper::onSelectionChanged(GtkDialog *gtkDialog, QGtk2FileDi
emit helper->currentChanged(QUrl::fromLocalFile(selection));
}
-void QGtk2FileDialogHelper::onCurrentFolderChanged(QGtk2FileDialogHelper *dialog)
+void QGtk3FileDialogHelper::onCurrentFolderChanged(QGtk3FileDialogHelper *dialog)
{
emit dialog->directoryEntered(dialog->directory());
}
@@ -410,7 +395,7 @@ static GtkFileChooserAction gtkFileChooserAction(const QSharedPointer<QFileDialo
}
}
-void QGtk2FileDialogHelper::applyOptions()
+void QGtk3FileDialogHelper::applyOptions()
{
GtkDialog *gtkDialog = d->gtkDialog();
const QSharedPointer<QFileDialogOptions> &opts = options();
@@ -441,7 +426,6 @@ void QGtk2FileDialogHelper::applyOptions()
if (!initialNameFilter.isEmpty())
selectNameFilter(initialNameFilter);
-#if GTK_CHECK_VERSION(2, 20, 0)
GtkWidget *acceptButton = gtk_dialog_get_widget_for_response(gtkDialog, GTK_RESPONSE_OK);
if (acceptButton) {
if (opts->isLabelExplicitlySet(QFileDialogOptions::Accept))
@@ -459,10 +443,9 @@ void QGtk2FileDialogHelper::applyOptions()
else
gtk_button_set_label(GTK_BUTTON(rejectButton), GTK_STOCK_CANCEL);
}
-#endif
}
-void QGtk2FileDialogHelper::setNameFilters(const QStringList &filters)
+void QGtk3FileDialogHelper::setNameFilters(const QStringList &filters)
{
GtkDialog *gtkDialog = d->gtkDialog();
foreach (GtkFileFilter *filter, _filters)
@@ -487,29 +470,29 @@ void QGtk2FileDialogHelper::setNameFilters(const QStringList &filters)
}
}
-QGtk2FontDialogHelper::QGtk2FontDialogHelper()
+QGtk3FontDialogHelper::QGtk3FontDialogHelper()
{
- d.reset(new QGtk2Dialog(gtk_font_selection_dialog_new("")));
+ d.reset(new QGtk3Dialog(gtk_font_chooser_dialog_new("", 0)));
connect(d.data(), SIGNAL(accept()), this, SLOT(onAccepted()));
connect(d.data(), SIGNAL(reject()), this, SIGNAL(reject()));
}
-QGtk2FontDialogHelper::~QGtk2FontDialogHelper()
+QGtk3FontDialogHelper::~QGtk3FontDialogHelper()
{
}
-bool QGtk2FontDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
+bool QGtk3FontDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent)
{
applyOptions();
return d->show(flags, modality, parent);
}
-void QGtk2FontDialogHelper::exec()
+void QGtk3FontDialogHelper::exec()
{
d->exec();
}
-void QGtk2FontDialogHelper::hide()
+void QGtk3FontDialogHelper::hide()
{
d->hide();
}
@@ -580,43 +563,36 @@ static QFont qt_fontFromString(const QString &name)
return font;
}
-void QGtk2FontDialogHelper::setCurrentFont(const QFont &font)
+void QGtk3FontDialogHelper::setCurrentFont(const QFont &font)
{
- GtkFontSelectionDialog *gtkDialog = GTK_FONT_SELECTION_DIALOG(d->gtkDialog());
- gtk_font_selection_dialog_set_font_name(gtkDialog, qt_fontToString(font).toUtf8());
+ GtkFontChooser *gtkDialog = GTK_FONT_CHOOSER(d->gtkDialog());
+ gtk_font_chooser_set_font(gtkDialog, qt_fontToString(font).toUtf8());
}
-QFont QGtk2FontDialogHelper::currentFont() const
+QFont QGtk3FontDialogHelper::currentFont() const
{
- GtkFontSelectionDialog *gtkDialog = GTK_FONT_SELECTION_DIALOG(d->gtkDialog());
- gchar *name = gtk_font_selection_dialog_get_font_name(gtkDialog);
+ GtkFontChooser *gtkDialog = GTK_FONT_CHOOSER(d->gtkDialog());
+ gchar *name = gtk_font_chooser_get_font(gtkDialog);
QFont font = qt_fontFromString(QString::fromUtf8(name));
g_free(name);
return font;
}
-void QGtk2FontDialogHelper::onAccepted()
+void QGtk3FontDialogHelper::onAccepted()
{
emit currentFontChanged(currentFont());
emit accept();
emit fontSelected(currentFont());
}
-void QGtk2FontDialogHelper::applyOptions()
+void QGtk3FontDialogHelper::applyOptions()
{
GtkDialog *gtkDialog = d->gtkDialog();
const QSharedPointer<QFontDialogOptions> &opts = options();
gtk_window_set_title(GTK_WINDOW(gtkDialog), opts->windowTitle().toUtf8());
-
- GtkWidget *okButton = gtk_font_selection_dialog_get_ok_button(GTK_FONT_SELECTION_DIALOG(gtkDialog));
- GtkWidget *cancelButton = gtk_font_selection_dialog_get_cancel_button(GTK_FONT_SELECTION_DIALOG(gtkDialog));
- if (okButton)
- gtk_widget_set_visible(okButton, !options()->testOption(QFontDialogOptions::NoButtons));
- if (cancelButton)
- gtk_widget_set_visible(cancelButton, !options()->testOption(QFontDialogOptions::NoButtons));
}
QT_END_NAMESPACE
-#include "qgtk2dialoghelpers.moc"
+#include "qgtk3dialoghelpers.moc"
diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h
index 141056637e..438dee861b 100644
--- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.h
+++ b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#ifndef QGTK2DIALOGHELPERS_P_H
-#define QGTK2DIALOGHELPERS_P_H
+#ifndef QGTK3DIALOGHELPERS_H
+#define QGTK3DIALOGHELPERS_H
#include <QtCore/qhash.h>
#include <QtCore/qlist.h>
@@ -46,16 +46,16 @@ typedef struct _GtkFileFilter GtkFileFilter;
QT_BEGIN_NAMESPACE
-class QGtk2Dialog;
+class QGtk3Dialog;
class QColor;
-class QGtk2ColorDialogHelper : public QPlatformColorDialogHelper
+class QGtk3ColorDialogHelper : public QPlatformColorDialogHelper
{
Q_OBJECT
public:
- QGtk2ColorDialogHelper();
- ~QGtk2ColorDialogHelper();
+ QGtk3ColorDialogHelper();
+ ~QGtk3ColorDialogHelper();
bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) Q_DECL_OVERRIDE;
void exec() Q_DECL_OVERRIDE;
@@ -68,19 +68,19 @@ private Q_SLOTS:
void onAccepted();
private:
- static void onColorChanged(QGtk2ColorDialogHelper *helper);
+ static void onColorChanged(QGtk3ColorDialogHelper *helper);
void applyOptions();
- QScopedPointer<QGtk2Dialog> d;
+ QScopedPointer<QGtk3Dialog> d;
};
-class QGtk2FileDialogHelper : public QPlatformFileDialogHelper
+class QGtk3FileDialogHelper : public QPlatformFileDialogHelper
{
Q_OBJECT
public:
- QGtk2FileDialogHelper();
- ~QGtk2FileDialogHelper();
+ QGtk3FileDialogHelper();
+ ~QGtk3FileDialogHelper();
bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) Q_DECL_OVERRIDE;
void exec() Q_DECL_OVERRIDE;
@@ -99,8 +99,8 @@ private Q_SLOTS:
void onAccepted();
private:
- static void onSelectionChanged(GtkDialog *dialog, QGtk2FileDialogHelper *helper);
- static void onCurrentFolderChanged(QGtk2FileDialogHelper *helper);
+ static void onSelectionChanged(GtkDialog *dialog, QGtk3FileDialogHelper *helper);
+ static void onCurrentFolderChanged(QGtk3FileDialogHelper *helper);
void applyOptions();
void setNameFilters(const QStringList &filters);
@@ -108,16 +108,16 @@ private:
QList<QUrl> _selection;
QHash<QString, GtkFileFilter*> _filters;
QHash<GtkFileFilter*, QString> _filterNames;
- QScopedPointer<QGtk2Dialog> d;
+ QScopedPointer<QGtk3Dialog> d;
};
-class QGtk2FontDialogHelper : public QPlatformFontDialogHelper
+class QGtk3FontDialogHelper : public QPlatformFontDialogHelper
{
Q_OBJECT
public:
- QGtk2FontDialogHelper();
- ~QGtk2FontDialogHelper();
+ QGtk3FontDialogHelper();
+ ~QGtk3FontDialogHelper();
bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) Q_DECL_OVERRIDE;
void exec() Q_DECL_OVERRIDE;
@@ -132,9 +132,9 @@ private Q_SLOTS:
private:
void applyOptions();
- QScopedPointer<QGtk2Dialog> d;
+ QScopedPointer<QGtk3Dialog> d;
};
QT_END_NAMESPACE
-#endif // QGTK2DIALOGHELPERS_P_H
+#endif // QGTK3DIALOGHELPERS_H
diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index a7f08bc047..76afc441a4 100644
--- a/src/plugins/platformthemes/gtk2/qgtk2theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -31,8 +31,8 @@
**
****************************************************************************/
-#include "qgtk2theme.h"
-#include "qgtk2dialoghelpers.h"
+#include "qgtk3theme.h"
+#include "qgtk3dialoghelpers.h"
#include <QVariant>
#undef signals
@@ -42,7 +42,7 @@
QT_BEGIN_NAMESPACE
-const char *QGtk2Theme::name = "gtk2";
+const char *QGtk3Theme::name = "gtk3";
static QString gtkSetting(const gchar *propertyName)
{
@@ -54,7 +54,21 @@ static QString gtkSetting(const gchar *propertyName)
return str;
}
-QGtk2Theme::QGtk2Theme()
+void gtkMessageHandler(const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer unused_data) {
+ /* Silence false-positive Gtk warnings (we are using Xlib to set
+ * the WM_TRANSIENT_FOR hint).
+ */
+ if (g_strcmp0(message, "GtkDialog mapped without a transient parent. "
+ "This is discouraged.") != 0) {
+ /* For other messages, call the default handler. */
+ g_log_default_handler(log_domain, log_level, message, unused_data);
+ }
+}
+
+QGtk3Theme::QGtk3Theme()
{
// gtk_init will reset the Xlib error handler, and that causes
// Qt applications to quit on X errors. Therefore, we need to manually restore it.
@@ -63,9 +77,18 @@ QGtk2Theme::QGtk2Theme()
gtk_init(0, 0);
XSetErrorHandler(oldErrorHandler);
+
+ /* Initialize some types here so that Gtk+ does not crash when reading
+ * the treemodel for GtkFontChooser.
+ */
+ g_type_ensure(PANGO_TYPE_FONT_FAMILY);
+ g_type_ensure(PANGO_TYPE_FONT_FACE);
+
+ /* Use our custom log handler. */
+ g_log_set_handler("Gtk", G_LOG_LEVEL_MESSAGE, gtkMessageHandler, NULL);
}
-QVariant QGtk2Theme::themeHint(QPlatformTheme::ThemeHint hint) const
+QVariant QGtk3Theme::themeHint(QPlatformTheme::ThemeHint hint) const
{
switch (hint) {
case QPlatformTheme::SystemIconThemeName:
@@ -77,7 +100,7 @@ QVariant QGtk2Theme::themeHint(QPlatformTheme::ThemeHint hint) const
}
}
-QString QGtk2Theme::gtkFontName() const
+QString QGtk3Theme::gtkFontName() const
{
QString cfgFontName = gtkSetting("gtk-font-name");
if (!cfgFontName.isEmpty())
@@ -85,7 +108,7 @@ QString QGtk2Theme::gtkFontName() const
return QGnomeTheme::gtkFontName();
}
-bool QGtk2Theme::usePlatformNativeDialog(DialogType type) const
+bool QGtk3Theme::usePlatformNativeDialog(DialogType type) const
{
switch (type) {
case ColorDialog:
@@ -99,15 +122,15 @@ bool QGtk2Theme::usePlatformNativeDialog(DialogType type) const
}
}
-QPlatformDialogHelper *QGtk2Theme::createPlatformDialogHelper(DialogType type) const
+QPlatformDialogHelper *QGtk3Theme::createPlatformDialogHelper(DialogType type) const
{
switch (type) {
case ColorDialog:
- return new QGtk2ColorDialogHelper;
+ return new QGtk3ColorDialogHelper;
case FileDialog:
- return new QGtk2FileDialogHelper;
+ return new QGtk3FileDialogHelper;
case FontDialog:
- return new QGtk2FontDialogHelper;
+ return new QGtk3FontDialogHelper;
default:
return 0;
}
diff --git a/src/plugins/platformthemes/gtk2/qgtk2theme.h b/src/plugins/platformthemes/gtk3/qgtk3theme.h
index 8798fed1f7..1597f6e911 100644
--- a/src/plugins/platformthemes/gtk2/qgtk2theme.h
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.h
@@ -31,17 +31,17 @@
**
****************************************************************************/
-#ifndef QGTK2THEME_H
-#define QGTK2THEME_H
+#ifndef QGTK3THEME_H
+#define QGTK3THEME_H
#include <private/qgenericunixthemes_p.h>
QT_BEGIN_NAMESPACE
-class QGtk2Theme : public QGnomeTheme
+class QGtk3Theme : public QGnomeTheme
{
public:
- QGtk2Theme();
+ QGtk3Theme();
virtual QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE;
virtual QString gtkFontName() const Q_DECL_OVERRIDE;
@@ -54,4 +54,4 @@ public:
QT_END_NAMESPACE
-#endif // QGTK2THEME_H
+#endif // QGTK3THEME_H
diff --git a/src/plugins/platformthemes/platformthemes.pro b/src/plugins/platformthemes/platformthemes.pro
index 23dcda2c82..f5f54068a2 100644
--- a/src/plugins/platformthemes/platformthemes.pro
+++ b/src/plugins/platformthemes/platformthemes.pro
@@ -1,3 +1,3 @@
TEMPLATE = subdirs
-contains(QT_CONFIG, gtk2): SUBDIRS += gtk2
+contains(QT_CONFIG, gtk3): SUBDIRS += gtk3
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 03b7dc266b..55660ce31c 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -8,7 +8,6 @@ qtHaveModule(gui) {
!contains(QT_DISABLED_FEATURES, imageformatplugin): SUBDIRS *= imageformats
!contains(QT_DISABLED_FEATURES, library): SUBDIRS *= generic
}
-qtHaveModule(widgets): SUBDIRS *= styles
!winrt:!wince*:qtHaveModule(widgets):!contains(QT_DISABLED_FEATURES, printer) {
SUBDIRS += printsupport
diff --git a/src/plugins/printsupport/cocoa/cocoa.pro b/src/plugins/printsupport/cocoa/cocoa.pro
index a3b9e2dfcf..c993b42574 100644
--- a/src/plugins/printsupport/cocoa/cocoa.pro
+++ b/src/plugins/printsupport/cocoa/cocoa.pro
@@ -5,7 +5,7 @@ PLUGIN_CLASS_NAME = QCocoaPrinterSupportPlugin
load(qt_plugin)
QT += gui-private printsupport-private
-LIBS += -framework Cocoa
+LIBS += -framework AppKit
SOURCES += main.cpp
diff --git a/src/plugins/styles/bb10style/bb10lightstyle.qrc b/src/plugins/styles/bb10style/bb10lightstyle.qrc
deleted file mode 100644
index 0777e009bb..0000000000
--- a/src/plugins/styles/bb10style/bb10lightstyle.qrc
+++ /dev/null
@@ -1,54 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>light/button/core_button_disabled.png</file>
- <file>light/button/core_button_inactive.png</file>
- <file>light/button/core_button_pressed.png</file>
- <file>light/checkbox/core_checkbox_checked.png</file>
- <file>light/checkbox/core_checkbox_disabled.png</file>
- <file>light/checkbox/core_checkbox_disabledchecked.png</file>
- <file>light/checkbox/core_checkbox_enabled.png</file>
- <file>light/checkbox/core_checkbox_pressed.png</file>
- <file>light/checkbox/core_checkbox_pressedchecked.png</file>
- <file>light/radiobutton/core_radiobutton_checked.png</file>
- <file>light/radiobutton/core_radiobutton_disabled.png</file>
- <file>light/radiobutton/core_radiobutton_disabledchecked.png</file>
- <file>light/radiobutton/core_radiobutton_enabled.png</file>
- <file>light/radiobutton/core_radiobutton_pressed.png</file>
- <file>light/slider/core_slider_active.png</file>
- <file>light/slider/core_slider_disabled.png</file>
- <file>light/slider/core_slider_handle.png</file>
- <file>light/slider/core_slider_handle_disabled.png</file>
- <file>light/slider/core_slider_handle_pressed.png</file>
- <file>light/slider/core_slider_inactive.png</file>
- <file>light/slider/core_slider_vactive.png</file>
- <file>light/slider/core_slider_vdisabled.png</file>
- <file>light/slider/core_slider_vinactive.png</file>
- <file>light/slider/core_slider_black.png</file>
- <file>light/slider/core_slider_enabled.png</file>
- <file>light/slider/core_slider_vblack.png</file>
- <file>light/slider/core_slider_venabled.png</file>
- <file>light/button/core_button_active.png</file>
- <file>light/lineedit/core_textinput_bg.png</file>
- <file>light/lineedit/core_textinput_bg_disabled.png</file>
- <file>light/lineedit/core_textinput_bg_focused.png</file>
- <file>light/progressbar/core_progressindicator_bg.png</file>
- <file>light/progressbar/core_progressindicator_complete.png</file>
- <file>light/progressbar/core_progressindicator_fill.png</file>
- <file>light/progressbar/core_progressindicator_vbg.png</file>
- <file>light/progressbar/core_progressindicator_vcomplete.png</file>
- <file>light/progressbar/core_progressindicator_vfill.png</file>
- <file>light/combobox/core_dropdown_button.png</file>
- <file>light/combobox/core_dropdown_button_arrowdown.png</file>
- <file>light/combobox/core_dropdown_button_arrowdown_pressed.png</file>
- <file>light/combobox/core_dropdown_button_arrowup.png</file>
- <file>light/combobox/core_dropdown_button_disabled.png</file>
- <file>light/combobox/core_dropdown_button_pressed.png</file>
- <file>light/combobox/core_dropdown_checkmark.png</file>
- <file>light/combobox/core_dropdown_divider.png</file>
- <file>light/combobox/core_dropdown_menu.png</file>
- <file>light/combobox/core_dropdown_menuup.png</file>
- <file>light/combobox/core_listitem_active.png</file>
- <file>light/listitem/core_listitem_active.png</file>
- <file>light/listitem/core_listitem_divider.png</file>
- </qresource>
-</RCC>
diff --git a/src/plugins/styles/bb10style/bb10style.pro b/src/plugins/styles/bb10style/bb10style.pro
deleted file mode 100644
index ad35df6de7..0000000000
--- a/src/plugins/styles/bb10style/bb10style.pro
+++ /dev/null
@@ -1,28 +0,0 @@
-TARGET = bb10styleplugin
-
-PLUGIN_TYPE = styles
-PLUGIN_CLASS_NAME = BlackBerry10StylePlugin
-load(qt_plugin)
-
-INCLUDEPATH += $$PWD
-
-QT += widgets
-
-HEADERS += \
- qpixmapstyle.h \
- qbb10brightstyle.h \
- qbb10darkstyle.h \
- qbb10styleplugin.h
-
-SOURCES += \
- qpixmapstyle.cpp \
- qbb10brightstyle.cpp \
- qbb10darkstyle.cpp \
- qbb10styleplugin.cpp
-
-RESOURCES += \
- qbb10brightstyle.qrc \
- qbb10darkstyle.qrc
-
-OTHER_FILES += qbb10styleplugin.json
-
diff --git a/src/plugins/styles/bb10style/bright/button/core_button_disabled.png b/src/plugins/styles/bb10style/bright/button/core_button_disabled.png
deleted file mode 100644
index 578a2383b8..0000000000
--- a/src/plugins/styles/bb10style/bright/button/core_button_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/button/core_button_disabled_selected.png b/src/plugins/styles/bb10style/bright/button/core_button_disabled_selected.png
deleted file mode 100644
index 7cd998af46..0000000000
--- a/src/plugins/styles/bb10style/bright/button/core_button_disabled_selected.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/button/core_button_enabled_selected.png b/src/plugins/styles/bb10style/bright/button/core_button_enabled_selected.png
deleted file mode 100644
index ff0850f616..0000000000
--- a/src/plugins/styles/bb10style/bright/button/core_button_enabled_selected.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/button/core_button_inactive.png b/src/plugins/styles/bb10style/bright/button/core_button_inactive.png
deleted file mode 100644
index 7769f15e44..0000000000
--- a/src/plugins/styles/bb10style/bright/button/core_button_inactive.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/button/core_button_pressed.png b/src/plugins/styles/bb10style/bright/button/core_button_pressed.png
deleted file mode 100644
index 59b5bfa7c2..0000000000
--- a/src/plugins/styles/bb10style/bright/button/core_button_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_checked.png b/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_checked.png
deleted file mode 100644
index c59f60633c..0000000000
--- a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_checked.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_disabled.png b/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_disabled.png
deleted file mode 100644
index 49d9cfdf94..0000000000
--- a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_disabled_checked.png b/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_disabled_checked.png
deleted file mode 100644
index 35751553e1..0000000000
--- a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_disabled_checked.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_enabled.png b/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_enabled.png
deleted file mode 100644
index 2a0c56b503..0000000000
--- a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_enabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.png b/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.png
deleted file mode 100644
index f1c2ee3bed..0000000000
--- a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed_checked.png b/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed_checked.png
deleted file mode 100644
index d58df47cbf..0000000000
--- a/src/plugins/styles/bb10style/bright/checkbox/core_checkbox_pressed_checked.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button.png b/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button.png
deleted file mode 100644
index 1aa844309f..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowdown.png b/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowdown.png
deleted file mode 100644
index 9ac049fb3d..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowdown.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowdown_pressed.png b/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowdown_pressed.png
deleted file mode 100644
index d11af56b71..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowdown_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowup.png b/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowup.png
deleted file mode 100644
index d10779d8d7..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_arrowup.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_disabled.png b/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_disabled.png
deleted file mode 100644
index f9e1c9465b..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_pressed.png b/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_pressed.png
deleted file mode 100644
index 27a321e387..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_button_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_checkmark.png b/src/plugins/styles/bb10style/bright/combobox/core_dropdown_checkmark.png
deleted file mode 100644
index a8270aed56..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_checkmark.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_divider.png b/src/plugins/styles/bb10style/bright/combobox/core_dropdown_divider.png
deleted file mode 100644
index 0198293ad6..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_divider.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_menu.png b/src/plugins/styles/bb10style/bright/combobox/core_dropdown_menu.png
deleted file mode 100644
index 47e7b2d4b6..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_menu.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_menuup.png b/src/plugins/styles/bb10style/bright/combobox/core_dropdown_menuup.png
deleted file mode 100644
index 2bde84e71d..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_dropdown_menuup.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/combobox/core_listitem_active.png b/src/plugins/styles/bb10style/bright/combobox/core_listitem_active.png
deleted file mode 100644
index 4935d13c05..0000000000
--- a/src/plugins/styles/bb10style/bright/combobox/core_listitem_active.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.png b/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.png
deleted file mode 100644
index 07b8ea21bf..0000000000
--- a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_disabled.png b/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_disabled.png
deleted file mode 100644
index ab1083e9fa..0000000000
--- a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.png b/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.png
deleted file mode 100644
index 55f8aee066..0000000000
--- a/src/plugins/styles/bb10style/bright/lineedit/core_textinput_bg_highlight.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/listitem/core_listitem_active.png b/src/plugins/styles/bb10style/bright/listitem/core_listitem_active.png
deleted file mode 100644
index 34daccc27e..0000000000
--- a/src/plugins/styles/bb10style/bright/listitem/core_listitem_active.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.png b/src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.png
deleted file mode 100644
index 7a1e22321d..0000000000
--- a/src/plugins/styles/bb10style/bright/listitem/core_listitem_divider.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.png b/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.png
deleted file mode 100644
index 3ff930dea7..0000000000
--- a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_bg.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_complete.png b/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_complete.png
deleted file mode 100644
index 87974668ff..0000000000
--- a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_complete.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_fill.png b/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_fill.png
deleted file mode 100644
index 8ff257dad3..0000000000
--- a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_fill.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vbg.png b/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vbg.png
deleted file mode 100644
index 66cf8cac8f..0000000000
--- a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vbg.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vcomplete.png b/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vcomplete.png
deleted file mode 100644
index f18e0abafb..0000000000
--- a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vcomplete.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vfill.png b/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vfill.png
deleted file mode 100644
index 94e388a7aa..0000000000
--- a/src/plugins/styles/bb10style/bright/progressbar/core_progressindicator_vfill.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_checked.png b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_checked.png
deleted file mode 100644
index 5dc5e52d88..0000000000
--- a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_checked.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_disabled.png b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_disabled.png
deleted file mode 100644
index 077aa79c65..0000000000
--- a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_disabled_checked.png b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_disabled_checked.png
deleted file mode 100644
index 439499040a..0000000000
--- a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_disabled_checked.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.png b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.png
deleted file mode 100644
index cb4c6a8136..0000000000
--- a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_inactive.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.png b/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.png
deleted file mode 100644
index 88fd1344d2..0000000000
--- a/src/plugins/styles/bb10style/bright/radiobutton/core_radiobutton_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.png b/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.png
deleted file mode 100644
index 79154e0568..0000000000
--- a/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar_v.png b/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar_v.png
deleted file mode 100644
index 169a4e1656..0000000000
--- a/src/plugins/styles/bb10style/bright/scrollbar/core_scrollbar_v.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_active.png b/src/plugins/styles/bb10style/bright/slider/core_slider_active.png
deleted file mode 100644
index c23c0ebc26..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_active.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_cache.png b/src/plugins/styles/bb10style/bright/slider/core_slider_cache.png
deleted file mode 100644
index 6b7224d702..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_cache.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_disabled.png b/src/plugins/styles/bb10style/bright/slider/core_slider_disabled.png
deleted file mode 100644
index 9de7567e68..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_enabled.png b/src/plugins/styles/bb10style/bright/slider/core_slider_enabled.png
deleted file mode 100644
index ad5c35076c..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_enabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_handle.png b/src/plugins/styles/bb10style/bright/slider/core_slider_handle.png
deleted file mode 100644
index 076e272794..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_handle.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_handle_disabled.png b/src/plugins/styles/bb10style/bright/slider/core_slider_handle_disabled.png
deleted file mode 100644
index 5989fcaaeb..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_handle_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.png b/src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.png
deleted file mode 100644
index 8cb79118b9..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_handle_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_inactive.png b/src/plugins/styles/bb10style/bright/slider/core_slider_inactive.png
deleted file mode 100644
index 8836534923..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_inactive.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_vactive.png b/src/plugins/styles/bb10style/bright/slider/core_slider_vactive.png
deleted file mode 100644
index 03062326f2..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_vactive.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_vcache.png b/src/plugins/styles/bb10style/bright/slider/core_slider_vcache.png
deleted file mode 100644
index b0d94d7127..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_vcache.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_vdisabled.png b/src/plugins/styles/bb10style/bright/slider/core_slider_vdisabled.png
deleted file mode 100644
index ce99b1a3ac..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_vdisabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_venabled.png b/src/plugins/styles/bb10style/bright/slider/core_slider_venabled.png
deleted file mode 100644
index 910b6627d4..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_venabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/bright/slider/core_slider_vinactive.png b/src/plugins/styles/bb10style/bright/slider/core_slider_vinactive.png
deleted file mode 100644
index 18a9819af8..0000000000
--- a/src/plugins/styles/bb10style/bright/slider/core_slider_vinactive.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/button/core_button_disabled.png b/src/plugins/styles/bb10style/dark/button/core_button_disabled.png
deleted file mode 100644
index 79245dbf11..0000000000
--- a/src/plugins/styles/bb10style/dark/button/core_button_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/button/core_button_disabled_selected.png b/src/plugins/styles/bb10style/dark/button/core_button_disabled_selected.png
deleted file mode 100644
index 5eb86b70f3..0000000000
--- a/src/plugins/styles/bb10style/dark/button/core_button_disabled_selected.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/button/core_button_enabled_selected.png b/src/plugins/styles/bb10style/dark/button/core_button_enabled_selected.png
deleted file mode 100644
index 7b1a6ce40b..0000000000
--- a/src/plugins/styles/bb10style/dark/button/core_button_enabled_selected.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/button/core_button_inactive.png b/src/plugins/styles/bb10style/dark/button/core_button_inactive.png
deleted file mode 100644
index 97842e1ac4..0000000000
--- a/src/plugins/styles/bb10style/dark/button/core_button_inactive.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/button/core_button_pressed.png b/src/plugins/styles/bb10style/dark/button/core_button_pressed.png
deleted file mode 100644
index c149b64a26..0000000000
--- a/src/plugins/styles/bb10style/dark/button/core_button_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_checked.png b/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_checked.png
deleted file mode 100644
index 5a8af33094..0000000000
--- a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_checked.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_disabled.png b/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_disabled.png
deleted file mode 100644
index 74a24522fa..0000000000
--- a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_disabled_checked.png b/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_disabled_checked.png
deleted file mode 100644
index 1e953221b6..0000000000
--- a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_disabled_checked.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_enabled.png b/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_enabled.png
deleted file mode 100644
index 5e51e7f39b..0000000000
--- a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_enabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.png b/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.png
deleted file mode 100644
index 507a77b3ea..0000000000
--- a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed_checked.png b/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed_checked.png
deleted file mode 100644
index 7fa85428a0..0000000000
--- a/src/plugins/styles/bb10style/dark/checkbox/core_checkbox_pressed_checked.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button.png b/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button.png
deleted file mode 100644
index a68d93acb5..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowdown.png b/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowdown.png
deleted file mode 100644
index 4c1d085360..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowdown.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowdown_pressed.png b/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowdown_pressed.png
deleted file mode 100644
index 1ee578e07c..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowdown_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowup.png b/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowup.png
deleted file mode 100644
index 3239ef4bd6..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_arrowup.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_disabled.png b/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_disabled.png
deleted file mode 100644
index af6793b87c..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_pressed.png b/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_pressed.png
deleted file mode 100644
index df6d402554..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_button_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_checkmark.png b/src/plugins/styles/bb10style/dark/combobox/core_dropdown_checkmark.png
deleted file mode 100644
index 578c80aa5f..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_checkmark.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_divider.png b/src/plugins/styles/bb10style/dark/combobox/core_dropdown_divider.png
deleted file mode 100644
index 43b1025d36..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_divider.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_menu.png b/src/plugins/styles/bb10style/dark/combobox/core_dropdown_menu.png
deleted file mode 100644
index 1f52362050..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_menu.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_menuup.png b/src/plugins/styles/bb10style/dark/combobox/core_dropdown_menuup.png
deleted file mode 100644
index 62c7a2e558..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_dropdown_menuup.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/combobox/core_listitem_active.png b/src/plugins/styles/bb10style/dark/combobox/core_listitem_active.png
deleted file mode 100644
index 1df4a7aad9..0000000000
--- a/src/plugins/styles/bb10style/dark/combobox/core_listitem_active.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.png b/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.png
deleted file mode 100644
index 07b8ea21bf..0000000000
--- a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_disabled.png b/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_disabled.png
deleted file mode 100644
index 6bcaf91f87..0000000000
--- a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.png b/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.png
deleted file mode 100644
index 9b115897e8..0000000000
--- a/src/plugins/styles/bb10style/dark/lineedit/core_textinput_bg_highlight.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/listitem/core_listitem_active.png b/src/plugins/styles/bb10style/dark/listitem/core_listitem_active.png
deleted file mode 100644
index 52aa4e4aa2..0000000000
--- a/src/plugins/styles/bb10style/dark/listitem/core_listitem_active.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.png b/src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.png
deleted file mode 100644
index 39e3a8a4f5..0000000000
--- a/src/plugins/styles/bb10style/dark/listitem/core_listitem_divider.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.png b/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.png
deleted file mode 100644
index 95fcafb437..0000000000
--- a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_bg.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_complete.png b/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_complete.png
deleted file mode 100644
index e849c8f179..0000000000
--- a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_complete.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_fill.png b/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_fill.png
deleted file mode 100644
index e8fd3b0173..0000000000
--- a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_fill.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vbg.png b/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vbg.png
deleted file mode 100644
index 1433f3ec33..0000000000
--- a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vbg.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vcomplete.png b/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vcomplete.png
deleted file mode 100644
index d750e4671c..0000000000
--- a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vcomplete.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vfill.png b/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vfill.png
deleted file mode 100644
index 2c3c0a5e6c..0000000000
--- a/src/plugins/styles/bb10style/dark/progressbar/core_progressindicator_vfill.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_checked.png b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_checked.png
deleted file mode 100644
index 1721586ac5..0000000000
--- a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_checked.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_disabled.png b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_disabled.png
deleted file mode 100644
index e646c9174b..0000000000
--- a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_disabled_checked.png b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_disabled_checked.png
deleted file mode 100644
index 93b3118e8d..0000000000
--- a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_disabled_checked.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.png b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.png
deleted file mode 100644
index fd61937d65..0000000000
--- a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_inactive.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.png b/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.png
deleted file mode 100644
index 58a1a57b4c..0000000000
--- a/src/plugins/styles/bb10style/dark/radiobutton/core_radiobutton_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.png b/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.png
deleted file mode 100644
index 384f60758a..0000000000
--- a/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar_v.png b/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar_v.png
deleted file mode 100644
index 2542f2acaf..0000000000
--- a/src/plugins/styles/bb10style/dark/scrollbar/core_scrollbar_v.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_active.png b/src/plugins/styles/bb10style/dark/slider/core_slider_active.png
deleted file mode 100644
index 6bdb413ced..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_active.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_cache.png b/src/plugins/styles/bb10style/dark/slider/core_slider_cache.png
deleted file mode 100644
index eea5b3d78e..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_cache.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_disabled.png b/src/plugins/styles/bb10style/dark/slider/core_slider_disabled.png
deleted file mode 100644
index 6a233315e4..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_enabled.png b/src/plugins/styles/bb10style/dark/slider/core_slider_enabled.png
deleted file mode 100644
index 2b297e5ca2..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_enabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_handle.png b/src/plugins/styles/bb10style/dark/slider/core_slider_handle.png
deleted file mode 100644
index fbd37e5584..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_handle.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_handle_disabled.png b/src/plugins/styles/bb10style/dark/slider/core_slider_handle_disabled.png
deleted file mode 100644
index 49cb6a42a7..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_handle_disabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.png b/src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.png
deleted file mode 100644
index 803c374015..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_handle_pressed.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_inactive.png b/src/plugins/styles/bb10style/dark/slider/core_slider_inactive.png
deleted file mode 100644
index 08a1aecb6c..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_inactive.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_vactive.png b/src/plugins/styles/bb10style/dark/slider/core_slider_vactive.png
deleted file mode 100644
index c8e467d9e6..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_vactive.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_vcache.png b/src/plugins/styles/bb10style/dark/slider/core_slider_vcache.png
deleted file mode 100644
index ff160cbb1d..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_vcache.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_vdisabled.png b/src/plugins/styles/bb10style/dark/slider/core_slider_vdisabled.png
deleted file mode 100644
index 27d348122b..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_vdisabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_venabled.png b/src/plugins/styles/bb10style/dark/slider/core_slider_venabled.png
deleted file mode 100644
index ff8a74a19f..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_venabled.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/dark/slider/core_slider_vinactive.png b/src/plugins/styles/bb10style/dark/slider/core_slider_vinactive.png
deleted file mode 100644
index b2b19a5460..0000000000
--- a/src/plugins/styles/bb10style/dark/slider/core_slider_vinactive.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/styles/bb10style/qbb10brightstyle.cpp b/src/plugins/styles/bb10style/qbb10brightstyle.cpp
deleted file mode 100644
index 9f14e3b134..0000000000
--- a/src/plugins/styles/bb10style/qbb10brightstyle.cpp
+++ /dev/null
@@ -1,344 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qbb10brightstyle.h"
-
-#include <QApplication>
-#include <QFont>
-#include <QStyleOption>
-#include <QProgressBar>
-#include <QComboBox>
-#include <QAbstractItemView>
-#include <QPainter>
-
-QT_BEGIN_NAMESPACE
-
-QBB10BrightStyle::QBB10BrightStyle() :
- QPixmapStyle()
-{
- addDescriptor(PB_Enabled,
- QLatin1String("://bright/button/core_button_inactive.png"),
- QMargins(13, 13, 13, 13),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_Checked,
- QLatin1String("://bright/button/core_button_enabled_selected.png"),
- QMargins(13, 13, 13, 13),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_Pressed,
- QLatin1String("://bright/button/core_button_pressed.png"),
- QMargins(13, 13, 13, 13),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_Disabled,
- QLatin1String("://bright/button/core_button_disabled.png"),
- QMargins(13, 13, 13, 13),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_PressedDisabled,
- QLatin1String("://bright/button/core_button_disabled_selected.png"),
- QMargins(13, 13, 13, 13),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
-
- addDescriptor(LE_Enabled,
- QLatin1String("://bright/lineedit/core_textinput_bg.png"),
- QMargins(8, 8, 8, 8));
- addDescriptor(LE_Disabled,
- QLatin1String("://bright/lineedit/core_textinput_bg_disabled.png"),
- QMargins(8, 8, 8, 8));
- addDescriptor(LE_Focused,
- QLatin1String("://bright/lineedit/core_textinput_bg_highlight.png"),
- QMargins(8, 8, 8, 8));
-
- copyDescriptor(LE_Enabled, TE_Enabled);
- copyDescriptor(LE_Disabled, TE_Disabled);
- copyDescriptor(LE_Focused, TE_Focused);
-
- addPixmap(CB_Enabled,
- QLatin1String("://bright/checkbox/core_checkbox_enabled.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(CB_Checked,
- QLatin1String("://bright/checkbox/core_checkbox_checked.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(CB_Pressed,
- QLatin1String("://bright/checkbox/core_checkbox_pressed.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(CB_PressedChecked,
- QLatin1String("://bright/checkbox/core_checkbox_pressed_checked.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(CB_Disabled,
- QLatin1String("://bright/checkbox/core_checkbox_disabled.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(CB_DisabledChecked,
- QLatin1String("://bright/checkbox/core_checkbox_disabled_checked.png"),
- QMargins(16, 16, 16, 16));
-
- addPixmap(RB_Enabled,
- QLatin1String("://bright/radiobutton/core_radiobutton_inactive.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(RB_Checked,
- QLatin1String("://bright/radiobutton/core_radiobutton_checked.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(RB_Pressed,
- QLatin1String("://bright/radiobutton/core_radiobutton_pressed.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(RB_Disabled,
- QLatin1String("://bright/radiobutton/core_radiobutton_disabled.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(RB_DisabledChecked,
- QLatin1String("://bright/radiobutton/core_radiobutton_disabled_checked.png"),
- QMargins(16, 16, 16, 16));
-
- addDescriptor(PB_HBackground,
- QLatin1String("://bright/progressbar/core_progressindicator_bg.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_HContent,
- QLatin1String("://bright/progressbar/core_progressindicator_fill.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_HComplete,
- QLatin1String("://bright/progressbar/core_progressindicator_complete.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_VBackground,
- QLatin1String("://bright/progressbar/core_progressindicator_vbg.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(PB_VContent,
- QLatin1String("://bright/progressbar/core_progressindicator_vfill.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(PB_VComplete,
- QLatin1String("://bright/progressbar/core_progressindicator_vcomplete.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
-
- addDescriptor(SG_HEnabled,
- QLatin1String("://bright/slider/core_slider_enabled.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SG_HDisabled,
- QLatin1String("://bright/slider/core_slider_disabled.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SG_HActiveEnabled,
- QLatin1String("://bright/slider/core_slider_inactive.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SG_HActivePressed,
- QLatin1String("://bright/slider/core_slider_active.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SG_HActiveDisabled,
- QLatin1String("://bright/slider/core_slider_cache.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SG_VEnabled,
- QLatin1String("://bright/slider/core_slider_venabled.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(SG_VDisabled,
- QLatin1String("://bright/slider/core_slider_vdisabled.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(SG_VActiveEnabled,
- QLatin1String("://bright/slider/core_slider_vinactive.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(SG_VActivePressed,
- QLatin1String("://bright/slider/core_slider_vactive.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(SG_VActiveDisabled,
- QLatin1String("://bright/slider/core_slider_vcache.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
-
- addPixmap(SH_HEnabled,
- QLatin1String("://bright/slider/core_slider_handle.png"));
- addPixmap(SH_HDisabled,
- QLatin1String("://bright/slider/core_slider_handle_disabled.png"));
- addPixmap(SH_HPressed,
- QLatin1String("://bright/slider/core_slider_handle_pressed.png"));
- addPixmap(SH_VEnabled,
- QLatin1String("://bright/slider/core_slider_handle.png"));
- addPixmap(SH_VDisabled,
- QLatin1String("://bright/slider/core_slider_handle_disabled.png"));
- addPixmap(SH_VPressed,
- QLatin1String("://bright/slider/core_slider_handle_pressed.png"));
-
- addDescriptor(DD_ButtonEnabled,
- QLatin1String("://bright/combobox/core_dropdown_button.png"),
- QMargins(14, 14, 14, 14),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(DD_ButtonDisabled,
- QLatin1String("://bright/combobox/core_dropdown_button_disabled.png"),
- QMargins(14, 14, 14, 14),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(DD_ButtonPressed,
- QLatin1String("://bright/combobox/core_dropdown_button_pressed.png"),
- QMargins(14, 14, 14, 14),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(DD_ItemSelected,
- QLatin1String("://bright/combobox/core_listitem_active.png"));
-
- addPixmap(DD_ArrowEnabled,
- QLatin1String("://bright/combobox/core_dropdown_button_arrowdown.png"),
- QMargins(35, 39, 35, 39));
- copyPixmap(DD_ArrowEnabled, DD_ArrowDisabled);
- addPixmap(DD_ArrowPressed,
- QLatin1String("://bright/combobox/core_dropdown_button_arrowdown_pressed.png"),
- QMargins(35, 39, 35, 39));
- addPixmap(DD_ArrowOpen,
- QLatin1String("://bright/combobox/core_dropdown_button_arrowup.png"),
- QMargins(35, 39, 35, 39));
- addDescriptor(DD_PopupDown,
- QLatin1String("://bright/combobox/core_dropdown_menu.png"),
- QMargins(12, 12, 12, 12),
- QTileRules(Qt::StretchTile, Qt::StretchTile));
- addDescriptor(DD_PopupUp,
- QLatin1String("://bright/combobox/core_dropdown_menuup.png"),
- QMargins(12, 12, 12, 12),
- QTileRules(Qt::StretchTile, Qt::StretchTile));
- addPixmap(DD_ItemSeparator,
- QLatin1String("://bright/combobox/core_dropdown_divider.png"),
- QMargins(5, 0, 5, 0));
-
- addDescriptor(ID_Selected,
- QLatin1String("://bright/listitem/core_listitem_active.png"));
- addPixmap(ID_Separator,
- QLatin1String("://bright/listitem/core_listitem_divider.png"));
-
- addDescriptor(SB_Horizontal,
- QLatin1String("://bright/scrollbar/core_scrollbar.png"),
- QMargins(7, 8, 7, 8),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SB_Vertical,
- QLatin1String("://bright/scrollbar/core_scrollbar_v.png"),
- QMargins(8, 7, 8, 7),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
-}
-
-QBB10BrightStyle::~QBB10BrightStyle()
-{
-}
-
-void QBB10BrightStyle::polish(QApplication *application)
-{
- QPixmapStyle::polish(application);
-}
-
-void QBB10BrightStyle::polish(QWidget *widget)
-{
- // Hide the text by default
- if (QProgressBar *pb = qobject_cast<QProgressBar*>(widget))
- pb->setTextVisible(false);
-
- if (QComboBox *cb = qobject_cast<QComboBox*>(widget)) {
- QAbstractItemView *list = cb->view();
- QPalette p = list->palette();
- p.setBrush(QPalette::HighlightedText, p.brush(QPalette::Text));
- list->setPalette(p);
- }
-
- if (qobject_cast<QAbstractItemView*>(widget)) {
- QPalette p = widget->palette();
- p.setBrush(QPalette::Disabled, QPalette::HighlightedText, p.brush(QPalette::Text));
- widget->setPalette(p);
- }
-
- QPixmapStyle::polish(widget);
-}
-
-QPalette QBB10BrightStyle::standardPalette() const
-{
- QPalette p;
-
- QColor color = QColor(38, 38, 38);
- p.setBrush(QPalette::ButtonText, color);
- p.setBrush(QPalette::WindowText, color);
- p.setBrush(QPalette::Text, color);
-
- color.setAlpha(179);
- p.setBrush(QPalette::Disabled, QPalette::ButtonText, color);
- p.setBrush(QPalette::Disabled, QPalette::WindowText, color);
- p.setBrush(QPalette::Disabled, QPalette::Text, color);
-
- p.setColor(QPalette::Window, QColor(248, 248, 248));
-
- p.setBrush(QPalette::Highlight, QColor(0, 168, 223));
- p.setBrush(QPalette::HighlightedText, QColor(250, 250,250));
-
- return p;
-}
-
-void QBB10BrightStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const
-{
- switch (element) {
- case CE_PushButtonLabel:
- {
- const bool on = option->state & State_On || option->state & State_Sunken;
- const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option);
- QStyleOptionButton newOpt = *button;
- if (on)
- newOpt.palette.setBrush(QPalette::ButtonText, QColor(250, 250, 250));
- QPixmapStyle::drawControl(CE_PushButtonLabel, &newOpt, painter, widget);
- break;
- }
- case CE_ProgressBarLabel:
- // Don't draw the progress bar label
- break;
- default:
- QPixmapStyle::drawControl(element, option, painter, widget);
- }
-}
-
-void QBB10BrightStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const
-{
- QPixmapStyle::drawPrimitive(element, option, painter, widget);
-
- if (element == PE_PanelItemViewItem) {
- // Draw the checkbox for current item
- if (widget->property("_pixmap_combobox_list").toBool()
- && option->state & QStyle::State_Selected) {
- QPixmap pix(QLatin1String("://bright/combobox/core_dropdown_checkmark.png"));
- QRect rect = option->rect;
- const int margin = rect.height() / 2;
- QPoint pos(rect.right() - margin - pix.width() / 2,
- rect.top() + margin - pix.height() / 2);
- painter->drawPixmap(pos, pix);
- }
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/styles/bb10style/qbb10brightstyle.h b/src/plugins/styles/bb10style/qbb10brightstyle.h
deleted file mode 100644
index 5b88b0ef95..0000000000
--- a/src/plugins/styles/bb10style/qbb10brightstyle.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBB10BRIGHTSTYLE_H
-#define QBB10BRIGHTSTYLE_H
-
-#include "qpixmapstyle.h"
-
-QT_BEGIN_NAMESPACE
-
-class QBB10BrightStyle : public QPixmapStyle
-{
- Q_OBJECT
-
-public:
- QBB10BrightStyle();
- ~QBB10BrightStyle();
-
- void polish(QApplication *application);
- void polish(QWidget *widget);
-
- QPalette standardPalette() const;
-
- void drawControl(ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget = 0) const;
- void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const;
-};
-
-QT_END_NAMESPACE
-
-#endif // QBB10BRIGHTSTYLE_H
diff --git a/src/plugins/styles/bb10style/qbb10brightstyle.qrc b/src/plugins/styles/bb10style/qbb10brightstyle.qrc
deleted file mode 100644
index 2172536fa3..0000000000
--- a/src/plugins/styles/bb10style/qbb10brightstyle.qrc
+++ /dev/null
@@ -1,57 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>bright/button/core_button_disabled.png</file>
- <file>bright/button/core_button_disabled_selected.png</file>
- <file>bright/button/core_button_inactive.png</file>
- <file>bright/button/core_button_enabled_selected.png</file>
- <file>bright/button/core_button_pressed.png</file>
- <file>bright/checkbox/core_checkbox_checked.png</file>
- <file>bright/checkbox/core_checkbox_disabled.png</file>
- <file>bright/checkbox/core_checkbox_disabled_checked.png</file>
- <file>bright/checkbox/core_checkbox_enabled.png</file>
- <file>bright/checkbox/core_checkbox_pressed.png</file>
- <file>bright/checkbox/core_checkbox_pressed_checked.png</file>
- <file>bright/combobox/core_dropdown_button.png</file>
- <file>bright/combobox/core_dropdown_button_arrowdown.png</file>
- <file>bright/combobox/core_dropdown_button_arrowdown_pressed.png</file>
- <file>bright/combobox/core_dropdown_button_arrowup.png</file>
- <file>bright/combobox/core_dropdown_button_disabled.png</file>
- <file>bright/combobox/core_dropdown_button_pressed.png</file>
- <file>bright/combobox/core_dropdown_checkmark.png</file>
- <file>bright/combobox/core_dropdown_divider.png</file>
- <file>bright/combobox/core_dropdown_menu.png</file>
- <file>bright/combobox/core_dropdown_menuup.png</file>
- <file>bright/combobox/core_listitem_active.png</file>
- <file>bright/lineedit/core_textinput_bg.png</file>
- <file>bright/lineedit/core_textinput_bg_disabled.png</file>
- <file>bright/lineedit/core_textinput_bg_highlight.png</file>
- <file>bright/listitem/core_listitem_active.png</file>
- <file>bright/listitem/core_listitem_divider.png</file>
- <file>bright/progressbar/core_progressindicator_bg.png</file>
- <file>bright/progressbar/core_progressindicator_complete.png</file>
- <file>bright/progressbar/core_progressindicator_fill.png</file>
- <file>bright/progressbar/core_progressindicator_vbg.png</file>
- <file>bright/progressbar/core_progressindicator_vcomplete.png</file>
- <file>bright/progressbar/core_progressindicator_vfill.png</file>
- <file>bright/radiobutton/core_radiobutton_checked.png</file>
- <file>bright/radiobutton/core_radiobutton_disabled.png</file>
- <file>bright/radiobutton/core_radiobutton_disabled_checked.png</file>
- <file>bright/radiobutton/core_radiobutton_inactive.png</file>
- <file>bright/radiobutton/core_radiobutton_pressed.png</file>
- <file>bright/scrollbar/core_scrollbar.png</file>
- <file>bright/scrollbar/core_scrollbar_v.png</file>
- <file>bright/slider/core_slider_active.png</file>
- <file>bright/slider/core_slider_cache.png</file>
- <file>bright/slider/core_slider_disabled.png</file>
- <file>bright/slider/core_slider_enabled.png</file>
- <file>bright/slider/core_slider_handle.png</file>
- <file>bright/slider/core_slider_handle_disabled.png</file>
- <file>bright/slider/core_slider_handle_pressed.png</file>
- <file>bright/slider/core_slider_inactive.png</file>
- <file>bright/slider/core_slider_vactive.png</file>
- <file>bright/slider/core_slider_vcache.png</file>
- <file>bright/slider/core_slider_vdisabled.png</file>
- <file>bright/slider/core_slider_venabled.png</file>
- <file>bright/slider/core_slider_vinactive.png</file>
- </qresource>
-</RCC>
diff --git a/src/plugins/styles/bb10style/qbb10darkstyle.cpp b/src/plugins/styles/bb10style/qbb10darkstyle.cpp
deleted file mode 100644
index be2697510e..0000000000
--- a/src/plugins/styles/bb10style/qbb10darkstyle.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qbb10darkstyle.h"
-
-#include <QApplication>
-#include <QFont>
-#include <QStyleOption>
-#include <QProgressBar>
-#include <QComboBox>
-#include <QAbstractItemView>
-#include <QPainter>
-#include <QLineEdit>
-#include <QTextEdit>
-
-QT_BEGIN_NAMESPACE
-
-QBB10DarkStyle::QBB10DarkStyle() :
- QPixmapStyle()
-{
- addDescriptor(PB_Enabled,
- QLatin1String("://dark/button/core_button_inactive.png"),
- QMargins(13, 13, 13, 13),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_Checked,
- QLatin1String("://dark/button/core_button_enabled_selected.png"),
- QMargins(13, 13, 13, 13),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_Pressed,
- QLatin1String("://dark/button/core_button_pressed.png"),
- QMargins(13, 13, 13, 13),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_Disabled,
- QLatin1String("://dark/button/core_button_disabled.png"),
- QMargins(13, 13, 13, 13),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_PressedDisabled,
- QLatin1String("://dark/button/core_button_disabled_selected.png"),
- QMargins(13, 13, 13, 13),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
-
- addDescriptor(LE_Enabled,
- QLatin1String("://dark/lineedit/core_textinput_bg.png"),
- QMargins(8, 8, 8, 8));
- addDescriptor(LE_Disabled,
- QLatin1String("://dark/lineedit/core_textinput_bg_disabled.png"),
- QMargins(8, 8, 8, 8));
- addDescriptor(LE_Focused,
- QLatin1String("://dark/lineedit/core_textinput_bg_highlight.png"),
- QMargins(8, 8, 8, 8));
-
- copyDescriptor(LE_Enabled, TE_Enabled);
- copyDescriptor(LE_Disabled, TE_Disabled);
- copyDescriptor(LE_Focused, TE_Focused);
-
- addPixmap(CB_Enabled,
- QLatin1String("://dark/checkbox/core_checkbox_enabled.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(CB_Checked,
- QLatin1String("://dark/checkbox/core_checkbox_checked.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(CB_Pressed,
- QLatin1String("://dark/checkbox/core_checkbox_pressed.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(CB_PressedChecked,
- QLatin1String("://dark/checkbox/core_checkbox_pressed_checked.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(CB_Disabled,
- QLatin1String("://dark/checkbox/core_checkbox_disabled.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(CB_DisabledChecked,
- QLatin1String("://dark/checkbox/core_checkbox_disabled_checked.png"),
- QMargins(16, 16, 16, 16));
-
- addPixmap(RB_Enabled,
- QLatin1String("://dark/radiobutton/core_radiobutton_inactive.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(RB_Checked,
- QLatin1String("://dark/radiobutton/core_radiobutton_checked.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(RB_Pressed,
- QLatin1String("://dark/radiobutton/core_radiobutton_pressed.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(RB_Disabled,
- QLatin1String("://dark/radiobutton/core_radiobutton_disabled.png"),
- QMargins(16, 16, 16, 16));
- addPixmap(RB_DisabledChecked,
- QLatin1String("://dark/radiobutton/core_radiobutton_disabled_checked.png"),
- QMargins(16, 16, 16, 16));
-
- addDescriptor(PB_HBackground,
- QLatin1String("://dark/progressbar/core_progressindicator_bg.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_HContent,
- QLatin1String("://dark/progressbar/core_progressindicator_fill.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_HComplete,
- QLatin1String("://dark/progressbar/core_progressindicator_complete.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(PB_VBackground,
- QLatin1String("://dark/progressbar/core_progressindicator_vbg.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(PB_VContent,
- QLatin1String("://dark/progressbar/core_progressindicator_vfill.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(PB_VComplete,
- QLatin1String("://dark/progressbar/core_progressindicator_vcomplete.png"),
- QMargins(10, 10, 10, 10),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
-
- addDescriptor(SG_HEnabled,
- QLatin1String("://dark/slider/core_slider_enabled.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SG_HDisabled,
- QLatin1String("://dark/slider/core_slider_disabled.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SG_HActiveEnabled,
- QLatin1String("://dark/slider/core_slider_inactive.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SG_HActivePressed,
- QLatin1String("://dark/slider/core_slider_active.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SG_HActiveDisabled,
- QLatin1String("://dark/slider/core_slider_cache.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SG_VEnabled,
- QLatin1String("://dark/slider/core_slider_venabled.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(SG_VDisabled,
- QLatin1String("://dark/slider/core_slider_vdisabled.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(SG_VActiveEnabled,
- QLatin1String("://dark/slider/core_slider_vinactive.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(SG_VActivePressed,
- QLatin1String("://dark/slider/core_slider_vactive.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
- addDescriptor(SG_VActiveDisabled,
- QLatin1String("://dark/slider/core_slider_vcache.png"),
- QMargins(50, 50, 50, 50),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
-
- addPixmap(SH_HEnabled,
- QLatin1String("://dark/slider/core_slider_handle.png"));
- addPixmap(SH_HDisabled,
- QLatin1String("://dark/slider/core_slider_handle_disabled.png"));
- addPixmap(SH_HPressed,
- QLatin1String("://dark/slider/core_slider_handle_pressed.png"));
- addPixmap(SH_VEnabled,
- QLatin1String("://dark/slider/core_slider_handle.png"));
- addPixmap(SH_VDisabled,
- QLatin1String("://dark/slider/core_slider_handle_disabled.png"));
- addPixmap(SH_VPressed,
- QLatin1String("://dark/slider/core_slider_handle_pressed.png"));
-
- addDescriptor(DD_ButtonEnabled,
- QLatin1String("://dark/combobox/core_dropdown_button.png"),
- QMargins(14, 14, 14, 14),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(DD_ButtonDisabled,
- QLatin1String("://dark/combobox/core_dropdown_button_disabled.png"),
- QMargins(14, 14, 14, 14),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(DD_ButtonPressed,
- QLatin1String("://dark/combobox/core_dropdown_button_pressed.png"),
- QMargins(14, 14, 14, 14),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(DD_ItemSelected,
- QLatin1String("://dark/combobox/core_listitem_active.png"));
- addPixmap(DD_ArrowEnabled,
- QLatin1String("://dark/combobox/core_dropdown_button_arrowdown.png"),
- QMargins(35, 39, 35, 39));
- copyPixmap(DD_ArrowEnabled, DD_ArrowDisabled);
- addPixmap(DD_ArrowPressed,
- QLatin1String("://dark/combobox/core_dropdown_button_arrowdown_pressed.png"),
- QMargins(35, 39, 35, 39));
- addPixmap(DD_ArrowOpen,
- QLatin1String("://dark/combobox/core_dropdown_button_arrowup.png"),
- QMargins(35, 39, 35, 39));
- addDescriptor(DD_PopupDown,
- QLatin1String("://dark/combobox/core_dropdown_menu.png"),
- QMargins(12, 12, 12, 12), QTileRules(Qt::StretchTile, Qt::StretchTile));
- addDescriptor(DD_PopupUp,
- QLatin1String("://dark/combobox/core_dropdown_menuup.png"),
- QMargins(12, 12, 12, 12), QTileRules(Qt::StretchTile, Qt::StretchTile));
- addPixmap(DD_ItemSeparator,
- QLatin1String("://dark/combobox/core_dropdown_divider.png"),
- QMargins(5, 0, 5, 0));
-
- addDescriptor(ID_Selected,
- QLatin1String("://dark/listitem/core_listitem_active.png"));
- addPixmap(ID_Separator,
- QLatin1String("://dark/listitem/core_listitem_divider.png"));
-
- addDescriptor(SB_Horizontal,
- QLatin1String("://dark/scrollbar/core_scrollbar.png"),
- QMargins(7, 8, 7, 8),
- QTileRules(Qt::RepeatTile, Qt::StretchTile));
- addDescriptor(SB_Vertical,
- QLatin1String("://dark/scrollbar/core_scrollbar_v.png"),
- QMargins(8, 7, 8, 7),
- QTileRules(Qt::StretchTile, Qt::RepeatTile));
-}
-
-QBB10DarkStyle::~QBB10DarkStyle()
-{
-}
-
-void QBB10DarkStyle::polish(QApplication *application)
-{
- QPixmapStyle::polish(application);
-}
-
-void QBB10DarkStyle::polish(QWidget *widget)
-{
- // Hide the text by default
- if (QProgressBar *pb = qobject_cast<QProgressBar*>(widget))
- pb->setTextVisible(false);
-
- if (QComboBox *cb = qobject_cast<QComboBox*>(widget)) {
- QAbstractItemView *list = cb->view();
- QPalette p = list->palette();
- p.setBrush(QPalette::HighlightedText, p.brush(QPalette::Text));
- list->setPalette(p);
- }
-
- if (qobject_cast<QLineEdit*>(widget) || qobject_cast<QTextEdit*>(widget)) {
- QPalette p = widget->palette();
- p.setBrush(QPalette::Text, QColor(38, 38, 38));
- widget->setPalette(p);
- }
-
- if (qobject_cast<QAbstractItemView*>(widget)) {
- QPalette p = widget->palette();
- p.setBrush(QPalette::Disabled, QPalette::HighlightedText, p.brush(QPalette::Text));
- widget->setPalette(p);
- }
-
- QPixmapStyle::polish(widget);
-}
-
-QPalette QBB10DarkStyle::standardPalette() const
-{
- QPalette p;
-
- QColor color = QColor(250, 250, 250);
- p.setBrush(QPalette::ButtonText, color);
- p.setBrush(QPalette::WindowText, color);
- p.setBrush(QPalette::Text, color);
-
- color.setAlpha(179);
- p.setBrush(QPalette::Disabled, QPalette::ButtonText, color);
- p.setBrush(QPalette::Disabled, QPalette::WindowText, color);
- p.setBrush(QPalette::Disabled, QPalette::Text, color);
-
- p.setColor(QPalette::Window, QColor(18, 18, 18));
-
- p.setBrush(QPalette::Highlight, QColor(0, 168, 223));
- p.setBrush(QPalette::HighlightedText, QColor(250, 250,250));
-
- return p;
-}
-
-void QBB10DarkStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const
-{
- switch (element) {
- case CE_PushButtonLabel:
- {
- const bool on = option->state & State_On || option->state & State_Sunken;
- const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option);
- QStyleOptionButton newOpt = *button;
- if (on)
- newOpt.palette.setBrush(QPalette::ButtonText, QColor(38, 38, 38));
- QPixmapStyle::drawControl(CE_PushButtonLabel, &newOpt, painter, widget);
- break;
- }
- case CE_ProgressBarLabel:
- // Don't draw the progress bar label
- break;
- default:
- QPixmapStyle::drawControl(element, option, painter, widget);
- }
-}
-
-void QBB10DarkStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const
-{
- QPixmapStyle::drawPrimitive(element, option, painter, widget);
-
- if (element == PE_PanelItemViewItem) {
- // Draw the checkbox for current item
- if (widget->property("_pixmap_combobox_list").toBool()
- && option->state & QStyle::State_Selected) {
- QPixmap pix(QLatin1String("://dark/combobox/core_dropdown_checkmark.png"));
- QRect rect = option->rect;
- const int margin = rect.height() / 2;
- QPoint pos(rect.right() - margin - pix.width() / 2,
- rect.top() + margin - pix.height() / 2);
- painter->drawPixmap(pos, pix);
- }
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/styles/bb10style/qbb10darkstyle.h b/src/plugins/styles/bb10style/qbb10darkstyle.h
deleted file mode 100644
index 65ba7cd283..0000000000
--- a/src/plugins/styles/bb10style/qbb10darkstyle.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBB10DARKSTYLE_H
-#define QBB10DARKSTYLE_H
-
-#include "qpixmapstyle.h"
-
-QT_BEGIN_NAMESPACE
-
-class QBB10DarkStyle : public QPixmapStyle
-{
- Q_OBJECT
-
-public:
- QBB10DarkStyle();
- ~QBB10DarkStyle();
-
- void polish(QApplication *application);
- void polish(QWidget *widget);
-
- QPalette standardPalette() const;
-
- void drawControl(ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget = 0) const;
- void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const;
-};
-
-QT_END_NAMESPACE
-
-#endif // QBB10DARKSTYLE_H
diff --git a/src/plugins/styles/bb10style/qbb10darkstyle.qrc b/src/plugins/styles/bb10style/qbb10darkstyle.qrc
deleted file mode 100644
index 31a5236207..0000000000
--- a/src/plugins/styles/bb10style/qbb10darkstyle.qrc
+++ /dev/null
@@ -1,57 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>dark/button/core_button_disabled.png</file>
- <file>dark/button/core_button_disabled_selected.png</file>
- <file>dark/button/core_button_inactive.png</file>
- <file>dark/button/core_button_enabled_selected.png</file>
- <file>dark/button/core_button_pressed.png</file>
- <file>dark/checkbox/core_checkbox_checked.png</file>
- <file>dark/checkbox/core_checkbox_disabled.png</file>
- <file>dark/checkbox/core_checkbox_disabled_checked.png</file>
- <file>dark/checkbox/core_checkbox_enabled.png</file>
- <file>dark/checkbox/core_checkbox_pressed.png</file>
- <file>dark/checkbox/core_checkbox_pressed_checked.png</file>
- <file>dark/combobox/core_dropdown_button.png</file>
- <file>dark/combobox/core_dropdown_button_arrowdown.png</file>
- <file>dark/combobox/core_dropdown_button_arrowdown_pressed.png</file>
- <file>dark/combobox/core_dropdown_button_arrowup.png</file>
- <file>dark/combobox/core_dropdown_button_disabled.png</file>
- <file>dark/combobox/core_dropdown_button_pressed.png</file>
- <file>dark/combobox/core_dropdown_checkmark.png</file>
- <file>dark/combobox/core_dropdown_divider.png</file>
- <file>dark/combobox/core_dropdown_menu.png</file>
- <file>dark/combobox/core_dropdown_menuup.png</file>
- <file>dark/combobox/core_listitem_active.png</file>
- <file>dark/lineedit/core_textinput_bg.png</file>
- <file>dark/lineedit/core_textinput_bg_disabled.png</file>
- <file>dark/lineedit/core_textinput_bg_highlight.png</file>
- <file>dark/listitem/core_listitem_active.png</file>
- <file>dark/listitem/core_listitem_divider.png</file>
- <file>dark/progressbar/core_progressindicator_bg.png</file>
- <file>dark/progressbar/core_progressindicator_complete.png</file>
- <file>dark/progressbar/core_progressindicator_fill.png</file>
- <file>dark/progressbar/core_progressindicator_vbg.png</file>
- <file>dark/progressbar/core_progressindicator_vcomplete.png</file>
- <file>dark/progressbar/core_progressindicator_vfill.png</file>
- <file>dark/radiobutton/core_radiobutton_checked.png</file>
- <file>dark/radiobutton/core_radiobutton_disabled.png</file>
- <file>dark/radiobutton/core_radiobutton_disabled_checked.png</file>
- <file>dark/radiobutton/core_radiobutton_inactive.png</file>
- <file>dark/radiobutton/core_radiobutton_pressed.png</file>
- <file>dark/scrollbar/core_scrollbar.png</file>
- <file>dark/scrollbar/core_scrollbar_v.png</file>
- <file>dark/slider/core_slider_active.png</file>
- <file>dark/slider/core_slider_cache.png</file>
- <file>dark/slider/core_slider_disabled.png</file>
- <file>dark/slider/core_slider_enabled.png</file>
- <file>dark/slider/core_slider_handle.png</file>
- <file>dark/slider/core_slider_handle_disabled.png</file>
- <file>dark/slider/core_slider_handle_pressed.png</file>
- <file>dark/slider/core_slider_inactive.png</file>
- <file>dark/slider/core_slider_vactive.png</file>
- <file>dark/slider/core_slider_vcache.png</file>
- <file>dark/slider/core_slider_vdisabled.png</file>
- <file>dark/slider/core_slider_venabled.png</file>
- <file>dark/slider/core_slider_vinactive.png</file>
- </qresource>
-</RCC>
diff --git a/src/plugins/styles/bb10style/qbb10styleplugin.cpp b/src/plugins/styles/bb10style/qbb10styleplugin.cpp
deleted file mode 100644
index 98607f174a..0000000000
--- a/src/plugins/styles/bb10style/qbb10styleplugin.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qbb10styleplugin.h"
-#include "qbb10darkstyle.h"
-#include "qbb10brightstyle.h"
-
-QT_BEGIN_NAMESPACE
-
-QBB10StylePlugin::QBB10StylePlugin()
-{
-}
-
-QBB10StylePlugin::~QBB10StylePlugin()
-{
-}
-
-QStyle *QBB10StylePlugin::create(const QString &key)
-{
- const QString keyLower(key.toLower());
- if (keyLower == QLatin1String("bb10bright"))
- return new QBB10BrightStyle;
- else if (keyLower == QLatin1String("bb10dark"))
- return new QBB10DarkStyle;
-
- return 0;
-}
-
-QStringList QBB10StylePlugin::keys() const
-{
- return QStringList() << QLatin1String("bb10bright") << QLatin1String("bb10dark");
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qbb10styleplugin.cpp"
diff --git a/src/plugins/styles/bb10style/qbb10styleplugin.h b/src/plugins/styles/bb10style/qbb10styleplugin.h
deleted file mode 100644
index 8058e4859e..0000000000
--- a/src/plugins/styles/bb10style/qbb10styleplugin.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/***************************************************************************
-**
-** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QBB10STYLEPLUGIN_H
-#define QBB10STYLEPLUGIN_H
-
-#include <QStylePlugin>
-
-QT_BEGIN_NAMESPACE
-
-class QBB10StylePlugin : public QStylePlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "qbb10styleplugin.json")
-
-public:
- QBB10StylePlugin();
- ~QBB10StylePlugin();
-
- QStyle *create(const QString &key);
- QStringList keys() const;
-};
-
-QT_END_NAMESPACE
-
-#endif // QBB10STYLEPLUGIN_H
diff --git a/src/plugins/styles/bb10style/qbb10styleplugin.json b/src/plugins/styles/bb10style/qbb10styleplugin.json
deleted file mode 100644
index 8f79b706c3..0000000000
--- a/src/plugins/styles/bb10style/qbb10styleplugin.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "Keys": [ "bb10bright", "bb10dark" ]
-}
diff --git a/src/plugins/styles/styles.pro b/src/plugins/styles/styles.pro
deleted file mode 100644
index 88b3f90e0c..0000000000
--- a/src/plugins/styles/styles.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE = subdirs
-
-blackberry:SUBDIRS += bb10style
diff --git a/src/printsupport/dialogs/dialogs.pri b/src/printsupport/dialogs/dialogs.pri
index bb07167f68..7b520a05de 100644
--- a/src/printsupport/dialogs/dialogs.pri
+++ b/src/printsupport/dialogs/dialogs.pri
@@ -8,10 +8,10 @@ HEADERS += \
dialogs/qprintdialog.h \
dialogs/qprintpreviewdialog.h
-mac:!ios {
+osx {
OBJECTIVE_SOURCES += dialogs/qpagesetupdialog_mac.mm \
dialogs/qprintdialog_mac.mm
- LIBS_PRIVATE += -framework Cocoa
+ LIBS_PRIVATE += -framework AppKit
}
win32 {
diff --git a/src/printsupport/dialogs/qpagesetupdialog_mac.mm b/src/printsupport/dialogs/qpagesetupdialog_mac.mm
index b86de31883..3147ccb58e 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_mac.mm
+++ b/src/printsupport/dialogs/qpagesetupdialog_mac.mm
@@ -32,7 +32,7 @@
****************************************************************************/
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include "qpagesetupdialog.h"
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
index 7748a8af01..f94f049680 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
@@ -339,9 +339,9 @@ void QPageSetupWidget::initPageSizes()
QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
if (ps) {
QPrintDevice printDevice = ps->createPrintDevice(m_printerName);
- foreach (const QPageSize &pageSize, printDevice.supportedPageSizes()) {
+ const auto pageSizes = printDevice.supportedPageSizes();
+ for (const QPageSize &pageSize : pageSizes)
m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize.id()));
- }
if (m_ui.pageSizeCombo->count() > 0 && printDevice.supportsCustomPageSizes()) {
m_ui.pageSizeCombo->addItem(tr("Custom"), QVariant::fromValue(QPageSize::Custom));
m_blockSignals = false;
diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm
index 030526954d..e7948c2a37 100644
--- a/src/printsupport/dialogs/qprintdialog_mac.mm
+++ b/src/printsupport/dialogs/qprintdialog_mac.mm
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include "qprintdialog.h"
#include "qabstractprintdialog_p.h"
diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp
index 9633032a0f..c6c84ca701 100644
--- a/src/printsupport/dialogs/qprintdialog_unix.cpp
+++ b/src/printsupport/dialogs/qprintdialog_unix.cpp
@@ -661,18 +661,16 @@ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *
widget.setupUi(parent);
int currentPrinterIndex = 0;
- QStringList printers;
- QString defaultPrinter;
QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
if (ps) {
- printers = ps->availablePrintDeviceIds();
- defaultPrinter = ps->defaultPrintDeviceId();
- }
+ const QStringList printers = ps->availablePrintDeviceIds();
+ const QString defaultPrinter = ps->defaultPrintDeviceId();
+
+ widget.printers->addItems(printers);
- for (int i = 0; i < printers.size(); ++i) {
- widget.printers->addItem(printers.at(i));
- if (printers.at(i) == defaultPrinter)
- currentPrinterIndex = i;
+ const int idx = printers.indexOf(defaultPrinter);
+ if (idx >= 0)
+ currentPrinterIndex = idx;
}
widget.properties->setEnabled(true);
@@ -827,12 +825,9 @@ void QUnixPrintWidgetPrivate::applyPrinterProperties()
widget.filename->setText( printer->outputFileName() );
QString printerName = printer->printerName();
if (!printerName.isEmpty()) {
- for (int i = 0; i < widget.printers->count(); ++i) {
- if (widget.printers->itemText(i) == printerName) {
- widget.printers->setCurrentIndex(i);
- break;
- }
- }
+ const int i = widget.printers->findText(printerName);
+ if (i >= 0)
+ widget.printers->setCurrentIndex(i);
}
// PDF printer not added to the dialog yet, we'll handle those cases in QUnixPrintWidgetPrivate::updateWidget
diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp
index 6385f58aa1..507c66d895 100644
--- a/src/printsupport/kernel/qplatformprintdevice.cpp
+++ b/src/printsupport/kernel/qplatformprintdevice.cpp
@@ -168,7 +168,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QPageSize &pageSize) con
// e.g. Windows defines DMPAPER_11X17 and DMPAPER_TABLOID with names "11x17" and "Tabloid", but both
// map to QPageSize::Tabloid / PPD Key "Tabloid" / ANSI B Tabloid
if (pageSize.id() != QPageSize::Custom) {
- foreach (const QPageSize &ps, m_pageSizes) {
+ for (const QPageSize &ps : m_pageSizes) {
if (ps.id() == pageSize.id() && ps.name() == pageSize.name())
return ps;
}
@@ -176,7 +176,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QPageSize &pageSize) con
// Next try match on id only if not custom
if (pageSize.id() != QPageSize::Custom) {
- foreach (const QPageSize &ps, m_pageSizes) {
+ for (const QPageSize &ps : m_pageSizes) {
if (ps.id() == pageSize.id())
return ps;
}
@@ -191,7 +191,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(QPageSize::PageSizeId pageSize
if (!m_havePageSizes)
loadPageSizes();
- foreach (const QPageSize &ps, m_pageSizes) {
+ for (const QPageSize &ps : m_pageSizes) {
if (ps.id() == pageSizeId)
return ps;
}
@@ -205,7 +205,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QString &pageName) const
if (!m_havePageSizes)
loadPageSizes();
- foreach (const QPageSize &ps, m_pageSizes) {
+ for (const QPageSize &ps : m_pageSizes) {
if (ps.name() == pageName)
return ps;
}
@@ -234,7 +234,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QSizeF &size, QPageSize:
QPageSize QPlatformPrintDevice::supportedPageSizeMatch(const QPageSize &pageSize) const
{
// Try to find a supported page size based on point size
- foreach (const QPageSize &ps, m_pageSizes) {
+ for (const QPageSize &ps : m_pageSizes) {
if (ps.sizePoints() == pageSize.sizePoints())
return ps;
}
diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp
index 00a8ca7c98..06a1e371bf 100644
--- a/src/printsupport/kernel/qprintengine_win.cpp
+++ b/src/printsupport/kernel/qprintengine_win.cpp
@@ -1463,7 +1463,9 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
case PPK_SupportedResolutions: {
QList<QVariant> list;
- foreach (int resolution, d->m_printDevice.supportedResolutions())
+ const auto resolutions = d->m_printDevice.supportedResolutions();
+ list.reserve(resolutions.size());
+ for (int resolution : resolutions)
list << resolution;
value = list;
break;
@@ -1475,7 +1477,9 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
case PPK_PaperSources: {
QList<QVariant> out;
- foreach (const QPrint::InputSlot inputSlot, d->m_printDevice.supportedInputSlots())
+ const auto inputSlots = d->m_printDevice.supportedInputSlots();
+ out.reserve(inputSlots.size());
+ for (const QPrint::InputSlot inputSlot : inputSlots)
out << QVariant(inputSlot.id == QPrint::CustomInputSlot ? inputSlot.windowsId : int(inputSlot.id));
value = out;
break;
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index 2cecf61573..7f08bdb3e9 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -160,7 +160,8 @@ void QPrinterPrivate::changeEngines(QPrinter::OutputFormat format, const QPrinte
initEngines(format, printer);
if (oldPrintEngine) {
- foreach (QPrintEngine::PrintEnginePropertyKey key, m_properties) {
+ const auto properties = m_properties; // take a copy: setProperty() below modifies m_properties
+ for (const auto &key : properties) {
QVariant prop;
// PPK_NumberOfCopies need special treatmeant since it in most cases
// will return 1, disregarding the actual value that was set
@@ -695,7 +696,7 @@ QPrinter::QPrinter(const QPrinterInfo& printer, PrinterMode mode)
void QPrinterPrivate::init(const QPrinterInfo &printer, QPrinter::PrinterMode mode)
{
- if (!QCoreApplication::instance()) {
+ if (Q_UNLIKELY(!QCoreApplication::instance())) {
qFatal("QPrinter: Must construct a QCoreApplication before a QPrinter");
return;
}
diff --git a/src/printsupport/kernel/qprinterinfo.cpp b/src/printsupport/kernel/qprinterinfo.cpp
index 1be574891b..7ccd7d1fea 100644
--- a/src/printsupport/kernel/qprinterinfo.cpp
+++ b/src/printsupport/kernel/qprinterinfo.cpp
@@ -318,7 +318,7 @@ QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
QList<QPrinter::PaperSize> list;
const QList<QPageSize> supportedPageSizes = d->m_printDevice.supportedPageSizes();
list.reserve(supportedPageSizes.size());
- foreach (const QPageSize &pageSize, supportedPageSizes)
+ for (const QPageSize &pageSize : supportedPageSizes)
list.append(QPrinter::PaperSize(pageSize.id()));
return list;
}
@@ -340,7 +340,7 @@ QList<QPair<QString, QSizeF> > QPrinterInfo::supportedSizesWithNames() const
QList<QPair<QString, QSizeF> > list;
const QList<QPageSize> supportedPageSizes = d->m_printDevice.supportedPageSizes();
list.reserve(supportedPageSizes.size());
- foreach (const QPageSize &pageSize, supportedPageSizes)
+ for (const QPageSize &pageSize : supportedPageSizes)
list.append(qMakePair(pageSize.name(), pageSize.size(QPageSize::Millimeter)));
return list;
}
@@ -382,7 +382,7 @@ QList<QPrinter::DuplexMode> QPrinterInfo::supportedDuplexModes() const
QList<QPrinter::DuplexMode> list;
const QList<QPrint::DuplexMode> supportedDuplexModes = d->m_printDevice.supportedDuplexModes();
list.reserve(supportedDuplexModes.size());
- foreach (QPrint::DuplexMode mode, supportedDuplexModes)
+ for (QPrint::DuplexMode mode : supportedDuplexModes)
list << QPrinter::DuplexMode(mode);
return list;
}
@@ -424,7 +424,7 @@ QList<QPrinterInfo> QPrinterInfo::availablePrinters()
if (ps) {
const QStringList availablePrintDeviceIds = ps->availablePrintDeviceIds();
list.reserve(availablePrintDeviceIds.size());
- foreach (const QString &id, availablePrintDeviceIds)
+ for (const QString &id : availablePrintDeviceIds)
list.append(QPrinterInfo(id));
}
return list;
diff --git a/src/printsupport/widgets/qprintpreviewwidget.cpp b/src/printsupport/widgets/qprintpreviewwidget.cpp
index 686dab07bf..bf18223cf0 100644
--- a/src/printsupport/widgets/qprintpreviewwidget.cpp
+++ b/src/printsupport/widgets/qprintpreviewwidget.cpp
@@ -223,8 +223,8 @@ void QPrintPreviewWidgetPrivate::_q_fit(bool doFitting)
if (doFitting && fitting) {
QRect viewRect = graphicsView->viewport()->rect();
if (zoomMode == QPrintPreviewWidget::FitInView) {
- QList<QGraphicsItem*> containedItems = graphicsView->items(viewRect, Qt::ContainsItemBoundingRect);
- foreach(QGraphicsItem* item, containedItems) {
+ const QList<QGraphicsItem*> containedItems = graphicsView->items(viewRect, Qt::ContainsItemBoundingRect);
+ for (QGraphicsItem* item : containedItems) {
PageItem* pg = static_cast<PageItem*>(item);
if (pg->pageNumber() == curPage)
return;
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
index 78b396f423..cc16a68916 100644
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ b/src/sql/drivers/db2/qsql_db2.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include "qsql_db2_p.h"
-#include <QtSql/private/qsqldriver_p.h>
#include <qcoreapplication.h>
#include <qdatetime.h>
#include <qsqlfield.h>
@@ -43,6 +42,8 @@
#include <qvarlengtharray.h>
#include <qvector.h>
#include <QDebug>
+#include <QtSql/private/qsqldriver_p.h>
+#include <QtSql/private/qsqlresult_p.h>
#if defined(Q_CC_BOR)
// DB2's sqlsystm.h (included through sqlcli1.h) defines the SQL_BIGINT_TYPE
@@ -65,6 +66,8 @@ static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL
class QDB2DriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QDB2Driver)
+
public:
QDB2DriverPrivate() : QSqlDriverPrivate(), hEnv(0), hDbc(0) { dbmsType = QSqlDriver::DB2; }
SQLHANDLE hEnv;
@@ -72,10 +75,44 @@ public:
QString user;
};
-class QDB2ResultPrivate
+class QDB2ResultPrivate;
+
+class QDB2Result: public QSqlResult
{
+ Q_DECLARE_PRIVATE(QDB2Result)
+
public:
- QDB2ResultPrivate(const QDB2DriverPrivate* d): dp(d), hStmt(0)
+ QDB2Result(const QDB2Driver *drv);
+ ~QDB2Result();
+ bool prepare(const QString &query) Q_DECL_OVERRIDE;
+ bool exec() Q_DECL_OVERRIDE;
+ QVariant handle() const Q_DECL_OVERRIDE;
+
+protected:
+ QVariant data(int field) Q_DECL_OVERRIDE;
+ bool reset(const QString &query) Q_DECL_OVERRIDE;
+ bool fetch(int i) Q_DECL_OVERRIDE;
+ bool fetchNext() Q_DECL_OVERRIDE;
+ bool fetchFirst() Q_DECL_OVERRIDE;
+ bool fetchLast() Q_DECL_OVERRIDE;
+ bool isNull(int i) Q_DECL_OVERRIDE;
+ int size() Q_DECL_OVERRIDE;
+ int numRowsAffected() Q_DECL_OVERRIDE;
+ QSqlRecord record() const Q_DECL_OVERRIDE;
+ void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
+ void detachFromResultSet() Q_DECL_OVERRIDE;
+ bool nextResult() Q_DECL_OVERRIDE;
+};
+
+class QDB2ResultPrivate: public QSqlResultPrivate
+{
+ Q_DECLARE_PUBLIC(QDB2Result)
+
+public:
+ Q_DECLARE_SQLDRIVER_PRIVATE(QDB2Driver)
+ QDB2ResultPrivate(QDB2Result *q, const QDB2Driver *drv)
+ : QSqlResultPrivate(q, drv),
+ hStmt(0)
{}
~QDB2ResultPrivate()
{
@@ -94,7 +131,6 @@ public:
valueCache.clear();
}
- const QDB2DriverPrivate* dp;
SQLHANDLE hStmt;
QSqlRecord recInf;
QVector<QVariant*> valueCache;
@@ -140,8 +176,8 @@ static QString qDB2Warn(const QDB2DriverPrivate* d)
static QString qDB2Warn(const QDB2ResultPrivate* d)
{
- return (qWarnDB2Handle(SQL_HANDLE_ENV, d->dp->hEnv) + QLatin1Char(' ')
- + qWarnDB2Handle(SQL_HANDLE_DBC, d->dp->hDbc)
+ return (qWarnDB2Handle(SQL_HANDLE_ENV, d->drv_d_func()->hEnv) + QLatin1Char(' ')
+ + qWarnDB2Handle(SQL_HANDLE_DBC, d->drv_d_func()->hDbc)
+ qWarnDB2Handle(SQL_HANDLE_STMT, d->hStmt));
}
@@ -466,7 +502,7 @@ static bool qMakeStatement(QDB2ResultPrivate* d, bool forwardOnly, bool setForwa
SQLRETURN r;
if (!d->hStmt) {
r = SQLAllocHandle(SQL_HANDLE_STMT,
- d->dp->hDbc,
+ d->drv_d_func()->hDbc,
&d->hStmt);
if (r != SQL_SUCCESS) {
qSqlWarning(QLatin1String("QDB2Result::reset: Unable to allocate statement handle"), d);
@@ -505,30 +541,31 @@ static bool qMakeStatement(QDB2ResultPrivate* d, bool forwardOnly, bool setForwa
QVariant QDB2Result::handle() const
{
+ Q_D(const QDB2Result);
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt);
}
/************************************/
-QDB2Result::QDB2Result(const QDB2Driver* dr, const QDB2DriverPrivate* dp)
- : QSqlResult(dr)
+QDB2Result::QDB2Result(const QDB2Driver *drv)
+ : QSqlResult(*new QDB2ResultPrivate(this, drv))
{
- d = new QDB2ResultPrivate(dp);
}
QDB2Result::~QDB2Result()
{
+ Q_D(const QDB2Result);
if (d->hStmt) {
SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
if (r != SQL_SUCCESS)
qSqlWarning(QLatin1String("QDB2Driver: Unable to free statement handle ")
+ QString::number(r), d);
}
- delete d;
}
bool QDB2Result::reset (const QString& query)
{
+ Q_D(QDB2Result);
setActive(false);
setAt(QSql::BeforeFirstRow);
SQLRETURN r;
@@ -565,6 +602,7 @@ bool QDB2Result::reset (const QString& query)
bool QDB2Result::prepare(const QString& query)
{
+ Q_D(QDB2Result);
setActive(false);
setAt(QSql::BeforeFirstRow);
SQLRETURN r;
@@ -589,6 +627,7 @@ bool QDB2Result::prepare(const QString& query)
bool QDB2Result::exec()
{
+ Q_D(QDB2Result);
QList<QByteArray> tmpStorage; // holds temporary ptrs
QVarLengthArray<SQLINTEGER, 32> indicators(boundValues().count());
@@ -840,6 +879,7 @@ bool QDB2Result::exec()
bool QDB2Result::fetch(int i)
{
+ Q_D(QDB2Result);
if (isForwardOnly() && i < at())
return false;
if (i == at())
@@ -874,6 +914,7 @@ bool QDB2Result::fetch(int i)
bool QDB2Result::fetchNext()
{
+ Q_D(QDB2Result);
SQLRETURN r;
d->clearValueCache();
r = SQLFetchScroll(d->hStmt,
@@ -891,6 +932,7 @@ bool QDB2Result::fetchNext()
bool QDB2Result::fetchFirst()
{
+ Q_D(QDB2Result);
if (isForwardOnly() && at() != QSql::BeforeFirstRow)
return false;
if (isForwardOnly())
@@ -912,6 +954,7 @@ bool QDB2Result::fetchFirst()
bool QDB2Result::fetchLast()
{
+ Q_D(QDB2Result);
d->clearValueCache();
int i = at();
@@ -943,6 +986,7 @@ bool QDB2Result::fetchLast()
QVariant QDB2Result::data(int field)
{
+ Q_D(QDB2Result);
if (field >= d->recInf.count()) {
qWarning("QDB2Result::data: column %d out of range", field);
return QVariant();
@@ -1049,6 +1093,7 @@ QVariant QDB2Result::data(int field)
bool QDB2Result::isNull(int i)
{
+ Q_D(const QDB2Result);
if (i >= d->valueCache.size())
return true;
@@ -1059,6 +1104,7 @@ bool QDB2Result::isNull(int i)
int QDB2Result::numRowsAffected()
{
+ Q_D(const QDB2Result);
SQLINTEGER affectedRowCount = 0;
SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount);
if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
@@ -1075,6 +1121,7 @@ int QDB2Result::size()
QSqlRecord QDB2Result::record() const
{
+ Q_D(const QDB2Result);
if (isActive())
return d->recInf;
return QSqlRecord();
@@ -1082,6 +1129,7 @@ QSqlRecord QDB2Result::record() const
bool QDB2Result::nextResult()
{
+ Q_D(QDB2Result);
setActive(false);
setAt(QSql::BeforeFirstRow);
d->recInf.clear();
@@ -1117,6 +1165,7 @@ void QDB2Result::virtual_hook(int id, void *data)
void QDB2Result::detachFromResultSet()
{
+ Q_D(QDB2Result);
if (d->hStmt)
SQLCloseCursor(d->hStmt);
}
@@ -1132,8 +1181,8 @@ QDB2Driver::QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent)
: QSqlDriver(*new QDB2DriverPrivate, parent)
{
Q_D(QDB2Driver);
- d->hEnv = (SQLHANDLE)env;
- d->hDbc = (SQLHANDLE)con;
+ d->hEnv = reinterpret_cast<intptr_t>(env);
+ d->hDbc = reinterpret_cast<intptr_t>(con);
if (env && con) {
setOpen(true);
setOpenError(false);
@@ -1197,10 +1246,10 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
tmp.toLocal8Bit().constData());
continue;
}
- r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_ACCESS_MODE, (SQLPOINTER) v, 0);
+ r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_ACCESS_MODE, reinterpret_cast<SQLPOINTER>(v), 0);
} else if (opt == QLatin1String("SQL_ATTR_LOGIN_TIMEOUT")) {
v = val.toUInt();
- r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0);
+ r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, reinterpret_cast<SQLPOINTER>(v), 0);
} else if (opt.compare(QLatin1String("PROTOCOL"), Qt::CaseInsensitive) == 0) {
protocol = tmp;
}
@@ -1278,8 +1327,7 @@ void QDB2Driver::close()
QSqlResult *QDB2Driver::createResult() const
{
- Q_D(const QDB2Driver);
- return new QDB2Result(this, d);
+ return new QDB2Result(this);
}
QSqlRecord QDB2Driver::record(const QString& tableName) const
@@ -1506,6 +1554,7 @@ bool QDB2Driver::hasFeature(DriverFeature f) const
case LastInsertId:
case SimpleLocking:
case EventNotifications:
+ case CancelQuery:
return false;
case BLOB:
case Transactions:
@@ -1572,7 +1621,7 @@ bool QDB2Driver::setAutoCommit(bool autoCommit)
SQLUINTEGER ac = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
SQLRETURN r = SQLSetConnectAttr(d->hDbc,
SQL_ATTR_AUTOCOMMIT,
- (SQLPOINTER)ac,
+ reinterpret_cast<SQLPOINTER>(ac),
sizeof(ac));
if (r != SQL_SUCCESS) {
setLastError(qMakeError(tr("Unable to set autocommit"),
diff --git a/src/sql/drivers/db2/qsql_db2_p.h b/src/sql/drivers/db2/qsql_db2_p.h
index 7b5d751b89..0b07456122 100644
--- a/src/sql/drivers/db2/qsql_db2_p.h
+++ b/src/sql/drivers/db2/qsql_db2_p.h
@@ -53,70 +53,40 @@
#define Q_EXPORT_SQLDRIVER_DB2 Q_SQL_EXPORT
#endif
-#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
QT_BEGIN_NAMESPACE
-class QDB2Driver;
class QDB2DriverPrivate;
-class QDB2ResultPrivate;
-class QSqlRecord;
-
-class QDB2Result : public QSqlResult
-{
-public:
- QDB2Result(const QDB2Driver* dr, const QDB2DriverPrivate* dp);
- ~QDB2Result();
- bool prepare(const QString& query);
- bool exec();
- QVariant handle() const;
-
-protected:
- QVariant data(int field);
- bool reset (const QString& query);
- bool fetch(int i);
- bool fetchNext();
- bool fetchFirst();
- bool fetchLast();
- bool isNull(int i);
- int size();
- int numRowsAffected();
- QSqlRecord record() const;
- void virtual_hook(int id, void *data);
- void detachFromResultSet();
- bool nextResult();
-
-private:
- QDB2ResultPrivate* d;
-};
class Q_EXPORT_SQLDRIVER_DB2 QDB2Driver : public QSqlDriver
{
Q_DECLARE_PRIVATE(QDB2Driver)
Q_OBJECT
+ friend class QDB2ResultPrivate;
+
public:
explicit QDB2Driver(QObject* parent = 0);
QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent = 0);
~QDB2Driver();
- bool hasFeature(DriverFeature) const;
- void close();
- QSqlRecord record(const QString& tableName) const;
- QStringList tables(QSql::TableType type) const;
- QSqlResult *createResult() const;
- QSqlIndex primaryIndex(const QString& tablename) const;
- bool beginTransaction();
- bool commitTransaction();
- bool rollbackTransaction();
- QString formatValue(const QSqlField &field, bool trimStrings) const;
- QVariant handle() const;
- bool open(const QString& db,
- const QString& user,
- const QString& password,
- const QString& host,
+ bool hasFeature(DriverFeature) const Q_DECL_OVERRIDE;
+ void close() Q_DECL_OVERRIDE;
+ QSqlRecord record(const QString &tableName) const Q_DECL_OVERRIDE;
+ QStringList tables(QSql::TableType type) const Q_DECL_OVERRIDE;
+ QSqlResult *createResult() const Q_DECL_OVERRIDE;
+ QSqlIndex primaryIndex(const QString &tablename) const Q_DECL_OVERRIDE;
+ bool beginTransaction() Q_DECL_OVERRIDE;
+ bool commitTransaction() Q_DECL_OVERRIDE;
+ bool rollbackTransaction() Q_DECL_OVERRIDE;
+ QString formatValue(const QSqlField &field, bool trimStrings) const Q_DECL_OVERRIDE;
+ QVariant handle() const Q_DECL_OVERRIDE;
+ bool open(const QString &db,
+ const QString &user,
+ const QString &password,
+ const QString &host,
int port,
- const QString& connOpts);
- QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
+ const QString& connOpts) Q_DECL_OVERRIDE;
+ QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE;
private:
bool setAutoCommit(bool autoCommit);
diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp
index d68ac276ef..c45415b56b 100644
--- a/src/sql/drivers/ibase/qsql_ibase.cpp
+++ b/src/sql/drivers/ibase/qsql_ibase.cpp
@@ -345,36 +345,37 @@ class QIBaseResultPrivate;
class QIBaseResult : public QSqlCachedResult
{
- friend class QIBaseResultPrivate;
+ Q_DECLARE_PRIVATE(QIBaseResult)
public:
explicit QIBaseResult(const QIBaseDriver* db);
- virtual ~QIBaseResult();
- bool prepare(const QString& query);
- bool exec();
- QVariant handle() const;
+ bool prepare(const QString &query) Q_DECL_OVERRIDE;
+ bool exec() Q_DECL_OVERRIDE;
+ QVariant handle() const Q_DECL_OVERRIDE;
protected:
- bool gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx);
- bool reset (const QString& query);
- int size();
- int numRowsAffected();
- QSqlRecord record() const;
-
-private:
- QIBaseResultPrivate* d;
+ bool gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx) Q_DECL_OVERRIDE;
+ bool reset (const QString &query) Q_DECL_OVERRIDE;
+ int size() Q_DECL_OVERRIDE;
+ int numRowsAffected() Q_DECL_OVERRIDE;
+ QSqlRecord record() const Q_DECL_OVERRIDE;
};
-class QIBaseResultPrivate
+class QIBaseResultPrivate: public QSqlCachedResultPrivate
{
+ Q_DECLARE_PUBLIC(QIBaseResult)
+
public:
- QIBaseResultPrivate(QIBaseResult *d, const QIBaseDriver *ddb);
+ Q_DECLARE_SQLDRIVER_PRIVATE(QIBaseDriver)
+
+ QIBaseResultPrivate(QIBaseResult *q, const QIBaseDriver *drv);
~QIBaseResultPrivate() { cleanup(); }
void cleanup();
bool isError(const char *msg, QSqlError::ErrorType typ = QSqlError::UnknownError)
{
+ Q_Q(QIBaseResult);
QString imsg;
ISC_LONG sqlcode;
if (!getIBaseError(imsg, status, sqlcode, tc))
@@ -395,8 +396,6 @@ public:
bool writeArray(int i, const QList<QVariant> &list);
public:
- QIBaseResult *q;
- const QIBaseDriver *db;
ISC_STATUS status[20];
isc_tr_handle trans;
//indicator whether we have a local transaction or a transaction on driver level
@@ -410,14 +409,22 @@ public:
};
-QIBaseResultPrivate::QIBaseResultPrivate(QIBaseResult *d, const QIBaseDriver *ddb):
- q(d), db(ddb), trans(0), stmt(0), ibase(ddb->d_func()->ibase), sqlda(0), inda(0), queryType(-1), tc(ddb->d_func()->tc)
+QIBaseResultPrivate::QIBaseResultPrivate(QIBaseResult *q, const QIBaseDriver *drv)
+ : QSqlCachedResultPrivate(q, drv),
+ trans(0),
+ localTransaction(!drv_d_func()->ibase),
+ stmt(0),
+ ibase(drv_d_func()->ibase),
+ sqlda(0),
+ inda(0),
+ queryType(-1),
+ tc(drv_d_func()->tc)
{
- localTransaction = (ddb->d_func()->ibase == 0);
}
void QIBaseResultPrivate::cleanup()
{
+ Q_Q(QIBaseResult);
commit();
if (!localTransaction)
trans = 0;
@@ -779,6 +786,7 @@ static char* createArrayBuffer(char *buffer, const QList<QVariant> &list,
bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list)
{
+ Q_Q(QIBaseResult);
QString error;
ISC_QUAD *arrayId = (ISC_QUAD*) inda->sqlvar[column].sqldata;
ISC_ARRAY_DESC desc;
@@ -854,9 +862,9 @@ bool QIBaseResultPrivate::transaction()
{
if (trans)
return true;
- if (db->d_func()->trans) {
+ if (drv_d_func()->trans) {
localTransaction = false;
- trans = db->d_func()->trans;
+ trans = drv_d_func()->trans;
return true;
}
localTransaction = true;
@@ -887,19 +895,14 @@ bool QIBaseResultPrivate::commit()
//////////
-QIBaseResult::QIBaseResult(const QIBaseDriver* db):
- QSqlCachedResult(db)
-{
- d = new QIBaseResultPrivate(this, db);
-}
-
-QIBaseResult::~QIBaseResult()
+QIBaseResult::QIBaseResult(const QIBaseDriver *db)
+ : QSqlCachedResult(*new QIBaseResultPrivate(this, db))
{
- delete d;
}
bool QIBaseResult::prepare(const QString& query)
{
+ Q_D(QIBaseResult);
// qDebug("prepare: %s", qPrintable(query));
if (!driver() || !driver()->isOpen() || driver()->isOpenError())
return false;
@@ -976,6 +979,7 @@ bool QIBaseResult::prepare(const QString& query)
bool QIBaseResult::exec()
{
+ Q_D(QIBaseResult);
bool ok = true;
if (!d->trans)
@@ -1113,6 +1117,7 @@ bool QIBaseResult::reset (const QString& query)
bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx)
{
+ Q_D(QIBaseResult);
ISC_STATUS stat = 0;
// Stored Procedures are special - they populate our d->sqlda when executing,
@@ -1307,6 +1312,7 @@ int QIBaseResult::size()
int QIBaseResult::numRowsAffected()
{
+ Q_D(QIBaseResult);
static char acCountInfo[] = {isc_info_sql_records};
char cCountType;
bool bIsProcedure = false;
@@ -1361,6 +1367,7 @@ int QIBaseResult::numRowsAffected()
QSqlRecord QIBaseResult::record() const
{
+ Q_D(const QIBaseResult);
QSqlRecord rec;
if (!isActive() || !d->sqlda)
return rec;
@@ -1374,7 +1381,7 @@ QSqlRecord QIBaseResult::record() const
f.setPrecision(qAbs(v.sqlscale));
f.setRequiredStatus((v.sqltype & 1) == 0 ? QSqlField::Required : QSqlField::Optional);
if(v.sqlscale < 0) {
- QSqlQuery q(new QIBaseResult(d->db));
+ QSqlQuery q(driver()->createResult());
q.setForwardOnly(true);
q.exec(QLatin1String("select b.RDB$FIELD_PRECISION, b.RDB$FIELD_SCALE, b.RDB$FIELD_LENGTH, a.RDB$NULL_FLAG "
"FROM RDB$RELATION_FIELDS a, RDB$FIELDS b "
@@ -1400,6 +1407,7 @@ QSqlRecord QIBaseResult::record() const
QVariant QIBaseResult::handle() const
{
+ Q_D(const QIBaseResult);
return QVariant(qRegisterMetaType<isc_stmt_handle>("isc_stmt_handle"), &d->stmt);
}
@@ -1910,7 +1918,7 @@ void QIBaseDriver::qHandleEventNotification(void *updatedResultBuffer)
(isc_callback)qEventCallback,
#endif
eBuffer->resultBuffer);
- if (status[0] == 1 && status[1]) {
+ if (Q_UNLIKELY(status[0] == 1 && status[1])) {
qCritical("QIBaseDriver::qHandleEventNotification: could not resubscribe to '%s'",
qPrintable(i.key()));
}
diff --git a/src/sql/drivers/ibase/qsql_ibase_p.h b/src/sql/drivers/ibase/qsql_ibase_p.h
index 3a61f3394b..e052e83641 100644
--- a/src/sql/drivers/ibase/qsql_ibase_p.h
+++ b/src/sql/drivers/ibase/qsql_ibase_p.h
@@ -45,16 +45,21 @@
// We mean it.
//
-#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
#include <ibase.h>
+#ifdef QT_PLUGIN
+#define Q_EXPORT_SQLDRIVER_IBASE
+#else
+#define Q_EXPORT_SQLDRIVER_IBASE Q_SQL_EXPORT
+#endif
+
QT_BEGIN_NAMESPACE
+class QSqlResult;
class QIBaseDriverPrivate;
-class QIBaseDriver;
-class QIBaseDriver : public QSqlDriver
+class Q_EXPORT_SQLDRIVER_IBASE QIBaseDriver : public QSqlDriver
{
friend class QIBaseResultPrivate;
Q_DECLARE_PRIVATE(QIBaseDriver)
@@ -63,36 +68,36 @@ public:
explicit QIBaseDriver(QObject *parent = 0);
explicit QIBaseDriver(isc_db_handle connection, QObject *parent = 0);
virtual ~QIBaseDriver();
- bool hasFeature(DriverFeature f) const;
- bool open(const QString & db,
- const QString & user,
- const QString & password,
- const QString & host,
+ bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE;
+ bool open(const QString &db,
+ const QString &user,
+ const QString &password,
+ const QString &host,
int port,
- const QString & connOpts);
- bool open(const QString & db,
- const QString & user,
- const QString & password,
- const QString & host,
- int port) { return open (db, user, password, host, port, QString()); }
- void close();
- QSqlResult *createResult() const;
- bool beginTransaction();
- bool commitTransaction();
- bool rollbackTransaction();
- QStringList tables(QSql::TableType) const;
+ const QString &connOpts) Q_DECL_OVERRIDE;
+ bool open(const QString &db,
+ const QString &user,
+ const QString &password,
+ const QString &host,
+ int port) { return open(db, user, password, host, port, QString()); }
+ void close() Q_DECL_OVERRIDE;
+ QSqlResult *createResult() const Q_DECL_OVERRIDE;
+ bool beginTransaction() Q_DECL_OVERRIDE;
+ bool commitTransaction() Q_DECL_OVERRIDE;
+ bool rollbackTransaction() Q_DECL_OVERRIDE;
+ QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE;
- QSqlRecord record(const QString& tablename) const;
- QSqlIndex primaryIndex(const QString &table) const;
+ QSqlRecord record(const QString& tablename) const Q_DECL_OVERRIDE;
+ QSqlIndex primaryIndex(const QString &table) const Q_DECL_OVERRIDE;
- QString formatValue(const QSqlField &field, bool trimStrings) const;
- QVariant handle() const;
+ QString formatValue(const QSqlField &field, bool trimStrings) const Q_DECL_OVERRIDE;
+ QVariant handle() const Q_DECL_OVERRIDE;
- QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
+ QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE;
- bool subscribeToNotification(const QString &name);
- bool unsubscribeFromNotification(const QString &name);
- QStringList subscribedToNotifications() const;
+ bool subscribeToNotification(const QString &name) Q_DECL_OVERRIDE;
+ bool unsubscribeFromNotification(const QString &name) Q_DECL_OVERRIDE;
+ QStringList subscribedToNotifications() const Q_DECL_OVERRIDE;
private Q_SLOTS:
void qHandleEventNotification(void* updatedResultBuffer);
diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index 96bdcc42fa..99f351a2bb 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -33,7 +33,6 @@
#include "qsql_mysql_p.h"
-#include <QtSql/private/qsqldriver_p.h>
#include <qcoreapplication.h>
#include <qvariant.h>
#include <qdatetime.h>
@@ -46,8 +45,9 @@
#include <qtextcodec.h>
#include <qvector.h>
#include <qfile.h>
-
#include <qdebug.h>
+#include <QtSql/private/qsqldriver_p.h>
+#include <QtSql/private/qsqlresult_p.h>
#ifdef Q_OS_WIN32
// comment the next line out if you want to use MySQL/embedded on Win32 systems.
@@ -72,6 +72,8 @@ QT_BEGIN_NAMESPACE
class QMYSQLDriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QMYSQLDriver)
+
public:
QMYSQLDriverPrivate() : QSqlDriverPrivate(), mysql(0),
#ifndef QT_NO_TEXTCODEC
@@ -156,24 +158,60 @@ static inline QVariant qDateTimeFromString(QString &val)
#endif
}
-class QMYSQLResultPrivate : public QObject
+class QMYSQLResultPrivate;
+
+class QMYSQLResult : public QSqlResult
{
- Q_OBJECT
+ Q_DECLARE_PRIVATE(QMYSQLResult)
+ friend class QMYSQLDriver;
+
public:
- QMYSQLResultPrivate(const QMYSQLDriver* dp, const QMYSQLResult* d) : driver(dp), result(0), q(d),
- rowsAffected(0), hasBlobs(false)
+ explicit QMYSQLResult(const QMYSQLDriver *db);
+ ~QMYSQLResult();
+
+ QVariant handle() const Q_DECL_OVERRIDE;
+protected:
+ void cleanup();
+ bool fetch(int i) Q_DECL_OVERRIDE;
+ bool fetchNext() Q_DECL_OVERRIDE;
+ bool fetchLast() Q_DECL_OVERRIDE;
+ bool fetchFirst() Q_DECL_OVERRIDE;
+ QVariant data(int field) Q_DECL_OVERRIDE;
+ bool isNull(int field) Q_DECL_OVERRIDE;
+ bool reset (const QString& query) Q_DECL_OVERRIDE;
+ int size() Q_DECL_OVERRIDE;
+ int numRowsAffected() Q_DECL_OVERRIDE;
+ QVariant lastInsertId() const Q_DECL_OVERRIDE;
+ QSqlRecord record() const Q_DECL_OVERRIDE;
+ void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
+ bool nextResult() Q_DECL_OVERRIDE;
+
+#if MYSQL_VERSION_ID >= 40108
+ bool prepare(const QString &stmt) Q_DECL_OVERRIDE;
+ bool exec() Q_DECL_OVERRIDE;
+#endif
+};
+
+class QMYSQLResultPrivate: public QSqlResultPrivate
+{
+ Q_DECLARE_PUBLIC(QMYSQLResult)
+
+public:
+ Q_DECLARE_SQLDRIVER_PRIVATE(QMYSQLDriver)
+
+ QMYSQLResultPrivate(QMYSQLResult *q, const QMYSQLDriver *drv)
+ : QSqlResultPrivate(q, drv),
+ result(0),
+ rowsAffected(0),
+ hasBlobs(false)
#if MYSQL_VERSION_ID >= 40108
, stmt(0), meta(0), inBinds(0), outBinds(0)
#endif
, preparedQuery(false)
- {
- connect(dp, SIGNAL(destroyed()), this, SLOT(driverDestroyed()));
- }
+ { }
- const QMYSQLDriver* driver;
MYSQL_RES *result;
MYSQL_ROW row;
- const QMYSQLResult* q;
int rowsAffected;
@@ -205,9 +243,6 @@ public:
#endif
bool preparedQuery;
-
-private Q_SLOTS:
- void driverDestroyed() { driver = NULL; }
};
#ifndef QT_NO_TEXTCODEC
@@ -396,19 +431,18 @@ bool QMYSQLResultPrivate::bindInValues()
#endif
QMYSQLResult::QMYSQLResult(const QMYSQLDriver* db)
-: QSqlResult(db)
+ : QSqlResult(*new QMYSQLResultPrivate(this, db))
{
- d = new QMYSQLResultPrivate(db, this);
}
QMYSQLResult::~QMYSQLResult()
{
cleanup();
- delete d;
}
QVariant QMYSQLResult::handle() const
{
+ Q_D(const QMYSQLResult);
#if MYSQL_VERSION_ID >= 40108
if(d->preparedQuery)
return d->meta ? QVariant::fromValue(d->meta) : QVariant::fromValue(d->stmt);
@@ -419,14 +453,15 @@ QVariant QMYSQLResult::handle() const
void QMYSQLResult::cleanup()
{
+ Q_D(QMYSQLResult);
if (d->result)
mysql_free_result(d->result);
// must iterate trough leftover result sets from multi-selects or stored procedures
// if this isn't done subsequent queries will fail with "Commands out of sync"
#if MYSQL_VERSION_ID >= 40100
- while (d->driver && d->driver->d_func()->mysql && mysql_next_result(d->driver->d_func()->mysql) == 0) {
- MYSQL_RES *res = mysql_store_result(d->driver->d_func()->mysql);
+ while (driver() && d->drv_d_func()->mysql && mysql_next_result(d->drv_d_func()->mysql) == 0) {
+ MYSQL_RES *res = mysql_store_result(d->drv_d_func()->mysql);
if (res)
mysql_free_result(res);
}
@@ -469,7 +504,8 @@ void QMYSQLResult::cleanup()
bool QMYSQLResult::fetch(int i)
{
- if(!d->driver)
+ Q_D(QMYSQLResult);
+ if (!driver())
return false;
if (isForwardOnly()) { // fake a forward seek
if (at() < i) {
@@ -513,7 +549,8 @@ bool QMYSQLResult::fetch(int i)
bool QMYSQLResult::fetchNext()
{
- if(!d->driver)
+ Q_D(QMYSQLResult);
+ if (!driver())
return false;
if (d->preparedQuery) {
#if MYSQL_VERSION_ID >= 40108
@@ -542,7 +579,8 @@ bool QMYSQLResult::fetchNext()
bool QMYSQLResult::fetchLast()
{
- if(!d->driver)
+ Q_D(QMYSQLResult);
+ if (!driver())
return false;
if (isForwardOnly()) { // fake this since MySQL can't seek on forward only queries
bool success = fetchNext(); // did we move at all?
@@ -579,13 +617,13 @@ bool QMYSQLResult::fetchFirst()
QVariant QMYSQLResult::data(int field)
{
-
+ Q_D(QMYSQLResult);
if (!isSelect() || field >= d->fields.count()) {
qWarning("QMYSQLResult::data: column %d out of range", field);
return QVariant();
}
- if (!d->driver)
+ if (!driver())
return QVariant();
int fieldLength = 0;
@@ -599,7 +637,7 @@ QVariant QMYSQLResult::data(int field)
return QVariant(f.type, f.outField);
if (f.type != QVariant::ByteArray)
- val = toUnicode(d->driver->d_func()->tc, f.outField, f.bufLength);
+ val = toUnicode(d->drv_d_func()->tc, f.outField, f.bufLength);
} else {
if (d->row[field] == NULL) {
// NULL value
@@ -609,7 +647,7 @@ QVariant QMYSQLResult::data(int field)
fieldLength = mysql_fetch_lengths(d->result)[field];
if (f.type != QVariant::ByteArray)
- val = toUnicode(d->driver->d_func()->tc, d->row[field], fieldLength);
+ val = toUnicode(d->drv_d_func()->tc, d->row[field], fieldLength);
}
switch (static_cast<int>(f.type)) {
@@ -677,6 +715,7 @@ QVariant QMYSQLResult::data(int field)
bool QMYSQLResult::isNull(int field)
{
+ Q_D(const QMYSQLResult);
if (field < 0 || field >= d->fields.count())
return true;
if (d->preparedQuery)
@@ -687,29 +726,30 @@ bool QMYSQLResult::isNull(int field)
bool QMYSQLResult::reset (const QString& query)
{
- if (!driver() || !driver()->isOpen() || driver()->isOpenError() || !d->driver)
+ Q_D(QMYSQLResult);
+ if (!driver() || !driver()->isOpen() || driver()->isOpenError())
return false;
d->preparedQuery = false;
cleanup();
- const QByteArray encQuery(fromUnicode(d->driver->d_func()->tc, query));
- if (mysql_real_query(d->driver->d_func()->mysql, encQuery.data(), encQuery.length())) {
+ const QByteArray encQuery(fromUnicode(d->drv_d_func()->tc, query));
+ if (mysql_real_query(d->drv_d_func()->mysql, encQuery.data(), encQuery.length())) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute query"),
- QSqlError::StatementError, d->driver->d_func()));
+ QSqlError::StatementError, d->drv_d_func()));
return false;
}
- d->result = mysql_store_result(d->driver->d_func()->mysql);
- if (!d->result && mysql_field_count(d->driver->d_func()->mysql) > 0) {
+ d->result = mysql_store_result(d->drv_d_func()->mysql);
+ if (!d->result && mysql_field_count(d->drv_d_func()->mysql) > 0) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store result"),
- QSqlError::StatementError, d->driver->d_func()));
+ QSqlError::StatementError, d->drv_d_func()));
return false;
}
- int numFields = mysql_field_count(d->driver->d_func()->mysql);
+ int numFields = mysql_field_count(d->drv_d_func()->mysql);
setSelect(numFields != 0);
d->fields.resize(numFields);
- d->rowsAffected = mysql_affected_rows(d->driver->d_func()->mysql);
+ d->rowsAffected = mysql_affected_rows(d->drv_d_func()->mysql);
if (isSelect()) {
for(int i = 0; i < numFields; i++) {
@@ -724,7 +764,8 @@ bool QMYSQLResult::reset (const QString& query)
int QMYSQLResult::size()
{
- if (d->driver && isSelect())
+ Q_D(const QMYSQLResult);
+ if (driver() && isSelect())
if (d->preparedQuery)
#if MYSQL_VERSION_ID >= 40108
return mysql_stmt_num_rows(d->stmt);
@@ -739,12 +780,14 @@ int QMYSQLResult::size()
int QMYSQLResult::numRowsAffected()
{
+ Q_D(const QMYSQLResult);
return d->rowsAffected;
}
QVariant QMYSQLResult::lastInsertId() const
{
- if (!isActive() || !d->driver)
+ Q_D(const QMYSQLResult);
+ if (!isActive() || !driver())
return QVariant();
if (d->preparedQuery) {
@@ -754,7 +797,7 @@ QVariant QMYSQLResult::lastInsertId() const
return QVariant(id);
#endif
} else {
- quint64 id = mysql_insert_id(d->driver->d_func()->mysql);
+ quint64 id = mysql_insert_id(d->drv_d_func()->mysql);
if (id)
return QVariant(id);
}
@@ -763,9 +806,10 @@ QVariant QMYSQLResult::lastInsertId() const
QSqlRecord QMYSQLResult::record() const
{
+ Q_D(const QMYSQLResult);
QSqlRecord info;
MYSQL_RES *res;
- if (!isActive() || !isSelect() || !d->driver)
+ if (!isActive() || !isSelect() || !driver())
return info;
#if MYSQL_VERSION_ID >= 40108
@@ -774,11 +818,11 @@ QSqlRecord QMYSQLResult::record() const
res = d->result;
#endif
- if (!mysql_errno(d->driver->d_func()->mysql)) {
+ if (!mysql_errno(d->drv_d_func()->mysql)) {
mysql_field_seek(res, 0);
MYSQL_FIELD* field = mysql_fetch_field(res);
while(field) {
- info.append(qToField(field, d->driver->d_func()->tc));
+ info.append(qToField(field, d->drv_d_func()->tc));
field = mysql_fetch_field(res);
}
}
@@ -788,7 +832,8 @@ QSqlRecord QMYSQLResult::record() const
bool QMYSQLResult::nextResult()
{
- if(!d->driver)
+ Q_D(QMYSQLResult);
+ if (!driver())
return false;
#if MYSQL_VERSION_ID >= 40100
setAt(-1);
@@ -803,26 +848,26 @@ bool QMYSQLResult::nextResult()
delete[] d->fields[i].outField;
d->fields.clear();
- int status = mysql_next_result(d->driver->d_func()->mysql);
+ int status = mysql_next_result(d->drv_d_func()->mysql);
if (status > 0) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute next query"),
- QSqlError::StatementError, d->driver->d_func()));
+ QSqlError::StatementError, d->drv_d_func()));
return false;
} else if (status == -1) {
return false; // No more result sets
}
- d->result = mysql_store_result(d->driver->d_func()->mysql);
- int numFields = mysql_field_count(d->driver->d_func()->mysql);
+ d->result = mysql_store_result(d->drv_d_func()->mysql);
+ int numFields = mysql_field_count(d->drv_d_func()->mysql);
if (!d->result && numFields > 0) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store next result"),
- QSqlError::StatementError, d->driver->d_func()));
+ QSqlError::StatementError, d->drv_d_func()));
return false;
}
setSelect(numFields > 0);
d->fields.resize(numFields);
- d->rowsAffected = mysql_affected_rows(d->driver->d_func()->mysql);
+ d->rowsAffected = mysql_affected_rows(d->drv_d_func()->mysql);
if (isSelect()) {
for (int i = 0; i < numFields; i++) {
@@ -871,11 +916,12 @@ static MYSQL_TIME *toMySqlDate(QDate date, QTime time, QVariant::Type type)
bool QMYSQLResult::prepare(const QString& query)
{
- if(!d->driver)
+ Q_D(QMYSQLResult);
+ if (!driver())
return false;
#if MYSQL_VERSION_ID >= 40108
cleanup();
- if (!d->driver->d_func()->preparedQuerysEnabled)
+ if (!d->drv_d_func()->preparedQuerysEnabled)
return QSqlResult::prepare(query);
int r;
@@ -884,14 +930,14 @@ bool QMYSQLResult::prepare(const QString& query)
return false;
if (!d->stmt)
- d->stmt = mysql_stmt_init(d->driver->d_func()->mysql);
+ d->stmt = mysql_stmt_init(d->drv_d_func()->mysql);
if (!d->stmt) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to prepare statement"),
- QSqlError::StatementError, d->driver->d_func()));
+ QSqlError::StatementError, d->drv_d_func()));
return false;
}
- const QByteArray encQuery(fromUnicode(d->driver->d_func()->tc, query));
+ const QByteArray encQuery(fromUnicode(d->drv_d_func()->tc, query));
r = mysql_stmt_prepare(d->stmt, encQuery.constData(), encQuery.length());
if (r != 0) {
setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult",
@@ -914,7 +960,8 @@ bool QMYSQLResult::prepare(const QString& query)
bool QMYSQLResult::exec()
{
- if (!d->driver)
+ Q_D(QMYSQLResult);
+ if (!driver())
return false;
if (!d->preparedQuery)
return QSqlResult::exec();
@@ -1011,7 +1058,7 @@ bool QMYSQLResult::exec()
break;
case QVariant::String:
default: {
- QByteArray ba = fromUnicode(d->driver->d_func()->tc, val.toString());
+ QByteArray ba = fromUnicode(d->drv_d_func()->tc, val.toString());
stringVector.append(ba);
currBind->buffer_type = MYSQL_TYPE_STRING;
currBind->buffer = const_cast<char *>(ba.constData());
@@ -1610,5 +1657,3 @@ bool QMYSQLDriver::isIdentifierEscaped(const QString &identifier, IdentifierType
}
QT_END_NAMESPACE
-
-#include "qsql_mysql.moc"
diff --git a/src/sql/drivers/mysql/qsql_mysql_p.h b/src/sql/drivers/mysql/qsql_mysql_p.h
index 724cc1fd28..d8e08b1f17 100644
--- a/src/sql/drivers/mysql/qsql_mysql_p.h
+++ b/src/sql/drivers/mysql/qsql_mysql_p.h
@@ -46,7 +46,6 @@
//
#include <QtSql/qsqldriver.h>
-#include <QtSql/qsqlresult.h>
#if defined (Q_OS_WIN32)
#include <QtCore/qt_windows.h>
@@ -63,46 +62,10 @@
QT_BEGIN_NAMESPACE
class QMYSQLDriverPrivate;
-class QMYSQLResultPrivate;
-class QMYSQLDriver;
-class QSqlRecordInfo;
-
-class QMYSQLResult : public QSqlResult
-{
- friend class QMYSQLDriver;
- friend class QMYSQLResultPrivate;
-public:
- explicit QMYSQLResult(const QMYSQLDriver* db);
- ~QMYSQLResult();
-
- QVariant handle() const Q_DECL_OVERRIDE;
-protected:
- void cleanup();
- bool fetch(int i) Q_DECL_OVERRIDE;
- bool fetchNext() Q_DECL_OVERRIDE;
- bool fetchLast() Q_DECL_OVERRIDE;
- bool fetchFirst() Q_DECL_OVERRIDE;
- QVariant data(int field) Q_DECL_OVERRIDE;
- bool isNull(int field) Q_DECL_OVERRIDE;
- bool reset (const QString& query) Q_DECL_OVERRIDE;
- int size() Q_DECL_OVERRIDE;
- int numRowsAffected() Q_DECL_OVERRIDE;
- QVariant lastInsertId() const Q_DECL_OVERRIDE;
- QSqlRecord record() const Q_DECL_OVERRIDE;
- void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
- bool nextResult() Q_DECL_OVERRIDE;
-
-#if MYSQL_VERSION_ID >= 40108
- bool prepare(const QString& stmt) Q_DECL_OVERRIDE;
- bool exec() Q_DECL_OVERRIDE;
-#endif
-private:
- QMYSQLResultPrivate* d;
-};
class Q_EXPORT_SQLDRIVER_MYSQL QMYSQLDriver : public QSqlDriver
{
- friend class QMYSQLResult;
+ friend class QMYSQLResultPrivate;
Q_DECLARE_PRIVATE(QMYSQLDriver)
Q_OBJECT
public:
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index f0c0b224bd..eb35c91e88 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -155,42 +155,62 @@ QT_BEGIN_INCLUDE_NAMESPACE
Q_DECLARE_METATYPE(QOCIRowIdPointer)
QT_END_INCLUDE_NAMESPACE
+class QOCIDriverPrivate : public QSqlDriverPrivate
+{
+ Q_DECLARE_PUBLIC(QOCIDriver)
+
+public:
+ QOCIDriverPrivate();
+
+ OCIEnv *env;
+ OCISvcCtx *svc;
+ OCIServer *srvhp;
+ OCISession *authp;
+ OCIError *err;
+ bool transaction;
+ int serverVersion;
+ int prefetchRows;
+ int prefetchMem;
+ QString user;
+
+ void allocErrorHandle();
+};
+
class QOCICols;
-struct QOCIResultPrivate;
+class QOCIResultPrivate;
-class Q_EXPORT_SQLDRIVER_OCI QOCIResult : public QSqlCachedResult
+class QOCIResult: public QSqlCachedResult
{
+ Q_DECLARE_PRIVATE(QOCIResult)
friend class QOCIDriver;
- friend struct QOCIResultPrivate;
friend class QOCICols;
public:
- QOCIResult(const QOCIDriver * db, const QOCIDriverPrivate* p);
+ QOCIResult(const QOCIDriver *db);
~QOCIResult();
- bool prepare(const QString& query);
- bool exec();
- QVariant handle() const;
+ bool prepare(const QString &query) Q_DECL_OVERRIDE;
+ bool exec() Q_DECL_OVERRIDE;
+ QVariant handle() const Q_DECL_OVERRIDE;
protected:
- bool gotoNext(ValueCache &values, int index);
- bool reset (const QString& query);
- int size();
- int numRowsAffected();
- QSqlRecord record() const;
- QVariant lastInsertId() const;
- bool execBatch(bool arrayBind = false);
- void virtual_hook(int id, void *data);
-
-private:
- QOCIResultPrivate *d;
+ bool gotoNext(ValueCache &values, int index) Q_DECL_OVERRIDE;
+ bool reset(const QString &query) Q_DECL_OVERRIDE;
+ int size() Q_DECL_OVERRIDE;
+ int numRowsAffected() Q_DECL_OVERRIDE;
+ QSqlRecord record() const Q_DECL_OVERRIDE;
+ QVariant lastInsertId() const Q_DECL_OVERRIDE;
+ bool execBatch(bool arrayBind = false) Q_DECL_OVERRIDE;
+ void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
};
-struct QOCIResultPrivate
+class QOCIResultPrivate: public QSqlCachedResultPrivate
{
- QOCIResultPrivate(QOCIResult *result, const QOCIDriverPrivate *driver);
+public:
+ Q_DECLARE_PUBLIC(QOCIResult)
+ Q_DECLARE_SQLDRIVER_PRIVATE(QOCIDriver)
+ QOCIResultPrivate(QOCIResult *q, const QOCIDriver *drv);
~QOCIResultPrivate();
QOCICols *cols;
- QOCIResult *q;
OCIEnv *env;
OCIError *err;
OCISvcCtx *&svc;
@@ -207,9 +227,9 @@ struct QOCIResultPrivate
void outValues(QVector<QVariant> &values, IndicatorArray &indicators,
QList<QByteArray> &tmpStorage);
inline bool isOutValue(int i) const
- { return q->bindValueType(i) & QSql::Out; }
+ { Q_Q(const QOCIResult); return q->bindValueType(i) & QSql::Out; }
inline bool isBinaryValue(int i) const
- { return q->bindValueType(i) & QSql::Binary; }
+ { Q_Q(const QOCIResult); return q->bindValueType(i) & QSql::Binary; }
void setCharset(dvoid* handle, ub4 type) const
{
@@ -485,25 +505,6 @@ void QOCIResultPrivate::outValues(QVector<QVariant> &values, IndicatorArray &ind
}
-class QOCIDriverPrivate : public QSqlDriverPrivate
-{
-public:
- QOCIDriverPrivate();
-
- OCIEnv *env;
- OCISvcCtx *svc;
- OCIServer *srvhp;
- OCISession *authp;
- OCIError *err;
- bool transaction;
- int serverVersion;
- ub4 prefetchRows;
- ub2 prefetchMem;
- QString user;
-
- void allocErrorHandle();
-};
-
QOCIDriverPrivate::QOCIDriverPrivate()
: QSqlDriverPrivate(), env(0), svc(0), srvhp(0), authp(0), err(0), transaction(false),
serverVersion(-1), prefetchRows(-1), prefetchMem(QOCI_PREFETCH_MEM)
@@ -1221,7 +1222,7 @@ OraFieldInfo QOCICols::qMakeOraField(const QOCIResultPrivate* p, OCIParam* param
if (r != 0)
qOraWarning("qMakeOraField:", p->err);
- type = qDecodeOCIType(colType, p->q->numericalPrecisionPolicy());
+ type = qDecodeOCIType(colType, p->q_func()->numericalPrecisionPolicy());
if (type == QVariant::Int) {
if (colLength == 22 && colPrecision == 0 && colScale == 0)
@@ -1232,16 +1233,16 @@ OraFieldInfo QOCICols::qMakeOraField(const QOCIResultPrivate* p, OCIParam* param
// bind as double if the precision policy asks for it
if (((colType == SQLT_FLT) || (colType == SQLT_NUM))
- && (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)) {
+ && (p->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)) {
type = QVariant::Double;
}
// bind as int32 or int64 if the precision policy asks for it
if ((colType == SQLT_NUM) || (colType == SQLT_VNU) || (colType == SQLT_UIN)
|| (colType == SQLT_INT)) {
- if (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
+ if (p->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
type = QVariant::LongLong;
- else if (p->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
+ else if (p->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
type = QVariant::Int;
}
@@ -1336,7 +1337,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err);
- d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
+ d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
"Unable to bind column for batch execute"),
QSqlError::StatementError, d->err));
return false;
@@ -1530,7 +1531,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err);
- d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
+ d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
"Unable to bind column for batch execute"),
QSqlError::StatementError, d->err));
return false;
@@ -1545,7 +1546,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
qOraWarning("QOCIPrivate::execBatch: unable to bind column:", d->err);
- d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
+ d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
"Unable to bind column for batch execute"),
QSqlError::StatementError, d->err));
return false;
@@ -1560,7 +1561,7 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
if (r != OCI_SUCCESS && r != OCI_SUCCESS_WITH_INFO) {
qOraWarning("QOCIPrivate::execBatch: unable to execute batch statement:", d->err);
- d->q->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
+ d->q_func()->setLastError(qMakeError(QCoreApplication::translate("QOCIResult",
"Unable to execute batch statement"),
QSqlError::StatementError, d->err));
return false;
@@ -1635,9 +1636,9 @@ bool QOCICols::execBatch(QOCIResultPrivate *d, QVector<QVariant> &boundValues, b
}
}
- d->q->setSelect(false);
- d->q->setAt(QSql::BeforeFirstRow);
- d->q->setActive(true);
+ d->q_func()->setSelect(false);
+ d->q_func()->setAt(QSql::BeforeFirstRow);
+ d->q_func()->setActive(true);
return true;
}
@@ -1752,12 +1753,12 @@ void QOCICols::getValues(QVector<QVariant> &v, int index)
case QVariant::Double:
case QVariant::Int:
case QVariant::LongLong:
- if (d->q->numericalPrecisionPolicy() != QSql::HighPrecision) {
- if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)
+ if (d->q_func()->numericalPrecisionPolicy() != QSql::HighPrecision) {
+ if ((d->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionDouble)
&& (fld.typ == QVariant::Double)) {
v[index + i] = *reinterpret_cast<double *>(fld.data);
break;
- } else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
+ } else if ((d->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt64)
&& (fld.typ == QVariant::LongLong)) {
qint64 qll = 0;
int r = OCINumberToInt(d->err, reinterpret_cast<OCINumber *>(fld.data), sizeof(qint64),
@@ -1767,7 +1768,7 @@ void QOCICols::getValues(QVector<QVariant> &v, int index)
else
v[index + i] = QVariant();
break;
- } else if ((d->q->numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
+ } else if ((d->q_func()->numericalPrecisionPolicy() == QSql::LowPrecisionInt32)
&& (fld.typ == QVariant::Int)) {
v[index + i] = *reinterpret_cast<int *>(fld.data);
break;
@@ -1790,10 +1791,17 @@ void QOCICols::getValues(QVector<QVariant> &v, int index)
}
}
-QOCIResultPrivate::QOCIResultPrivate(QOCIResult *result, const QOCIDriverPrivate *driver)
- : cols(0), q(result), env(driver->env), err(0), svc(const_cast<OCISvcCtx*&>(driver->svc)),
- sql(0), transaction(driver->transaction), serverVersion(driver->serverVersion),
- prefetchRows(driver->prefetchRows), prefetchMem(driver->prefetchMem)
+QOCIResultPrivate::QOCIResultPrivate(QOCIResult *q, const QOCIDriver *drv)
+ : QSqlCachedResultPrivate(q, drv),
+ cols(0),
+ env(drv_d_func()->env),
+ err(0),
+ svc(const_cast<OCISvcCtx*&>(drv_d_func()->svc)),
+ sql(0),
+ transaction(drv_d_func()->transaction),
+ serverVersion(drv_d_func()->serverVersion),
+ prefetchRows(drv_d_func()->prefetchRows),
+ prefetchMem(drv_d_func()->prefetchMem)
{
int r = OCIHandleAlloc(env,
reinterpret_cast<void **>(&err),
@@ -1816,24 +1824,24 @@ QOCIResultPrivate::~QOCIResultPrivate()
////////////////////////////////////////////////////////////////////////////
-QOCIResult::QOCIResult(const QOCIDriver * db, const QOCIDriverPrivate* p)
- : QSqlCachedResult(db)
+QOCIResult::QOCIResult(const QOCIDriver *db)
+ : QSqlCachedResult(*new QOCIResultPrivate(this, db))
{
- d = new QOCIResultPrivate(this, p);
}
QOCIResult::~QOCIResult()
{
+ Q_D(QOCIResult);
if (d->sql) {
int r = OCIHandleFree(d->sql, OCI_HTYPE_STMT);
if (r != 0)
qWarning("~QOCIResult: unable to free statement handle");
}
- delete d;
}
QVariant QOCIResult::handle() const
{
+ Q_D(const QOCIResult);
return QVariant::fromValue(d->sql);
}
@@ -1846,6 +1854,7 @@ bool QOCIResult::reset (const QString& query)
bool QOCIResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
{
+ Q_D(QOCIResult);
if (at() == QSql::AfterLastRow)
return false;
@@ -1905,6 +1914,7 @@ int QOCIResult::size()
int QOCIResult::numRowsAffected()
{
+ Q_D(QOCIResult);
int rowCount;
OCIAttrGet(d->sql,
OCI_HTYPE_STMT,
@@ -1917,6 +1927,7 @@ int QOCIResult::numRowsAffected()
bool QOCIResult::prepare(const QString& query)
{
+ Q_D(QOCIResult);
int r = 0;
QSqlResult::prepare(query);
@@ -1962,6 +1973,7 @@ bool QOCIResult::prepare(const QString& query)
bool QOCIResult::exec()
{
+ Q_D(QOCIResult);
int r = 0;
ub2 stmtType=0;
ub4 iters;
@@ -2043,6 +2055,7 @@ bool QOCIResult::exec()
QSqlRecord QOCIResult::record() const
{
+ Q_D(const QOCIResult);
QSqlRecord inf;
if (!isActive() || !isSelect() || !d->cols)
return inf;
@@ -2051,6 +2064,7 @@ QSqlRecord QOCIResult::record() const
QVariant QOCIResult::lastInsertId() const
{
+ Q_D(const QOCIResult);
if (isActive()) {
QOCIRowIdPointer ptr(new QOCIRowId(d->env));
@@ -2064,6 +2078,7 @@ QVariant QOCIResult::lastInsertId() const
bool QOCIResult::execBatch(bool arrayBind)
{
+ Q_D(QOCIResult);
QOCICols::execBatch(d, boundValues(), arrayBind);
resetBindCount();
return lastError().type() == QSqlError::NoError;
@@ -2301,8 +2316,7 @@ void QOCIDriver::close()
QSqlResult *QOCIDriver::createResult() const
{
- Q_D(const QOCIDriver);
- return new QOCIResult(this, d);
+ return new QOCIResult(this);
}
bool QOCIDriver::beginTransaction()
diff --git a/src/sql/drivers/oci/qsql_oci_p.h b/src/sql/drivers/oci/qsql_oci_p.h
index 48da952d56..c42e689437 100644
--- a/src/sql/drivers/oci/qsql_oci_p.h
+++ b/src/sql/drivers/oci/qsql_oci_p.h
@@ -45,7 +45,6 @@
// We mean it.
//
-#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
#ifdef QT_PLUGIN
@@ -59,41 +58,41 @@ typedef struct OCISvcCtx OCISvcCtx;
QT_BEGIN_NAMESPACE
-class QOCIDriver;
-class QOCICols;
+class QSqlResult;
class QOCIDriverPrivate;
class Q_EXPORT_SQLDRIVER_OCI QOCIDriver : public QSqlDriver
{
Q_DECLARE_PRIVATE(QOCIDriver)
Q_OBJECT
- friend struct QOCIResultPrivate;
- friend class QOCIPrivate;
+ friend class QOCICols;
+ friend class QOCIResultPrivate;
+
public:
explicit QOCIDriver(QObject* parent = 0);
QOCIDriver(OCIEnv* env, OCISvcCtx* ctx, QObject* parent = 0);
~QOCIDriver();
bool hasFeature(DriverFeature f) const;
- bool open(const QString & db,
- const QString & user,
- const QString & password,
- const QString & host,
+ bool open(const QString &db,
+ const QString &user,
+ const QString &password,
+ const QString &host,
int port,
- const QString& connOpts);
- void close();
- QSqlResult *createResult() const;
- QStringList tables(QSql::TableType) const;
- QSqlRecord record(const QString& tablename) const;
- QSqlIndex primaryIndex(const QString& tablename) const;
+ const QString &connOpts) Q_DECL_OVERRIDE;
+ void close() Q_DECL_OVERRIDE;
+ QSqlResult *createResult() const Q_DECL_OVERRIDE;
+ QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE;
+ QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE;
+ QSqlIndex primaryIndex(const QString& tablename) const Q_DECL_OVERRIDE;
QString formatValue(const QSqlField &field,
- bool trimStrings) const;
- QVariant handle() const;
- QString escapeIdentifier(const QString &identifier, IdentifierType) const;
+ bool trimStrings) const Q_DECL_OVERRIDE;
+ QVariant handle() const Q_DECL_OVERRIDE;
+ QString escapeIdentifier(const QString &identifier, IdentifierType) const Q_DECL_OVERRIDE;
protected:
- bool beginTransaction();
- bool commitTransaction();
- bool rollbackTransaction();
+ bool beginTransaction() Q_DECL_OVERRIDE;
+ bool commitTransaction() Q_DECL_OVERRIDE;
+ bool rollbackTransaction() Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index 8db06e6831..db1e36daa2 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -50,6 +50,7 @@
#include <QDebug>
#include <QSqlQuery>
#include <QtSql/private/qsqldriver_p.h>
+#include <QtSql/private/qsqlresult_p.h>
QT_BEGIN_NAMESPACE
@@ -106,6 +107,8 @@ inline static QVarLengthArray<SQLTCHAR> toSQLTCHAR(const QString &input)
class QODBCDriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QODBCDriver)
+
public:
enum DefaultCase{Lower, Mixed, Upper, Sensitive};
QODBCDriverPrivate()
@@ -143,23 +146,62 @@ private:
QChar quote;
};
-class QODBCPrivate
+class QODBCResultPrivate;
+
+class QODBCResult: public QSqlResult
+{
+ Q_DECLARE_PRIVATE(QODBCResult)
+
+public:
+ QODBCResult(const QODBCDriver *db);
+ virtual ~QODBCResult();
+
+ bool prepare(const QString &query) Q_DECL_OVERRIDE;
+ bool exec() Q_DECL_OVERRIDE;
+
+ QVariant lastInsertId() const Q_DECL_OVERRIDE;
+ QVariant handle() const Q_DECL_OVERRIDE;
+
+protected:
+ bool fetchNext() Q_DECL_OVERRIDE;
+ bool fetchFirst() Q_DECL_OVERRIDE;
+ bool fetchLast() Q_DECL_OVERRIDE;
+ bool fetchPrevious() Q_DECL_OVERRIDE;
+ bool fetch(int i) Q_DECL_OVERRIDE;
+ bool reset(const QString &query) Q_DECL_OVERRIDE;
+ QVariant data(int field) Q_DECL_OVERRIDE;
+ bool isNull(int field) Q_DECL_OVERRIDE;
+ int size() Q_DECL_OVERRIDE;
+ int numRowsAffected() Q_DECL_OVERRIDE;
+ QSqlRecord record() const Q_DECL_OVERRIDE;
+ void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
+ void detachFromResultSet() Q_DECL_OVERRIDE;
+ bool nextResult() Q_DECL_OVERRIDE;
+};
+
+class QODBCResultPrivate: public QSqlResultPrivate
{
+ Q_DECLARE_PUBLIC(QODBCResult)
+
public:
- QODBCPrivate(QODBCDriverPrivate *dpp)
- : hStmt(0), useSchema(false), hasSQLFetchScroll(true), driverPrivate(dpp), userForwardOnly(false)
+ Q_DECLARE_SQLDRIVER_PRIVATE(QODBCDriver)
+ QODBCResultPrivate(QODBCResult *q, const QODBCDriver *db)
+ : QSqlResultPrivate(q, db),
+ hStmt(0),
+ useSchema(false),
+ hasSQLFetchScroll(true)
{
- unicode = dpp->unicode;
- useSchema = dpp->useSchema;
- disconnectCount = dpp->disconnectCount;
- hasSQLFetchScroll = dpp->hasSQLFetchScroll;
+ unicode = drv_d_func()->unicode;
+ useSchema = drv_d_func()->useSchema;
+ disconnectCount = drv_d_func()->disconnectCount;
+ hasSQLFetchScroll = drv_d_func()->hasSQLFetchScroll;
}
inline void clearValues()
{ fieldCache.fill(QVariant()); fieldCacheIdx = 0; }
- SQLHANDLE dpEnv() const { return driverPrivate ? driverPrivate->hEnv : 0;}
- SQLHANDLE dpDbc() const { return driverPrivate ? driverPrivate->hDbc : 0;}
+ SQLHANDLE dpEnv() const { return drv_d_func() ? drv_d_func()->hEnv : 0;}
+ SQLHANDLE dpDbc() const { return drv_d_func() ? drv_d_func()->hDbc : 0;}
SQLHANDLE hStmt;
bool unicode;
@@ -170,23 +212,19 @@ public:
int fieldCacheIdx;
int disconnectCount;
bool hasSQLFetchScroll;
- QODBCDriverPrivate *driverPrivate;
- bool userForwardOnly;
- bool isStmtHandleValid(const QSqlDriver *driver);
- void updateStmtHandleState(const QSqlDriver *driver);
+ bool isStmtHandleValid();
+ void updateStmtHandleState();
};
-bool QODBCPrivate::isStmtHandleValid(const QSqlDriver *driver)
+bool QODBCResultPrivate::isStmtHandleValid()
{
- const QODBCDriver *odbcdriver = static_cast<const QODBCDriver*> (driver);
- return disconnectCount == odbcdriver->d_func()->disconnectCount;
+ return disconnectCount == drv_d_func()->disconnectCount;
}
-void QODBCPrivate::updateStmtHandleState(const QSqlDriver *driver)
+void QODBCResultPrivate::updateStmtHandleState()
{
- const QODBCDriver *odbcdriver = static_cast<const QODBCDriver*> (driver);
- disconnectCount = odbcdriver->d_func()->disconnectCount;
+ disconnectCount = drv_d_func()->disconnectCount;
}
static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode = 0)
@@ -261,7 +299,7 @@ static QString qODBCWarn(const SQLHANDLE hStmt, const SQLHANDLE envHandle = 0,
return result;
}
-static QString qODBCWarn(const QODBCPrivate* odbc, int *nativeCode = 0)
+static QString qODBCWarn(const QODBCResultPrivate* odbc, int *nativeCode = 0)
{
return qODBCWarn(odbc->hStmt, odbc->dpEnv(), odbc->dpDbc(), nativeCode);
}
@@ -271,7 +309,7 @@ static QString qODBCWarn(const QODBCDriverPrivate* odbc, int *nativeCode = 0)
return qODBCWarn(0, odbc->hEnv, odbc->hDbc, nativeCode);
}
-static void qSqlWarning(const QString& message, const QODBCPrivate* odbc)
+static void qSqlWarning(const QString& message, const QODBCResultPrivate* odbc)
{
qWarning() << message << "\tError:" << qODBCWarn(odbc);
}
@@ -286,7 +324,7 @@ static void qSqlWarning(const QString &message, const SQLHANDLE hStmt)
qWarning() << message << "\tError:" << qODBCWarn(hStmt);
}
-static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, const QODBCPrivate* p)
+static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, const QODBCResultPrivate* p)
{
int nativeCode = -1;
QString message = qODBCWarn(p, &nativeCode);
@@ -626,7 +664,7 @@ static QSqlField qMakeFieldInfo(const SQLHANDLE hStmt, const QODBCDriverPrivate*
return f;
}
-static QSqlField qMakeFieldInfo(const QODBCPrivate* p, int i )
+static QSqlField qMakeFieldInfo(const QODBCResultPrivate* p, int i )
{
QString errorMessage;
const QSqlField result = qMakeFieldInfo(p->hStmt, i, &errorMessage);
@@ -911,26 +949,25 @@ QString QODBCDriverPrivate::adjustCase(const QString &identifier) const
////////////////////////////////////////////////////////////////////////////
-QODBCResult::QODBCResult(const QODBCDriver * db, QODBCDriverPrivate* p)
-: QSqlResult(db)
+QODBCResult::QODBCResult(const QODBCDriver *db)
+ : QSqlResult(*new QODBCResultPrivate(this, db))
{
- d = new QODBCPrivate(p);
}
QODBCResult::~QODBCResult()
{
- if (d->hStmt && d->isStmtHandleValid(driver()) && driver()->isOpen()) {
+ Q_D(QODBCResult);
+ if (d->hStmt && d->isStmtHandleValid() && driver()->isOpen()) {
SQLRETURN r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
if (r != SQL_SUCCESS)
qSqlWarning(QLatin1String("QODBCDriver: Unable to free statement handle ")
+ QString::number(r), d);
}
-
- delete d;
}
bool QODBCResult::reset (const QString& query)
{
+ Q_D(QODBCResult);
setActive(false);
setAt(QSql::BeforeFirstRow);
d->rInf.clear();
@@ -940,7 +977,7 @@ bool QODBCResult::reset (const QString& query)
// Always reallocate the statement handle - the statement attributes
// are not reset if SQLFreeStmt() is called which causes some problems.
SQLRETURN r;
- if (d->hStmt && d->isStmtHandleValid(driver())) {
+ if (d->hStmt && d->isStmtHandleValid()) {
r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
if (r != SQL_SUCCESS) {
qSqlWarning(QLatin1String("QODBCResult::reset: Unable to free statement handle"), d);
@@ -955,9 +992,9 @@ bool QODBCResult::reset (const QString& query)
return false;
}
- d->updateStmtHandleState(driver());
+ d->updateStmtHandleState();
- if (d->userForwardOnly) {
+ if (isForwardOnly()) {
r = SQLSetStmtAttr(d->hStmt,
SQL_ATTR_CURSOR_TYPE,
(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
@@ -987,7 +1024,7 @@ bool QODBCResult::reset (const QString& query)
SQLULEN isScrollable = 0;
r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, 0);
if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
- QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE);
+ setForwardOnly(isScrollable == SQL_NONSCROLLABLE);
SQLSMALLINT count = 0;
SQLNumResultCols(d->hStmt, &count);
@@ -1007,6 +1044,7 @@ bool QODBCResult::reset (const QString& query)
bool QODBCResult::fetch(int i)
{
+ Q_D(QODBCResult);
if (!driver()->isOpen())
return false;
@@ -1043,6 +1081,7 @@ bool QODBCResult::fetch(int i)
bool QODBCResult::fetchNext()
{
+ Q_D(QODBCResult);
SQLRETURN r;
d->clearValues();
@@ -1065,6 +1104,7 @@ bool QODBCResult::fetchNext()
bool QODBCResult::fetchFirst()
{
+ Q_D(QODBCResult);
if (isForwardOnly() && at() != QSql::BeforeFirstRow)
return false;
SQLRETURN r;
@@ -1087,6 +1127,7 @@ bool QODBCResult::fetchFirst()
bool QODBCResult::fetchPrevious()
{
+ Q_D(QODBCResult);
if (isForwardOnly())
return false;
SQLRETURN r;
@@ -1106,6 +1147,7 @@ bool QODBCResult::fetchPrevious()
bool QODBCResult::fetchLast()
{
+ Q_D(QODBCResult);
SQLRETURN r;
d->clearValues();
@@ -1145,6 +1187,7 @@ bool QODBCResult::fetchLast()
QVariant QODBCResult::data(int field)
{
+ Q_D(QODBCResult);
if (field >= d->rInf.count() || field < 0) {
qWarning() << "QODBCResult::data: column" << field << "out of range";
return QVariant();
@@ -1245,6 +1288,7 @@ QVariant QODBCResult::data(int field)
bool QODBCResult::isNull(int field)
{
+ Q_D(const QODBCResult);
if (field < 0 || field > d->fieldCache.size())
return true;
if (field <= d->fieldCacheIdx) {
@@ -1263,6 +1307,7 @@ int QODBCResult::size()
int QODBCResult::numRowsAffected()
{
+ Q_D(QODBCResult);
SQLLEN affectedRowCount = 0;
SQLRETURN r = SQLRowCount(d->hStmt, &affectedRowCount);
if (r == SQL_SUCCESS)
@@ -1274,12 +1319,13 @@ int QODBCResult::numRowsAffected()
bool QODBCResult::prepare(const QString& query)
{
+ Q_D(QODBCResult);
setActive(false);
setAt(QSql::BeforeFirstRow);
SQLRETURN r;
d->rInf.clear();
- if (d->hStmt && d->isStmtHandleValid(driver())) {
+ if (d->hStmt && d->isStmtHandleValid()) {
r = SQLFreeHandle(SQL_HANDLE_STMT, d->hStmt);
if (r != SQL_SUCCESS) {
qSqlWarning(QLatin1String("QODBCResult::prepare: Unable to close statement"), d);
@@ -1294,9 +1340,9 @@ bool QODBCResult::prepare(const QString& query)
return false;
}
- d->updateStmtHandleState(driver());
+ d->updateStmtHandleState();
- if (d->userForwardOnly) {
+ if (isForwardOnly()) {
r = SQLSetStmtAttr(d->hStmt,
SQL_ATTR_CURSOR_TYPE,
(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
@@ -1328,6 +1374,7 @@ bool QODBCResult::prepare(const QString& query)
bool QODBCResult::exec()
{
+ Q_D(QODBCResult);
setActive(false);
setAt(QSql::BeforeFirstRow);
d->rInf.clear();
@@ -1408,7 +1455,7 @@ bool QODBCResult::exec()
dt->minute = qdt.time().minute();
dt->second = qdt.time().second();
- int precision = d->driverPrivate->datetime_precision - 20; // (20 includes a separating period)
+ int precision = d->drv_d_func()->datetime_precision - 20; // (20 includes a separating period)
if (precision <= 0) {
dt->fraction = 0;
} else {
@@ -1424,7 +1471,7 @@ bool QODBCResult::exec()
qParamType[bindValueType(i) & QSql::InOut],
SQL_C_TIMESTAMP,
SQL_TIMESTAMP,
- d->driverPrivate->datetime_precision,
+ d->drv_d_func()->datetime_precision,
precision,
(void *) dt,
0,
@@ -1608,7 +1655,7 @@ bool QODBCResult::exec()
SQLULEN isScrollable = 0;
r = SQLGetStmtAttr(d->hStmt, SQL_ATTR_CURSOR_SCROLLABLE, &isScrollable, SQL_IS_INTEGER, 0);
if(r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
- QSqlResult::setForwardOnly(isScrollable==SQL_NONSCROLLABLE);
+ setForwardOnly(isScrollable == SQL_NONSCROLLABLE);
SQLSMALLINT count = 0;
SQLNumResultCols(d->hStmt, &count);
@@ -1677,6 +1724,7 @@ bool QODBCResult::exec()
QSqlRecord QODBCResult::record() const
{
+ Q_D(const QODBCResult);
if (!isActive() || !isSelect())
return QSqlRecord();
return d->rInf;
@@ -1684,9 +1732,10 @@ QSqlRecord QODBCResult::record() const
QVariant QODBCResult::lastInsertId() const
{
+ Q_D(const QODBCResult);
QString sql;
- switch (d->driverPrivate->dbmsType) {
+ switch (driver()->dbmsType()) {
case QSqlDriver::MSSqlServer:
case QSqlDriver::Sybase:
sql = QLatin1String("SELECT @@IDENTITY;");
@@ -1716,11 +1765,13 @@ QVariant QODBCResult::lastInsertId() const
QVariant QODBCResult::handle() const
{
+ Q_D(const QODBCResult);
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt);
}
bool QODBCResult::nextResult()
{
+ Q_D(QODBCResult);
setActive(false);
setAt(QSql::BeforeFirstRow);
d->rInf.clear();
@@ -1765,16 +1816,11 @@ void QODBCResult::virtual_hook(int id, void *data)
void QODBCResult::detachFromResultSet()
{
+ Q_D(QODBCResult);
if (d->hStmt)
SQLCloseCursor(d->hStmt);
}
-void QODBCResult::setForwardOnly(bool forward)
-{
- d->userForwardOnly = forward;
- QSqlResult::setForwardOnly(forward);
-}
-
////////////////////////////////////////
@@ -2185,8 +2231,7 @@ void QODBCDriverPrivate::checkDateTimePrecision()
QSqlResult *QODBCDriver::createResult() const
{
- Q_D(const QODBCDriver);
- return new QODBCResult(this, const_cast<QODBCDriverPrivate*>(d));
+ return new QODBCResult(this);
}
bool QODBCDriver::beginTransaction()
diff --git a/src/sql/drivers/odbc/qsql_odbc_p.h b/src/sql/drivers/odbc/qsql_odbc_p.h
index 96e7abd7dd..25cc6aaa2c 100644
--- a/src/sql/drivers/odbc/qsql_odbc_p.h
+++ b/src/sql/drivers/odbc/qsql_odbc_p.h
@@ -46,7 +46,6 @@
//
#include <QtSql/qsqldriver.h>
-#include <QtSql/qsqlresult.h>
#if defined (Q_OS_WIN32)
#include <QtCore/qt_windows.h>
@@ -75,81 +74,46 @@
QT_BEGIN_NAMESPACE
-class QODBCPrivate;
class QODBCDriverPrivate;
-class QODBCDriver;
-class QSqlRecordInfo;
-
-class QODBCResult : public QSqlResult
-{
-public:
- QODBCResult(const QODBCDriver * db, QODBCDriverPrivate* p);
- virtual ~QODBCResult();
-
- bool prepare(const QString& query);
- bool exec();
-
- QVariant lastInsertId() const;
- QVariant handle() const;
- virtual void setForwardOnly(bool forward);
-
-protected:
- bool fetchNext();
- bool fetchFirst();
- bool fetchLast();
- bool fetchPrevious();
- bool fetch(int i);
- bool reset (const QString& query);
- QVariant data(int field);
- bool isNull(int field);
- int size();
- int numRowsAffected();
- QSqlRecord record() const;
- void virtual_hook(int id, void *data);
- void detachFromResultSet();
- bool nextResult();
-
-private:
- QODBCPrivate *d;
-};
class Q_EXPORT_SQLDRIVER_ODBC QODBCDriver : public QSqlDriver
{
Q_DECLARE_PRIVATE(QODBCDriver)
Q_OBJECT
+ friend class QODBCResultPrivate;
+
public:
explicit QODBCDriver(QObject *parent=0);
QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent=0);
virtual ~QODBCDriver();
- bool hasFeature(DriverFeature f) const;
- void close();
- QSqlResult *createResult() const;
- QStringList tables(QSql::TableType) const;
- QSqlRecord record(const QString& tablename) const;
- QSqlIndex primaryIndex(const QString& tablename) const;
- QVariant handle() const;
+ bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE;
+ void close() Q_DECL_OVERRIDE;
+ QSqlResult *createResult() const Q_DECL_OVERRIDE;
+ QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE;
+ QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE;
+ QSqlIndex primaryIndex(const QString &tablename) const Q_DECL_OVERRIDE;
+ QVariant handle() const Q_DECL_OVERRIDE;
QString formatValue(const QSqlField &field,
- bool trimStrings) const;
- bool open(const QString& db,
- const QString& user,
- const QString& password,
- const QString& host,
+ bool trimStrings) const Q_DECL_OVERRIDE;
+ bool open(const QString &db,
+ const QString &user,
+ const QString &password,
+ const QString &host,
int port,
- const QString& connOpts);
+ const QString &connOpts) Q_DECL_OVERRIDE;
- QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
+ QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE;
- bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const;
+ bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE;
protected:
- bool beginTransaction();
- bool commitTransaction();
- bool rollbackTransaction();
+ bool beginTransaction() Q_DECL_OVERRIDE;
+ bool commitTransaction() Q_DECL_OVERRIDE;
+ bool rollbackTransaction() Q_DECL_OVERRIDE;
private:
bool endTrans();
void cleanup();
- friend class QODBCPrivate;
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index 5dcabb0646..f9c3f8ba75 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -119,6 +119,35 @@ inline void qPQfreemem(void *buffer)
PQfreemem(buffer);
}
+class QPSQLResultPrivate;
+
+class QPSQLResult: public QSqlResult
+{
+ Q_DECLARE_PRIVATE(QPSQLResult)
+
+public:
+ QPSQLResult(const QPSQLDriver *db);
+ ~QPSQLResult();
+
+ QVariant handle() const Q_DECL_OVERRIDE;
+ void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
+
+protected:
+ void cleanup();
+ bool fetch(int i) Q_DECL_OVERRIDE;
+ bool fetchFirst() Q_DECL_OVERRIDE;
+ bool fetchLast() Q_DECL_OVERRIDE;
+ QVariant data(int i) Q_DECL_OVERRIDE;
+ bool isNull(int field) Q_DECL_OVERRIDE;
+ bool reset (const QString &query) Q_DECL_OVERRIDE;
+ int size() Q_DECL_OVERRIDE;
+ int numRowsAffected() Q_DECL_OVERRIDE;
+ QSqlRecord record() const Q_DECL_OVERRIDE;
+ QVariant lastInsertId() const Q_DECL_OVERRIDE;
+ bool prepare(const QString &query) Q_DECL_OVERRIDE;
+ bool exec() Q_DECL_OVERRIDE;
+};
+
class QPSQLDriverPrivate : public QSqlDriverPrivate
{
Q_DECLARE_PUBLIC(QPSQLDriver)
@@ -193,8 +222,9 @@ class QPSQLResultPrivate : public QSqlResultPrivate
{
Q_DECLARE_PUBLIC(QPSQLResult)
public:
- QPSQLResultPrivate()
- : QSqlResultPrivate(),
+ Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver);
+ QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv)
+ : QSqlResultPrivate(q, drv),
result(0),
currentSize(-1),
preparedQueriesEnabled(false)
@@ -202,11 +232,6 @@ public:
QString fieldSerial(int i) const Q_DECL_OVERRIDE { return QLatin1Char('$') + QString::number(i + 1); }
void deallocatePreparedStmt();
- const QPSQLDriverPrivate * privDriver() const
- {
- Q_Q(const QPSQLResult);
- return reinterpret_cast<const QPSQLDriver *>(q->driver())->d_func();
- }
PGresult *result;
int currentSize;
@@ -248,7 +273,7 @@ bool QPSQLResultPrivate::processResults()
return true;
}
q->setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
- "Unable to create query"), QSqlError::StatementError, privDriver(), result));
+ "Unable to create query"), QSqlError::StatementError, drv_d_func(), result));
return false;
}
@@ -301,16 +326,16 @@ static QVariant::Type qDecodePSQLType(int t)
void QPSQLResultPrivate::deallocatePreparedStmt()
{
const QString stmt = QLatin1String("DEALLOCATE ") + preparedStmtId;
- PGresult *result = privDriver()->exec(stmt);
+ PGresult *result = drv_d_func()->exec(stmt);
if (PQresultStatus(result) != PGRES_COMMAND_OK)
- qWarning("Unable to free statement: %s", PQerrorMessage(privDriver()->connection));
+ qWarning("Unable to free statement: %s", PQerrorMessage(drv_d_func()->connection));
PQclear(result);
preparedStmtId.clear();
}
QPSQLResult::QPSQLResult(const QPSQLDriver* db)
- : QSqlResult(*new QPSQLResultPrivate, db)
+ : QSqlResult(*new QPSQLResultPrivate(this, db))
{
Q_D(QPSQLResult);
d->preparedQueriesEnabled = db->hasFeature(QSqlDriver::PreparedQueries);
@@ -384,7 +409,7 @@ QVariant QPSQLResult::data(int i)
case QVariant::Bool:
return QVariant((bool)(val[0] == 't'));
case QVariant::String:
- return d->privDriver()->isUtf8 ? QString::fromUtf8(val) : QString::fromLatin1(val);
+ return d->drv_d_func()->isUtf8 ? QString::fromUtf8(val) : QString::fromLatin1(val);
case QVariant::LongLong:
if (val[0] == '-')
return QString::fromLatin1(val).toLongLong();
@@ -475,7 +500,7 @@ bool QPSQLResult::reset (const QString& query)
return false;
if (!driver()->isOpen() || driver()->isOpenError())
return false;
- d->result = d->privDriver()->exec(query);
+ d->result = d->drv_d_func()->exec(query);
return d->processResults();
}
@@ -494,7 +519,7 @@ int QPSQLResult::numRowsAffected()
QVariant QPSQLResult::lastInsertId() const
{
Q_D(const QPSQLResult);
- if (d->privDriver()->pro >= QPSQLDriver::Version81) {
+ if (d->drv_d_func()->pro >= QPSQLDriver::Version81) {
QSqlQuery qry(driver()->createResult());
// Most recent sequence value obtained from nextval
if (qry.exec(QLatin1String("SELECT lastval();")) && qry.next())
@@ -517,7 +542,7 @@ QSqlRecord QPSQLResult::record() const
int count = PQnfields(d->result);
for (int i = 0; i < count; ++i) {
QSqlField f;
- if (d->privDriver()->isUtf8)
+ if (d->drv_d_func()->isUtf8)
f.setName(QString::fromUtf8(PQfname(d->result, i)));
else
f.setName(QString::fromLocal8Bit(PQfname(d->result, i)));
@@ -611,11 +636,11 @@ bool QPSQLResult::prepare(const QString &query)
const QString stmtId = qMakePreparedStmtId();
const QString stmt = QString::fromLatin1("PREPARE %1 AS ").arg(stmtId).append(d->positionalToNamedBinding(query));
- PGresult *result = d->privDriver()->exec(stmt);
+ PGresult *result = d->drv_d_func()->exec(stmt);
if (PQresultStatus(result) != PGRES_COMMAND_OK) {
setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
- "Unable to prepare statement"), QSqlError::StatementError, d->privDriver(), result));
+ "Unable to prepare statement"), QSqlError::StatementError, d->drv_d_func(), result));
PQclear(result);
d->preparedStmtId.clear();
return false;
@@ -641,7 +666,7 @@ bool QPSQLResult::exec()
else
stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId).arg(params);
- d->result = d->privDriver()->exec(stmt);
+ d->result = d->drv_d_func()->exec(stmt);
return d->processResults();
}
diff --git a/src/sql/drivers/psql/qsql_psql_p.h b/src/sql/drivers/psql/qsql_psql_p.h
index 61e201ae5e..d989f70ae3 100644
--- a/src/sql/drivers/psql/qsql_psql_p.h
+++ b/src/sql/drivers/psql/qsql_psql_p.h
@@ -45,7 +45,6 @@
// We mean it.
//
-#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
#ifdef QT_PLUGIN
@@ -59,44 +58,12 @@ typedef struct pg_result PGresult;
QT_BEGIN_NAMESPACE
-class QPSQLResultPrivate;
-class QPSQLDriver;
-class QSqlRecordInfo;
-
-class QPSQLResult : public QSqlResult
-{
- Q_DECLARE_PRIVATE(QPSQLResult)
-
-public:
- QPSQLResult(const QPSQLDriver* db);
- ~QPSQLResult();
-
- QVariant handle() const Q_DECL_OVERRIDE;
- void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
-
-protected:
- void cleanup();
- bool fetch(int i) Q_DECL_OVERRIDE;
- bool fetchFirst() Q_DECL_OVERRIDE;
- bool fetchLast() Q_DECL_OVERRIDE;
- QVariant data(int i) Q_DECL_OVERRIDE;
- bool isNull(int field) Q_DECL_OVERRIDE;
- bool reset (const QString& query) Q_DECL_OVERRIDE;
- int size() Q_DECL_OVERRIDE;
- int numRowsAffected() Q_DECL_OVERRIDE;
- QSqlRecord record() const Q_DECL_OVERRIDE;
- QVariant lastInsertId() const Q_DECL_OVERRIDE;
- bool prepare(const QString& query) Q_DECL_OVERRIDE;
- bool exec() Q_DECL_OVERRIDE;
-};
-
class QPSQLDriverPrivate;
class Q_EXPORT_SQLDRIVER_PSQL QPSQLDriver : public QSqlDriver
{
friend class QPSQLResultPrivate;
Q_DECLARE_PRIVATE(QPSQLDriver)
-
Q_OBJECT
public:
enum Protocol {
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index 4286f5b338..66e5724e6f 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -105,8 +105,9 @@ class QSQLiteResultPrivate;
class QSQLiteResult : public QSqlCachedResult
{
+ Q_DECLARE_PRIVATE(QSQLiteResult)
friend class QSQLiteDriver;
- friend class QSQLiteResultPrivate;
+
public:
explicit QSQLiteResult(const QSQLiteDriver* db);
~QSQLiteResult();
@@ -123,13 +124,12 @@ protected:
QSqlRecord record() const Q_DECL_OVERRIDE;
void detachFromResultSet() Q_DECL_OVERRIDE;
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
-
-private:
- QSQLiteResultPrivate* d;
};
class QSQLiteDriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QSQLiteDriver)
+
public:
inline QSQLiteDriverPrivate() : QSqlDriverPrivate(), access(0) { dbmsType = QSqlDriver::SQLite; }
sqlite3 *access;
@@ -137,19 +137,19 @@ public:
};
-class QSQLiteResultPrivate
+class QSQLiteResultPrivate: public QSqlCachedResultPrivate
{
+ Q_DECLARE_PUBLIC(QSQLiteResult)
+
public:
- QSQLiteResultPrivate(QSQLiteResult *res);
+ Q_DECLARE_SQLDRIVER_PRIVATE(QSQLiteDriver)
+ QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv);
void cleanup();
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
// initializes the recordInfo and the cache
void initColumns(bool emptyResultset);
void finalize();
- QSQLiteResult* q;
- sqlite3 *access;
-
sqlite3_stmt *stmt;
bool skippedStatus; // the status of the fetchNext() that's skipped
@@ -158,13 +158,17 @@ public:
QVector<QVariant> firstRow;
};
-QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult* res) : q(res), access(0),
- stmt(0), skippedStatus(false), skipRow(false)
+QSQLiteResultPrivate::QSQLiteResultPrivate(QSQLiteResult *q, const QSQLiteDriver *drv)
+ : QSqlCachedResultPrivate(q, drv),
+ stmt(0),
+ skippedStatus(false),
+ skipRow(false)
{
}
void QSQLiteResultPrivate::cleanup()
{
+ Q_Q(QSQLiteResult);
finalize();
rInf.clear();
skippedStatus = false;
@@ -185,6 +189,7 @@ void QSQLiteResultPrivate::finalize()
void QSQLiteResultPrivate::initColumns(bool emptyResultset)
{
+ Q_Q(QSQLiteResult);
int nCols = sqlite3_column_count(stmt);
if (nCols <= 0)
return;
@@ -236,6 +241,7 @@ void QSQLiteResultPrivate::initColumns(bool emptyResultset)
bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch)
{
+ Q_Q(QSQLiteResult);
int res;
int i;
@@ -318,7 +324,7 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i
// SQLITE_ERROR is a generic error code and we must call sqlite3_reset()
// to get the specific error message.
res = sqlite3_reset(stmt);
- q->setLastError(qMakeError(access, QCoreApplication::translate("QSQLiteResult",
+ q->setLastError(qMakeError(drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to fetch row"), QSqlError::ConnectionError, res));
q->setAt(QSql::AfterLastRow);
return false;
@@ -326,7 +332,7 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i
case SQLITE_BUSY:
default:
// something wrong, don't get col info, but still return false
- q->setLastError(qMakeError(access, QCoreApplication::translate("QSQLiteResult",
+ q->setLastError(qMakeError(drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to fetch row"), QSqlError::ConnectionError, res));
sqlite3_reset(stmt);
q->setAt(QSql::AfterLastRow);
@@ -336,20 +342,18 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i
}
QSQLiteResult::QSQLiteResult(const QSQLiteDriver* db)
- : QSqlCachedResult(db)
+ : QSqlCachedResult(*new QSQLiteResultPrivate(this, db))
{
- d = new QSQLiteResultPrivate(this);
- d->access = db->d_func()->access;
- const_cast<QSQLiteDriverPrivate*>(db->d_func())->results.append(this);
+ Q_D(QSQLiteResult);
+ const_cast<QSQLiteDriverPrivate*>(d->drv_d_func())->results.append(this);
}
QSQLiteResult::~QSQLiteResult()
{
- const QSqlDriver *sqlDriver = driver();
- if (sqlDriver)
- const_cast<QSQLiteDriverPrivate*>(qobject_cast<const QSQLiteDriver *>(sqlDriver)->d_func())->results.removeOne(this);
+ Q_D(QSQLiteResult);
+ if (d->drv_d_func())
+ const_cast<QSQLiteDriverPrivate*>(d->drv_d_func())->results.removeOne(this);
d->cleanup();
- delete d;
}
void QSQLiteResult::virtual_hook(int id, void *data)
@@ -366,6 +370,7 @@ bool QSQLiteResult::reset(const QString &query)
bool QSQLiteResult::prepare(const QString &query)
{
+ Q_D(QSQLiteResult);
if (!driver() || !driver()->isOpen() || driver()->isOpenError())
return false;
@@ -376,7 +381,7 @@ bool QSQLiteResult::prepare(const QString &query)
const void *pzTail = NULL;
#if (SQLITE_VERSION_NUMBER >= 3003011)
- int res = sqlite3_prepare16_v2(d->access, query.constData(), (query.size() + 1) * sizeof(QChar),
+ int res = sqlite3_prepare16_v2(d->drv_d_func()->access, query.constData(), (query.size() + 1) * sizeof(QChar),
&d->stmt, &pzTail);
#else
int res = sqlite3_prepare16(d->access, query.constData(), (query.size() + 1) * sizeof(QChar),
@@ -384,12 +389,12 @@ bool QSQLiteResult::prepare(const QString &query)
#endif
if (res != SQLITE_OK) {
- setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
+ setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to execute statement"), QSqlError::StatementError, res));
d->finalize();
return false;
} else if (pzTail && !QString(reinterpret_cast<const QChar *>(pzTail)).trimmed().isEmpty()) {
- setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
+ setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to execute multiple statements at a time"), QSqlError::StatementError, SQLITE_MISUSE));
d->finalize();
return false;
@@ -399,6 +404,7 @@ bool QSQLiteResult::prepare(const QString &query)
bool QSQLiteResult::exec()
{
+ Q_D(QSQLiteResult);
const QVector<QVariant> values = boundValues();
d->skippedStatus = false;
@@ -409,7 +415,7 @@ bool QSQLiteResult::exec()
int res = sqlite3_reset(d->stmt);
if (res != SQLITE_OK) {
- setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
+ setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to reset statement"), QSqlError::StatementError, res));
d->finalize();
return false;
@@ -469,7 +475,7 @@ bool QSQLiteResult::exec()
}
}
if (res != SQLITE_OK) {
- setLastError(qMakeError(d->access, QCoreApplication::translate("QSQLiteResult",
+ setLastError(qMakeError(d->drv_d_func()->access, QCoreApplication::translate("QSQLiteResult",
"Unable to bind parameters"), QSqlError::StatementError, res));
d->finalize();
return false;
@@ -493,6 +499,7 @@ bool QSQLiteResult::exec()
bool QSQLiteResult::gotoNext(QSqlCachedResult::ValueCache& row, int idx)
{
+ Q_D(QSQLiteResult);
return d->fetchNext(row, idx, false);
}
@@ -503,13 +510,15 @@ int QSQLiteResult::size()
int QSQLiteResult::numRowsAffected()
{
- return sqlite3_changes(d->access);
+ Q_D(const QSQLiteResult);
+ return sqlite3_changes(d->drv_d_func()->access);
}
QVariant QSQLiteResult::lastInsertId() const
{
+ Q_D(const QSQLiteResult);
if (isActive()) {
- qint64 id = sqlite3_last_insert_rowid(d->access);
+ qint64 id = sqlite3_last_insert_rowid(d->drv_d_func()->access);
if (id)
return id;
}
@@ -518,6 +527,7 @@ QVariant QSQLiteResult::lastInsertId() const
QSqlRecord QSQLiteResult::record() const
{
+ Q_D(const QSQLiteResult);
if (!isActive() || !isSelect())
return QSqlRecord();
return d->rInf;
@@ -525,12 +535,14 @@ QSqlRecord QSQLiteResult::record() const
void QSQLiteResult::detachFromResultSet()
{
+ Q_D(QSQLiteResult);
if (d->stmt)
sqlite3_reset(d->stmt);
}
QVariant QSQLiteResult::handle() const
{
+ Q_D(const QSQLiteResult);
return QVariant::fromValue(d->stmt);
}
@@ -640,7 +652,7 @@ void QSQLiteDriver::close()
Q_D(QSQLiteDriver);
if (isOpen()) {
foreach (QSQLiteResult *result, d->results) {
- result->d->finalize();
+ result->d_func()->finalize();
}
if (sqlite3_close(d->access) != SQLITE_OK)
diff --git a/src/sql/drivers/sqlite/qsql_sqlite_p.h b/src/sql/drivers/sqlite/qsql_sqlite_p.h
index 23b598de98..d0dc91daab 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite_p.h
+++ b/src/sql/drivers/sqlite/qsql_sqlite_p.h
@@ -46,7 +46,6 @@
//
#include <QtSql/qsqldriver.h>
-#include <QtSql/qsqlresult.h>
struct sqlite3;
@@ -58,14 +57,14 @@ struct sqlite3;
QT_BEGIN_NAMESPACE
+class QSqlResult;
class QSQLiteDriverPrivate;
-class QSQLiteDriver;
class Q_EXPORT_SQLDRIVER_SQLITE QSQLiteDriver : public QSqlDriver
{
Q_DECLARE_PRIVATE(QSQLiteDriver)
Q_OBJECT
- friend class QSQLiteResult;
+ friend class QSQLiteResultPrivate;
public:
explicit QSQLiteDriver(QObject *parent = 0);
explicit QSQLiteDriver(sqlite3 *connection, QObject *parent = 0);
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
index 3b540fd193..cd449e28e8 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
@@ -77,6 +77,8 @@ static QVariant::Type nameToType(const QString& typeName)
class QSQLite2DriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QSQLite2Driver)
+
public:
QSQLite2DriverPrivate();
sqlite *access;
@@ -93,30 +95,31 @@ class QSQLite2ResultPrivate;
class QSQLite2Result : public QSqlCachedResult
{
+ Q_DECLARE_PRIVATE(QSQLite2Result)
friend class QSQLite2Driver;
- friend class QSQLite2ResultPrivate;
+
public:
explicit QSQLite2Result(const QSQLite2Driver* db);
~QSQLite2Result();
- QVariant handle() const;
+ QVariant handle() const Q_DECL_OVERRIDE;
protected:
- bool gotoNext(QSqlCachedResult::ValueCache& row, int idx);
- bool reset (const QString& query);
- int size();
- int numRowsAffected();
- QSqlRecord record() const;
- void detachFromResultSet();
- void virtual_hook(int id, void *data);
-
-private:
- QSQLite2ResultPrivate* d;
+ bool gotoNext(QSqlCachedResult::ValueCache &row, int idx) Q_DECL_OVERRIDE;
+ bool reset(const QString &query) Q_DECL_OVERRIDE;
+ int size() Q_DECL_OVERRIDE;
+ int numRowsAffected() Q_DECL_OVERRIDE;
+ QSqlRecord record() const Q_DECL_OVERRIDE;
+ void detachFromResultSet() Q_DECL_OVERRIDE;
+ void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
};
-class QSQLite2ResultPrivate
+class QSQLite2ResultPrivate: public QSqlCachedResultPrivate
{
+ Q_DECLARE_PUBLIC(QSQLite2Result)
+
public:
- QSQLite2ResultPrivate(QSQLite2Result *res);
+ Q_DECLARE_SQLDRIVER_PRIVATE(QSQLite2Driver);
+ QSQLite2ResultPrivate(QSQLite2Result *q, const QSQLite2Driver *drv);
void cleanup();
bool fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch);
bool isSelect();
@@ -124,9 +127,6 @@ public:
void init(const char **cnames, int numCols);
void finalize();
- QSQLite2Result* q;
- sqlite *access;
-
// and we have too keep our own struct for the data (sqlite works via
// callback.
const char *currentTail;
@@ -134,20 +134,24 @@ public:
bool skippedStatus; // the status of the fetchNext() that's skipped
bool skipRow; // skip the next fetchNext()?
- bool utf8;
QSqlRecord rInf;
QVector<QVariant> firstRow;
};
static const uint initial_cache_size = 128;
-QSQLite2ResultPrivate::QSQLite2ResultPrivate(QSQLite2Result* res) : q(res), access(0), currentTail(0),
- currentMachine(0), skippedStatus(false), skipRow(false), utf8(false)
+QSQLite2ResultPrivate::QSQLite2ResultPrivate(QSQLite2Result *q, const QSQLite2Driver *drv)
+ : QSqlCachedResultPrivate(q, drv),
+ currentTail(0),
+ currentMachine(0),
+ skippedStatus(false),
+ skipRow(false)
{
}
void QSQLite2ResultPrivate::cleanup()
{
+ Q_Q(QSQLite2Result);
finalize();
rInf.clear();
currentTail = 0;
@@ -161,6 +165,7 @@ void QSQLite2ResultPrivate::cleanup()
void QSQLite2ResultPrivate::finalize()
{
+ Q_Q(QSQLite2Result);
if (!currentMachine)
return;
@@ -178,6 +183,7 @@ void QSQLite2ResultPrivate::finalize()
// called on first fetch
void QSQLite2ResultPrivate::init(const char **cnames, int numCols)
{
+ Q_Q(QSQLite2Result);
if (!cnames)
return;
@@ -204,6 +210,7 @@ void QSQLite2ResultPrivate::init(const char **cnames, int numCols)
bool QSQLite2ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int idx, bool initialFetch)
{
+ Q_Q(QSQLite2Result);
// may be caching.
const char **fvals;
const char **cnames;
@@ -250,7 +257,7 @@ bool QSQLite2ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int
if (idx < 0 && !initialFetch)
return true;
for (i = 0; i < colNum; ++i)
- values[i + idx] = utf8 ? QString::fromUtf8(fvals[i]) : QString::fromLatin1(fvals[i]);
+ values[i + idx] = drv_d_func()->utf8 ? QString::fromUtf8(fvals[i]) : QString::fromLatin1(fvals[i]);
return true;
case SQLITE_DONE:
if (rInf.isEmpty())
@@ -270,17 +277,14 @@ bool QSQLite2ResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int
}
QSQLite2Result::QSQLite2Result(const QSQLite2Driver* db)
-: QSqlCachedResult(db)
+ : QSqlCachedResult(*new QSQLite2ResultPrivate(this, db))
{
- d = new QSQLite2ResultPrivate(this);
- d->access = db->d_func()->access;
- d->utf8 = db->d_func()->utf8;
}
QSQLite2Result::~QSQLite2Result()
{
+ Q_D(QSQLite2Result);
d->cleanup();
- delete d;
}
void QSQLite2Result::virtual_hook(int id, void *data)
@@ -293,6 +297,7 @@ void QSQLite2Result::virtual_hook(int id, void *data)
*/
bool QSQLite2Result::reset (const QString& query)
{
+ Q_D(QSQLite2Result);
// this is where we build a query.
if (!driver())
return false;
@@ -304,8 +309,8 @@ bool QSQLite2Result::reset (const QString& query)
// Um, ok. callback based so.... pass private static function for this.
setSelect(false);
char *err = 0;
- int res = sqlite_compile(d->access,
- d->utf8 ? query.toUtf8().constData()
+ int res = sqlite_compile(d->drv_d_func()->access,
+ d->drv_d_func()->utf8 ? query.toUtf8().constData()
: query.toLatin1().constData(),
&(d->currentTail),
&(d->currentMachine),
@@ -336,6 +341,7 @@ bool QSQLite2Result::reset (const QString& query)
bool QSQLite2Result::gotoNext(QSqlCachedResult::ValueCache& row, int idx)
{
+ Q_D(QSQLite2Result);
return d->fetchNext(row, idx, false);
}
@@ -346,11 +352,13 @@ int QSQLite2Result::size()
int QSQLite2Result::numRowsAffected()
{
- return sqlite_changes(d->access);
+ Q_D(QSQLite2Result);
+ return sqlite_changes(d->drv_d_func()->access);
}
QSqlRecord QSQLite2Result::record() const
{
+ Q_D(const QSQLite2Result);
if (!isActive() || !isSelect())
return QSqlRecord();
return d->rInf;
@@ -358,11 +366,13 @@ QSqlRecord QSQLite2Result::record() const
void QSQLite2Result::detachFromResultSet()
{
+ Q_D(QSQLite2Result);
d->finalize();
}
QVariant QSQLite2Result::handle() const
{
+ Q_D(const QSQLite2Result);
return QVariant::fromValue(d->currentMachine);
}
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2_p.h b/src/sql/drivers/sqlite2/qsql_sqlite2_p.h
index 95766dacd0..408cc832a3 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2_p.h
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2_p.h
@@ -46,9 +46,6 @@
//
#include <QtSql/qsqldriver.h>
-#include <QtSql/qsqlresult.h>
-#include <QtSql/qsqlrecord.h>
-#include <QtSql/qsqlindex.h>
#if defined (Q_OS_WIN32)
# include <QtCore/qt_windows.h>
@@ -56,43 +53,49 @@
struct sqlite;
+#ifdef QT_PLUGIN
+#define Q_EXPORT_SQLDRIVER_SQLITE2
+#else
+#define Q_EXPORT_SQLDRIVER_SQLITE2 Q_SQL_EXPORT
+#endif
+
QT_BEGIN_NAMESPACE
+class QSqlResult;
class QSQLite2DriverPrivate;
-class QSQLite2Driver;
-class QSQLite2Driver : public QSqlDriver
+class Q_EXPORT_SQLDRIVER_SQLITE2 QSQLite2Driver : public QSqlDriver
{
- friend class QSQLite2Result;
+ friend class QSQLite2ResultPrivate;
Q_DECLARE_PRIVATE(QSQLite2Driver)
Q_OBJECT
public:
explicit QSQLite2Driver(QObject *parent = 0);
explicit QSQLite2Driver(sqlite *connection, QObject *parent = 0);
~QSQLite2Driver();
- bool hasFeature(DriverFeature f) const;
- bool open(const QString & db,
- const QString & user,
- const QString & password,
- const QString & host,
+ bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE;
+ bool open(const QString &db,
+ const QString &user,
+ const QString &password,
+ const QString &host,
int port,
- const QString & connOpts);
- bool open(const QString & db,
- const QString & user,
- const QString & password,
- const QString & host,
- int port) { return open (db, user, password, host, port, QString()); }
- void close();
- QSqlResult *createResult() const;
- bool beginTransaction();
- bool commitTransaction();
- bool rollbackTransaction();
- QStringList tables(QSql::TableType) const;
+ const QString &connOpts) Q_DECL_OVERRIDE;
+ bool open(const QString &db,
+ const QString &user,
+ const QString &password,
+ const QString &host,
+ int port) { return open(db, user, password, host, port, QString()); }
+ void close() Q_DECL_OVERRIDE;
+ QSqlResult *createResult() const Q_DECL_OVERRIDE;
+ bool beginTransaction() Q_DECL_OVERRIDE;
+ bool commitTransaction() Q_DECL_OVERRIDE;
+ bool rollbackTransaction() Q_DECL_OVERRIDE;
+ QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE;
- QSqlRecord record(const QString& tablename) const;
- QSqlIndex primaryIndex(const QString &table) const;
- QVariant handle() const;
- QString escapeIdentifier(const QString &identifier, IdentifierType) const;
+ QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE;
+ QSqlIndex primaryIndex(const QString &table) const Q_DECL_OVERRIDE;
+ QVariant handle() const Q_DECL_OVERRIDE;
+ QString escapeIdentifier(const QString &identifier, IdentifierType) const Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp
index f048440113..75d6cc2cd6 100644
--- a/src/sql/drivers/tds/qsql_tds.cpp
+++ b/src/sql/drivers/tds/qsql_tds.cpp
@@ -131,6 +131,8 @@ QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, int errNo =
class QTDSDriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QTDSDriver)
+
public:
QTDSDriverPrivate() : QSqlDriverPrivate(), login(0), initialized(false) { dbmsType = QSqlDriver::Sybase; }
LOGINREC* login; // login information
@@ -150,6 +152,8 @@ class QTDSResultPrivate;
class QTDSResult : public QSqlCachedResult
{
+ Q_DECLARE_PRIVATE(QTDSResult)
+
public:
explicit QTDSResult(const QTDSDriver* db);
~QTDSResult();
@@ -157,20 +161,23 @@ public:
protected:
void cleanup();
- bool reset (const QString& query);
- int size();
- int numRowsAffected();
- bool gotoNext(QSqlCachedResult::ValueCache &values, int index);
- QSqlRecord record() const;
-
-private:
- QTDSResultPrivate* d;
+ bool reset(const QString &query) Q_DECL_OVERRIDE;
+ int size() Q_DECL_OVERRIDE;
+ int numRowsAffected() Q_DECL_OVERRIDE;
+ bool gotoNext(QSqlCachedResult::ValueCache &values, int index) Q_DECL_OVERRIDE;
+ QSqlRecord record() const Q_DECL_OVERRIDE;
};
-class QTDSResultPrivate
+class QTDSResultPrivate: public QSqlCachedResultPrivate
{
+ Q_DECLARE_PUBLIC(QTDSResult)
+
public:
- QTDSResultPrivate():login(0), dbproc(0) {}
+ Q_DECLARE_SQLDRIVER_PRIVATE(QTDSDriver)
+ QTDSResultPrivate(QTDSResult *q, const QTDSDriver *drv)
+ : QSqlCachedResultPrivate(q, drv),
+ login(0),
+ dbproc(0) {}
LOGINREC* login; // login information
DBPROCESS* dbproc; // connection from app to server
QSqlError lastError;
@@ -316,15 +323,15 @@ QVariant::Type qFieldType(QTDSResultPrivate* d, int i)
QTDSResult::QTDSResult(const QTDSDriver* db)
- : QSqlCachedResult(db)
+ : QSqlCachedResult(*new QTDSResultPrivate(this, db))
{
- d = new QTDSResultPrivate();
- d->login = db->d_func()->login;
+ Q_D(QTDSResult);
+ d->login = d->drv_d_func()->login;
- d->dbproc = dbopen(d->login, const_cast<char*>(db->d_func()->hostName.toLatin1().constData()));
+ d->dbproc = dbopen(d->login, const_cast<char*>(d->drv_d_func()->hostName.toLatin1().constData()));
if (!d->dbproc)
return;
- if (dbuse(d->dbproc, const_cast<char*>(db->d_func()->db.toLatin1().constData())) == FAIL)
+ if (dbuse(d->dbproc, const_cast<char*>(d->drv_d_func()->db.toLatin1().constData())) == FAIL)
return;
// insert d in error handler dict
@@ -335,15 +342,16 @@ QTDSResult::QTDSResult(const QTDSDriver* db)
QTDSResult::~QTDSResult()
{
+ Q_D(QTDSResult);
cleanup();
if (d->dbproc)
dbclose(d->dbproc);
errs()->remove(d->dbproc);
- delete d;
}
void QTDSResult::cleanup()
{
+ Q_D(QTDSResult);
d->clearErrorMsgs();
d->rec.clear();
for (int i = 0; i < d->buffer.size(); ++i)
@@ -358,6 +366,7 @@ void QTDSResult::cleanup()
QVariant QTDSResult::handle() const
{
+ Q_D(const QTDSResult);
return QVariant(qRegisterMetaType<DBPROCESS *>("DBPROCESS*"), &d->dbproc);
}
@@ -368,6 +377,7 @@ static inline bool qIsNull(const QTDSColumnData &p)
bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
{
+ Q_D(QTDSResult);
STATUS stat = dbnextrow(d->dbproc);
if (stat == NO_MORE_ROWS) {
setAt(QSql::AfterLastRow);
@@ -427,6 +437,7 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index)
bool QTDSResult::reset (const QString& query)
{
+ Q_D(QTDSResult);
cleanup();
if (!driver() || !driver()-> isOpen() || driver()->isOpenError())
return false;
@@ -515,6 +526,7 @@ int QTDSResult::size()
int QTDSResult::numRowsAffected()
{
+ Q_D(const QTDSResult);
#ifdef DBNTWIN32
if (dbiscount(d->dbproc)) {
return DBCOUNT(d->dbproc);
@@ -527,6 +539,7 @@ int QTDSResult::numRowsAffected()
QSqlRecord QTDSResult::record() const
{
+ Q_D(const QTDSResult);
return d->rec;
}
diff --git a/src/sql/drivers/tds/qsql_tds_p.h b/src/sql/drivers/tds/qsql_tds_p.h
index fae5dc2877..25a5aa1fe7 100644
--- a/src/sql/drivers/tds/qsql_tds_p.h
+++ b/src/sql/drivers/tds/qsql_tds_p.h
@@ -45,7 +45,6 @@
// We mean it.
//
-#include <QtSql/qsqlresult.h>
#include <QtSql/qsqldriver.h>
#ifdef Q_OS_WIN32
@@ -71,41 +70,41 @@
QT_BEGIN_NAMESPACE
+class QSqlResult;
class QTDSDriverPrivate;
-class QTDSDriver;
class Q_EXPORT_SQLDRIVER_TDS QTDSDriver : public QSqlDriver
{
Q_DECLARE_PRIVATE(QTDSDriver)
Q_OBJECT
- friend class QTDSResult;
+ friend class QTDSResultPrivate;
public:
explicit QTDSDriver(QObject* parent = 0);
QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QObject* parent = 0);
~QTDSDriver();
- bool hasFeature(DriverFeature f) const;
- bool open(const QString & db,
- const QString & user,
- const QString & password,
- const QString & host,
+ bool hasFeature(DriverFeature f) const Q_DECL_OVERRIDE;
+ bool open(const QString &db,
+ const QString &user,
+ const QString &password,
+ const QString &host,
int port,
- const QString& connOpts);
- void close();
- QStringList tables(QSql::TableType) const;
- QSqlResult *createResult() const;
- QSqlRecord record(const QString& tablename) const;
- QSqlIndex primaryIndex(const QString& tablename) const;
+ const QString &connOpts) Q_DECL_OVERRIDE;
+ void close() Q_DECL_OVERRIDE;
+ QStringList tables(QSql::TableType) const Q_DECL_OVERRIDE;
+ QSqlResult *createResult() const Q_DECL_OVERRIDE;
+ QSqlRecord record(const QString &tablename) const Q_DECL_OVERRIDE;
+ QSqlIndex primaryIndex(const QString &tablename) const Q_DECL_OVERRIDE;
QString formatValue(const QSqlField &field,
- bool trimStrings) const;
- QVariant handle() const;
+ bool trimStrings) const Q_DECL_OVERRIDE;
+ QVariant handle() const Q_DECL_OVERRIDE;
- QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
+ QString escapeIdentifier(const QString &identifier, IdentifierType type) const Q_DECL_OVERRIDE;
protected:
- bool beginTransaction();
- bool commitTransaction();
- bool rollbackTransaction();
+ bool beginTransaction() Q_DECL_OVERRIDE;
+ bool commitTransaction() Q_DECL_OVERRIDE;
+ bool rollbackTransaction() Q_DECL_OVERRIDE;
private:
void init();
};
diff --git a/src/sql/kernel/qsqlcachedresult.cpp b/src/sql/kernel/qsqlcachedresult.cpp
index b9611ae8c7..ce93688cb2 100644
--- a/src/sql/kernel/qsqlcachedresult.cpp
+++ b/src/sql/kernel/qsqlcachedresult.cpp
@@ -36,6 +36,7 @@
#include <qvariant.h>
#include <qdatetime.h>
#include <qvector.h>
+#include <QtSql/private/qsqldriver_p.h>
QT_BEGIN_NAMESPACE
@@ -53,33 +54,17 @@ QT_BEGIN_NAMESPACE
static const uint initial_cache_size = 128;
-class QSqlCachedResultPrivate
-{
-public:
- QSqlCachedResultPrivate();
- bool canSeek(int i) const;
- inline int cacheCount() const;
- void init(int count, bool fo);
- void cleanup();
- int nextIndex();
- void revertLast();
-
- QSqlCachedResult::ValueCache cache;
- int rowCacheEnd;
- int colCount;
- bool forwardOnly;
- bool atEnd;
-};
-
-QSqlCachedResultPrivate::QSqlCachedResultPrivate():
- rowCacheEnd(0), colCount(0), forwardOnly(false), atEnd(false)
+QSqlCachedResultPrivate::QSqlCachedResultPrivate(QSqlCachedResult *q, const QSqlDriver *drv)
+ : QSqlResultPrivate(q, drv),
+ rowCacheEnd(0),
+ colCount(0),
+ atEnd(false)
{
}
void QSqlCachedResultPrivate::cleanup()
{
cache.clear();
- forwardOnly = false;
atEnd = false;
colCount = 0;
rowCacheEnd = 0;
@@ -134,23 +119,20 @@ inline int QSqlCachedResultPrivate::cacheCount() const
//////////////
-QSqlCachedResult::QSqlCachedResult(const QSqlDriver * db): QSqlResult (db)
-{
- d = new QSqlCachedResultPrivate();
-}
-
-QSqlCachedResult::~QSqlCachedResult()
+QSqlCachedResult::QSqlCachedResult(QSqlCachedResultPrivate &d)
+ : QSqlResult(d)
{
- delete d;
}
void QSqlCachedResult::init(int colCount)
{
+ Q_D(QSqlCachedResult);
d->init(colCount, isForwardOnly());
}
bool QSqlCachedResult::fetch(int i)
{
+ Q_D(QSqlCachedResult);
if ((!isActive()) || (i < 0))
return false;
if (at() == i)
@@ -189,6 +171,7 @@ bool QSqlCachedResult::fetch(int i)
bool QSqlCachedResult::fetchNext()
{
+ Q_D(QSqlCachedResult);
if (d->canSeek(at() + 1)) {
setAt(at() + 1);
return true;
@@ -203,6 +186,7 @@ bool QSqlCachedResult::fetchPrevious()
bool QSqlCachedResult::fetchFirst()
{
+ Q_D(QSqlCachedResult);
if (d->forwardOnly && at() != QSql::BeforeFirstRow) {
return false;
}
@@ -215,6 +199,7 @@ bool QSqlCachedResult::fetchFirst()
bool QSqlCachedResult::fetchLast()
{
+ Q_D(QSqlCachedResult);
if (d->atEnd) {
if (d->forwardOnly)
return false;
@@ -235,6 +220,7 @@ bool QSqlCachedResult::fetchLast()
QVariant QSqlCachedResult::data(int i)
{
+ Q_D(const QSqlCachedResult);
int idx = d->forwardOnly ? i : at() * d->colCount + i;
if (i >= d->colCount || i < 0 || at() < 0 || idx >= d->rowCacheEnd)
return QVariant();
@@ -244,6 +230,7 @@ QVariant QSqlCachedResult::data(int i)
bool QSqlCachedResult::isNull(int i)
{
+ Q_D(const QSqlCachedResult);
int idx = d->forwardOnly ? i : at() * d->colCount + i;
if (i >= d->colCount || i < 0 || at() < 0 || idx >= d->rowCacheEnd)
return true;
@@ -253,6 +240,7 @@ bool QSqlCachedResult::isNull(int i)
void QSqlCachedResult::cleanup()
{
+ Q_D(QSqlCachedResult);
setAt(QSql::BeforeFirstRow);
setActive(false);
d->cleanup();
@@ -260,6 +248,7 @@ void QSqlCachedResult::cleanup()
void QSqlCachedResult::clearValues()
{
+ Q_D(QSqlCachedResult);
setAt(QSql::BeforeFirstRow);
d->rowCacheEnd = 0;
d->atEnd = false;
@@ -267,6 +256,7 @@ void QSqlCachedResult::clearValues()
bool QSqlCachedResult::cacheNext()
{
+ Q_D(QSqlCachedResult);
if (d->atEnd)
return false;
@@ -286,11 +276,13 @@ bool QSqlCachedResult::cacheNext()
int QSqlCachedResult::colCount() const
{
+ Q_D(const QSqlCachedResult);
return d->colCount;
}
QSqlCachedResult::ValueCache &QSqlCachedResult::cache()
{
+ Q_D(QSqlCachedResult);
return d->cache;
}
diff --git a/src/sql/kernel/qsqlcachedresult_p.h b/src/sql/kernel/qsqlcachedresult_p.h
index 798de01f63..a24964bfb2 100644
--- a/src/sql/kernel/qsqlcachedresult_p.h
+++ b/src/sql/kernel/qsqlcachedresult_p.h
@@ -46,6 +46,7 @@
//
#include "QtSql/qsqlresult.h"
+#include "QtSql/private/qsqlresult_p.h"
QT_BEGIN_NAMESPACE
@@ -56,13 +57,13 @@ class QSqlCachedResultPrivate;
class Q_SQL_EXPORT QSqlCachedResult: public QSqlResult
{
-public:
- virtual ~QSqlCachedResult();
+ Q_DECLARE_PRIVATE(QSqlCachedResult)
+public:
typedef QVector<QVariant> ValueCache;
protected:
- QSqlCachedResult(const QSqlDriver * db);
+ QSqlCachedResult(QSqlCachedResultPrivate &d);
void init(int colCount);
void cleanup();
@@ -70,23 +71,41 @@ protected:
virtual bool gotoNext(ValueCache &values, int index) = 0;
- QVariant data(int i);
- bool isNull(int i);
- bool fetch(int i);
- bool fetchNext();
- bool fetchPrevious();
- bool fetchFirst();
- bool fetchLast();
+ QVariant data(int i) Q_DECL_OVERRIDE;
+ bool isNull(int i) Q_DECL_OVERRIDE;
+ bool fetch(int i) Q_DECL_OVERRIDE;
+ bool fetchNext() Q_DECL_OVERRIDE;
+ bool fetchPrevious() Q_DECL_OVERRIDE;
+ bool fetchFirst() Q_DECL_OVERRIDE;
+ bool fetchLast() Q_DECL_OVERRIDE;
int colCount() const;
ValueCache &cache();
- void virtual_hook(int id, void *data);
- void detachFromResultSet();
- void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy);
+ void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
+ void detachFromResultSet() Q_DECL_OVERRIDE;
+ void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy) Q_DECL_OVERRIDE;
private:
bool cacheNext();
- QSqlCachedResultPrivate *d;
+};
+
+class Q_SQL_EXPORT QSqlCachedResultPrivate: public QSqlResultPrivate
+{
+ Q_DECLARE_PUBLIC(QSqlCachedResult)
+
+public:
+ QSqlCachedResultPrivate(QSqlCachedResult *q, const QSqlDriver *drv);
+ bool canSeek(int i) const;
+ inline int cacheCount() const;
+ void init(int count, bool fo);
+ void cleanup();
+ int nextIndex();
+ void revertLast();
+
+ QSqlCachedResult::ValueCache cache;
+ int rowCacheEnd;
+ int colCount;
+ bool atEnd;
};
QT_END_NAMESPACE
diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp
index ccfc6e04f0..337b093c83 100644
--- a/src/sql/kernel/qsqldriver.cpp
+++ b/src/sql/kernel/qsqldriver.cpp
@@ -157,7 +157,8 @@ QSqlDriver::~QSqlDriver()
bool QSqlDriver::isOpen() const
{
- return d_func()->isOpen;
+ Q_D(const QSqlDriver);
+ return d->isOpen;
}
/*!
@@ -167,7 +168,8 @@ bool QSqlDriver::isOpen() const
bool QSqlDriver::isOpenError() const
{
- return d_func()->isOpenError;
+ Q_D(const QSqlDriver);
+ return d->isOpenError;
}
/*!
@@ -274,7 +276,8 @@ bool QSqlDriver::isOpenError() const
void QSqlDriver::setOpen(bool open)
{
- d_func()->isOpen = open;
+ Q_D(QSqlDriver);
+ d->isOpen = open;
}
/*!
@@ -288,9 +291,10 @@ void QSqlDriver::setOpen(bool open)
void QSqlDriver::setOpenError(bool error)
{
- d_func()->isOpenError = error;
+ Q_D(QSqlDriver);
+ d->isOpenError = error;
if (error)
- d_func()->isOpen = false;
+ d->isOpen = false;
}
/*!
@@ -341,7 +345,8 @@ bool QSqlDriver::rollbackTransaction()
void QSqlDriver::setLastError(const QSqlError &error)
{
- d_func()->error = error;
+ Q_D(QSqlDriver);
+ d->error = error;
}
/*!
@@ -351,7 +356,8 @@ void QSqlDriver::setLastError(const QSqlError &error)
QSqlError QSqlDriver::lastError() const
{
- return d_func()->error;
+ Q_D(const QSqlDriver);
+ return d->error;
}
/*!
@@ -766,7 +772,8 @@ QStringList QSqlDriver::subscribedToNotifications() const
*/
void QSqlDriver::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
{
- d_func()->precisionPolicy = precisionPolicy;
+ Q_D(QSqlDriver);
+ d->precisionPolicy = precisionPolicy;
}
/*!
@@ -779,7 +786,8 @@ void QSqlDriver::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy prec
*/
QSql::NumericalPrecisionPolicy QSqlDriver::numericalPrecisionPolicy() const
{
- return d_func()->precisionPolicy;
+ Q_D(const QSqlDriver);
+ return d->precisionPolicy;
}
/*!
@@ -789,7 +797,8 @@ QSql::NumericalPrecisionPolicy QSqlDriver::numericalPrecisionPolicy() const
*/
QSqlDriver::DbmsType QSqlDriver::dbmsType() const
{
- return d_func()->dbmsType;
+ Q_D(const QSqlDriver);
+ return d->dbmsType;
}
/*!
diff --git a/src/sql/kernel/qsqlnulldriver_p.h b/src/sql/kernel/qsqlnulldriver_p.h
index fef2942325..3d2cd98931 100644
--- a/src/sql/kernel/qsqlnulldriver_p.h
+++ b/src/sql/kernel/qsqlnulldriver_p.h
@@ -59,27 +59,27 @@ public:
{ QSqlResult::setLastError(
QSqlError(QLatin1String("Driver not loaded"), QLatin1String("Driver not loaded"), QSqlError::ConnectionError)); }
protected:
- inline QVariant data(int) { return QVariant(); }
- inline bool reset (const QString&) { return false; }
- inline bool fetch(int) { return false; }
- inline bool fetchFirst() { return false; }
- inline bool fetchLast() { return false; }
- inline bool isNull(int) { return false; }
- inline int size() { return -1; }
- inline int numRowsAffected() { return 0; }
+ inline QVariant data(int) Q_DECL_OVERRIDE { return QVariant(); }
+ inline bool reset (const QString&) Q_DECL_OVERRIDE { return false; }
+ inline bool fetch(int) Q_DECL_OVERRIDE { return false; }
+ inline bool fetchFirst() Q_DECL_OVERRIDE { return false; }
+ inline bool fetchLast() Q_DECL_OVERRIDE { return false; }
+ inline bool isNull(int) Q_DECL_OVERRIDE { return false; }
+ inline int size() Q_DECL_OVERRIDE { return -1; }
+ inline int numRowsAffected() Q_DECL_OVERRIDE { return 0; }
- inline void setAt(int) {}
- inline void setActive(bool) {}
- inline void setLastError(const QSqlError&) {}
- inline void setQuery(const QString&) {}
- inline void setSelect(bool) {}
- inline void setForwardOnly(bool) {}
+ inline void setAt(int) Q_DECL_OVERRIDE {}
+ inline void setActive(bool) Q_DECL_OVERRIDE {}
+ inline void setLastError(const QSqlError&) Q_DECL_OVERRIDE {}
+ inline void setQuery(const QString&) Q_DECL_OVERRIDE {}
+ inline void setSelect(bool) Q_DECL_OVERRIDE {}
+ inline void setForwardOnly(bool) Q_DECL_OVERRIDE {}
- inline bool exec() { return false; }
- inline bool prepare(const QString&) { return false; }
- inline bool savePrepare(const QString&) { return false; }
- inline void bindValue(int, const QVariant&, QSql::ParamType) {}
- inline void bindValue(const QString&, const QVariant&, QSql::ParamType) {}
+ inline bool exec() Q_DECL_OVERRIDE { return false; }
+ inline bool prepare(const QString&) Q_DECL_OVERRIDE { return false; }
+ inline bool savePrepare(const QString&) Q_DECL_OVERRIDE { return false; }
+ inline void bindValue(int, const QVariant&, QSql::ParamType) Q_DECL_OVERRIDE {}
+ inline void bindValue(const QString&, const QVariant&, QSql::ParamType) Q_DECL_OVERRIDE {}
};
class QSqlNullDriver : public QSqlDriver
@@ -88,17 +88,16 @@ public:
inline QSqlNullDriver(): QSqlDriver()
{ QSqlDriver::setLastError(
QSqlError(QLatin1String("Driver not loaded"), QLatin1String("Driver not loaded"), QSqlError::ConnectionError)); }
- inline bool hasFeature(DriverFeature) const { return false; }
- inline bool open(const QString &, const QString & , const QString & ,
- const QString &, int, const QString&)
+ inline bool hasFeature(DriverFeature) const Q_DECL_OVERRIDE { return false; }
+ inline bool open(const QString &, const QString &, const QString &, const QString &, int, const QString&) Q_DECL_OVERRIDE
{ return false; }
- inline void close() {}
- inline QSqlResult *createResult() const { return new QSqlNullResult(this); }
+ inline void close() Q_DECL_OVERRIDE {}
+ inline QSqlResult *createResult() const Q_DECL_OVERRIDE { return new QSqlNullResult(this); }
protected:
- inline void setOpen(bool) {}
- inline void setOpenError(bool) {}
- inline void setLastError(const QSqlError&) {}
+ inline void setOpen(bool) Q_DECL_OVERRIDE {}
+ inline void setOpenError(bool) Q_DECL_OVERRIDE {}
+ inline void setLastError(const QSqlError&) Q_DECL_OVERRIDE {}
};
QT_END_NAMESPACE
diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp
index c35fca7217..a701f9f669 100644
--- a/src/sql/kernel/qsqlresult.cpp
+++ b/src/sql/kernel/qsqlresult.cpp
@@ -87,7 +87,7 @@ QString QSqlResultPrivate::positionalToNamedBinding(const QString &query) const
result.reserve(n * 5 / 4);
QChar closingQuote;
int count = 0;
- bool ignoreBraces = (sqldriver->d_func()->dbmsType == QSqlDriver::PostgreSQL);
+ bool ignoreBraces = (sqldriver->dbmsType() == QSqlDriver::PostgreSQL);
for (int i = 0; i < n; ++i) {
QChar ch = query.at(i);
@@ -128,7 +128,7 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query)
QChar closingQuote;
int count = 0;
int i = 0;
- bool ignoreBraces = (sqldriver->d_func()->dbmsType == QSqlDriver::PostgreSQL);
+ bool ignoreBraces = (sqldriver->dbmsType() == QSqlDriver::PostgreSQL);
while (i < n) {
QChar ch = query.at(i);
@@ -218,22 +218,18 @@ QString QSqlResultPrivate::namedToPositionalBinding(const QString &query)
QSqlResult::QSqlResult(const QSqlDriver *db)
{
- d_ptr = new QSqlResultPrivate;
+ d_ptr = new QSqlResultPrivate(this, db);
Q_D(QSqlResult);
- d->q_ptr = this;
- d->sqldriver = const_cast<QSqlDriver *>(db);
if (d->sqldriver)
setNumericalPrecisionPolicy(d->sqldriver->numericalPrecisionPolicy());
}
/*! \internal
*/
-QSqlResult::QSqlResult(QSqlResultPrivate &dd, const QSqlDriver *db)
+QSqlResult::QSqlResult(QSqlResultPrivate &dd)
+ : d_ptr(&dd)
{
- d_ptr = &dd;
Q_D(QSqlResult);
- d->q_ptr = this;
- d->sqldriver = const_cast<QSqlDriver *>(db);
if (d->sqldriver)
setNumericalPrecisionPolicy(d->sqldriver->numericalPrecisionPolicy());
}
diff --git a/src/sql/kernel/qsqlresult.h b/src/sql/kernel/qsqlresult.h
index c86a8f858f..4a4b358a49 100644
--- a/src/sql/kernel/qsqlresult.h
+++ b/src/sql/kernel/qsqlresult.h
@@ -66,7 +66,7 @@ protected:
};
explicit QSqlResult(const QSqlDriver * db);
- QSqlResult(QSqlResultPrivate &dd, const QSqlDriver *db);
+ QSqlResult(QSqlResultPrivate &dd);
int at() const;
QString lastQuery() const;
QSqlError lastError() const;
diff --git a/src/sql/kernel/qsqlresult_p.h b/src/sql/kernel/qsqlresult_p.h
index 34b260d89b..b158618b78 100644
--- a/src/sql/kernel/qsqlresult_p.h
+++ b/src/sql/kernel/qsqlresult_p.h
@@ -46,12 +46,17 @@
//
#include <QtCore/qpointer.h>
-#include <QtSql/qsqldriver.h>
#include "qsqlerror.h"
#include "qsqlresult.h"
+#include "qsqldriver.h"
QT_BEGIN_NAMESPACE
+// convenience method Q*ResultPrivate::drv_d_func() returns pointer to private driver. Compare to Q_DECLARE_PRIVATE in qglobal.h.
+#define Q_DECLARE_SQLDRIVER_PRIVATE(Class) \
+ inline const Class##Private* drv_d_func() const { return !sqldriver ? nullptr : reinterpret_cast<const Class *>(static_cast<const QSqlDriver*>(sqldriver))->d_func(); } \
+ inline Class##Private* drv_d_func() { return !sqldriver ? nullptr : reinterpret_cast<Class *>(static_cast<QSqlDriver*>(sqldriver))->d_func(); }
+
struct QHolder {
QHolder(const QString &hldr = QString(), int index = -1): holderName(hldr), holderPos(index) { }
bool operator==(const QHolder &h) const { return h.holderPos == holderPos && h.holderName == holderName; }
@@ -62,10 +67,12 @@ struct QHolder {
class Q_SQL_EXPORT QSqlResultPrivate
{
+ Q_DECLARE_PUBLIC(QSqlResult)
public:
- QSqlResultPrivate()
- : q_ptr(0),
+ QSqlResultPrivate(QSqlResult *q, const QSqlDriver *drv)
+ : q_ptr(q),
+ sqldriver(const_cast<QSqlDriver*>(drv)),
idx(QSql::BeforeFirstRow),
active(false),
isSel(false),
diff --git a/src/testlib/qbenchmarkvalgrind.cpp b/src/testlib/qbenchmarkvalgrind.cpp
index ada3cfc768..7cb5eef30c 100644
--- a/src/testlib/qbenchmarkvalgrind.cpp
+++ b/src/testlib/qbenchmarkvalgrind.cpp
@@ -96,7 +96,7 @@ qint64 QBenchmarkValgrindUtils::extractResult(const QString &fileName)
break;
}
}
- if (!valSeen)
+ if (Q_UNLIKELY(!valSeen))
qFatal("Failed to extract result");
return val;
}
diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp
index d820e87ccb..80b93886bb 100644
--- a/src/testlib/qplaintestlogger.cpp
+++ b/src/testlib/qplaintestlogger.cpp
@@ -348,16 +348,17 @@ void QPlainTestLogger::startLogging()
void QPlainTestLogger::stopLogging()
{
char buf[1024];
+ const int timeMs = qRound(QTestLog::msecsTotalTime());
if (QTestLog::verboseLevel() < 0) {
- qsnprintf(buf, sizeof(buf), "Totals: %d passed, %d failed, %d skipped, %d blacklisted\n",
+ qsnprintf(buf, sizeof(buf), "Totals: %d passed, %d failed, %d skipped, %d blacklisted, %dms\n",
QTestLog::passCount(), QTestLog::failCount(),
- QTestLog::skipCount(), QTestLog::blacklistCount());
+ QTestLog::skipCount(), QTestLog::blacklistCount(), timeMs);
} else {
qsnprintf(buf, sizeof(buf),
- "Totals: %d passed, %d failed, %d skipped, %d blacklisted\n"
+ "Totals: %d passed, %d failed, %d skipped, %d blacklisted, %dms\n"
"********* Finished testing of %s *********\n",
QTestLog::passCount(), QTestLog::failCount(),
- QTestLog::skipCount(), QTestLog::blacklistCount(),
+ QTestLog::skipCount(), QTestLog::blacklistCount(), timeMs,
QTestResult::currentTestObjectName());
}
outputMessage(buf);
diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp
index c2643a2304..fe69e097e7 100644
--- a/src/testlib/qtestblacklist.cpp
+++ b/src/testlib/qtestblacklist.cpp
@@ -121,6 +121,13 @@ static QSet<QByteArray> keywords()
#endif
#endif
+#ifdef Q_PROCESSOR_X86
+ << "x86"
+#endif
+#ifdef Q_PROCESSOR_ARM
+ << "arm"
+#endif
+
#ifdef Q_AUTOTEST_EXPORT
<< "developer-build"
#endif
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 286da52be2..9acddcc7ea 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -97,6 +97,8 @@
#include <IOKit/pwr_mgt/IOPMLib.h>
#endif
+#include <vector>
+
QT_BEGIN_NAMESPACE
using QtMiscUtils::toHexUpper;
@@ -136,1261 +138,6 @@ static void stackTrace()
#endif
}
-/*!
- \namespace QTest
- \inmodule QtTest
-
- \brief The QTest namespace contains all the functions and
- declarations that are related to Qt Test.
-
- See the \l{Qt Test Overview} for information about how to write unit tests.
-*/
-
-/*!
- \namespace QTest::Internal
- \internal
-*/
-
-/*! \macro QVERIFY(condition)
-
- \relates QTest
-
- The QVERIFY() macro checks whether the \a condition is true or not. If it is
- true, execution continues. If not, a failure is recorded in the test log
- and the test won't be executed further.
-
- \b {Note:} This macro can only be used in a test function that is invoked
- by the test framework.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 0
-
- \sa QCOMPARE(), QTRY_VERIFY()
-*/
-
-/*! \macro QVERIFY2(condition, message)
-
- \relates QTest
-
- The QVERIFY2() macro behaves exactly like QVERIFY(), except that it outputs
- a verbose \a message when \a condition is false. The \a message is a plain
- C string.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 1
-
- \sa QVERIFY(), QCOMPARE()
-*/
-
-/*! \macro QCOMPARE(actual, expected)
-
- \relates QTest
-
- The QCOMPARE macro compares an \a actual value to an \a expected value using
- the equals operator. If \a actual and \a expected are identical, execution
- continues. If not, a failure is recorded in the test log and the test
- won't be executed further.
-
- In the case of comparing floats and doubles, qFuzzyCompare() is used for
- comparing. This means that comparing to 0 will likely fail. One solution
- to this is to compare to 1, and add 1 to the produced output.
-
- QCOMPARE tries to output the contents of the values if the comparison fails,
- so it is visible from the test log why the comparison failed.
-
- QCOMPARE is very strict on the data types. Both \a actual and \a expected
- have to be of the same type, otherwise the test won't compile. This prohibits
- unspecified behavior from being introduced; that is behavior that usually
- occurs when the compiler implicitly casts the argument.
-
- For your own classes, you can use \l QTest::toString() to format values for
- outputting into the test log.
-
- \note This macro can only be used in a test function that is invoked
- by the test framework.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 2
-
- \sa QVERIFY(), QTRY_COMPARE(), QTest::toString()
-*/
-
-/*! \macro QVERIFY_EXCEPTION_THROWN(expression, exceptiontype)
- \since 5.3
-
- \relates QTest
-
- The QVERIFY_EXCEPTION_THROWN macro executes an \a expression and tries
- to catch an exception thrown from the \a expression. If the \a expression
- throws an exception and its type is the same as \a exceptiontype
- or \a exceptiontype is substitutable with the type of thrown exception
- (i.e. usually the type of thrown exception is publically derived
- from \a exceptiontype) then execution will be continued. If not-substitutable
- type of exception is thrown or the \a expression doesn't throw an exception
- at all, then a failure will be recorded in the test log and
- the test won't be executed further.
-
- \note This macro can only be used in a test function that is invoked
- by the test framework.
-*/
-
-/*! \macro QTRY_VERIFY_WITH_TIMEOUT(condition, timeout)
- \since 5.0
-
- \relates QTest
-
- The QTRY_VERIFY_WITH_TIMEOUT() macro is similar to QVERIFY(), but checks the \a condition
- repeatedly, until either the condition becomes true or the \a timeout is
- reached. Between each evaluation, events will be processed. If the timeout
- is reached, a failure is recorded in the test log and the test won't be
- executed further.
-
- \note This macro can only be used in a test function that is invoked
- by the test framework.
-
- \sa QTRY_VERIFY(), QTRY_VERIFY2_WITH_TIMEOUT(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
-*/
-
-
-/*! \macro QTRY_VERIFY(condition)
- \since 5.0
-
- \relates QTest
-
- Checks the \a condition by invoking QTRY_VERIFY_WITH_TIMEOUT() with a timeout of five seconds.
-
- \note This macro can only be used in a test function that is invoked
- by the test framework.
-
- \sa QTRY_VERIFY_WITH_TIMEOUT(), QTRY_VERIFY2(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
-*/
-
-/*! \macro QTRY_VERIFY2_WITH_TIMEOUT(condition, message, timeout)
- \since 5.6
-
- \relates QTest
-
- The QTRY_VERIFY2_WITH_TIMEOUT macro is similar to QTRY_VERIFY_WITH_TIMEOUT()
- except that it outputs a verbose \a message when \a condition is still false
- after the specified \a timeout. The \a message is a plain C string.
-
- Example:
- \code
- QTRY_VERIFY2_WITH_TIMEOUT(list.size() > 2, QByteArray::number(list.size()).constData(), 10000);
- \endcode
-
- \note This macro can only be used in a test function that is invoked
- by the test framework.
-
- \sa QTRY_VERIFY(), QTRY_VERIFY_WITH_TIMEOUT(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
-*/
-
-/*! \macro QTRY_VERIFY2(condition, message)
- \since 5.6
-
- \relates QTest
-
- Checks the \a condition by invoking QTRY_VERIFY2_WITH_TIMEOUT() with a timeout
- of five seconds. If \a condition is then still false, \a message is output.
- The \a message is a plain C string.
-
- Example:
- \code
- QTRY_VERIFY2_WITH_TIMEOUT(list.size() > 2, QByteArray::number(list.size()).constData());
- \endcode
-
- \note This macro can only be used in a test function that is invoked
- by the test framework.
-
- \sa QTRY_VERIFY2_WITH_TIMEOUT(), QTRY_VERIFY2(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
-*/
-
-/*! \macro QTRY_COMPARE_WITH_TIMEOUT(actual, expected, timeout)
- \since 5.0
-
- \relates QTest
-
- The QTRY_COMPARE_WITH_TIMEOUT() macro is similar to QCOMPARE(), but performs the comparison
- of the \a actual and \a expected values repeatedly, until either the two values
- are equal or the \a timeout is reached. Between each comparison, events
- will be processed. If the timeout is reached, a failure is recorded in the
- test log and the test won't be executed further.
-
- \note This macro can only be used in a test function that is invoked
- by the test framework.
-
- \sa QTRY_COMPARE(), QCOMPARE(), QVERIFY(), QTRY_VERIFY()
-*/
-
-/*! \macro QTRY_COMPARE(actual, expected)
- \since 5.0
-
- \relates QTest
-
- Performs a comparison of the \a actual and \a expected values by
- invoking QTRY_COMPARE_WITH_TIMEOUT() with a timeout of five seconds.
-
- \note This macro can only be used in a test function that is invoked
- by the test framework.
-
- \sa QTRY_COMPARE_WITH_TIMEOUT(), QCOMPARE(), QVERIFY(), QTRY_VERIFY()
-*/
-
-/*! \macro QFETCH(type, name)
-
- \relates QTest
-
- The fetch macro creates a local variable named \a name with the type \a type
- on the stack. \a name has to match the element name from the test's data.
- If no such element exists, the test will assert.
-
- Assuming a test has the following data:
-
- \snippet code/src_qtestlib_qtestcase.cpp 3
-
- The test data has two elements, a QString called \c aString and an integer
- called \c expected. To fetch these values in the actual test:
-
- \snippet code/src_qtestlib_qtestcase.cpp 4
-
- \c aString and \c expected are variables on the stack that are initialized with
- the current test data.
-
- \b {Note:} This macro can only be used in a test function that is invoked
- by the test framework. The test function must have a _data function.
-*/
-
-/*! \macro QWARN(message)
-
- \relates QTest
- \threadsafe
-
- Appends \a message as a warning to the test log. This macro can be used anywhere
- in your tests.
-*/
-
-/*! \macro QFAIL(message)
-
- \relates QTest
-
- This macro can be used to force a test failure. The test stops
- executing and the failure \a message is appended to the test log.
-
- \b {Note:} This macro can only be used in a test function that is invoked
- by the test framework.
-
- Example:
-
- \snippet code/src_qtestlib_qtestcase.cpp 5
-*/
-
-/*! \macro QTEST(actual, testElement)
-
- \relates QTest
-
- QTEST() is a convenience macro for \l QCOMPARE() that compares
- the value \a actual with the element \a testElement from the test's data.
- If there is no such element, the test asserts.
-
- Apart from that, QTEST() behaves exactly as \l QCOMPARE().
-
- Instead of writing:
-
- \snippet code/src_qtestlib_qtestcase.cpp 6
-
- you can write:
-
- \snippet code/src_qtestlib_qtestcase.cpp 7
-
- \sa QCOMPARE()
-*/
-
-/*! \macro QSKIP(description)
-
- \relates QTest
-
- If called from a test function, the QSKIP() macro stops execution of the test
- without adding a failure to the test log. You can use it to skip tests that
- wouldn't make sense in the current configuration. The text \a description is
- appended to the test log and should contain an explanation of why the test
- couldn't be executed.
-
- If the test is data-driven, each call to QSKIP() will skip only the current
- row of test data, so an unconditional call to QSKIP will produce one skip
- message in the test log for each row of test data.
-
- If called from an _data function, the QSKIP() macro will stop execution of
- the _data function and will prevent execution of the associated test
- function.
-
- If called from initTestCase() or initTestCase_data(), the QSKIP() macro will
- skip all test and _data functions.
-
- \b {Note:} This macro can only be used in a test function or _data
- function that is invoked by the test framework.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 8
-*/
-
-/*! \macro QEXPECT_FAIL(dataIndex, comment, mode)
-
- \relates QTest
-
- The QEXPECT_FAIL() macro marks the next \l QCOMPARE() or \l QVERIFY() as an
- expected failure. Instead of adding a failure to the test log, an expected
- failure will be reported.
-
- If a \l QVERIFY() or \l QCOMPARE() is marked as an expected failure,
- but passes instead, an unexpected pass (XPASS) is written to the test log.
-
- The parameter \a dataIndex describes for which entry in the test data the
- failure is expected. Pass an empty string (\c{""}) if the failure
- is expected for all entries or if no test data exists.
-
- \a comment will be appended to the test log for the expected failure.
-
- \a mode is a \l QTest::TestFailMode and sets whether the test should
- continue to execute or not.
-
- \b {Note:} This macro can only be used in a test function that is invoked
- by the test framework.
-
- Example 1:
- \snippet code/src_qtestlib_qtestcase.cpp 9
-
- In the example above, an expected fail will be written into the test output
- if the variable \c i is not 42. If the variable \c i is 42, an unexpected pass
- is written instead. The QEXPECT_FAIL() has no influence on the second QCOMPARE()
- statement in the example.
-
- Example 2:
- \snippet code/src_qtestlib_qtestcase.cpp 10
-
- The above testfunction will not continue executing for the test data
- entry \c{data27}.
-
- \sa QTest::TestFailMode, QVERIFY(), QCOMPARE()
-*/
-
-/*! \macro QFINDTESTDATA(filename)
- \since 5.0
-
- \relates QTest
-
- Returns a QString for the testdata file referred to by \a filename, or an
- empty QString if the testdata file could not be found.
-
- This macro allows the test to load data from an external file without
- hardcoding an absolute filename into the test, or using relative paths
- which may be error prone.
-
- The returned path will be the first path from the following list which
- resolves to an existing file or directory:
-
- \list
- \li \a filename relative to QCoreApplication::applicationDirPath()
- (only if a QCoreApplication or QApplication object has been created).
- \li \a filename relative to the test's standard install directory
- (QLibraryInfo::TestsPath with the lowercased testcase name appended).
- \li \a filename relative to the directory containing the source file from which
- QFINDTESTDATA is invoked.
- \endlist
-
- If the named file/directory does not exist at any of these locations,
- a warning is printed to the test log.
-
- For example, in this code:
- \snippet code/src_qtestlib_qtestcase.cpp 26
-
- The testdata file will be resolved as the first existing file from:
-
- \list
- \li \c{/home/user/build/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
- \li \c{/usr/local/Qt-5.0.0/tests/tst_myxmlparser/testxml/simple1.xml}
- \li \c{/home/user/sources/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
- \endlist
-
- This allows the test to find its testdata regardless of whether the
- test has been installed, and regardless of whether the test's build tree
- is equal to the test's source tree.
-
- \b {Note:} reliable detection of testdata from the source directory requires
- either that qmake is used, or the \c{QT_TESTCASE_BUILDDIR} macro is defined to
- point to the working directory from which the compiler is invoked, or only
- absolute paths to the source files are passed to the compiler. Otherwise, the
- absolute path of the source directory cannot be determined.
-
- \b {Note:} For tests that use the \l QTEST_APPLESS_MAIN() macro to generate a
- \c{main()} function, \c{QFINDTESTDATA} will not attempt to find test data
- relative to QCoreApplication::applicationDirPath(). In practice, this means that
- tests using \c{QTEST_APPLESS_MAIN()} will fail to find their test data
- if run from a shadow build tree.
-*/
-
-/*! \macro QTEST_MAIN(TestClass)
-
- \relates QTest
-
- Implements a main() function that instantiates an application object and
- the \a TestClass, and executes all tests in the order they were defined.
- Use this macro to build stand-alone executables.
-
- If \c QT_WIDGETS_LIB is defined, the application object will be a QApplication,
- if \c QT_GUI_LIB is defined, the application object will be a QGuiApplication,
- otherwise it will be a QCoreApplication. If qmake is used and the configuration
- includes \c{QT += widgets}, then \c QT_WIDGETS_LIB will be defined automatically.
- Similarly, if qmake is used and the configuration includes \c{QT += gui}, then
- \c QT_GUI_LIB will be defined automatically.
-
- \b {Note:} On platforms that have keypad navigation enabled by default,
- this macro will forcefully disable it if \c QT_WIDGETS_LIB is defined. This is done
- to simplify the usage of key events when writing autotests. If you wish to write a
- test case that uses keypad navigation, you should enable it either in the
- \c {initTestCase()} or \c {init()} functions of your test case by calling
- \l {QApplication::setNavigationMode()}.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 11
-
- \sa QTEST_APPLESS_MAIN(), QTEST_GUILESS_MAIN(), QTest::qExec(),
- QApplication::setNavigationMode()
-*/
-
-/*! \macro QTEST_APPLESS_MAIN(TestClass)
-
- \relates QTest
-
- Implements a main() function that executes all tests in \a TestClass.
-
- Behaves like \l QTEST_MAIN(), but doesn't instantiate a QApplication
- object. Use this macro for really simple stand-alone non-GUI tests.
-
- \sa QTEST_MAIN()
-*/
-
-/*! \macro QTEST_GUILESS_MAIN(TestClass)
- \since 5.0
-
- \relates QTest
-
- Implements a main() function that instantiates a QCoreApplication object
- and the \a TestClass, and executes all tests in the order they were
- defined. Use this macro to build stand-alone executables.
-
- Behaves like \l QTEST_MAIN(), but instantiates a QCoreApplication instead
- of the QApplication object. Use this macro if your test case doesn't need
- functionality offered by QApplication, but the event loop is still necessary.
-
- \sa QTEST_MAIN()
-*/
-
-/*!
- \macro QBENCHMARK
-
- \relates QTest
-
- This macro is used to measure the performance of code within a test.
- The code to be benchmarked is contained within a code block following
- this macro.
-
- For example:
-
- \snippet code/src_qtestlib_qtestcase.cpp 27
-
- \sa {Qt Test Overview#Creating a Benchmark}{Creating a Benchmark},
- {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
-*/
-
-/*!
- \macro QBENCHMARK_ONCE
- \since 4.6
-
- \relates QTest
-
- \brief The QBENCHMARK_ONCE macro is for measuring performance of a
- code block by running it once.
-
- This macro is used to measure the performance of code within a test.
- The code to be benchmarked is contained within a code block following
- this macro.
-
- Unlike QBENCHMARK, the contents of the contained code block is only run
- once. The elapsed time will be reported as "0" if it's to short to
- be measured by the selected backend. (Use)
-
- \sa {Qt Test Overview#Creating a Benchmark}{Creating a Benchmark},
- {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
-*/
-
-/*! \enum QTest::TestFailMode
-
- This enum describes the modes for handling an expected failure of the
- \l QVERIFY() or \l QCOMPARE() macros.
-
- \value Abort Aborts the execution of the test. Use this mode when it
- doesn't make sense to execute the test any further after the
- expected failure.
-
- \value Continue Continues execution of the test after the expected failure.
-
- \sa QEXPECT_FAIL()
-*/
-
-/*! \enum QTest::KeyAction
-
- This enum describes possible actions for key handling.
-
- \value Press The key is pressed.
- \value Release The key is released.
- \value Click The key is clicked (pressed and released).
-*/
-
-/*! \enum QTest::MouseAction
-
- This enum describes possible actions for mouse handling.
-
- \value MousePress A mouse button is pressed.
- \value MouseRelease A mouse button is released.
- \value MouseClick A mouse button is clicked (pressed and released).
- \value MouseDClick A mouse button is double clicked (pressed and released twice).
- \value MouseMove The mouse pointer has moved.
-*/
-
-/*! \fn void QTest::keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
-
- Simulates clicking of \a key with an optional \a modifier on a \a widget.
- If \a delay is larger than 0, the test will wait for \a delay milliseconds
- before clicking the key.
-
- Examples:
- \snippet code/src_qtestlib_qtestcase.cpp 14
-
- The first example above simulates clicking the \c escape key on \c
- myWidget without any keyboard modifiers and without delay. The
- second example simulates clicking \c shift-escape on \c myWidget
- following a 200 ms delay of the test.
-
- \sa QTest::keyClicks()
-*/
-
-/*! \fn void QTest::keyClick(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
-
- Simulates clicking of \a key with an optional \a modifier on a \a widget.
- If \a delay is larger than 0, the test will wait for \a delay milliseconds
- before clicking the key.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 13
-
- The example above simulates clicking \c a on \c myWidget without
- any keyboard modifiers and without delay of the test.
-
- \sa QTest::keyClicks()
-*/
-
-/*! \fn void QTest::keyClick(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
- \since 5.0
-
- Simulates clicking of \a key with an optional \a modifier on a \a window.
- If \a delay is larger than 0, the test will wait for \a delay milliseconds
- before clicking the key.
-
- Examples:
- \snippet code/src_qtestlib_qtestcase.cpp 29
-
- The first example above simulates clicking the \c escape key on \c
- myWindow without any keyboard modifiers and without delay. The
- second example simulates clicking \c shift-escape on \c myWindow
- following a 200 ms delay of the test.
-
- \sa QTest::keyClicks()
-*/
-
-/*! \fn void QTest::keyClick(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
- \since 5.0
-
- Simulates clicking of \a key with an optional \a modifier on a \a window.
- If \a delay is larger than 0, the test will wait for \a delay milliseconds
- before clicking the key.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 28
-
- The example above simulates clicking \c a on \c myWindow without
- any keyboard modifiers and without delay of the test.
-
- \sa QTest::keyClicks()
-*/
-
-/*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
-
- Sends a Qt key event to \a widget with the given \a key and an associated \a action.
- Optionally, a keyboard \a modifier can be specified, as well as a \a delay
- (in milliseconds) of the test before sending the event.
-*/
-
-/*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, char ascii, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
-
- Sends a Qt key event to \a widget with the given key \a ascii and an associated \a action.
- Optionally, a keyboard \a modifier can be specified, as well as a \a delay
- (in milliseconds) of the test before sending the event.
-*/
-
-/*! \fn void QTest::keyEvent(KeyAction action, QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
- \since 5.0
-
- Sends a Qt key event to \a window with the given \a key and an associated \a action.
- Optionally, a keyboard \a modifier can be specified, as well as a \a delay
- (in milliseconds) of the test before sending the event.
-*/
-
-/*! \fn void QTest::keyEvent(KeyAction action, QWindow *window, char ascii, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
- \since 5.0
-
- Sends a Qt key event to \a window with the given key \a ascii and an associated \a action.
- Optionally, a keyboard \a modifier can be specified, as well as a \a delay
- (in milliseconds) of the test before sending the event.
-*/
-
-/*! \fn void QTest::keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
-
- Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay
- is larger than 0, the test will wait for \a delay milliseconds before pressing the key.
-
- \b {Note:} At some point you should release the key using \l keyRelease().
-
- \sa QTest::keyRelease(), QTest::keyClick()
-*/
-
-/*! \fn void QTest::keyPress(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
-
- Simulates pressing a \a key with an optional \a modifier on a \a widget.
- If \a delay is larger than 0, the test will wait for \a delay milliseconds
- before pressing the key.
-
- \b {Note:} At some point you should release the key using \l keyRelease().
-
- \sa QTest::keyRelease(), QTest::keyClick()
-*/
-
-/*! \fn void QTest::keyPress(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
- \since 5.0
-
- Simulates pressing a \a key with an optional \a modifier on a \a window. If \a delay
- is larger than 0, the test will wait for \a delay milliseconds before pressing the key.
-
- \b {Note:} At some point you should release the key using \l keyRelease().
-
- \sa QTest::keyRelease(), QTest::keyClick()
-*/
-
-/*! \fn void QTest::keyPress(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
- \since 5.0
-
- Simulates pressing a \a key with an optional \a modifier on a \a window.
- If \a delay is larger than 0, the test will wait for \a delay milliseconds
- before pressing the key.
-
- \b {Note:} At some point you should release the key using \l keyRelease().
-
- \sa QTest::keyRelease(), QTest::keyClick()
-*/
-
-/*! \fn void QTest::keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
-
- Simulates releasing a \a key with an optional \a modifier on a \a widget.
- If \a delay is larger than 0, the test will wait for \a delay milliseconds
- before releasing the key.
-
- \sa QTest::keyPress(), QTest::keyClick()
-*/
-
-/*! \fn void QTest::keyRelease(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
-
- Simulates releasing a \a key with an optional \a modifier on a \a widget.
- If \a delay is larger than 0, the test will wait for \a delay milliseconds
- before releasing the key.
-
- \sa QTest::keyClick()
-*/
-
-/*! \fn void QTest::keyRelease(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
- \since 5.0
-
- Simulates releasing a \a key with an optional \a modifier on a \a window.
- If \a delay is larger than 0, the test will wait for \a delay milliseconds
- before releasing the key.
-
- \sa QTest::keyPress(), QTest::keyClick()
-*/
-
-/*! \fn void QTest::keyRelease(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
- \overload
- \since 5.0
-
- Simulates releasing a \a key with an optional \a modifier on a \a window.
- If \a delay is larger than 0, the test will wait for \a delay milliseconds
- before releasing the key.
-
- \sa QTest::keyClick()
-*/
-
-/*! \fn void QTest::keyClicks(QWidget *widget, const QString &sequence, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
-
- Simulates clicking a \a sequence of keys on a \a
- widget. Optionally, a keyboard \a modifier can be specified as
- well as a \a delay (in milliseconds) of the test before each key
- click.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 15
-
- The example above simulates clicking the sequence of keys
- representing "hello world" on \c myWidget without any keyboard
- modifiers and without delay of the test.
-
- \sa QTest::keyClick()
-*/
-
-/*! \fn void QTest::waitForEvents()
- \internal
-*/
-
-/*! \fn void QTest::mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
- \internal
-*/
-
-/*! \fn void QTest::mouseEvent(MouseAction action, QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
- \internal
-*/
-
-/*! \fn void QTest::mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
-
- Simulates pressing a mouse \a button with an optional \a modifier
- on a \a widget. The position is defined by \a pos; the default
- position is the center of the widget. If \a delay is specified,
- the test will wait for the specified amount of milliseconds before
- the press.
-
- \sa QTest::mouseRelease(), QTest::mouseClick()
-*/
-
-/*! \fn void QTest::mousePress(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, QPoint pos = QPoint(), int delay=-1)
- \overload
- \since 5.0
-
- Simulates pressing a mouse \a button with an optional \a stateKey modifier
- on a \a window. The position is defined by \a pos; the default
- position is the center of the window. If \a delay is specified,
- the test will wait for the specified amount of milliseconds before
- the press.
-
- \sa QTest::mouseRelease(), QTest::mouseClick()
-*/
-
-/*! \fn void QTest::mouseRelease(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
-
- Simulates releasing a mouse \a button with an optional \a modifier
- on a \a widget. The position of the release is defined by \a pos;
- the default position is the center of the widget. If \a delay is
- specified, the test will wait for the specified amount of
- milliseconds before releasing the button.
-
- \sa QTest::mousePress(), QTest::mouseClick()
-*/
-
-/*! \fn void QTest::mouseRelease(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, QPoint pos = QPoint(), int delay=-1)
- \overload
- \since 5.0
-
- Simulates releasing a mouse \a button with an optional \a stateKey modifier
- on a \a window. The position of the release is defined by \a pos;
- the default position is the center of the window. If \a delay is
- specified, the test will wait for the specified amount of
- milliseconds before releasing the button.
-
- \sa QTest::mousePress(), QTest::mouseClick()
-*/
-
-/*! \fn void QTest::mouseClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
-
- Simulates clicking a mouse \a button with an optional \a modifier
- on a \a widget. The position of the click is defined by \a pos;
- the default position is the center of the widget. If \a delay is
- specified, the test will wait for the specified amount of
- milliseconds before pressing and before releasing the button.
-
- \sa QTest::mousePress(), QTest::mouseRelease()
-*/
-
-/*! \fn void QTest::mouseClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, QPoint pos = QPoint(), int delay=-1)
- \overload
- \since 5.0
-
- Simulates clicking a mouse \a button with an optional \a stateKey modifier
- on a \a window. The position of the click is defined by \a pos;
- the default position is the center of the window. If \a delay is
- specified, the test will wait for the specified amount of
- milliseconds before pressing and before releasing the button.
-
- \sa QTest::mousePress(), QTest::mouseRelease()
-*/
-
-/*! \fn void QTest::mouseDClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
-
- Simulates double clicking a mouse \a button with an optional \a
- modifier on a \a widget. The position of the click is defined by
- \a pos; the default position is the center of the widget. If \a
- delay is specified, the test will wait for the specified amount of
- milliseconds before each press and release.
-
- \sa QTest::mouseClick()
-*/
-
-/*! \fn void QTest::mouseDClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, QPoint pos = QPoint(), int delay=-1)
- \overload
- \since 5.0
-
- Simulates double clicking a mouse \a button with an optional \a stateKey
- modifier on a \a window. The position of the click is defined by
- \a pos; the default position is the center of the window. If \a
- delay is specified, the test will wait for the specified amount of
- milliseconds before each press and release.
-
- \sa QTest::mouseClick()
-*/
-
-/*! \fn void QTest::mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay=-1)
-
- Moves the mouse pointer to a \a widget. If \a pos is not
- specified, the mouse pointer moves to the center of the widget. If
- a \a delay (in milliseconds) is given, the test will wait before
- moving the mouse pointer.
-*/
-
-/*! \fn void QTest::mouseMove(QWindow *window, QPoint pos = QPoint(), int delay=-1)
- \overload
- \since 5.0
-
- Moves the mouse pointer to a \a window. If \a pos is not
- specified, the mouse pointer moves to the center of the window. If
- a \a delay (in milliseconds) is given, the test will wait before
- moving the mouse pointer.
-*/
-
-/*!
- \fn char *QTest::toString(const T &value)
-
- Returns a textual representation of \a value. This function is used by
- \l QCOMPARE() to output verbose information in case of a test failure.
-
- You can add specializations or overloads of this function to your test to enable
- verbose output.
-
- \b {Note:} Starting with Qt 5.5, you should prefer to provide a toString() function
- in the type's namespace instead of specializing this template.
- If your code needs to continue to work with the QTestLib from Qt 5.4 or
- earlier, you need to continue to use specialization.
-
- \b {Note:} The caller of toString() must delete the returned data
- using \c{delete[]}. Your implementation should return a string
- created with \c{new[]} or qstrdup(). The easiest way to do so is to
- create a QByteArray or QString and calling QTest::toString() on it
- (see second example below).
-
- Example for specializing (Qt ≤ 5.4):
-
- \snippet code/src_qtestlib_qtestcase.cpp 16
-
- The example above defines a toString() specialization for a class
- called \c MyPoint. Whenever a comparison of two instances of \c
- MyPoint fails, \l QCOMPARE() will call this function to output the
- contents of \c MyPoint to the test log.
-
- Same example, but with overloading (Qt ≥ 5.5):
-
- \snippet code/src_qtestlib_qtestcase.cpp toString-overload
-
- \sa QCOMPARE()
-*/
-
-/*!
- \fn char *QTest::toString(const QLatin1String &string)
- \overload
-
- Returns a textual representation of the given \a string.
-*/
-
-/*!
- \fn char *QTest::toString(const QString &string)
- \overload
-
- Returns a textual representation of the given \a string.
-*/
-
-/*!
- \fn char *QTest::toString(const QByteArray &ba)
- \overload
-
- Returns a textual representation of the byte array \a ba.
-
- \sa QTest::toHexRepresentation()
-*/
-
-/*!
- \fn char *QTest::toString(const QTime &time)
- \overload
-
- Returns a textual representation of the given \a time.
-*/
-
-/*!
- \fn char *QTest::toString(const QDate &date)
- \overload
-
- Returns a textual representation of the given \a date.
-*/
-
-/*!
- \fn char *QTest::toString(const QDateTime &dateTime)
- \overload
-
- Returns a textual representation of the date and time specified by
- \a dateTime.
-*/
-
-/*!
- \fn char *QTest::toString(const QChar &character)
- \overload
-
- Returns a textual representation of the given \a character.
-*/
-
-/*!
- \fn char *QTest::toString(const QPoint &point)
- \overload
-
- Returns a textual representation of the given \a point.
-*/
-
-/*!
- \fn char *QTest::toString(const QSize &size)
- \overload
-
- Returns a textual representation of the given \a size.
-*/
-
-/*!
- \fn char *QTest::toString(const QRect &rectangle)
- \overload
-
- Returns a textual representation of the given \a rectangle.
-*/
-
-/*!
- \fn char *QTest::toString(const QUrl &url)
- \since 4.4
- \overload
-
- Returns a textual representation of the given \a url.
-*/
-
-/*!
- \fn char *QTest::toString(const QPointF &point)
- \overload
-
- Returns a textual representation of the given \a point.
-*/
-
-/*!
- \fn char *QTest::toString(const QSizeF &size)
- \overload
-
- Returns a textual representation of the given \a size.
-*/
-
-/*!
- \fn char *QTest::toString(const QRectF &rectangle)
- \overload
-
- Returns a textual representation of the given \a rectangle.
-*/
-
-/*!
- \fn char *QTest::toString(const QVariant &variant)
- \overload
-
- Returns a textual representation of the given \a variant.
-*/
-
-/*!
- \fn char *QTest::toString(QSizePolicy::ControlType ct)
- \overload
- \since 5.5
-
- Returns a textual representation of control type \a ct.
-*/
-
-/*!
- \fn char *QTest::toString(QSizePolicy::ControlTypes cts)
- \overload
- \since 5.5
-
- Returns a textual representation of control types \a cts.
-*/
-
-/*!
- \fn char *QTest::toString(QSizePolicy::Policy p)
- \overload
- \since 5.5
-
- Returns a textual representation of policy \a p.
-*/
-
-/*!
- \fn char *QTest::toString(QSizePolicy sp)
- \overload
- \since 5.5
-
- Returns a textual representation of size policy \a sp.
-*/
-
-/*! \fn void QTest::qWait(int ms)
-
- Waits for \a ms milliseconds. While waiting, events will be processed and
- your test will stay responsive to user interface events or network communication.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 17
-
- The code above will wait until the network server is responding for a
- maximum of about 12.5 seconds.
-
- \sa QTest::qSleep(), QSignalSpy::wait()
-*/
-
-/*! \fn bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
- \since 5.0
-
- Waits for \a timeout milliseconds or until the \a window is exposed.
- Returns \c true if \c window is exposed within \a timeout milliseconds, otherwise returns \c false.
-
- This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
- time after being asked to show itself on the screen.
-
- \sa QTest::qWaitForWindowActive(), QWindow::isExposed()
-*/
-
-/*! \fn bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
- \since 5.0
-
- Waits for \a timeout milliseconds or until the \a window is active.
-
- Returns \c true if \c window is active within \a timeout milliseconds, otherwise returns \c false.
-
- \sa QTest::qWaitForWindowExposed(), QWindow::isActive()
-*/
-
-/*! \fn bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout)
- \since 5.0
-
- Waits for \a timeout milliseconds or until the \a widget's window is exposed.
- Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
-
- This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
- time after being asked to show itself on the screen.
-
- \sa QTest::qWaitForWindowActive()
-*/
-
-/*! \fn bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
- \since 5.0
-
- Waits for \a timeout milliseconds or until the \a widget's window is active.
-
- Returns \c true if \c widget's window is active within \a timeout milliseconds, otherwise returns \c false.
-
- \sa QTest::qWaitForWindowExposed(), QWidget::isActiveWindow()
-*/
-
-/*! \fn bool QTest::qWaitForWindowShown(QWidget *widget, int timeout)
- \since 5.0
- \deprecated
-
- Waits for \a timeout milliseconds or until the \a widget's window is exposed.
- Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
-
- This function does the same as qWaitForWindowExposed().
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 24
-
- \sa QTest::qWaitForWindowActive(), QTest::qWaitForWindowExposed()
-*/
-
-/*!
- \class QTest::QTouchEventSequence
- \inmodule QtTest
- \since 4.6
-
- \brief The QTouchEventSequence class is used to simulate a sequence of touch events.
-
- To simulate a sequence of touch events on a specific device for a window or widget, call
- QTest::touchEvent to create a QTouchEventSequence instance. Add touch events to
- the sequence by calling press(), move(), release() and stationary(), and let the
- instance run out of scope to commit the sequence to the event system.
-
- Example:
- \snippet code/src_qtestlib_qtestcase.cpp 25
-*/
-
-/*!
- \fn QTest::QTouchEventSequence::~QTouchEventSequence()
-
- Commits this sequence of touch events, unless autoCommit was disabled, and frees allocated resources.
-*/
-
-/*!
- \fn void QTest::QTouchEventSequence::commit(bool processEvents)
-
- Commits this sequence of touch events to the event system. Normally there is no need to call this
- function because it is called from the destructor. However, if autoCommit is disabled, the events
- only get committed upon explicitly calling this function.
-
- In special cases tests may want to disable the processing of the events. This can be achieved by
- setting \a processEvents to false. This results in merely queuing the events, the event loop will
- not be forced to process them.
-*/
-
-/*!
- \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWindow *window)
- \since 5.0
-
- Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns
- a reference to this QTouchEventSequence.
-
- The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
- \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
-
- Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId.
-*/
-
-/*!
- \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWidget *widget)
-
- Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns
- a reference to this QTouchEventSequence.
-
- The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
- \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
-
- Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId.
-*/
-
-/*!
- \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWindow *window)
- \since 5.0
-
- Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns
- a reference to this QTouchEventSequence.
-
- The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
- \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
-
- Simulates that the user moved the finger identified by \a touchId.
-*/
-
-/*!
- \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWidget *widget)
-
- Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns
- a reference to this QTouchEventSequence.
-
- The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
- \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
-
- Simulates that the user moved the finger identified by \a touchId.
-*/
-
-/*!
- \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWindow *window)
- \since 5.0
-
- Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns
- a reference to this QTouchEventSequence.
-
- The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
- \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
-
- Simulates that the user lifted the finger identified by \a touchId.
-*/
-
-/*!
- \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWidget *widget)
-
- Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns
- a reference to this QTouchEventSequence.
-
- The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
- \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
-
- Simulates that the user lifted the finger identified by \a touchId.
-*/
-
-/*!
- \fn QTouchEventSequence &QTest::QTouchEventSequence::stationary(int touchId)
-
- Adds a stationary event for touchpoint \a touchId to this sequence and returns
- a reference to this QTouchEventSequence.
-
- Simulates that the user did not move the finger identified by \a touchId.
-*/
-
-/*!
- \fn QTouchEventSequence QTest::touchEvent(QWindow *window, QTouchDevice *device, bool autoCommit)
- \since 5.0
-
- Creates and returns a QTouchEventSequence for the \a device to
- simulate events for \a window.
-
- When adding touch events to the sequence, \a window will also be used to translate
- the position provided to screen coordinates, unless another window is provided in the
- respective calls to press(), move() etc.
-
- The touch events are committed to the event system when the destructor of the
- QTouchEventSequence is called (ie when the object returned runs out of scope), unless
- \a autoCommit is set to false. When \a autoCommit is false, commit() has to be called
- manually.
-*/
-
-/*!
- \fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QTouchDevice *device, bool autoCommit)
-
- Creates and returns a QTouchEventSequence for the \a device to
- simulate events for \a widget.
-
- When adding touch events to the sequence, \a widget will also be used to translate
- the position provided to screen coordinates, unless another widget is provided in the
- respective calls to press(), move() etc.
-
- The touch events are committed to the event system when the destructor of the
- QTouchEventSequence is called (ie when the object returned runs out of scope), unless
- \a autoCommit is set to false. When \a autoCommit is false, commit() has to be called
- manually.
-*/
-
static bool installCoverageTool(const char * appname, const char * testname)
{
#ifdef __COVERAGESCANNER__
@@ -1412,43 +159,74 @@ static bool installCoverageTool(const char * appname, const char * testname)
#endif
}
+static bool isValidSlot(const QMetaMethod &sl)
+{
+ if (sl.access() != QMetaMethod::Private || sl.parameterCount() != 0
+ || sl.returnType() != QMetaType::Void || sl.methodType() != QMetaMethod::Slot)
+ return false;
+ const QByteArray name = sl.name();
+ return !(name.isEmpty() || name.endsWith("_data")
+ || name == "initTestCase" || name == "cleanupTestCase"
+ || name == "init" || name == "cleanup");
+}
+
namespace QTest
{
+ class WatchDog;
+
static QObject *currentTestObject = 0;
static QString mainSourcePath;
- class TestFunction {
+ class TestMethods {
+ Q_DISABLE_COPY(TestMethods)
public:
- TestFunction() : function_(-1), data_(0) {}
- void set(int function, char *data) { function_ = function; data_ = data; }
- char *data() const { return data_; }
- int function() const { return function_; }
- ~TestFunction() { delete[] data_; }
+ typedef std::vector<QMetaMethod> MetaMethods;
+
+ explicit TestMethods(const QObject *o, const MetaMethods &m = MetaMethods());
+
+ void invokeTests(QObject *testObject) const;
+
+ static QMetaMethod findMethod(const QObject *obj, const char *signature);
+
private:
- int function_;
- char *data_;
+ bool invokeTest(int index, const char *data, WatchDog *watchDog) const;
+ void invokeTestOnData(int index) const;
+
+ QMetaMethod m_initTestCaseMethod; // might not exist, check isValid().
+ QMetaMethod m_initTestCaseDataMethod;
+ QMetaMethod m_cleanupTestCaseMethod;
+ QMetaMethod m_initMethod;
+ QMetaMethod m_cleanupMethod;
+
+ MetaMethods m_methods;
};
- /**
- * Contains the list of test functions that was supplied
- * on the command line, if any. Hence, if not empty,
- * those functions should be run instead of
- * all appearing in the test case.
- */
- static TestFunction * testFuncs = 0;
- static int testFuncCount = 0;
-
- /** Don't leak testFuncs on exit even on error */
- static struct TestFuncCleanup
+
+ TestMethods::TestMethods(const QObject *o, const MetaMethods &m)
+ : m_initTestCaseMethod(TestMethods::findMethod(o, "initTestCase()"))
+ , m_initTestCaseDataMethod(TestMethods::findMethod(o, "initTestCase_data()"))
+ , m_cleanupTestCaseMethod(TestMethods::findMethod(o, "cleanupTestCase()"))
+ , m_initMethod(TestMethods::findMethod(o, "init()"))
+ , m_cleanupMethod(TestMethods::findMethod(o, "cleanup()"))
+ , m_methods(m)
{
- void cleanup()
- {
- delete[] testFuncs;
- testFuncCount = 0;
- testFuncs = 0;
+ if (m.empty()) {
+ const QMetaObject *metaObject = o->metaObject();
+ const int count = metaObject->methodCount();
+ m_methods.reserve(count);
+ for (int i = 0; i < count; ++i) {
+ const QMetaMethod me = metaObject->method(i);
+ if (isValidSlot(me))
+ m_methods.push_back(me);
+ }
}
+ }
- ~TestFuncCleanup() { cleanup(); }
- } testFuncCleaner;
+ QMetaMethod TestMethods::findMethod(const QObject *obj, const char *signature)
+ {
+ const QMetaObject *metaObject = obj->metaObject();
+ const int funcIndex = metaObject->indexOfMethod(signature);
+ return funcIndex >= 0 ? metaObject->method(funcIndex) : QMetaMethod();
+ }
static int keyDelay = -1;
static int mouseDelay = -1;
@@ -1504,22 +282,6 @@ int Q_TESTLIB_EXPORT defaultKeyDelay()
return keyDelay;
}
-static bool isValidSlot(const QMetaMethod &sl)
-{
- if (sl.access() != QMetaMethod::Private || sl.parameterCount() != 0
- || sl.returnType() != QMetaType::Void || sl.methodType() != QMetaMethod::Slot)
- return false;
- QByteArray name = sl.name();
- if (name.isEmpty())
- return false;
- if (name.endsWith("_data"))
- return false;
- if (name == "initTestCase" || name == "cleanupTestCase"
- || name == "cleanup" || name == "init")
- return false;
- return true;
-}
-
Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
Q_TESTLIB_EXPORT QStringList testFunctions;
Q_TESTLIB_EXPORT QStringList testTags;
@@ -1617,6 +379,9 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
QTestLog::LogMode logFormat = QTestLog::Plain;
const char *logFilename = 0;
+ QTest::testFunctions.clear();
+ QTest::testTags.clear();
+
#if defined(Q_OS_MAC) && defined(HAVE_XCTEST)
if (QXcodeTestLogger::canLogTestProgress())
logFormat = QTestLog::XCTest;
@@ -1897,7 +662,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
fprintf(stderr, "\n"
" -help : This help\n");
exit(1);
- } else if (qml) {
+ } else {
// We can't check the availability of test functions until
// we load the QML files. So just store the data for now.
int colon = -1;
@@ -1923,36 +688,6 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
QTest::testTags +=
QString::fromLatin1(argv[i] + colon + 1);
}
- } else {
- if (!QTest::testFuncs) {
- QTest::testFuncs = new QTest::TestFunction[512];
- }
-
- int colon = -1;
- char buf[512], *data=0;
- int off;
- for (off = 0; *(argv[i]+off); ++off) {
- if (*(argv[i]+off) == ':') {
- colon = off;
- break;
- }
- }
- if (colon != -1) {
- data = qstrdup(argv[i]+colon+1);
- }
- qsnprintf(buf, qMin(512, off + 1), "%s", argv[i]); // copy text before the ':' into buf
- qsnprintf(buf + off, qMin(512 - off, 3), "()"); // append "()"
- int idx = QTest::currentTestObject->metaObject()->indexOfMethod(buf);
- if (idx < 0 || !isValidSlot(QTest::currentTestObject->metaObject()->method(idx))) {
- fprintf(stderr, "Unknown test function: '%s'. Possible matches:\n", buf);
- buf[off] = 0;
- qPrintTestSlots(stderr, buf);
- fprintf(stderr, "\n%s -functions\nlists all available test functions.\n", argv[0]);
- exit(1);
- }
- testFuncs[testFuncCount].set(idx, data);
- testFuncCount++;
- QTEST_ASSERT(QTest::testFuncCount < 512);
}
}
@@ -2005,7 +740,7 @@ qreal addResult(qreal current, const QBenchmarkResult& r)
}
-static void qInvokeTestMethodDataEntry(char *slot)
+void TestMethods::invokeTestOnData(int index) const
{
/* Benchmarking: for each median iteration*/
@@ -2020,7 +755,8 @@ static void qInvokeTestMethodDataEntry(char *slot)
/* Benchmarking: for each accumulation iteration*/
bool invokeOk;
do {
- invokeMethod(QTest::currentTestObject, "init()");
+ if (m_initMethod.isValid())
+ m_initMethod.invoke(QTest::currentTestObject, Qt::DirectConnection);
if (QTestResult::skipCurrentTest() || QTestResult::currentTestFailed())
break;
@@ -2032,8 +768,7 @@ static void qInvokeTestMethodDataEntry(char *slot)
QTestResult::currentDataTag()
? QTestResult::currentDataTag() : "");
- invokeOk = QMetaObject::invokeMethod(QTest::currentTestObject, slot,
- Qt::DirectConnection);
+ invokeOk = m_methods[index].invoke(QTest::currentTestObject, Qt::DirectConnection);
if (!invokeOk)
QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__);
@@ -2041,7 +776,8 @@ static void qInvokeTestMethodDataEntry(char *slot)
QTestResult::finishedCurrentTestData();
- invokeMethod(QTest::currentTestObject, "cleanup()");
+ if (m_cleanupMethod.isValid())
+ m_cleanupMethod.invoke(QTest::currentTestObject, Qt::DirectConnection);
// If the test isn't a benchmark, finalize the result after cleanup() has finished.
if (!isBenchmark)
@@ -2132,7 +868,7 @@ public:
int t = timeout.load();
if (!t)
break;
- if (!waitCondition.wait(&mutex, t)) {
+ if (Q_UNLIKELY(!waitCondition.wait(&mutex, t))) {
stackTrace();
qFatal("Test function timed out");
}
@@ -2155,21 +891,18 @@ private:
If the function was successfully called, true is returned, otherwise
false.
*/
-static bool qInvokeTestMethod(const char *slotName, const char *data, WatchDog *watchDog)
+bool TestMethods::invokeTest(int index, const char *data, WatchDog *watchDog) const
{
- QTEST_ASSERT(slotName);
-
QBenchmarkTestMethodData benchmarkData;
QBenchmarkTestMethodData::current = &benchmarkData;
- QBenchmarkGlobalData::current->context.slotName = QLatin1String(slotName);
+ const QByteArray &name = m_methods[index].name();
+ QBenchmarkGlobalData::current->context.slotName = QLatin1String(name) + QStringLiteral("()");
char member[512];
QTestTable table;
- char *slot = qstrdup(slotName);
- slot[strlen(slot) - 2] = '\0';
- QTestResult::setCurrentTestFunction(slot);
+ QTestResult::setCurrentTestFunction(name.constData());
const QTestTable *gTable = QTestTable::globalTestTable();
const int globalDataCount = gTable->dataCount();
@@ -2181,7 +914,7 @@ static bool qInvokeTestMethod(const char *slotName, const char *data, WatchDog *
QTestResult::setCurrentGlobalTestData(gTable->testData(curGlobalDataIndex));
if (curGlobalDataIndex == 0) {
- qsnprintf(member, 512, "%s_data()", slot);
+ qsnprintf(member, 512, "%s_data()", name.constData());
invokeMethod(QTest::currentTestObject, member);
}
@@ -2196,7 +929,7 @@ static bool qInvokeTestMethod(const char *slotName, const char *data, WatchDog *
if (!*data)
data = 0;
else {
- fprintf(stderr, "Unknown testdata for function %s: '%s'\n", slotName, data);
+ fprintf(stderr, "Unknown testdata for function %s(): '%s'\n", name.constData(), data);
fprintf(stderr, "Function has no testdata.\n");
return false;
}
@@ -2209,14 +942,14 @@ static bool qInvokeTestMethod(const char *slotName, const char *data, WatchDog *
if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) {
foundFunction = true;
- QTestPrivate::checkBlackLists(slot, dataCount ? table.testData(curDataIndex)->dataTag() : 0);
+ QTestPrivate::checkBlackLists(name.constData(), dataCount ? table.testData(curDataIndex)->dataTag() : 0);
QTestDataSetter s(curDataIndex >= dataCount ? static_cast<QTestData *>(0)
: table.testData(curDataIndex));
if (watchDog)
watchDog->beginTest();
- qInvokeTestMethodDataEntry(slot);
+ invokeTestOnData(index);
if (watchDog)
watchDog->testFinished();
@@ -2228,7 +961,7 @@ static bool qInvokeTestMethod(const char *slotName, const char *data, WatchDog *
}
if (data && !foundFunction) {
- fprintf(stderr, "Unknown testdata for function %s: '%s'\n", slotName, data);
+ fprintf(stderr, "Unknown testdata for function %s: '%s()'\n", name.constData(), data);
fprintf(stderr, "Available testdata:\n");
for (int i = 0; i < table.dataCount(); ++i)
fprintf(stderr, "%s\n", table.testData(i)->dataTag());
@@ -2243,7 +976,6 @@ static bool qInvokeTestMethod(const char *slotName, const char *data, WatchDog *
QTestResult::setSkipCurrentTest(false);
QTestResult::setBlacklistCurrentTest(false);
QTestResult::setCurrentTestData(0);
- delete[] slot;
return true;
}
@@ -2256,12 +988,12 @@ void *fetchData(QTestData *data, const char *tagName, int typeId)
int idx = data->parent()->indexOf(tagName);
- if (idx == -1 || idx >= data->dataCount()) {
+ if (Q_UNLIKELY(idx == -1 || idx >= data->dataCount())) {
qFatal("QFETCH: Requested testdata '%s' not available, check your _data function.",
tagName);
}
- if (typeId != data->parent()->elementTypeId(idx)) {
+ if (Q_UNLIKELY(typeId != data->parent()->elementTypeId(idx))) {
qFatal("Requested type '%s' does not match available type '%s'.",
QMetaType::typeName(typeId),
QMetaType::typeName(data->parent()->elementTypeId(idx)));
@@ -2521,21 +1253,23 @@ static bool debuggerPresent()
#endif
}
-static void qInvokeTestMethods(QObject *testObject)
+void TestMethods::invokeTests(QObject *testObject) const
{
const QMetaObject *metaObject = testObject->metaObject();
QTEST_ASSERT(metaObject);
QTestLog::startLogging();
QTestResult::setCurrentTestFunction("initTestCase");
QTestTable::globalTestTable();
- invokeMethod(testObject, "initTestCase_data()");
+ if (m_initTestCaseDataMethod.isValid())
+ m_initTestCaseDataMethod.invoke(testObject, Qt::DirectConnection);
QScopedPointer<WatchDog> watchDog;
if (!debuggerPresent())
watchDog.reset(new WatchDog);
if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) {
- invokeMethod(testObject, "initTestCase()");
+ if (m_initTestCaseMethod.isValid())
+ m_initTestCaseMethod.invoke(testObject, Qt::DirectConnection);
// finishedCurrentTestDataCleanup() resets QTestResult::currentTestFailed(), so use a local copy.
const bool previousFailed = QTestResult::currentTestFailed();
@@ -2544,35 +1278,22 @@ static void qInvokeTestMethods(QObject *testObject)
QTestResult::finishedCurrentTestFunction();
if (!QTestResult::skipCurrentTest() && !previousFailed) {
-
- if (QTest::testFuncs) {
- for (int i = 0; i != QTest::testFuncCount; i++) {
- if (!qInvokeTestMethod(metaObject->method(QTest::testFuncs[i].function()).methodSignature().constData(),
- QTest::testFuncs[i].data(), watchDog.data())) {
- break;
- }
- }
- testFuncCleaner.cleanup();
- } else {
- int methodCount = metaObject->methodCount();
- QMetaMethod *testMethods = new QMetaMethod[methodCount];
- for (int i = 0; i != methodCount; i++)
- testMethods[i] = metaObject->method(i);
- for (int i = 0; i != methodCount; i++) {
- if (!isValidSlot(testMethods[i]))
- continue;
- if (!qInvokeTestMethod(testMethods[i].methodSignature().constData(), 0, watchDog.data()))
- break;
- }
- delete[] testMethods;
- testMethods = 0;
+ for (int i = 0, count = int(m_methods.size()); i < count; ++i) {
+ const char *data = Q_NULLPTR;
+ if (i < QTest::testTags.size() && !QTest::testTags.at(i).isEmpty())
+ data = qstrdup(QTest::testTags.at(i).toLatin1().constData());
+ const bool ok = invokeTest(i, data, watchDog.data());
+ delete [] data;
+ if (!ok)
+ break;
}
}
QTestResult::setSkipCurrentTest(false);
QTestResult::setBlacklistCurrentTest(false);
QTestResult::setCurrentTestFunction("cleanupTestCase");
- invokeMethod(testObject, "cleanupTestCase()");
+ if (m_cleanupTestCaseMethod.isValid())
+ m_cleanupTestCaseMethod.invoke(testObject, Qt::DirectConnection);
QTestResult::finishedCurrentTestData();
QTestResult::finishedCurrentTestDataCleanup();
}
@@ -2940,7 +1661,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
#ifdef QTESTLIB_USE_VALGRIND
if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) {
- if (!qApp)
+ if (Q_UNLIKELY(!qApp))
qFatal("QtTest: -callgrind option is not available with QTEST_APPLESS_MAIN");
const QStringList origAppArgs(QCoreApplication::arguments());
@@ -2957,7 +1678,23 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
if (!noCrashHandler)
handler.reset(new FatalSignalHandler);
#endif
- qInvokeTestMethods(testObject);
+ TestMethods::MetaMethods commandLineMethods;
+ if (!QTest::testFunctions.isEmpty()) {
+ foreach (const QString &tf, QTest::testFunctions) {
+ const QByteArray tfB = tf.toLatin1();
+ const QByteArray signature = tfB + QByteArrayLiteral("()");
+ QMetaMethod m = TestMethods::findMethod(testObject, signature.constData());
+ if (!m.isValid() || !isValidSlot(m)) {
+ fprintf(stderr, "Unknown test function: '%s'. Possible matches:\n", tfB.constData());
+ qPrintTestSlots(stderr, tfB.constData());
+ fprintf(stderr, "\n%s -functions\nlists all available test functions.\n", argv[0]);
+ exit(1);
+ }
+ commandLineMethods.push_back(m);
+ }
+ }
+ TestMethods test(testObject, commandLineMethods);
+ test.invokeTests(testObject);
}
#ifndef QT_NO_EXCEPTIONS
@@ -3578,6 +2315,11 @@ bool QTest::compare_string_helper(const char *t1, const char *t2, const char *ac
toString(t1), toString(t2), actual, expected, file, line);
}
+/*!
+ \namespace QTest::Internal
+ \internal
+*/
+
/*! \fn bool QTest::compare_ptr_helper(const void *t1, const void *t2, const char *actual, const char *expected, const char *file, int line);
\internal
*/
diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc
new file mode 100644
index 0000000000..7e14a236bc
--- /dev/null
+++ b/src/testlib/qtestcase.qdoc
@@ -0,0 +1,1278 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \namespace QTest
+ \inmodule QtTest
+
+ \brief The QTest namespace contains all the functions and
+ declarations that are related to Qt Test.
+
+ See the \l{Qt Test Overview} for information about how to write unit tests.
+*/
+
+/*! \macro QVERIFY(condition)
+
+ \relates QTest
+
+ The QVERIFY() macro checks whether the \a condition is true or not. If it is
+ true, execution continues. If not, a failure is recorded in the test log
+ and the test won't be executed further.
+
+ \b {Note:} This macro can only be used in a test function that is invoked
+ by the test framework.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 0
+
+ \sa QCOMPARE(), QTRY_VERIFY()
+*/
+
+/*! \macro QVERIFY2(condition, message)
+
+ \relates QTest
+
+ The QVERIFY2() macro behaves exactly like QVERIFY(), except that it outputs
+ a verbose \a message when \a condition is false. The \a message is a plain
+ C string.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 1
+
+ \sa QVERIFY(), QCOMPARE()
+*/
+
+/*! \macro QCOMPARE(actual, expected)
+
+ \relates QTest
+
+ The QCOMPARE macro compares an \a actual value to an \a expected value using
+ the equals operator. If \a actual and \a expected are identical, execution
+ continues. If not, a failure is recorded in the test log and the test
+ won't be executed further.
+
+ In the case of comparing floats and doubles, qFuzzyCompare() is used for
+ comparing. This means that comparing to 0 will likely fail. One solution
+ to this is to compare to 1, and add 1 to the produced output.
+
+ QCOMPARE tries to output the contents of the values if the comparison fails,
+ so it is visible from the test log why the comparison failed.
+
+ QCOMPARE is very strict on the data types. Both \a actual and \a expected
+ have to be of the same type, otherwise the test won't compile. This prohibits
+ unspecified behavior from being introduced; that is behavior that usually
+ occurs when the compiler implicitly casts the argument.
+
+ For your own classes, you can use \l QTest::toString() to format values for
+ outputting into the test log.
+
+ \note This macro can only be used in a test function that is invoked
+ by the test framework.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 2
+
+ \sa QVERIFY(), QTRY_COMPARE(), QTest::toString()
+*/
+
+/*! \macro QVERIFY_EXCEPTION_THROWN(expression, exceptiontype)
+ \since 5.3
+
+ \relates QTest
+
+ The QVERIFY_EXCEPTION_THROWN macro executes an \a expression and tries
+ to catch an exception thrown from the \a expression. If the \a expression
+ throws an exception and its type is the same as \a exceptiontype
+ or \a exceptiontype is substitutable with the type of thrown exception
+ (i.e. usually the type of thrown exception is publically derived
+ from \a exceptiontype) then execution will be continued. If not-substitutable
+ type of exception is thrown or the \a expression doesn't throw an exception
+ at all, then a failure will be recorded in the test log and
+ the test won't be executed further.
+
+ \note This macro can only be used in a test function that is invoked
+ by the test framework.
+*/
+
+/*! \macro QTRY_VERIFY_WITH_TIMEOUT(condition, timeout)
+ \since 5.0
+
+ \relates QTest
+
+ The QTRY_VERIFY_WITH_TIMEOUT() macro is similar to QVERIFY(), but checks the \a condition
+ repeatedly, until either the condition becomes true or the \a timeout is
+ reached. Between each evaluation, events will be processed. If the timeout
+ is reached, a failure is recorded in the test log and the test won't be
+ executed further.
+
+ \note This macro can only be used in a test function that is invoked
+ by the test framework.
+
+ \sa QTRY_VERIFY(), QTRY_VERIFY2_WITH_TIMEOUT(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
+*/
+
+
+/*! \macro QTRY_VERIFY(condition)
+ \since 5.0
+
+ \relates QTest
+
+ Checks the \a condition by invoking QTRY_VERIFY_WITH_TIMEOUT() with a timeout of five seconds.
+
+ \note This macro can only be used in a test function that is invoked
+ by the test framework.
+
+ \sa QTRY_VERIFY_WITH_TIMEOUT(), QTRY_VERIFY2(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
+*/
+
+/*! \macro QTRY_VERIFY2_WITH_TIMEOUT(condition, message, timeout)
+ \since 5.6
+
+ \relates QTest
+
+ The QTRY_VERIFY2_WITH_TIMEOUT macro is similar to QTRY_VERIFY_WITH_TIMEOUT()
+ except that it outputs a verbose \a message when \a condition is still false
+ after the specified \a timeout. The \a message is a plain C string.
+
+ Example:
+ \code
+ QTRY_VERIFY2_WITH_TIMEOUT(list.size() > 2, QByteArray::number(list.size()).constData(), 10000);
+ \endcode
+
+ \note This macro can only be used in a test function that is invoked
+ by the test framework.
+
+ \sa QTRY_VERIFY(), QTRY_VERIFY_WITH_TIMEOUT(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
+*/
+
+/*! \macro QTRY_VERIFY2(condition, message)
+ \since 5.6
+
+ \relates QTest
+
+ Checks the \a condition by invoking QTRY_VERIFY2_WITH_TIMEOUT() with a timeout
+ of five seconds. If \a condition is then still false, \a message is output.
+ The \a message is a plain C string.
+
+ Example:
+ \code
+ QTRY_VERIFY2_WITH_TIMEOUT(list.size() > 2, QByteArray::number(list.size()).constData());
+ \endcode
+
+ \note This macro can only be used in a test function that is invoked
+ by the test framework.
+
+ \sa QTRY_VERIFY2_WITH_TIMEOUT(), QTRY_VERIFY2(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
+*/
+
+/*! \macro QTRY_COMPARE_WITH_TIMEOUT(actual, expected, timeout)
+ \since 5.0
+
+ \relates QTest
+
+ The QTRY_COMPARE_WITH_TIMEOUT() macro is similar to QCOMPARE(), but performs the comparison
+ of the \a actual and \a expected values repeatedly, until either the two values
+ are equal or the \a timeout is reached. Between each comparison, events
+ will be processed. If the timeout is reached, a failure is recorded in the
+ test log and the test won't be executed further.
+
+ \note This macro can only be used in a test function that is invoked
+ by the test framework.
+
+ \sa QTRY_COMPARE(), QCOMPARE(), QVERIFY(), QTRY_VERIFY()
+*/
+
+/*! \macro QTRY_COMPARE(actual, expected)
+ \since 5.0
+
+ \relates QTest
+
+ Performs a comparison of the \a actual and \a expected values by
+ invoking QTRY_COMPARE_WITH_TIMEOUT() with a timeout of five seconds.
+
+ \note This macro can only be used in a test function that is invoked
+ by the test framework.
+
+ \sa QTRY_COMPARE_WITH_TIMEOUT(), QCOMPARE(), QVERIFY(), QTRY_VERIFY()
+*/
+
+/*! \macro QFETCH(type, name)
+
+ \relates QTest
+
+ The fetch macro creates a local variable named \a name with the type \a type
+ on the stack. \a name has to match the element name from the test's data.
+ If no such element exists, the test will assert.
+
+ Assuming a test has the following data:
+
+ \snippet code/src_qtestlib_qtestcase.cpp 3
+
+ The test data has two elements, a QString called \c aString and an integer
+ called \c expected. To fetch these values in the actual test:
+
+ \snippet code/src_qtestlib_qtestcase.cpp 4
+
+ \c aString and \c expected are variables on the stack that are initialized with
+ the current test data.
+
+ \b {Note:} This macro can only be used in a test function that is invoked
+ by the test framework. The test function must have a _data function.
+*/
+
+/*! \macro QWARN(message)
+
+ \relates QTest
+ \threadsafe
+
+ Appends \a message as a warning to the test log. This macro can be used anywhere
+ in your tests.
+*/
+
+/*! \macro QFAIL(message)
+
+ \relates QTest
+
+ This macro can be used to force a test failure. The test stops
+ executing and the failure \a message is appended to the test log.
+
+ \b {Note:} This macro can only be used in a test function that is invoked
+ by the test framework.
+
+ Example:
+
+ \snippet code/src_qtestlib_qtestcase.cpp 5
+*/
+
+/*! \macro QTEST(actual, testElement)
+
+ \relates QTest
+
+ QTEST() is a convenience macro for \l QCOMPARE() that compares
+ the value \a actual with the element \a testElement from the test's data.
+ If there is no such element, the test asserts.
+
+ Apart from that, QTEST() behaves exactly as \l QCOMPARE().
+
+ Instead of writing:
+
+ \snippet code/src_qtestlib_qtestcase.cpp 6
+
+ you can write:
+
+ \snippet code/src_qtestlib_qtestcase.cpp 7
+
+ \sa QCOMPARE()
+*/
+
+/*! \macro QSKIP(description)
+
+ \relates QTest
+
+ If called from a test function, the QSKIP() macro stops execution of the test
+ without adding a failure to the test log. You can use it to skip tests that
+ wouldn't make sense in the current configuration. The text \a description is
+ appended to the test log and should contain an explanation of why the test
+ couldn't be executed.
+
+ If the test is data-driven, each call to QSKIP() will skip only the current
+ row of test data, so an unconditional call to QSKIP will produce one skip
+ message in the test log for each row of test data.
+
+ If called from an _data function, the QSKIP() macro will stop execution of
+ the _data function and will prevent execution of the associated test
+ function.
+
+ If called from initTestCase() or initTestCase_data(), the QSKIP() macro will
+ skip all test and _data functions.
+
+ \b {Note:} This macro can only be used in a test function or _data
+ function that is invoked by the test framework.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 8
+*/
+
+/*! \macro QEXPECT_FAIL(dataIndex, comment, mode)
+
+ \relates QTest
+
+ The QEXPECT_FAIL() macro marks the next \l QCOMPARE() or \l QVERIFY() as an
+ expected failure. Instead of adding a failure to the test log, an expected
+ failure will be reported.
+
+ If a \l QVERIFY() or \l QCOMPARE() is marked as an expected failure,
+ but passes instead, an unexpected pass (XPASS) is written to the test log.
+
+ The parameter \a dataIndex describes for which entry in the test data the
+ failure is expected. Pass an empty string (\c{""}) if the failure
+ is expected for all entries or if no test data exists.
+
+ \a comment will be appended to the test log for the expected failure.
+
+ \a mode is a \l QTest::TestFailMode and sets whether the test should
+ continue to execute or not.
+
+ \b {Note:} This macro can only be used in a test function that is invoked
+ by the test framework.
+
+ Example 1:
+ \snippet code/src_qtestlib_qtestcase.cpp 9
+
+ In the example above, an expected fail will be written into the test output
+ if the variable \c i is not 42. If the variable \c i is 42, an unexpected pass
+ is written instead. The QEXPECT_FAIL() has no influence on the second QCOMPARE()
+ statement in the example.
+
+ Example 2:
+ \snippet code/src_qtestlib_qtestcase.cpp 10
+
+ The above testfunction will not continue executing for the test data
+ entry \c{data27}.
+
+ \sa QTest::TestFailMode, QVERIFY(), QCOMPARE()
+*/
+
+/*! \macro QFINDTESTDATA(filename)
+ \since 5.0
+
+ \relates QTest
+
+ Returns a QString for the testdata file referred to by \a filename, or an
+ empty QString if the testdata file could not be found.
+
+ This macro allows the test to load data from an external file without
+ hardcoding an absolute filename into the test, or using relative paths
+ which may be error prone.
+
+ The returned path will be the first path from the following list which
+ resolves to an existing file or directory:
+
+ \list
+ \li \a filename relative to QCoreApplication::applicationDirPath()
+ (only if a QCoreApplication or QApplication object has been created).
+ \li \a filename relative to the test's standard install directory
+ (QLibraryInfo::TestsPath with the lowercased testcase name appended).
+ \li \a filename relative to the directory containing the source file from which
+ QFINDTESTDATA is invoked.
+ \endlist
+
+ If the named file/directory does not exist at any of these locations,
+ a warning is printed to the test log.
+
+ For example, in this code:
+ \snippet code/src_qtestlib_qtestcase.cpp 26
+
+ The testdata file will be resolved as the first existing file from:
+
+ \list
+ \li \c{/home/user/build/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
+ \li \c{/usr/local/Qt-5.0.0/tests/tst_myxmlparser/testxml/simple1.xml}
+ \li \c{/home/user/sources/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
+ \endlist
+
+ This allows the test to find its testdata regardless of whether the
+ test has been installed, and regardless of whether the test's build tree
+ is equal to the test's source tree.
+
+ \b {Note:} reliable detection of testdata from the source directory requires
+ either that qmake is used, or the \c{QT_TESTCASE_BUILDDIR} macro is defined to
+ point to the working directory from which the compiler is invoked, or only
+ absolute paths to the source files are passed to the compiler. Otherwise, the
+ absolute path of the source directory cannot be determined.
+
+ \b {Note:} For tests that use the \l QTEST_APPLESS_MAIN() macro to generate a
+ \c{main()} function, \c{QFINDTESTDATA} will not attempt to find test data
+ relative to QCoreApplication::applicationDirPath(). In practice, this means that
+ tests using \c{QTEST_APPLESS_MAIN()} will fail to find their test data
+ if run from a shadow build tree.
+*/
+
+/*! \macro QTEST_MAIN(TestClass)
+
+ \relates QTest
+
+ Implements a main() function that instantiates an application object and
+ the \a TestClass, and executes all tests in the order they were defined.
+ Use this macro to build stand-alone executables.
+
+ If \c QT_WIDGETS_LIB is defined, the application object will be a QApplication,
+ if \c QT_GUI_LIB is defined, the application object will be a QGuiApplication,
+ otherwise it will be a QCoreApplication. If qmake is used and the configuration
+ includes \c{QT += widgets}, then \c QT_WIDGETS_LIB will be defined automatically.
+ Similarly, if qmake is used and the configuration includes \c{QT += gui}, then
+ \c QT_GUI_LIB will be defined automatically.
+
+ \b {Note:} On platforms that have keypad navigation enabled by default,
+ this macro will forcefully disable it if \c QT_WIDGETS_LIB is defined. This is done
+ to simplify the usage of key events when writing autotests. If you wish to write a
+ test case that uses keypad navigation, you should enable it either in the
+ \c {initTestCase()} or \c {init()} functions of your test case by calling
+ \l {QApplication::setNavigationMode()}.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 11
+
+ \sa QTEST_APPLESS_MAIN(), QTEST_GUILESS_MAIN(), QTest::qExec(),
+ QApplication::setNavigationMode()
+*/
+
+/*! \macro QTEST_APPLESS_MAIN(TestClass)
+
+ \relates QTest
+
+ Implements a main() function that executes all tests in \a TestClass.
+
+ Behaves like \l QTEST_MAIN(), but doesn't instantiate a QApplication
+ object. Use this macro for really simple stand-alone non-GUI tests.
+
+ \sa QTEST_MAIN()
+*/
+
+/*! \macro QTEST_GUILESS_MAIN(TestClass)
+ \since 5.0
+
+ \relates QTest
+
+ Implements a main() function that instantiates a QCoreApplication object
+ and the \a TestClass, and executes all tests in the order they were
+ defined. Use this macro to build stand-alone executables.
+
+ Behaves like \l QTEST_MAIN(), but instantiates a QCoreApplication instead
+ of the QApplication object. Use this macro if your test case doesn't need
+ functionality offered by QApplication, but the event loop is still necessary.
+
+ \sa QTEST_MAIN()
+*/
+
+/*!
+ \macro QBENCHMARK
+
+ \relates QTest
+
+ This macro is used to measure the performance of code within a test.
+ The code to be benchmarked is contained within a code block following
+ this macro.
+
+ For example:
+
+ \snippet code/src_qtestlib_qtestcase.cpp 27
+
+ \sa {Qt Test Overview#Creating a Benchmark}{Creating a Benchmark},
+ {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
+*/
+
+/*!
+ \macro QBENCHMARK_ONCE
+ \since 4.6
+
+ \relates QTest
+
+ \brief The QBENCHMARK_ONCE macro is for measuring performance of a
+ code block by running it once.
+
+ This macro is used to measure the performance of code within a test.
+ The code to be benchmarked is contained within a code block following
+ this macro.
+
+ Unlike QBENCHMARK, the contents of the contained code block is only run
+ once. The elapsed time will be reported as "0" if it's to short to
+ be measured by the selected backend. (Use)
+
+ \sa {Qt Test Overview#Creating a Benchmark}{Creating a Benchmark},
+ {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
+*/
+
+/*! \enum QTest::TestFailMode
+
+ This enum describes the modes for handling an expected failure of the
+ \l QVERIFY() or \l QCOMPARE() macros.
+
+ \value Abort Aborts the execution of the test. Use this mode when it
+ doesn't make sense to execute the test any further after the
+ expected failure.
+
+ \value Continue Continues execution of the test after the expected failure.
+
+ \sa QEXPECT_FAIL()
+*/
+
+/*! \enum QTest::KeyAction
+
+ This enum describes possible actions for key handling.
+
+ \value Press The key is pressed.
+ \value Release The key is released.
+ \value Click The key is clicked (pressed and released).
+*/
+
+/*! \enum QTest::MouseAction
+
+ This enum describes possible actions for mouse handling.
+
+ \value MousePress A mouse button is pressed.
+ \value MouseRelease A mouse button is released.
+ \value MouseClick A mouse button is clicked (pressed and released).
+ \value MouseDClick A mouse button is double clicked (pressed and released twice).
+ \value MouseMove The mouse pointer has moved.
+*/
+
+/*! \fn void QTest::keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+
+ Simulates clicking of \a key with an optional \a modifier on a \a widget.
+ If \a delay is larger than 0, the test will wait for \a delay milliseconds
+ before clicking the key.
+
+ Examples:
+ \snippet code/src_qtestlib_qtestcase.cpp 14
+
+ The first example above simulates clicking the \c escape key on \c
+ myWidget without any keyboard modifiers and without delay. The
+ second example simulates clicking \c shift-escape on \c myWidget
+ following a 200 ms delay of the test.
+
+ \sa QTest::keyClicks()
+*/
+
+/*! \fn void QTest::keyClick(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+
+ Simulates clicking of \a key with an optional \a modifier on a \a widget.
+ If \a delay is larger than 0, the test will wait for \a delay milliseconds
+ before clicking the key.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 13
+
+ The example above simulates clicking \c a on \c myWidget without
+ any keyboard modifiers and without delay of the test.
+
+ \sa QTest::keyClicks()
+*/
+
+/*! \fn void QTest::keyClick(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+ \since 5.0
+
+ Simulates clicking of \a key with an optional \a modifier on a \a window.
+ If \a delay is larger than 0, the test will wait for \a delay milliseconds
+ before clicking the key.
+
+ Examples:
+ \snippet code/src_qtestlib_qtestcase.cpp 29
+
+ The first example above simulates clicking the \c escape key on \c
+ myWindow without any keyboard modifiers and without delay. The
+ second example simulates clicking \c shift-escape on \c myWindow
+ following a 200 ms delay of the test.
+
+ \sa QTest::keyClicks()
+*/
+
+/*! \fn void QTest::keyClick(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+ \since 5.0
+
+ Simulates clicking of \a key with an optional \a modifier on a \a window.
+ If \a delay is larger than 0, the test will wait for \a delay milliseconds
+ before clicking the key.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 28
+
+ The example above simulates clicking \c a on \c myWindow without
+ any keyboard modifiers and without delay of the test.
+
+ \sa QTest::keyClicks()
+*/
+
+/*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+
+ Sends a Qt key event to \a widget with the given \a key and an associated \a action.
+ Optionally, a keyboard \a modifier can be specified, as well as a \a delay
+ (in milliseconds) of the test before sending the event.
+*/
+
+/*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, char ascii, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+
+ Sends a Qt key event to \a widget with the given key \a ascii and an associated \a action.
+ Optionally, a keyboard \a modifier can be specified, as well as a \a delay
+ (in milliseconds) of the test before sending the event.
+*/
+
+/*! \fn void QTest::keyEvent(KeyAction action, QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+ \since 5.0
+
+ Sends a Qt key event to \a window with the given \a key and an associated \a action.
+ Optionally, a keyboard \a modifier can be specified, as well as a \a delay
+ (in milliseconds) of the test before sending the event.
+*/
+
+/*! \fn void QTest::keyEvent(KeyAction action, QWindow *window, char ascii, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+ \since 5.0
+
+ Sends a Qt key event to \a window with the given key \a ascii and an associated \a action.
+ Optionally, a keyboard \a modifier can be specified, as well as a \a delay
+ (in milliseconds) of the test before sending the event.
+*/
+
+/*! \fn void QTest::keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+
+ Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay
+ is larger than 0, the test will wait for \a delay milliseconds before pressing the key.
+
+ \b {Note:} At some point you should release the key using \l keyRelease().
+
+ \sa QTest::keyRelease(), QTest::keyClick()
+*/
+
+/*! \fn void QTest::keyPress(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+
+ Simulates pressing a \a key with an optional \a modifier on a \a widget.
+ If \a delay is larger than 0, the test will wait for \a delay milliseconds
+ before pressing the key.
+
+ \b {Note:} At some point you should release the key using \l keyRelease().
+
+ \sa QTest::keyRelease(), QTest::keyClick()
+*/
+
+/*! \fn void QTest::keyPress(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+ \since 5.0
+
+ Simulates pressing a \a key with an optional \a modifier on a \a window. If \a delay
+ is larger than 0, the test will wait for \a delay milliseconds before pressing the key.
+
+ \b {Note:} At some point you should release the key using \l keyRelease().
+
+ \sa QTest::keyRelease(), QTest::keyClick()
+*/
+
+/*! \fn void QTest::keyPress(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+ \since 5.0
+
+ Simulates pressing a \a key with an optional \a modifier on a \a window.
+ If \a delay is larger than 0, the test will wait for \a delay milliseconds
+ before pressing the key.
+
+ \b {Note:} At some point you should release the key using \l keyRelease().
+
+ \sa QTest::keyRelease(), QTest::keyClick()
+*/
+
+/*! \fn void QTest::keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+
+ Simulates releasing a \a key with an optional \a modifier on a \a widget.
+ If \a delay is larger than 0, the test will wait for \a delay milliseconds
+ before releasing the key.
+
+ \sa QTest::keyPress(), QTest::keyClick()
+*/
+
+/*! \fn void QTest::keyRelease(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+
+ Simulates releasing a \a key with an optional \a modifier on a \a widget.
+ If \a delay is larger than 0, the test will wait for \a delay milliseconds
+ before releasing the key.
+
+ \sa QTest::keyClick()
+*/
+
+/*! \fn void QTest::keyRelease(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+ \since 5.0
+
+ Simulates releasing a \a key with an optional \a modifier on a \a window.
+ If \a delay is larger than 0, the test will wait for \a delay milliseconds
+ before releasing the key.
+
+ \sa QTest::keyPress(), QTest::keyClick()
+*/
+
+/*! \fn void QTest::keyRelease(QWindow *window, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+ \overload
+ \since 5.0
+
+ Simulates releasing a \a key with an optional \a modifier on a \a window.
+ If \a delay is larger than 0, the test will wait for \a delay milliseconds
+ before releasing the key.
+
+ \sa QTest::keyClick()
+*/
+
+/*! \fn void QTest::keyClicks(QWidget *widget, const QString &sequence, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
+
+ Simulates clicking a \a sequence of keys on a \a
+ widget. Optionally, a keyboard \a modifier can be specified as
+ well as a \a delay (in milliseconds) of the test before each key
+ click.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 15
+
+ The example above simulates clicking the sequence of keys
+ representing "hello world" on \c myWidget without any keyboard
+ modifiers and without delay of the test.
+
+ \sa QTest::keyClick()
+*/
+
+/*! \fn void QTest::mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
+
+ Simulates pressing a mouse \a button with an optional \a modifier
+ on a \a widget. The position is defined by \a pos; the default
+ position is the center of the widget. If \a delay is specified,
+ the test will wait for the specified amount of milliseconds before
+ the press.
+
+ \sa QTest::mouseRelease(), QTest::mouseClick()
+*/
+
+/*! \fn void QTest::mousePress(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, QPoint pos = QPoint(), int delay=-1)
+ \overload
+ \since 5.0
+
+ Simulates pressing a mouse \a button with an optional \a stateKey modifier
+ on a \a window. The position is defined by \a pos; the default
+ position is the center of the window. If \a delay is specified,
+ the test will wait for the specified amount of milliseconds before
+ the press.
+
+ \sa QTest::mouseRelease(), QTest::mouseClick()
+*/
+
+/*! \fn void QTest::mouseRelease(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
+
+ Simulates releasing a mouse \a button with an optional \a modifier
+ on a \a widget. The position of the release is defined by \a pos;
+ the default position is the center of the widget. If \a delay is
+ specified, the test will wait for the specified amount of
+ milliseconds before releasing the button.
+
+ \sa QTest::mousePress(), QTest::mouseClick()
+*/
+
+/*! \fn void QTest::mouseRelease(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, QPoint pos = QPoint(), int delay=-1)
+ \overload
+ \since 5.0
+
+ Simulates releasing a mouse \a button with an optional \a stateKey modifier
+ on a \a window. The position of the release is defined by \a pos;
+ the default position is the center of the window. If \a delay is
+ specified, the test will wait for the specified amount of
+ milliseconds before releasing the button.
+
+ \sa QTest::mousePress(), QTest::mouseClick()
+*/
+
+/*! \fn void QTest::mouseClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
+
+ Simulates clicking a mouse \a button with an optional \a modifier
+ on a \a widget. The position of the click is defined by \a pos;
+ the default position is the center of the widget. If \a delay is
+ specified, the test will wait for the specified amount of
+ milliseconds before pressing and before releasing the button.
+
+ \sa QTest::mousePress(), QTest::mouseRelease()
+*/
+
+/*! \fn void QTest::mouseClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, QPoint pos = QPoint(), int delay=-1)
+ \overload
+ \since 5.0
+
+ Simulates clicking a mouse \a button with an optional \a stateKey modifier
+ on a \a window. The position of the click is defined by \a pos;
+ the default position is the center of the window. If \a delay is
+ specified, the test will wait for the specified amount of
+ milliseconds before pressing and before releasing the button.
+
+ \sa QTest::mousePress(), QTest::mouseRelease()
+*/
+
+/*! \fn void QTest::mouseDClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
+
+ Simulates double clicking a mouse \a button with an optional \a
+ modifier on a \a widget. The position of the click is defined by
+ \a pos; the default position is the center of the widget. If \a
+ delay is specified, the test will wait for the specified amount of
+ milliseconds before each press and release.
+
+ \sa QTest::mouseClick()
+*/
+
+/*! \fn void QTest::mouseDClick(QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = 0, QPoint pos = QPoint(), int delay=-1)
+ \overload
+ \since 5.0
+
+ Simulates double clicking a mouse \a button with an optional \a stateKey
+ modifier on a \a window. The position of the click is defined by
+ \a pos; the default position is the center of the window. If \a
+ delay is specified, the test will wait for the specified amount of
+ milliseconds before each press and release.
+
+ \sa QTest::mouseClick()
+*/
+
+/*! \fn void QTest::mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay=-1)
+
+ Moves the mouse pointer to a \a widget. If \a pos is not
+ specified, the mouse pointer moves to the center of the widget. If
+ a \a delay (in milliseconds) is given, the test will wait before
+ moving the mouse pointer.
+*/
+
+/*! \fn void QTest::mouseMove(QWindow *window, QPoint pos = QPoint(), int delay=-1)
+ \overload
+ \since 5.0
+
+ Moves the mouse pointer to a \a window. If \a pos is not
+ specified, the mouse pointer moves to the center of the window. If
+ a \a delay (in milliseconds) is given, the test will wait before
+ moving the mouse pointer.
+*/
+
+/*!
+ \fn char *QTest::toString(const T &value)
+
+ Returns a textual representation of \a value. This function is used by
+ \l QCOMPARE() to output verbose information in case of a test failure.
+
+ You can add specializations or overloads of this function to your test to enable
+ verbose output.
+
+ \b {Note:} Starting with Qt 5.5, you should prefer to provide a toString() function
+ in the type's namespace instead of specializing this template.
+ If your code needs to continue to work with the QTestLib from Qt 5.4 or
+ earlier, you need to continue to use specialization.
+
+ \b {Note:} The caller of toString() must delete the returned data
+ using \c{delete[]}. Your implementation should return a string
+ created with \c{new[]} or qstrdup(). The easiest way to do so is to
+ create a QByteArray or QString and calling QTest::toString() on it
+ (see second example below).
+
+ Example for specializing (Qt ≤ 5.4):
+
+ \snippet code/src_qtestlib_qtestcase.cpp 16
+
+ The example above defines a toString() specialization for a class
+ called \c MyPoint. Whenever a comparison of two instances of \c
+ MyPoint fails, \l QCOMPARE() will call this function to output the
+ contents of \c MyPoint to the test log.
+
+ Same example, but with overloading (Qt ≥ 5.5):
+
+ \snippet code/src_qtestlib_qtestcase.cpp toString-overload
+
+ \sa QCOMPARE()
+*/
+
+/*!
+ \fn char *QTest::toString(const QLatin1String &string)
+ \overload
+
+ Returns a textual representation of the given \a string.
+*/
+
+/*!
+ \fn char *QTest::toString(const QString &string)
+ \overload
+
+ Returns a textual representation of the given \a string.
+*/
+
+/*!
+ \fn char *QTest::toString(const QByteArray &ba)
+ \overload
+
+ Returns a textual representation of the byte array \a ba.
+
+ \sa QTest::toHexRepresentation()
+*/
+
+/*!
+ \fn char *QTest::toString(const QTime &time)
+ \overload
+
+ Returns a textual representation of the given \a time.
+*/
+
+/*!
+ \fn char *QTest::toString(const QDate &date)
+ \overload
+
+ Returns a textual representation of the given \a date.
+*/
+
+/*!
+ \fn char *QTest::toString(const QDateTime &dateTime)
+ \overload
+
+ Returns a textual representation of the date and time specified by
+ \a dateTime.
+*/
+
+/*!
+ \fn char *QTest::toString(const QChar &character)
+ \overload
+
+ Returns a textual representation of the given \a character.
+*/
+
+/*!
+ \fn char *QTest::toString(const QPoint &point)
+ \overload
+
+ Returns a textual representation of the given \a point.
+*/
+
+/*!
+ \fn char *QTest::toString(const QSize &size)
+ \overload
+
+ Returns a textual representation of the given \a size.
+*/
+
+/*!
+ \fn char *QTest::toString(const QRect &rectangle)
+ \overload
+
+ Returns a textual representation of the given \a rectangle.
+*/
+
+/*!
+ \fn char *QTest::toString(const QUrl &url)
+ \since 4.4
+ \overload
+
+ Returns a textual representation of the given \a url.
+*/
+
+/*!
+ \fn char *QTest::toString(const QPointF &point)
+ \overload
+
+ Returns a textual representation of the given \a point.
+*/
+
+/*!
+ \fn char *QTest::toString(const QSizeF &size)
+ \overload
+
+ Returns a textual representation of the given \a size.
+*/
+
+/*!
+ \fn char *QTest::toString(const QRectF &rectangle)
+ \overload
+
+ Returns a textual representation of the given \a rectangle.
+*/
+
+/*!
+ \fn char *QTest::toString(const QVariant &variant)
+ \overload
+
+ Returns a textual representation of the given \a variant.
+*/
+
+/*!
+ \fn char *QTest::toString(QSizePolicy::ControlType ct)
+ \overload
+ \since 5.5
+
+ Returns a textual representation of control type \a ct.
+*/
+
+/*!
+ \fn char *QTest::toString(QSizePolicy::ControlTypes cts)
+ \overload
+ \since 5.5
+
+ Returns a textual representation of control types \a cts.
+*/
+
+/*!
+ \fn char *QTest::toString(QSizePolicy::Policy p)
+ \overload
+ \since 5.5
+
+ Returns a textual representation of policy \a p.
+*/
+
+/*!
+ \fn char *QTest::toString(QSizePolicy sp)
+ \overload
+ \since 5.5
+
+ Returns a textual representation of size policy \a sp.
+*/
+
+/*! \fn void QTest::qWait(int ms)
+
+ Waits for \a ms milliseconds. While waiting, events will be processed and
+ your test will stay responsive to user interface events or network communication.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 17
+
+ The code above will wait until the network server is responding for a
+ maximum of about 12.5 seconds.
+
+ \sa QTest::qSleep(), QSignalSpy::wait()
+*/
+
+/*! \fn bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
+ \since 5.0
+
+ Waits for \a timeout milliseconds or until the \a window is exposed.
+ Returns \c true if \c window is exposed within \a timeout milliseconds, otherwise returns \c false.
+
+ This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
+ time after being asked to show itself on the screen.
+
+ \sa QTest::qWaitForWindowActive(), QWindow::isExposed()
+*/
+
+/*! \fn bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
+ \since 5.0
+
+ Waits for \a timeout milliseconds or until the \a window is active.
+
+ Returns \c true if \c window is active within \a timeout milliseconds, otherwise returns \c false.
+
+ \sa QTest::qWaitForWindowExposed(), QWindow::isActive()
+*/
+
+/*! \fn bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout)
+ \since 5.0
+
+ Waits for \a timeout milliseconds or until the \a widget's window is exposed.
+ Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
+
+ This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
+ time after being asked to show itself on the screen.
+
+ \sa QTest::qWaitForWindowActive()
+*/
+
+/*! \fn bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
+ \since 5.0
+
+ Waits for \a timeout milliseconds or until the \a widget's window is active.
+
+ Returns \c true if \c widget's window is active within \a timeout milliseconds, otherwise returns \c false.
+
+ \sa QTest::qWaitForWindowExposed(), QWidget::isActiveWindow()
+*/
+
+/*! \fn bool QTest::qWaitForWindowShown(QWidget *widget, int timeout)
+ \since 5.0
+ \deprecated
+
+ Waits for \a timeout milliseconds or until the \a widget's window is exposed.
+ Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false.
+
+ This function does the same as qWaitForWindowExposed().
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 24
+
+ \sa QTest::qWaitForWindowActive(), QTest::qWaitForWindowExposed()
+*/
+
+/*!
+ \class QTest::QTouchEventSequence
+ \inmodule QtTest
+ \since 4.6
+
+ \brief The QTouchEventSequence class is used to simulate a sequence of touch events.
+
+ To simulate a sequence of touch events on a specific device for a window or widget, call
+ QTest::touchEvent to create a QTouchEventSequence instance. Add touch events to
+ the sequence by calling press(), move(), release() and stationary(), and let the
+ instance run out of scope to commit the sequence to the event system.
+
+ Example:
+ \snippet code/src_qtestlib_qtestcase.cpp 25
+*/
+
+/*!
+ \fn QTest::QTouchEventSequence::~QTouchEventSequence()
+
+ Commits this sequence of touch events, unless autoCommit was disabled, and frees allocated resources.
+*/
+
+/*!
+ \fn void QTest::QTouchEventSequence::commit(bool processEvents)
+
+ Commits this sequence of touch events to the event system. Normally there is no need to call this
+ function because it is called from the destructor. However, if autoCommit is disabled, the events
+ only get committed upon explicitly calling this function.
+
+ In special cases tests may want to disable the processing of the events. This can be achieved by
+ setting \a processEvents to false. This results in merely queuing the events, the event loop will
+ not be forced to process them.
+*/
+
+/*!
+ \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWindow *window)
+ \since 5.0
+
+ Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns
+ a reference to this QTouchEventSequence.
+
+ The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
+ \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
+
+ Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId.
+*/
+
+/*!
+ \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWidget *widget)
+
+ Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns
+ a reference to this QTouchEventSequence.
+
+ The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
+ \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
+
+ Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId.
+*/
+
+/*!
+ \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWindow *window)
+ \since 5.0
+
+ Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns
+ a reference to this QTouchEventSequence.
+
+ The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
+ \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
+
+ Simulates that the user moved the finger identified by \a touchId.
+*/
+
+/*!
+ \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWidget *widget)
+
+ Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns
+ a reference to this QTouchEventSequence.
+
+ The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
+ \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
+
+ Simulates that the user moved the finger identified by \a touchId.
+*/
+
+/*!
+ \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWindow *window)
+ \since 5.0
+
+ Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns
+ a reference to this QTouchEventSequence.
+
+ The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
+ \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
+
+ Simulates that the user lifted the finger identified by \a touchId.
+*/
+
+/*!
+ \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWidget *widget)
+
+ Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns
+ a reference to this QTouchEventSequence.
+
+ The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
+ \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
+
+ Simulates that the user lifted the finger identified by \a touchId.
+*/
+
+/*!
+ \fn QTouchEventSequence &QTest::QTouchEventSequence::stationary(int touchId)
+
+ Adds a stationary event for touchpoint \a touchId to this sequence and returns
+ a reference to this QTouchEventSequence.
+
+ Simulates that the user did not move the finger identified by \a touchId.
+*/
+
+/*!
+ \fn QTouchEventSequence QTest::touchEvent(QWindow *window, QTouchDevice *device, bool autoCommit)
+ \since 5.0
+
+ Creates and returns a QTouchEventSequence for the \a device to
+ simulate events for \a window.
+
+ When adding touch events to the sequence, \a window will also be used to translate
+ the position provided to screen coordinates, unless another window is provided in the
+ respective calls to press(), move() etc.
+
+ The touch events are committed to the event system when the destructor of the
+ QTouchEventSequence is called (ie when the object returned runs out of scope), unless
+ \a autoCommit is set to false. When \a autoCommit is false, commit() has to be called
+ manually.
+*/
+
+/*!
+ \fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QTouchDevice *device, bool autoCommit)
+
+ Creates and returns a QTouchEventSequence for the \a device to
+ simulate events for \a widget.
+
+ When adding touch events to the sequence, \a widget will also be used to translate
+ the position provided to screen coordinates, unless another widget is provided in the
+ respective calls to press(), move() etc.
+
+ The touch events are committed to the event system when the destructor of the
+ QTouchEventSequence is called (ie when the object returned runs out of scope), unless
+ \a autoCommit is set to false. When \a autoCommit is false, commit() has to be called
+ manually.
+*/
+
+// Internals of qtestmouse.h:
+
+/*! \fn void QTest::waitForEvents()
+ \internal
+*/
+
+/*! \fn void QTest::mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
+ \internal
+*/
+
+/*! \fn void QTest::mouseEvent(MouseAction action, QWindow *window, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
+ \internal
+*/
diff --git a/src/testlib/qxctestlogger.mm b/src/testlib/qxctestlogger.mm
index 34116a2670..1e9119c9c0 100644
--- a/src/testlib/qxctestlogger.mm
+++ b/src/testlib/qxctestlogger.mm
@@ -124,7 +124,7 @@ private:
if (![XCTestProbe isTesting])
return;
- if (!([NSDate timeIntervalSinceReferenceDate] > 0))
+ if (Q_UNLIKELY(!([NSDate timeIntervalSinceReferenceDate] > 0)))
qFatal("error: Device date '%s' is bad, likely set to update automatically. Please correct.",
[[NSDate date] description].UTF8String);
diff --git a/src/tools/moc/parser.h b/src/tools/moc/parser.h
index 947e472dae..6b281eb339 100644
--- a/src/tools/moc/parser.h
+++ b/src/tools/moc/parser.h
@@ -34,9 +34,10 @@
#ifndef PARSER_H
#define PARSER_H
-#include <qstack.h>
#include "symbols.h"
+#include <stack>
+
QT_BEGIN_NAMESPACE
class Parser
@@ -57,7 +58,7 @@ public:
};
QList<IncludePath> includes;
- QStack<QByteArray> currentFilenames;
+ std::stack<QByteArray, QByteArrayList> currentFilenames;
inline bool hasNext() const { return (index < symbols.size()); }
inline Token next() { if (index >= symbols.size()) return NOTOKEN; return symbols.at(index++).token; }
diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp
index a2a1a958cf..a47896d722 100644
--- a/src/tools/moc/preprocessor.cpp
+++ b/src/tools/moc/preprocessor.cpp
@@ -154,6 +154,11 @@ bool Preprocessor::skipBranch()
Symbols Preprocessor::tokenize(const QByteArray& input, int lineNum, Preprocessor::TokenizeMode mode)
{
Symbols symbols;
+ // Preallocate some space to speed up the code below.
+ // The magic divisor value was found by calculating the average ratio between
+ // input size and the final size of symbols.
+ // This yielded a value of 16.x when compiling Qt Base.
+ symbols.reserve(input.size() / 16);
const char *begin = input.constData();
const char *data = begin;
while (*data) {
@@ -1217,6 +1222,10 @@ Symbols Preprocessor::preprocessed(const QByteArray &filename, QFile *file)
// phase 3: preprocess conditions and substitute macros
Symbols result;
+ // Preallocate some space to speed up the code below.
+ // The magic value was found by logging the final size
+ // and calculating an average when running moc over FOSS projects.
+ result.reserve(file->size() / 300000);
preprocess(filename, result);
mergeStringLiterals(&result);
diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp
index d8d5728414..1405f19a3a 100644
--- a/src/tools/rcc/main.cpp
+++ b/src/tools/rcc/main.cpp
@@ -304,7 +304,7 @@ int main(int argc, char *argv[])
{
// rcc uses a QHash to store files in the resource system.
// we must force a certain hash order when testing or tst_rcc will fail, see QTBUG-25078
- if (!qEnvironmentVariableIsEmpty("QT_RCC_TEST") && !qt_qhash_seed.testAndSetRelaxed(-1, 0))
+ if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QT_RCC_TEST") && !qt_qhash_seed.testAndSetRelaxed(-1, 0)))
qFatal("Cannot force QHash seed for testing as requested");
return QT_PREPEND_NAMESPACE(runRcc)(argc, argv);
diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp
index 1b724c9a17..a7c1c75066 100644
--- a/src/widgets/accessible/itemviews.cpp
+++ b/src/widgets/accessible/itemviews.cpp
@@ -132,7 +132,7 @@ QAccessibleInterface *QAccessibleTable::cellAt(int row, int column) const
return 0;
Q_ASSERT(role() != QAccessible::Tree);
QModelIndex index = view()->model()->index(row, column, view()->rootIndex());
- if (!index.isValid()) {
+ if (Q_UNLIKELY(!index.isValid())) {
qWarning() << "QAccessibleTable::cellAt: invalid index: " << index << " for " << view();
return 0;
}
@@ -505,7 +505,7 @@ QAccessibleInterface *QAccessibleTable::child(int logicalIndex) const
if (!iface) {
QModelIndex index = view()->model()->index(row, column, view()->rootIndex());
- if (!index.isValid()) {
+ if (Q_UNLIKELY(!index.isValid())) {
qWarning() << "QAccessibleTable::child: Invalid index at: " << row << column;
return 0;
}
@@ -666,7 +666,7 @@ QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const
return QModelIndex();
const QTreeView *treeView = qobject_cast<const QTreeView*>(view());
- if ((row < 0) || (column < 0) || (treeView->d_func()->viewItems.count() <= row)) {
+ if (Q_UNLIKELY(row < 0 || column < 0 || treeView->d_func()->viewItems.count() <= row)) {
qWarning() << "QAccessibleTree::indexFromLogical: invalid index: " << row << column << " for " << treeView;
return QModelIndex();
}
@@ -776,7 +776,7 @@ int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const
QAccessibleInterface *QAccessibleTree::cellAt(int row, int column) const
{
QModelIndex index = indexFromLogical(row, column);
- if (!index.isValid()) {
+ if (Q_UNLIKELY(!index.isValid())) {
qWarning() << "Requested invalid tree cell: " << row << column;
return 0;
}
@@ -835,7 +835,7 @@ bool QAccessibleTree::selectRow(int row)
QAccessibleTableCell::QAccessibleTableCell(QAbstractItemView *view_, const QModelIndex &index_, QAccessible::Role role_)
: /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), m_index(index_), m_role(role_)
{
- if (!index_.isValid())
+ if (Q_UNLIKELY(!index_.isValid()))
qWarning() << "QAccessibleTableCell::QAccessibleTableCell with invalid index: " << index_;
}
diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp
index 3a9422cc26..e540980a14 100644
--- a/src/widgets/accessible/qaccessiblewidget.cpp
+++ b/src/widgets/accessible/qaccessiblewidget.cpp
@@ -53,10 +53,9 @@ QT_BEGIN_NAMESPACE
static QList<QWidget*> childWidgets(const QWidget *widget)
{
- QList<QObject*> list = widget->children();
QList<QWidget*> widgets;
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(list.at(i));
+ for (QObject *o : widget->children()) {
+ QWidget *w = qobject_cast<QWidget *>(o);
if (w && !w->isWindow()
&& !qobject_cast<QFocusFrame*>(w)
#if !defined(QT_NO_MENU)
@@ -77,9 +76,8 @@ static QString buddyString(const QWidget *widget)
if (!parent)
return QString();
#ifndef QT_NO_SHORTCUT
- QObjectList ol = parent->children();
- for (int i = 0; i < ol.size(); ++i) {
- QLabel *label = qobject_cast<QLabel*>(ol.at(i));
+ for (QObject *o : parent->children()) {
+ QLabel *label = qobject_cast<QLabel*>(o);
if (label && label->buddy() == widget)
return label->text();
}
@@ -274,7 +272,7 @@ public:
void QAccessibleWidget::addControllingSignal(const QString &signal)
{
QByteArray s = QMetaObject::normalizedSignature(signal.toLatin1());
- if (object()->metaObject()->indexOfSignal(s) < 0)
+ if (Q_UNLIKELY(object()->metaObject()->indexOfSignal(s) < 0))
qWarning("Signal %s unknown in %s", s.constData(), object()->metaObject()->className());
d->primarySignals << QLatin1String(s);
}
@@ -302,8 +300,8 @@ QAccessibleWidget::relations(QAccessible::Relation match /*= QAccessible::AllRel
// ideally we would go through all objects and check, but that
// will be too expensive
const QList<QWidget*> kids = childWidgets(parent);
- for (int i = 0; i < kids.count(); ++i) {
- if (QLabel *labelSibling = qobject_cast<QLabel*>(kids.at(i))) {
+ for (QWidget *kid : kids) {
+ if (QLabel *labelSibling = qobject_cast<QLabel*>(kid)) {
if (labelSibling->buddy() == widget()) {
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(labelSibling);
rels.append(qMakePair(iface, rel));
diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp
index adf908b821..83ea83a922 100644
--- a/src/widgets/accessible/qaccessiblewidgets.cpp
+++ b/src/widgets/accessible/qaccessiblewidgets.cpp
@@ -71,10 +71,9 @@ QList<QWidget*> childWidgets(const QWidget *widget)
{
if (widget == 0)
return QList<QWidget*>();
- QList<QObject*> list = widget->children();
QList<QWidget*> widgets;
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(list.at(i));
+ for (QObject *o : widget->children()) {
+ QWidget *w = qobject_cast<QWidget *>(o);
if (!w)
continue;
QString objectName = w->objectName();
@@ -282,7 +281,7 @@ void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex)
r.y() + edit->verticalScrollBar()->value());
// E V I L, but ensureVisible is not public
- if (!QMetaObject::invokeMethod(edit, "_q_ensureVisible", Q_ARG(QRectF, r)))
+ if (Q_UNLIKELY(!QMetaObject::invokeMethod(edit, "_q_ensureVisible", Q_ARG(QRectF, r))))
qWarning("AccessibleTextEdit::scrollToSubstring failed!");
}
@@ -708,6 +707,53 @@ int QAccessibleTextWidget::selectionCount() const
return textCursor().hasSelection() ? 1 : 0;
}
+namespace {
+/*!
+ \internal
+ \brief Helper class for AttributeFormatter
+
+ This class is returned from AttributeFormatter's indexing operator to act
+ as a proxy for the following assignment.
+
+ It uses perfect forwarding in its assignment operator to amend the RHS
+ with the formatting of the key, using QStringBuilder. Consequently, the
+ RHS can be anything that QStringBuilder supports.
+*/
+class AttributeFormatterRef {
+ QString &string;
+ const char *key;
+ friend class AttributeFormatter;
+ AttributeFormatterRef(QString &string, const char *key) : string(string), key(key) {}
+public:
+ template <typename RHS>
+ void operator=(RHS &&rhs)
+ { string += QLatin1String(key) + QLatin1Char(':') + std::forward<RHS>(rhs) + QLatin1Char(';'); }
+};
+
+/*!
+ \internal
+ \brief Small string-builder class that supports a map-like API to serialize key-value pairs.
+ \code
+ AttributeFormatter attrs;
+ attrs["foo"] = QLatinString("hello") + world + QLatin1Char('!');
+ \endcode
+ The key type is always \c{const char*}, and the right-hand-side can
+ be any QStringBuilder expression.
+
+ Breaking it down, this class provides the indexing operator, stores
+ the key in an instance of, and then returns, AttributeFormatterRef,
+ which is the class that provides the assignment part of the operation.
+*/
+class AttributeFormatter {
+ QString string;
+public:
+ AttributeFormatterRef operator[](const char *key)
+ { return AttributeFormatterRef(string, key); }
+
+ QString toFormatted() const { return string; }
+};
+} // unnamed namespace
+
QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *endOffset) const
{
/* The list of attributes can be found at:
@@ -767,8 +813,10 @@ QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *end
QTextBlockFormat blockFormat = cursor.blockFormat();
- QMap<QByteArray, QString> attrs;
- QString family = charFormat.font().family();
+ const QFont charFormatFont = charFormat.font();
+
+ AttributeFormatter attrs;
+ QString family = charFormatFont.family();
if (!family.isEmpty()) {
family = family.replace('\\',QStringLiteral("\\\\"));
family = family.replace(':',QStringLiteral("\\:"));
@@ -779,18 +827,18 @@ QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *end
attrs["font-family"] = QString::fromLatin1("\"%1\"").arg(family);
}
- int fontSize = int(charFormat.font().pointSize());
+ int fontSize = int(charFormatFont.pointSize());
if (fontSize)
attrs["font-size"] = QString::fromLatin1("%1pt").arg(fontSize);
//Different weight values are not handled
- attrs["font-weight"] = QString::fromLatin1(charFormat.font().weight() > QFont::Normal ? "bold" : "normal");
+ attrs["font-weight"] = QString::fromLatin1(charFormatFont.weight() > QFont::Normal ? "bold" : "normal");
- QFont::Style style = charFormat.font().style();
+ QFont::Style style = charFormatFont.style();
attrs["font-style"] = QString::fromLatin1((style == QFont::StyleItalic) ? "italic" : ((style == QFont::StyleOblique) ? "oblique": "normal"));
QTextCharFormat::UnderlineStyle underlineStyle = charFormat.underlineStyle();
- if (underlineStyle == QTextCharFormat::NoUnderline && charFormat.font().underline()) // underline could still be set in the default font
+ if (underlineStyle == QTextCharFormat::NoUnderline && charFormatFont.underline()) // underline could still be set in the default font
underlineStyle = QTextCharFormat::SingleUnderline;
QString underlineStyleValue;
switch (underlineStyle) {
@@ -857,12 +905,7 @@ QString QAccessibleTextWidget::attributes(int offset, int *startOffset, int *end
break;
}
- QString result;
- foreach (const QByteArray &attributeName, attrs.keys()) {
- result.append(QString::fromLatin1(attributeName)).append(':').append(attrs[attributeName]).append(';');
- }
-
- return result;
+ return attrs.toFormatted();
}
int QAccessibleTextWidget::cursorPosition() const
@@ -1056,10 +1099,9 @@ QAccessibleInterface *QAccessibleMainWindow::childAt(int x, int y) const
if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y))
return 0;
- QWidgetList kids = childWidgets(mainWindow());
+ const QWidgetList kids = childWidgets(mainWindow());
QPoint rp = mainWindow()->mapFromGlobal(QPoint(x, y));
- for (int i = 0; i < kids.size(); ++i) {
- QWidget *child = kids.at(i);
+ for (QWidget *child : kids) {
if (!child->isWindow() && !child->isHidden() && child->geometry().contains(rp)) {
return QAccessible::queryAccessibleInterface(child);
}
diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp
index 065c618cf7..e77839cc12 100644
--- a/src/widgets/accessible/simplewidgets.cpp
+++ b/src/widgets/accessible/simplewidgets.cpp
@@ -570,8 +570,8 @@ QAccessibleGroupBox::relations(QAccessible::Relation match /* = QAccessible::All
if ((match & QAccessible::Labelled) && (!groupBox()->title().isEmpty())) {
const QList<QWidget*> kids = childWidgets(widget());
- for (int i = 0; i < kids.count(); ++i) {
- QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(kids.at(i));
+ for (QWidget *kid : kids) {
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(kid);
if (iface)
rels.append(qMakePair(iface, QAccessible::Relation(QAccessible::Labelled)));
}
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index 5124960ab4..13686f301e 100644
--- a/src/widgets/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
@@ -80,6 +80,11 @@ static inline int themeDialogType(const QDialog *dialog)
return -1;
}
+QDialogPrivate::~QDialogPrivate()
+{
+ delete m_platformHelper;
+}
+
QPlatformDialogHelper *QDialogPrivate::platformHelper() const
{
// Delayed creation of the platform, ensuring that
@@ -516,7 +521,7 @@ int QDialog::exec()
{
Q_D(QDialog);
- if (d->eventLoop) {
+ if (Q_UNLIKELY(d->eventLoop)) {
qWarning("QDialog::exec: Recursive call detected");
return -1;
}
diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h
index 556bd4ff30..d393cc7a94 100644
--- a/src/widgets/dialogs/qdialog_p.h
+++ b/src/widgets/dialogs/qdialog_p.h
@@ -70,7 +70,7 @@ public:
rescode(0), resetModalityTo(-1), wasModalitySet(true), eventLoop(0),
nativeDialogInUse(false), m_platformHelper(0), m_platformHelperCreated(false)
{}
- ~QDialogPrivate() { delete m_platformHelper; }
+ ~QDialogPrivate();
QWindow *parentWindow() const;
bool setNativeDialogVisible(bool visible);
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index bdfa27282f..efab847c77 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -976,7 +976,7 @@ void QFileDialog::setDirectoryUrl(const QUrl &directory)
d->setDirectory_sys(directory);
else if (directory.isLocalFile())
setDirectory(directory.toLocalFile());
- else if (d->usingWidgets())
+ else if (Q_UNLIKELY(d->usingWidgets()))
qWarning("Non-native QFileDialog supports only local files");
}
@@ -1091,46 +1091,43 @@ void QFileDialog::selectUrl(const QUrl &url)
}
#ifdef Q_OS_UNIX
-Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0)
+Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path)
{
- if (expanded != 0)
- *expanded = false;
if (!path.startsWith(QLatin1Char('~')))
return path;
- QString ret = path;
- QStringList tokens = ret.split(QDir::separator());
- if (tokens.first() == QLatin1String("~")) {
- ret.replace(0, 1, QDir::homePath());
+ int separatorPosition = path.indexOf(QDir::separator());
+ if (separatorPosition < 0)
+ separatorPosition = path.size();
+ if (separatorPosition == 1) {
+ return QDir::homePath() + path.midRef(1);
} else {
- QString userName = tokens.first();
- userName.remove(0, 1);
-#if defined(Q_OS_VXWORKS)
+#if defined(Q_OS_VXWORKS) || defined(Q_OS_INTEGRITY)
const QString homePath = QDir::homePath();
-#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
+#else
+ const QByteArray userName = path.midRef(1, separatorPosition - 1).toLocal8Bit();
+# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
passwd pw;
passwd *tmpPw;
char buf[200];
const int bufSize = sizeof(buf);
int err = 0;
-#if defined(Q_OS_SOLARIS) && (_POSIX_C_SOURCE - 0 < 199506L)
- tmpPw = getpwnam_r(userName.toLocal8Bit().constData(), &pw, buf, bufSize);
-#else
- err = getpwnam_r(userName.toLocal8Bit().constData(), &pw, buf, bufSize, &tmpPw);
-#endif
+# if defined(Q_OS_SOLARIS) && (_POSIX_C_SOURCE - 0 < 199506L)
+ tmpPw = getpwnam_r(userName.constData(), &pw, buf, bufSize);
+# else
+ err = getpwnam_r(userName.constData(), &pw, buf, bufSize, &tmpPw);
+# endif
if (err || !tmpPw)
- return ret;
+ return path;
const QString homePath = QString::fromLocal8Bit(pw.pw_dir);
-#else
- passwd *pw = getpwnam(userName.toLocal8Bit().constData());
+# else
+ passwd *pw = getpwnam(userName.constData());
if (!pw)
- return ret;
+ return path;
const QString homePath = QString::fromLocal8Bit(pw->pw_dir);
+# endif
#endif
- ret.replace(0, tokens.first().length(), homePath);
+ return homePath + path.midRef(separatorPosition);
}
- if (expanded != 0)
- *expanded = true;
- return ret;
}
#endif
@@ -1187,13 +1184,13 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const
const QModelIndexList selectedRows = qFileDialogUi->listView->selectionModel()->selectedRows();
files.reserve(selectedRows.size());
- foreach (const QModelIndex &index, selectedRows)
+ for (const QModelIndex &index : selectedRows)
files.append(QUrl::fromLocalFile(index.data(QFileSystemModel::FilePathRole).toString()));
if (files.isEmpty() && !lineEdit()->text().isEmpty()) {
const QStringList typedFilesList = typedFiles();
files.reserve(typedFilesList.size());
- foreach (const QString &path, typedFilesList)
+ for (const QString &path : typedFilesList)
files.append(QUrl::fromLocalFile(path));
}
@@ -1257,7 +1254,7 @@ QStringList QFileDialog::selectedFiles() const
QStringList files;
const QList<QUrl> userSelectedFiles = d->userSelectedFiles();
files.reserve(userSelectedFiles.size());
- foreach (const QUrl &file, userSelectedFiles)
+ for (const QUrl &file : userSelectedFiles)
files.append(file.toLocalFile());
if (files.isEmpty() && d->usingWidgets()) {
const FileMode fm = fileMode();
@@ -1284,7 +1281,7 @@ QList<QUrl> QFileDialog::selectedUrls() const
QList<QUrl> urls;
const QStringList selectedFileList = selectedFiles();
urls.reserve(selectedFileList.size());
- foreach (const QString &file, selectedFileList)
+ for (const QString &file : selectedFileList)
urls.append(QUrl::fromLocalFile(file));
return urls;
}
@@ -1554,7 +1551,7 @@ void QFileDialog::setMimeTypeFilters(const QStringList &filters)
{
Q_D(QFileDialog);
QStringList nameFilters;
- foreach (const QString &mimeType, filters) {
+ for (const QString &mimeType : filters) {
const QString text = nameFilterForMime(mimeType);
if (!text.isEmpty())
nameFilters.append(text);
@@ -2218,7 +2215,7 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent,
const QList<QUrl> selectedUrls = getOpenFileUrls(parent, caption, QUrl::fromLocalFile(dir), filter, selectedFilter, options, schemes);
QStringList fileNames;
fileNames.reserve(selectedUrls.size());
- foreach (const QUrl &url, selectedUrls)
+ for (const QUrl &url : selectedUrls)
fileNames << url.toLocalFile();
return fileNames;
}
@@ -2587,7 +2584,7 @@ void QFileDialog::accept()
return;
}
- QStringList files = selectedFiles();
+ const QStringList files = selectedFiles();
if (files.isEmpty())
return;
QString lineEditText = d->lineEdit()->text();
@@ -2657,10 +2654,10 @@ void QFileDialog::accept()
case ExistingFile:
case ExistingFiles:
- for (int i = 0; i < files.count(); ++i) {
- QFileInfo info(files.at(i));
+ for (const auto &file : files) {
+ QFileInfo info(file);
if (!info.exists())
- info = QFileInfo(d->getEnvironmentVariable(files.at(i)));
+ info = QFileInfo(d->getEnvironmentVariable(file));
if (!info.exists()) {
#ifndef QT_NO_MESSAGEBOX
QString message = tr("%1\nFile not found.\nPlease verify the "
@@ -2696,7 +2693,7 @@ void QFileDialogPrivate::saveSettings()
QStringList historyUrls;
const QStringList history = q->history();
historyUrls.reserve(history.size());
- foreach (const QString &path, history)
+ for (const QString &path : history)
historyUrls << QUrl::fromLocalFile(path).toString();
settings.setValue(QLatin1String("history"), historyUrls);
settings.setValue(QLatin1String("lastVisited"), lastVisitedDir()->toString());
@@ -2730,7 +2727,8 @@ bool QFileDialogPrivate::restoreFromSettings()
return true;
QStringList history;
- foreach (const QString &urlStr, settings.value(QLatin1String("history")).toStringList()) {
+ const auto urlStrings = settings.value(QLatin1String("history")).toStringList();
+ for (const QString &urlStr : urlStrings) {
QUrl url(urlStr);
if (url.isLocalFile())
history << url.toLocalFile();
@@ -2760,8 +2758,10 @@ bool QFileDialogPrivate::restoreWidgetState(QStringList &history, int splitterPo
}
qFileDialogUi->sidebar->setUrls(sidebarUrls);
- while (history.count() > 5)
- history.pop_front();
+
+ static const int MaxHistorySize = 5;
+ if (history.size() > MaxHistorySize)
+ history.erase(history.begin(), history.end() - MaxHistorySize);
q->setHistory(history);
QHeaderView *headerView = qFileDialogUi->treeView->header();
@@ -2998,7 +2998,8 @@ void QFileDialogPrivate::createWidgets()
q->setHistory(options->history());
if (options->initiallySelectedFiles().count() == 1)
q->selectFile(options->initiallySelectedFiles().first().fileName());
- foreach (const QUrl &url, options->initiallySelectedFiles())
+ const auto initiallySelectedFiles = options->initiallySelectedFiles();
+ for (const QUrl &url : initiallySelectedFiles)
q->selectUrl(url);
lineEdit()->selectAll();
_q_updateOkButton();
@@ -3442,15 +3443,13 @@ void QFileDialogPrivate::_q_autoCompleteFileName(const QString &text)
return;
}
- QStringList multipleFiles = typedFiles();
+ const QStringList multipleFiles = typedFiles();
if (multipleFiles.count() > 0) {
QModelIndexList oldFiles = qFileDialogUi->listView->selectionModel()->selectedRows();
QModelIndexList newFiles;
- for (int i = 0; i < multipleFiles.count(); ++i) {
- QModelIndex idx = model->index(multipleFiles.at(i));
- if (oldFiles.contains(idx))
- oldFiles.removeAll(idx);
- else
+ for (const auto &file : multipleFiles) {
+ QModelIndex idx = model->index(file);
+ if (oldFiles.removeAll(idx) == 0)
newFiles.append(idx);
}
for (int i = 0; i < newFiles.count(); ++i)
@@ -3477,7 +3476,7 @@ void QFileDialogPrivate::_q_updateOkButton()
bool enableButton = true;
bool isOpenDirectory = false;
- QStringList files = q->selectedFiles();
+ const QStringList files = q->selectedFiles();
QString lineEditText = lineEdit()->text();
if (lineEditText.startsWith(QLatin1String("//")) || lineEditText.startsWith(QLatin1Char('\\'))) {
@@ -3536,10 +3535,10 @@ void QFileDialogPrivate::_q_updateOkButton()
}
case QFileDialog::ExistingFile:
case QFileDialog::ExistingFiles:
- for (int i = 0; i < files.count(); ++i) {
- QModelIndex idx = model->index(files.at(i));
+ for (const auto &file : files) {
+ QModelIndex idx = model->index(file);
if (!idx.isValid())
- idx = model->index(getEnvironmentVariable(files.at(i)));
+ idx = model->index(getEnvironmentVariable(file));
if (!idx.isValid()) {
enableButton = false;
break;
@@ -3680,14 +3679,14 @@ void QFileDialogPrivate::_q_useNameFilter(int index)
void QFileDialogPrivate::_q_selectionChanged()
{
const QFileDialog::FileMode fileMode = q_func()->fileMode();
- QModelIndexList indexes = qFileDialogUi->listView->selectionModel()->selectedRows();
+ const QModelIndexList indexes = qFileDialogUi->listView->selectionModel()->selectedRows();
bool stripDirs = (fileMode != QFileDialog::DirectoryOnly && fileMode != QFileDialog::Directory);
QStringList allFiles;
- for (int i = 0; i < indexes.count(); ++i) {
- if (stripDirs && model->isDir(mapToSource(indexes.at(i))))
+ for (const auto &index : indexes) {
+ if (stripDirs && model->isDir(mapToSource(index)))
continue;
- allFiles.append(indexes.at(i).data().toString());
+ allFiles.append(index.data().toString());
}
if (allFiles.count() > 1)
for (int i = 0; i < allFiles.count(); ++i) {
@@ -3755,7 +3754,7 @@ void QFileDialogPrivate::_q_emitUrlsSelected(const QList<QUrl> &files)
Q_Q(QFileDialog);
emit q->urlsSelected(files);
QStringList localFiles;
- foreach (const QUrl &file, files)
+ for (const QUrl &file : files)
if (file.isLocalFile())
localFiles.append(file.toLocalFile());
if (!localFiles.isEmpty())
@@ -4042,15 +4041,17 @@ QStringList QFSCompleter::splitPath(const QString &path) const
else
doubleSlash.clear();
#elif defined(Q_OS_UNIX)
- bool expanded;
- pathCopy = qt_tildeExpansion(pathCopy, &expanded);
- if (expanded) {
- QFileSystemModel *dirModel;
- if (proxyModel)
- dirModel = qobject_cast<QFileSystemModel *>(proxyModel->sourceModel());
- else
- dirModel = sourceModel;
- dirModel->fetchMore(dirModel->index(pathCopy));
+ {
+ QString tildeExpanded = qt_tildeExpansion(pathCopy);
+ if (tildeExpanded != pathCopy) {
+ QFileSystemModel *dirModel;
+ if (proxyModel)
+ dirModel = qobject_cast<QFileSystemModel *>(proxyModel->sourceModel());
+ else
+ dirModel = sourceModel;
+ dirModel->fetchMore(dirModel->index(tildeExpanded));
+ }
+ pathCopy = std::move(tildeExpanded);
}
#endif
diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp
index 92d6b8f3be..d99e3df802 100644
--- a/src/widgets/dialogs/qfileinfogatherer.cpp
+++ b/src/widgets/dialogs/qfileinfogatherer.cpp
@@ -282,8 +282,8 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil
infoList = QDir::drives();
} else {
infoList.reserve(files.count());
- for (int i = 0; i < files.count(); ++i)
- infoList << QFileInfo(files.at(i));
+ for (const auto &file : files)
+ infoList << QFileInfo(file);
}
for (int i = infoList.count() - 1; i >= 0; --i) {
QString driveName = translateDriveName(infoList.at(i));
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index d23737f130..90d7db7bd1 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -258,6 +258,21 @@ QModelIndex QFileSystemModel::index(int row, int column, const QModelIndex &pare
}
/*!
+ \reimp
+*/
+QModelIndex QFileSystemModel::sibling(int row, int column, const QModelIndex &idx) const
+{
+ if (row == idx.row() && column < QFileSystemModelPrivate::NumColumns) {
+ // cheap sibling operation: just adjust the column:
+ return createIndex(row, column, idx.internalPointer());
+ } else {
+ // for anything else: call the default implementation
+ // (this could probably be optimized, too):
+ return QAbstractItemModel::sibling(row, column, idx);
+ }
+}
+
+/*!
\overload
Returns the model item index for the given \a path and \a column.
@@ -1548,10 +1563,9 @@ void QFileSystemModel::setNameFilters(const QStringList &filters)
d->bypassFilters.clear();
// We guarantee that rootPath will stick around
QPersistentModelIndex root(index(rootPath()));
- QModelIndexList persistantList = persistentIndexList();
- for (int i = 0; i < persistantList.count(); ++i) {
- QFileSystemModelPrivate::QFileSystemNode *node;
- node = d->node(persistantList.at(i));
+ const QModelIndexList persistentList = persistentIndexList();
+ for (const auto &persistentIndex : persistentList) {
+ QFileSystemModelPrivate::QFileSystemNode *node = d->node(persistentIndex);
while (node) {
if (d->bypassFilters.contains(node))
break;
@@ -1565,9 +1579,8 @@ void QFileSystemModel::setNameFilters(const QStringList &filters)
d->nameFilters.clear();
const Qt::CaseSensitivity caseSensitive =
(filter() & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive;
- for (int i = 0; i < filters.size(); ++i) {
- d->nameFilters << QRegExp(filters.at(i), caseSensitive, QRegExp::Wildcard);
- }
+ for (const auto &filter : filters)
+ d->nameFilters << QRegExp(filter, caseSensitive, QRegExp::Wildcard);
d->forceSort = true;
d->delayedSort();
#endif
@@ -1723,9 +1736,9 @@ void QFileSystemModelPrivate::addVisibleFiles(QFileSystemNode *parentNode, const
if (parentNode->dirtyChildrenIndex == -1)
parentNode->dirtyChildrenIndex = parentNode->visibleChildren.count();
- for (int i = 0; i < newFiles.count(); ++i) {
- parentNode->visibleChildren.append(newFiles.at(i));
- parentNode->children.value(newFiles.at(i))->isVisible = true;
+ for (const auto &newFile : newFiles) {
+ parentNode->visibleChildren.append(newFile);
+ parentNode->children.value(newFile)->isVisible = true;
}
if (!indexHidden)
q->endInsertRows();
@@ -1768,10 +1781,10 @@ void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QV
QStringList newFiles;
QFileSystemModelPrivate::QFileSystemNode *parentNode = node(path, false);
QModelIndex parentIndex = index(parentNode);
- for (int i = 0; i < updates.count(); ++i) {
- QString fileName = updates.at(i).first;
+ for (const auto &update : updates) {
+ QString fileName = update.first;
Q_ASSERT(!fileName.isEmpty());
- QExtendedInformation info = fileInfoGatherer.getInfo(updates.at(i).second);
+ QExtendedInformation info = fileInfoGatherer.getInfo(update.second);
bool previouslyHere = parentNode->children.contains(fileName);
if (!previouslyHere) {
addNode(parentNode, fileName, info.fileInfo());
@@ -1956,8 +1969,8 @@ bool QFileSystemModelPrivate::passNameFilters(const QFileSystemNode *node) const
// Check the name regularexpression filters
if (!(node->isDir() && (filters & QDir::AllDirs))) {
- for (int i = 0; i < nameFilters.size(); ++i) {
- QRegExp copy = nameFilters.at(i);
+ for (const auto &nameFilter : nameFilters) {
+ QRegExp copy = nameFilter;
if (copy.exactMatch(node->fileName))
return true;
}
diff --git a/src/widgets/dialogs/qfilesystemmodel.h b/src/widgets/dialogs/qfilesystemmodel.h
index 515417f225..51c01220a2 100644
--- a/src/widgets/dialogs/qfilesystemmodel.h
+++ b/src/widgets/dialogs/qfilesystemmodel.h
@@ -75,6 +75,7 @@ public:
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex index(const QString &path, int column = 0) const;
QModelIndex parent(const QModelIndex &child) const Q_DECL_OVERRIDE;
+ QModelIndex sibling(int row, int column, const QModelIndex &idx) const Q_DECL_OVERRIDE;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
bool canFetchMore(const QModelIndex &parent) const Q_DECL_OVERRIDE;
void fetchMore(const QModelIndex &parent) Q_DECL_OVERRIDE;
diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp
index d0177941f7..e97552880f 100644
--- a/src/widgets/dialogs/qfontdialog.cpp
+++ b/src/widgets/dialogs/qfontdialog.cpp
@@ -491,7 +491,8 @@ void QFontDialogPrivate::updateFamilies()
QFontDatabase fdb;
QStringList familyNames;
- foreach (const QString &family, fdb.families(writingSystem)) {
+ const auto families = fdb.families(writingSystem);
+ for (const QString &family : families) {
if (fdb.isPrivateFamily(family))
continue;
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index 8a48100ea7..704883b5c6 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -89,16 +89,14 @@ public:
{
public:
TextEdit(QWidget *parent=0) : QTextEdit(parent) { }
+#ifndef QT_NO_CONTEXTMENU
void contextMenuEvent(QContextMenuEvent * e) Q_DECL_OVERRIDE
{
-#ifndef QT_NO_CONTEXTMENU
QMenu *menu = createStandardContextMenu();
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->popup(e->globalPos());
-#else
- Q_UNUSED(e);
-#endif
}
+#endif // QT_NO_CONTEXTMENU
};
QMessageBoxDetailsText(QWidget *parent=0)
@@ -1049,26 +1047,26 @@ void QMessageBoxPrivate::detectEscapeButton()
}
// if the message box has one RejectRole button, make it the escape button
- for (int i = 0; i < buttons.count(); i++) {
- if (buttonBox->buttonRole(buttons.at(i)) == QDialogButtonBox::RejectRole) {
+ for (auto *button : buttons) {
+ if (buttonBox->buttonRole(button) == QDialogButtonBox::RejectRole) {
if (detectedEscapeButton) { // already detected!
detectedEscapeButton = 0;
break;
}
- detectedEscapeButton = buttons.at(i);
+ detectedEscapeButton = button;
}
}
if (detectedEscapeButton)
return;
// if the message box has one NoRole button, make it the escape button
- for (int i = 0; i < buttons.count(); i++) {
- if (buttonBox->buttonRole(buttons.at(i)) == QDialogButtonBox::NoRole) {
+ for (auto *button : buttons) {
+ if (buttonBox->buttonRole(button) == QDialogButtonBox::NoRole) {
if (detectedEscapeButton) { // already detected!
detectedEscapeButton = 0;
break;
}
- detectedEscapeButton = buttons.at(i);
+ detectedEscapeButton = button;
}
}
}
@@ -1480,24 +1478,21 @@ void QMessageBox::keyPressEvent(QKeyEvent *e)
#if defined(Q_OS_WIN)
if (e == QKeySequence::Copy) {
- QString separator = QString::fromLatin1("---------------------------\n");
- QString textToCopy = separator;
- separator.prepend(QLatin1Char('\n'));
- textToCopy += windowTitle() + separator; // title
- textToCopy += d->label->text() + separator; // text
+ const QLatin1String separator("---------------------------\n");
+ QString textToCopy;
+ textToCopy += separator + windowTitle() + QLatin1Char('\n') + separator // title
+ + d->label->text() + QLatin1Char('\n') + separator; // text
if (d->informativeLabel)
- textToCopy += d->informativeLabel->text() + separator;
+ textToCopy += d->informativeLabel->text() + QLatin1Char('\n') + separator;
- QString buttonTexts;
- QList<QAbstractButton *> buttons = d->buttonBox->buttons();
- for (int i = 0; i < buttons.count(); i++) {
- buttonTexts += buttons[i]->text() + QLatin1String(" ");
- }
- textToCopy += buttonTexts + separator;
+ const QList<QAbstractButton *> buttons = d->buttonBox->buttons();
+ for (const auto *button : buttons)
+ textToCopy += button->text() + QLatin1String(" ");
+ textToCopy += QLatin1Char('\n') + separator;
#ifndef QT_NO_TEXTEDIT
if (d->detailsText)
- textToCopy += d->detailsText->text() + separator;
+ textToCopy += d->detailsText->text() + QLatin1Char('\n') + separator;
#endif
QApplication::clipboard()->setText(textToCopy);
return;
@@ -1511,8 +1506,7 @@ void QMessageBox::keyPressEvent(QKeyEvent *e)
int key = e->key() & ~Qt::MODIFIER_MASK;
if (key) {
const QList<QAbstractButton *> buttons = d->buttonBox->buttons();
- for (int i = 0; i < buttons.count(); ++i) {
- QAbstractButton *pb = buttons.at(i);
+ for (auto *pb : buttons) {
QKeySequence shortcut = pb->shortcut();
if (!shortcut.isEmpty() && key == int(shortcut[0] & ~Qt::MODIFIER_MASK)) {
pb->animateClick();
diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp
index bbb251c8b2..619d0051ea 100644
--- a/src/widgets/dialogs/qprogressdialog.cpp
+++ b/src/widgets/dialogs/qprogressdialog.cpp
@@ -353,7 +353,7 @@ void QProgressDialog::setLabel(QLabel *label)
{
Q_D(QProgressDialog);
if (label == d->label) {
- if (label)
+ if (Q_UNLIKELY(label))
qWarning("QProgressDialog::setLabel: Attempt to set the same label again");
return;
}
@@ -402,7 +402,7 @@ void QProgressDialog::setCancelButton(QPushButton *cancelButton)
{
Q_D(QProgressDialog);
if (d->cancel == cancelButton) {
- if (cancelButton)
+ if (Q_UNLIKELY(cancelButton))
qWarning("QProgressDialog::setCancelButton: Attempt to set the same button again");
return;
}
@@ -465,16 +465,16 @@ void QProgressDialogPrivate::setCancelButtonText(const QString &cancelButtonText
void QProgressDialog::setBar(QProgressBar *bar)
{
Q_D(QProgressDialog);
- if (!bar) {
+ if (Q_UNLIKELY(!bar)) {
qWarning("QProgressDialog::setBar: Cannot set a null progress bar");
return;
}
#ifndef QT_NO_DEBUG
- if (value() > 0)
+ if (Q_UNLIKELY(value() > 0))
qWarning("QProgressDialog::setBar: Cannot set a new progress bar "
"while the old one is active");
#endif
- if (bar == d->bar) {
+ if (Q_UNLIKELY(bar == d->bar)) {
qWarning("QProgressDialog::setBar: Attempt to set the same progress bar again");
return;
}
diff --git a/src/widgets/dialogs/qsidebar.cpp b/src/widgets/dialogs/qsidebar.cpp
index f883705cc3..58a92800f4 100644
--- a/src/widgets/dialogs/qsidebar.cpp
+++ b/src/widgets/dialogs/qsidebar.cpp
@@ -103,9 +103,9 @@ Qt::ItemFlags QUrlModel::flags(const QModelIndex &index) const
QMimeData *QUrlModel::mimeData(const QModelIndexList &indexes) const
{
QList<QUrl> list;
- for (int i = 0; i < indexes.count(); ++i) {
- if (indexes.at(i).column() == 0)
- list.append(indexes.at(i).data(UrlRole).toUrl());
+ for (const auto &index : indexes) {
+ if (index.column() == 0)
+ list.append(index.data(UrlRole).toUrl());
}
QMimeData *data = new QMimeData();
data->setUrls(list);
@@ -125,8 +125,8 @@ bool QUrlModel::canDrop(QDragEnterEvent *event)
return false;
const QList<QUrl> list = event->mimeData()->urls();
- for (int i = 0; i < list.count(); ++i) {
- QModelIndex idx = fileSystemModel->index(list.at(0).toLocalFile());
+ for (const auto &url : list) {
+ const QModelIndex idx = fileSystemModel->index(url.toLocalFile());
if (!fileSystemModel->isDir(idx))
return false;
}
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index b9906f13da..6add83e135 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -799,8 +799,8 @@ void QWizardPrivate::addField(const QWizardField &field)
QWizardField myField = field;
myField.resolve(defaultPropertyTable);
- if (fieldIndexMap.contains(myField.name)) {
- qWarning("QWizardPage::addField: Duplicate field '%s'", qPrintable(myField.name));
+ if (Q_UNLIKELY(fieldIndexMap.contains(myField.name))) {
+ qWarning("QWizardPage::addField: Duplicate field '%ls'", qUtf16Printable(myField.name));
return;
}
@@ -2256,17 +2256,17 @@ void QWizard::setPage(int theid, QWizardPage *page)
{
Q_D(QWizard);
- if (!page) {
+ if (Q_UNLIKELY(!page)) {
qWarning("QWizard::setPage: Cannot insert null page");
return;
}
- if (theid == -1) {
+ if (Q_UNLIKELY(theid == -1)) {
qWarning("QWizard::setPage: Cannot insert page with ID -1");
return;
}
- if (d->pageMap.contains(theid)) {
+ if (Q_UNLIKELY(d->pageMap.contains(theid))) {
qWarning("QWizard::setPage: Page with duplicate ID %d ignored", theid);
return;
}
@@ -2450,7 +2450,7 @@ void QWizard::setStartId(int theid)
return;
}
- if (!d->pageMap.contains(newStart)) {
+ if (Q_UNLIKELY(!d->pageMap.contains(newStart))) {
qWarning("QWizard::setStartId: Invalid page ID %d", newStart);
return;
}
@@ -2508,15 +2508,15 @@ void QWizard::setField(const QString &name, const QVariant &value)
Q_D(QWizard);
int index = d->fieldIndexMap.value(name, -1);
- if (index != -1) {
- const QWizardField &field = d->fields.at(index);
- if (!field.object->setProperty(field.property, value))
- qWarning("QWizard::setField: Couldn't write to property '%s'",
- field.property.constData());
+ if (Q_UNLIKELY(index == -1)) {
+ qWarning("QWizard::setField: No such field '%ls'", qUtf16Printable(name));
return;
}
- qWarning("QWizard::setField: No such field '%s'", qPrintable(name));
+ const QWizardField &field = d->fields.at(index);
+ if (Q_UNLIKELY(!field.object->setProperty(field.property, value)))
+ qWarning("QWizard::setField: Couldn't write to property '%s'",
+ field.property.constData());
}
/*!
@@ -2531,13 +2531,13 @@ QVariant QWizard::field(const QString &name) const
Q_D(const QWizard);
int index = d->fieldIndexMap.value(name, -1);
- if (index != -1) {
- const QWizardField &field = d->fields.at(index);
- return field.object->property(field.property);
+ if (Q_UNLIKELY(index == -1)) {
+ qWarning("QWizard::field: No such field '%ls'", qUtf16Printable(name));
+ return QVariant();
}
- qWarning("QWizard::field: No such field '%s'", qPrintable(name));
- return QVariant();
+ const QWizardField &field = d->fields.at(index);
+ return field.object->property(field.property);
}
/*!
@@ -2763,7 +2763,7 @@ void QWizard::setButtonLayout(const QList<WizardButton> &layout)
// O(n^2), but n is very small
for (int j = 0; j < i; ++j) {
WizardButton button2 = layout.at(j);
- if (button2 == button1) {
+ if (Q_UNLIKELY(button2 == button1)) {
qWarning("QWizard::setButtonLayout: Duplicate button in layout");
return;
}
@@ -3140,11 +3140,11 @@ void QWizard::next()
if (validateCurrentPage()) {
int next = nextId();
if (next != -1) {
- if (d->history.contains(next)) {
+ if (Q_UNLIKELY(d->history.contains(next))) {
qWarning("QWizard::next: Page %d already met", next);
return;
}
- if (!d->pageMap.contains(next)) {
+ if (Q_UNLIKELY(!d->pageMap.contains(next))) {
qWarning("QWizard::next: No such page %d", next);
return;
}
@@ -3622,9 +3622,8 @@ void QWizardPage::cleanupPage()
{
Q_D(QWizardPage);
if (d->wizard) {
- QVector<QWizardField> &fields = d->wizard->d_func()->fields;
- for (int i = 0; i < fields.count(); ++i) {
- const QWizardField &field = fields.at(i);
+ const QVector<QWizardField> &fields = d->wizard->d_func()->fields;
+ for (const auto &field : fields) {
if (field.page == this)
field.object->setProperty(field.property, field.initialValue);
}
diff --git a/src/widgets/doc/images/gtk-calendarwidget.png b/src/widgets/doc/images/gtk-calendarwidget.png
deleted file mode 100644
index 568cd1a5da..0000000000
--- a/src/widgets/doc/images/gtk-calendarwidget.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-checkbox.png b/src/widgets/doc/images/gtk-checkbox.png
deleted file mode 100644
index 1fd5fc77bf..0000000000
--- a/src/widgets/doc/images/gtk-checkbox.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-combobox.png b/src/widgets/doc/images/gtk-combobox.png
deleted file mode 100644
index 3b4544df13..0000000000
--- a/src/widgets/doc/images/gtk-combobox.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-dateedit.png b/src/widgets/doc/images/gtk-dateedit.png
deleted file mode 100644
index 25229f0b3b..0000000000
--- a/src/widgets/doc/images/gtk-dateedit.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-datetimeedit.png b/src/widgets/doc/images/gtk-datetimeedit.png
deleted file mode 100644
index 0c934a4d0d..0000000000
--- a/src/widgets/doc/images/gtk-datetimeedit.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-dial.png b/src/widgets/doc/images/gtk-dial.png
deleted file mode 100644
index 18e14b3650..0000000000
--- a/src/widgets/doc/images/gtk-dial.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-doublespinbox.png b/src/widgets/doc/images/gtk-doublespinbox.png
deleted file mode 100644
index 3a69043c0b..0000000000
--- a/src/widgets/doc/images/gtk-doublespinbox.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-fontcombobox.png b/src/widgets/doc/images/gtk-fontcombobox.png
deleted file mode 100644
index 4cb1bc1343..0000000000
--- a/src/widgets/doc/images/gtk-fontcombobox.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-frame.png b/src/widgets/doc/images/gtk-frame.png
deleted file mode 100644
index c1bf52f6a6..0000000000
--- a/src/widgets/doc/images/gtk-frame.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-groupbox.png b/src/widgets/doc/images/gtk-groupbox.png
deleted file mode 100644
index 6d217c89f9..0000000000
--- a/src/widgets/doc/images/gtk-groupbox.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-horizontalscrollbar.png b/src/widgets/doc/images/gtk-horizontalscrollbar.png
deleted file mode 100644
index 2887730c13..0000000000
--- a/src/widgets/doc/images/gtk-horizontalscrollbar.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-label.png b/src/widgets/doc/images/gtk-label.png
deleted file mode 100644
index 006d0133d8..0000000000
--- a/src/widgets/doc/images/gtk-label.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-lcdnumber.png b/src/widgets/doc/images/gtk-lcdnumber.png
deleted file mode 100644
index 142d298ffc..0000000000
--- a/src/widgets/doc/images/gtk-lcdnumber.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-lineedit.png b/src/widgets/doc/images/gtk-lineedit.png
deleted file mode 100644
index 8fb513c39f..0000000000
--- a/src/widgets/doc/images/gtk-lineedit.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-listview.png b/src/widgets/doc/images/gtk-listview.png
deleted file mode 100644
index d32f8e8aee..0000000000
--- a/src/widgets/doc/images/gtk-listview.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-progressbar.png b/src/widgets/doc/images/gtk-progressbar.png
deleted file mode 100644
index 6162484bf3..0000000000
--- a/src/widgets/doc/images/gtk-progressbar.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-pushbutton.png b/src/widgets/doc/images/gtk-pushbutton.png
deleted file mode 100644
index f4f4d7c1e4..0000000000
--- a/src/widgets/doc/images/gtk-pushbutton.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-radiobutton.png b/src/widgets/doc/images/gtk-radiobutton.png
deleted file mode 100644
index b3620fa054..0000000000
--- a/src/widgets/doc/images/gtk-radiobutton.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-slider.png b/src/widgets/doc/images/gtk-slider.png
deleted file mode 100644
index 3d8e0ee89e..0000000000
--- a/src/widgets/doc/images/gtk-slider.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-spinbox.png b/src/widgets/doc/images/gtk-spinbox.png
deleted file mode 100644
index a39eb3aa93..0000000000
--- a/src/widgets/doc/images/gtk-spinbox.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-tableview.png b/src/widgets/doc/images/gtk-tableview.png
deleted file mode 100644
index a025193188..0000000000
--- a/src/widgets/doc/images/gtk-tableview.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-tabwidget.png b/src/widgets/doc/images/gtk-tabwidget.png
deleted file mode 100644
index 089c76dad2..0000000000
--- a/src/widgets/doc/images/gtk-tabwidget.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-textedit.png b/src/widgets/doc/images/gtk-textedit.png
deleted file mode 100644
index e4b91c01c9..0000000000
--- a/src/widgets/doc/images/gtk-textedit.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-timeedit.png b/src/widgets/doc/images/gtk-timeedit.png
deleted file mode 100644
index acf6730a86..0000000000
--- a/src/widgets/doc/images/gtk-timeedit.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-toolbox.png b/src/widgets/doc/images/gtk-toolbox.png
deleted file mode 100644
index 25e6137699..0000000000
--- a/src/widgets/doc/images/gtk-toolbox.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-toolbutton.png b/src/widgets/doc/images/gtk-toolbutton.png
deleted file mode 100644
index f0eb86efc5..0000000000
--- a/src/widgets/doc/images/gtk-toolbutton.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/images/gtk-treeview.png b/src/widgets/doc/images/gtk-treeview.png
deleted file mode 100644
index 7b4e3044be..0000000000
--- a/src/widgets/doc/images/gtk-treeview.png
+++ /dev/null
Binary files differ
diff --git a/src/widgets/doc/snippets/code/doc_src_stylesheet.cpp b/src/widgets/doc/snippets/code/doc_src_stylesheet.cpp
index a937498fe5..01f4c528a2 100644
--- a/src/widgets/doc/snippets/code/doc_src_stylesheet.cpp
+++ b/src/widgets/doc/snippets/code/doc_src_stylesheet.cpp
@@ -138,3 +138,7 @@ emailEdit->setProperty("mandatoryField", true);
QSpinBox *ageSpinBox = new QSpinBox(this);
ageSpinBox->setProperty("mandatoryField", true);
//! [95]
+
+//! [96]
+qApp->setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, true);
+//! [97]
diff --git a/src/widgets/doc/snippets/macmainwindow.mm b/src/widgets/doc/snippets/macmainwindow.mm
index d0d74631ab..17aff45fa0 100644
--- a/src/widgets/doc/snippets/macmainwindow.mm
+++ b/src/widgets/doc/snippets/macmainwindow.mm
@@ -31,7 +31,7 @@
**
****************************************************************************/
#include "macmainwindow.h"
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
#include <QtGui>
diff --git a/src/widgets/doc/snippets/qmacnativewidget/main.mm b/src/widgets/doc/snippets/qmacnativewidget/main.mm
index e541aac1f8..38701917c0 100644
--- a/src/widgets/doc/snippets/qmacnativewidget/main.mm
+++ b/src/widgets/doc/snippets/qmacnativewidget/main.mm
@@ -40,7 +40,7 @@
#include <QtGui/QtGui>
#include <QtGui/qmacnativewidget_mac.h>
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
int main(int argc, char **argv)
{
diff --git a/src/widgets/doc/snippets/styles/qcustompixmapstyle.cpp b/src/widgets/doc/snippets/styles/qcustompixmapstyle.cpp
new file mode 100644
index 0000000000..361b19f0e2
--- /dev/null
+++ b/src/widgets/doc/snippets/styles/qcustompixmapstyle.cpp
@@ -0,0 +1,85 @@
+/***************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcustompixmapstyle.h"
+
+#include <QtGui>
+
+//! [0]
+QCustomPixmapStyle::QCustomPixmapStyle() :
+ QPixmapStyle()
+{
+//! [1]
+ addDescriptor(PB_Enabled,
+ QLatin1String("://button/core_button_inactive.png"),
+ QMargins(13, 13, 13, 13),
+ QTileRules(Qt::RepeatTile, Qt::StretchTile));
+//! [1]
+ addDescriptor(PB_Checked,
+ QLatin1String("://button/core_button_enabled_selected.png"),
+ QMargins(13, 13, 13, 13),
+ QTileRules(Qt::RepeatTile, Qt::StretchTile));
+ addDescriptor(PB_Pressed,
+ QLatin1String("://button/core_button_pressed.png"),
+ QMargins(13, 13, 13, 13),
+ QTileRules(Qt::RepeatTile, Qt::StretchTile));
+ addDescriptor(PB_Disabled,
+ QLatin1String("://button/core_button_disabled.png"),
+ QMargins(13, 13, 13, 13),
+ QTileRules(Qt::RepeatTile, Qt::StretchTile));
+ addDescriptor(PB_PressedDisabled,
+ QLatin1String("://button/core_button_disabled_selected.png"),
+ QMargins(13, 13, 13, 13),
+ QTileRules(Qt::RepeatTile, Qt::StretchTile));
+
+//! [2]
+ addDescriptor(LE_Enabled,
+ QLatin1String("://lineedit/core_textinput_bg.png"),
+ QMargins(8, 8, 8, 8));
+ addDescriptor(LE_Disabled,
+ QLatin1String("://lineedit/core_textinput_bg_disabled.png"),
+ QMargins(8, 8, 8, 8));
+ addDescriptor(LE_Focused,
+ QLatin1String("://lineedit/core_textinput_bg_highlight.png"),
+ QMargins(8, 8, 8, 8));
+
+ copyDescriptor(LE_Enabled, TE_Enabled);
+ copyDescriptor(LE_Disabled, TE_Disabled);
+ copyDescriptor(LE_Focused, TE_Focused);
+//! [2]
+}
+//! [0]
+
+QCustomPixmapStyle::~QCustomPixmapStyle()
+{
+}
diff --git a/src/widgets/doc/src/widgets-and-layouts/gallery-gtk.qdoc b/src/widgets/doc/src/widgets-and-layouts/gallery-gtk.qdoc
deleted file mode 100644
index 5c3ae8cb97..0000000000
--- a/src/widgets/doc/src/widgets-and-layouts/gallery-gtk.qdoc
+++ /dev/null
@@ -1,142 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
- \page gallery-gtk.html
-
- \title GTK Style Widget Gallery
- \ingroup gallery
-
- This page shows some of the widgets available in Qt
- when configured to use the "gtk" style. This style is
- only available on desktop environments with GTK runtime
- support. This style provides native look'n'feel by
- integrating to the GTK platform theme. Thus, the final
- appearance varies depending on the active GTK theme.
-
-\section2 Buttons
-
-\table 100%
-\row
-\li \image gtk-pushbutton.png
- \caption The QPushButton widget provides a command button.
-\li \image gtk-toolbutton.png
- \caption The QToolButton class provides a quick-access button to commands
- or options, usually used inside a QToolBar.
-\endtable
-
-\table 100%
-\row
-\li \image gtk-checkbox.png
- \caption The QCheckBox widget provides a checkbox with a text label.
-\li \image gtk-radiobutton.png
- \caption The QRadioButton widget provides a radio button with a text or pixmap label.
-\endtable
-
-\section2 Containers
-
-\table 100%
-\row
-\li \image gtk-groupbox.png
- The QGroupBox widget provides a group box frame with a title.
-\li \image gtk-tabwidget.png
- The QTabWidget class provides a stack of tabbed widgets.
-\li \image gtk-frame.png
- The QFrame widget provides a simple decorated container for other widgets.
-\li \image gtk-toolbox.png
- The QToolBox class provides a column of tabbed widget items.
-\endtable
-
-\section2 Item Views
-
-\table 100%
-\row
-\li \image gtk-listview.png
- The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\li \image gtk-treeview.png
- The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\li \image gtk-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
-\li
-\endtable
-
-\section2 Display Widgets
-
-\table 100%
-\row
-\li \image gtk-progressbar.png
- The QProgressBar widget provides a horizontal progress bar.
-\li \image gtk-label.png
- The QLabel widget provides a text or image display.
-\li \image gtk-lcdnumber.png
- The QLCDNumber widget displays a number with LCD-like digits.
-\endtable
-
-\section2 Input Widgets
-
-\table 100%
-\row
-\li \image gtk-lineedit.png
- The QLineEdit widget is a one-line text editor.
-\li \image gtk-dateedit.png
- The QDateEdit class provides a widget for editing dates.
-\li \image gtk-timeedit.png
- The QTimeEdit class provides a widget for editing times.
-\li \image gtk-datetimeedit.png
- The QDateTimeEdit class provides a widget for editing dates and times.
-\endtable
-
-\table 100%
-\row
-\li \image gtk-slider.png
- The QSlider widget provides a vertical or horizontal slider.
-\li \image gtk-combobox.png
- The QComboBox widget is a combined button and pop-up list.
-\li \image gtk-spinbox.png
- The QSpinBox class provides a spin box widget.
-\endtable
-
-\table 100%
-\row
-\li \image gtk-fontcombobox.png
- The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\li \image gtk-doublespinbox.png
- The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\li \image gtk-horizontalscrollbar.png
- The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
-\endtable
-
-\table 100%
-\row
-\li \image gtk-dial.png
- The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\li \image gtk-textedit.png
- The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\li \image gtk-calendarwidget.png
- The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
-\endtable
-*/
diff --git a/src/widgets/doc/src/widgets-and-layouts/gallery.qdoc b/src/widgets/doc/src/widgets-and-layouts/gallery.qdoc
index cc6446b8a5..c32eceb558 100644
--- a/src/widgets/doc/src/widgets-and-layouts/gallery.qdoc
+++ b/src/widgets/doc/src/widgets-and-layouts/gallery.qdoc
@@ -54,10 +54,6 @@
\caption \l{Macintosh Style Widget Gallery}
The Macintosh style is provided by QMacStyle.
- \li \image gtk-tabwidget.png GTK Style Widget Gallery
- \caption \l{GTK Style Widget Gallery}
-
- The GTK style is provided by QGtkStyle.
\li \image fusion-tabwidget.png Fusion Style Widget Gallery
\caption \l{Fusion Style Widget Gallery}
diff --git a/src/widgets/doc/src/widgets-and-layouts/styles.qdoc b/src/widgets/doc/src/widgets-and-layouts/styles.qdoc
index 7d1bffd0b4..a42ee0db61 100644
--- a/src/widgets/doc/src/widgets-and-layouts/styles.qdoc
+++ b/src/widgets/doc/src/widgets-and-layouts/styles.qdoc
@@ -38,7 +38,7 @@
native widgets.
Qt comes with a selection of built-in styles. Some styles are only
- available on specific platforms (such as the Mac, GTK+ and Windows
+ available on specific platforms (such as the Mac and Windows
Vista styles). Custom styles are made available as plugins or by
creating an instance of a specific style class with
QStyleFactory::create() and setting it with QApplication::setStyle().
diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
index 2fb6819c47..047b63c23b 100644
--- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
+++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc
@@ -492,9 +492,9 @@
\section1 Inheritance
In classic CSS, when font and color of an item is not explicitly set,
- it gets automatically inherited from the parent. When using Qt Style Sheets,
- a widget does \b{not} automatically inherit its font and color setting
- from its parent widget.
+ it gets automatically inherited from the parent. By default, when using
+ Qt Style Sheets, a widget does \b{not} automatically inherit its font
+ and color setting from its parent widget.
For example, consider a QPushButton inside a QGroupBox:
@@ -507,9 +507,23 @@
\snippet code/doc_src_stylesheet.cpp 25
- In contrast, setting a font and propagate using QWidget::setFont() and
+ In contrast, setting a font and palette using QWidget::setFont() and
QWidget::setPalette() propagates to child widgets.
+ If you would prefer that the font and palette propagate to child widgets,
+ you can set the Qt::AA_UseStyleSheetPropagationInWidgetStyles flag, like
+ this:
+
+ Usage:
+ \snippet code/doc_src_stylesheet.cpp 96
+
+ When the widget-style font and palette propagation is enabled, font and
+ palette changes made through Qt Style Sheets will behave as though the
+ user had manually called the corresponding QWidget::setPalette() and
+ QWidget::setFont() methods on all of the QWidgets targeted by the style
+ sheet. If this would have caused propagation in C++, it will cause
+ propagation in style sheets and visa versa.
+
\section1 Widgets Inside C++ Namespaces
The Type Selector can be used to style widgets of a particular type. For
diff --git a/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc b/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc
index 6e58fe4499..172ea4742a 100644
--- a/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc
+++ b/src/widgets/doc/src/windows-and-dialogs/mainwindow.qdoc
@@ -139,19 +139,6 @@
depends on the result of QWidget::frameGeometry() and the
capability of the window manager to do proper window placement,
neither of which can be guaranteed.
-
- \section2 BlackBerry Peculiarities
-
- On the BlackBerry platform it is possible to set an alternate
- cover window that is shown when the application is minimized.
- The cover window must be a separate window with the
- \l{Qt::CoverWindow} flag set.
-
- The window should have a fixed size depending on the screen
- resolution (e.g. for a 768x1280 screen, 334 pixels wide by 396
- pixels high). The window can be rendered to as usual, however
- updates should occur very infrequently (a few updates per minute
- at most) in order save battery.
*/
/*!
diff --git a/src/widgets/effects/qgraphicseffect.cpp b/src/widgets/effects/qgraphicseffect.cpp
index 5a97be3d96..1f1e50d7fb 100644
--- a/src/widgets/effects/qgraphicseffect.cpp
+++ b/src/widgets/effects/qgraphicseffect.cpp
@@ -316,8 +316,8 @@ QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offse
return pixmapItem->pixmap();
}
- if (system == Qt::DeviceCoordinates && item
- && !static_cast<const QGraphicsItemEffectSourcePrivate *>(d_func())->info) {
+ if (Q_UNLIKELY(system == Qt::DeviceCoordinates && item &&
+ !static_cast<const QGraphicsItemEffectSourcePrivate *>(d_func())->info)) {
qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
return QPixmap();
}
diff --git a/src/widgets/effects/qpixmapfilter.cpp b/src/widgets/effects/qpixmapfilter.cpp
index b21726400f..fee8f83305 100644
--- a/src/widgets/effects/qpixmapfilter.cpp
+++ b/src/widgets/effects/qpixmapfilter.cpp
@@ -1019,6 +1019,15 @@ QPixmapColorizeFilter::QPixmapColorizeFilter(QObject *parent)
}
/*!
+ \internal
+*/
+QPixmapColorizeFilter::~QPixmapColorizeFilter()
+{
+ // was inline until Qt 5.6, so essentially
+ // must stay empty until ### Qt 6
+}
+
+/*!
Gets the color of the colorize filter.
\internal
diff --git a/src/widgets/effects/qpixmapfilter_p.h b/src/widgets/effects/qpixmapfilter_p.h
index 6ddd62dcfc..8e0eb08949 100644
--- a/src/widgets/effects/qpixmapfilter_p.h
+++ b/src/widgets/effects/qpixmapfilter_p.h
@@ -142,6 +142,7 @@ class Q_WIDGETS_EXPORT QPixmapColorizeFilter : public QPixmapFilter
public:
QPixmapColorizeFilter(QObject *parent = 0);
+ ~QPixmapColorizeFilter();
void setColor(const QColor& color);
QColor color() const;
diff --git a/src/widgets/graphicsview/qgraph_p.h b/src/widgets/graphicsview/qgraph_p.h
index c63c2c6f8e..2c9c58eb4c 100644
--- a/src/widgets/graphicsview/qgraph_p.h
+++ b/src/widgets/graphicsview/qgraph_p.h
@@ -222,9 +222,8 @@ public:
QSet<Vertex *> setOfVertices = vertices();
for (typename QSet<Vertex*>::const_iterator it = setOfVertices.begin(); it != setOfVertices.end(); ++it) {
Vertex *v = *it;
- QList<Vertex*> adjacents = adjacentVertices(v);
- for (int i = 0; i < adjacents.count(); ++i) {
- Vertex *v1 = adjacents.at(i);
+ const QList<Vertex*> adjacents = adjacentVertices(v);
+ for (auto *v1 : adjacents) {
EdgeData *data = edgeData(v, v1);
bool forward = data->from == v;
if (forward) {
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
index dac8e61645..e8501474a5 100644
--- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -31,6 +31,8 @@
**
****************************************************************************/
+#include "qgraphicsanchorlayout_p.h"
+
#include <QtWidgets/qwidget.h>
#include <QtWidgets/qapplication.h>
#include <QtCore/qlinkedlist.h>
@@ -40,7 +42,7 @@
#include <QtCore/qfile.h>
#endif
-#include "qgraphicsanchorlayout_p.h"
+#include <numeric>
#ifndef QT_NO_GRAPHICSVIEW
QT_BEGIN_NAMESPACE
@@ -602,10 +604,10 @@ QSimplexConstraint *GraphPath::constraint(const GraphPath &path) const
QString GraphPath::toString() const
{
QString string(QLatin1String("Path: "));
- foreach(AnchorData *edge, positives)
+ for (AnchorData *edge : positives)
string += QString::fromLatin1(" (+++) %1").arg(edge->toString());
- foreach(AnchorData *edge, negatives)
+ for (AnchorData *edge : negatives)
string += QString::fromLatin1(" (---) %1").arg(edge->toString());
return string;
@@ -1932,8 +1934,7 @@ void QGraphicsAnchorLayoutPrivate::removeVertex(QGraphicsLayoutItem *item, Qt::A
if (AnchorVertex *v = internalVertex(item, edge)) {
Graph<AnchorVertex, AnchorData> &g = graph[edgeOrientation(edge)];
const QList<AnchorVertex *> allVertices = graph[edgeOrientation(edge)].adjacentVertices(v);
- AnchorVertex *v2;
- foreach (v2, allVertices) {
+ for (auto *v2 : allVertices) {
g.removeEdge(v, v2);
removeInternalVertex(item, edge);
removeInternalVertex(v2->m_item, v2->m_edge);
@@ -2057,9 +2058,8 @@ QList<AnchorData *> getVariables(const QList<QSimplexConstraint *> &constraints)
QSet<AnchorData *> variableSet;
for (int i = 0; i < constraints.count(); ++i) {
const QSimplexConstraint *c = constraints.at(i);
- foreach (QSimplexVariable *var, c->variables.keys()) {
- variableSet += static_cast<AnchorData *>(var);
- }
+ for (auto it = c->variables.cbegin(), end = c->variables.cend(); it != end; ++it)
+ variableSet.insert(static_cast<AnchorData *>(it.key()));
}
return variableSet.toList();
}
@@ -2180,10 +2180,7 @@ static void shiftConstraints(const QList<QSimplexConstraint *> &constraints, qre
{
for (int i = 0; i < constraints.count(); ++i) {
QSimplexConstraint *c = constraints.at(i);
- qreal multiplier = 0;
- foreach (qreal v, c->variables) {
- multiplier += v;
- }
+ const qreal multiplier = std::accumulate(c->variables.cbegin(), c->variables.cend(), qreal(0));
c->constant += multiplier * amount;
}
}
@@ -2223,12 +2220,10 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const
// Calculate and set the preferred size for the layout,
// from the edge sizes that were calculated above.
qreal pref(0.0);
- foreach (const AnchorData *ad, path.positives) {
+ for (const AnchorData *ad : path.positives)
pref += ad->sizeAtPreferred;
- }
- foreach (const AnchorData *ad, path.negatives) {
+ for (const AnchorData *ad : path.negatives)
pref -= ad->sizeAtPreferred;
- }
sizeHints[orientation][Qt::MinimumSize] = min;
sizeHints[orientation][Qt::PreferredSize] = pref;
@@ -2323,9 +2318,9 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
graphPaths[orientation].insert(root, GraphPath());
- foreach (AnchorVertex *v, graph[orientation].adjacentVertices(root)) {
+ const auto adjacentVertices = graph[orientation].adjacentVertices(root);
+ for (AnchorVertex *v : adjacentVertices)
queue.enqueue(qMakePair(root, v));
- }
while(!queue.isEmpty()) {
QPair<AnchorVertex *, AnchorVertex *> pair = queue.dequeue();
@@ -2344,10 +2339,9 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
graphPaths[orientation].insert(pair.second, current);
- foreach (AnchorVertex *v,
- graph[orientation].adjacentVertices(pair.second)) {
+ const auto adjacentVertices = graph[orientation].adjacentVertices(pair.second);
+ for (AnchorVertex *v : adjacentVertices)
queue.enqueue(qMakePair(pair.second, v));
- }
}
// We will walk through every reachable items (non-float) store them in a temporary set.
@@ -2368,8 +2362,8 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
*/
void QGraphicsAnchorLayoutPrivate::constraintsFromPaths(Orientation orientation)
{
- foreach (AnchorVertex *vertex, graphPaths[orientation].uniqueKeys())
- {
+ const auto vertices = graphPaths[orientation].uniqueKeys();
+ for (AnchorVertex *vertex : vertices) {
int valueCount = graphPaths[orientation].count(vertex);
if (valueCount == 1)
continue;
@@ -2550,7 +2544,8 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
// remaining constraints.
if (match) {
trunkConstraints += c;
- trunkVariables += QSet<QSimplexVariable *>::fromList(c->variables.keys());
+ for (auto jt = c->variables.cbegin(), end = c->variables.cend(); jt != end; ++jt)
+ trunkVariables.insert(jt.key());
it = remainingConstraints.erase(it);
dirty = true;
} else {
@@ -2593,7 +2588,7 @@ void QGraphicsAnchorLayoutPrivate::identifyFloatItems(const QSet<AnchorData *> &
{
QSet<QGraphicsLayoutItem *> nonFloating;
- foreach (const AnchorData *ad, visited)
+ for (const AnchorData *ad : visited)
identifyNonFloatItems_helper(ad, &nonFloating);
QSet<QGraphicsLayoutItem *> allItems;
@@ -2707,9 +2702,9 @@ void QGraphicsAnchorLayoutPrivate::calculateVertexPositions(
visited.insert(root);
// Add initial edges to the queue
- foreach (AnchorVertex *v, graph[orientation].adjacentVertices(root)) {
+ const auto adjacentVertices = graph[orientation].adjacentVertices(root);
+ for (AnchorVertex *v : adjacentVertices)
queue.enqueue(qMakePair(root, v));
- }
// Do initial calculation required by "interpolateEdge()"
setupEdgesInterpolation(orientation);
@@ -2796,7 +2791,7 @@ void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base, AnchorDat
}
bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList<QSimplexConstraint *> &constraints,
- GraphPath path, qreal *min, qreal *max)
+ const GraphPath &path, qreal *min, qreal *max)
{
QSimplex simplex;
bool feasible = simplex.setConstraints(constraints);
@@ -2983,7 +2978,7 @@ void QGraphicsAnchorLayoutPrivate::dumpGraph(const QString &name)
{
QFile file(QString::fromLatin1("anchorlayout.%1.dot").arg(name));
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
- qWarning("Could not write to %s", file.fileName().toLocal8Bit().constData());
+ qWarning("Could not write to %ls", qUtf16Printable(file.fileName()));
QString str = QString::fromLatin1("digraph anchorlayout {\nnode [shape=\"rect\"]\n%1}");
QString dotContents = graph[0].serializeToDot();
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.h b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h
index a5c7f1e2ce..15fd0d0b79 100644
--- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.h
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.h
@@ -522,7 +522,7 @@ public:
// Linear Programming solver methods
bool solveMinMax(const QList<QSimplexConstraint *> &constraints,
- GraphPath path, qreal *min, qreal *max);
+ const GraphPath &path, qreal *min, qreal *max);
bool solvePreferred(const QList<QSimplexConstraint *> &constraints,
const QList<AnchorData *> &variables);
bool hasConflicts() const;
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 5f5c402a4a..31b2778251 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -812,6 +812,85 @@ static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, cons
/*!
\internal
+*/
+QGraphicsItemPrivate::QGraphicsItemPrivate()
+ : z(0),
+ opacity(1.),
+ scene(nullptr),
+ parent(nullptr),
+ transformData(nullptr),
+ graphicsEffect(nullptr),
+ index(-1),
+ siblingIndex(-1),
+ itemDepth(-1),
+ focusProxy(nullptr),
+ subFocusItem(nullptr),
+ focusScopeItem(nullptr),
+ imHints(Qt::ImhNone),
+ panelModality(QGraphicsItem::NonModal),
+ acceptedMouseButtons(0x1f),
+ visible(true),
+ explicitlyHidden(false),
+ enabled(true),
+ explicitlyDisabled(false),
+ selected(false),
+ acceptsHover(false),
+ acceptDrops(false),
+ isMemberOfGroup(false),
+ handlesChildEvents(false),
+ itemDiscovered(false),
+ hasCursor(false),
+ ancestorFlags(0),
+ cacheMode(0),
+ hasBoundingRegionGranularity(false),
+ isWidget(false),
+ dirty(false),
+ dirtyChildren(false),
+ localCollisionHack(false),
+ inSetPosHelper(false),
+ needSortChildren(false),
+ allChildrenDirty(false),
+ fullUpdatePending(false),
+ flags(0),
+ paintedViewBoundingRectsNeedRepaint(false),
+ dirtySceneTransform(true),
+ geometryChanged(true),
+ inDestructor(false),
+ isObject(false),
+ ignoreVisible(false),
+ ignoreOpacity(false),
+ acceptTouchEvents(false),
+ acceptedTouchBeginEvent(false),
+ filtersDescendantEvents(false),
+ sceneTransformTranslateOnly(false),
+ notifyBoundingRectChanged(false),
+ notifyInvalidated(false),
+ mouseSetsFocus(true),
+ explicitActivate(false),
+ wantsActive(false),
+ holesInSiblingIndex(false),
+ sequentialOrdering(true),
+ updateDueToGraphicsEffect(false),
+ scenePosDescendants(false),
+ pendingPolish(false),
+ mayHaveChildWithGraphicsEffect(false),
+ isDeclarativeItem(false),
+ sendParentChangeNotification(false),
+ dirtyChildrenBoundingRect(true),
+ globalStackingOrder(-1),
+ q_ptr(nullptr)
+{
+}
+
+/*!
+ \internal
+*/
+QGraphicsItemPrivate::~QGraphicsItemPrivate()
+{
+}
+
+/*!
+ \internal
Propagates the ancestor flag \a flag with value \a enabled to all this
item's children. If \a root is false, the flag is also set on this item
@@ -1373,12 +1452,9 @@ void QGraphicsItemCache::purge()
{
QPixmapCache::remove(key);
key = QPixmapCache::Key();
- QMutableHashIterator<QPaintDevice *, DeviceData> it(deviceData);
- while (it.hasNext()) {
- DeviceData &data = it.next().value();
+ const auto &constDeviceData = deviceData; // avoid detach
+ for (const auto &data : constDeviceData)
QPixmapCache::remove(data.key);
- data.cacheIndent = QPoint();
- }
deviceData.clear();
allExposed = true;
exposed.clear();
@@ -1443,7 +1519,8 @@ QGraphicsItem::~QGraphicsItem()
if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) {
QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
if (QGestureManager *manager = QGestureManager::instance()) {
- foreach (Qt::GestureType type, d_ptr->gestureContext.keys())
+ const auto types = d_ptr->gestureContext.keys(); // FIXME: iterate over the map directly?
+ for (Qt::GestureType type : types)
manager->cleanupCachedGestures(o, type);
}
}
@@ -2167,11 +2244,13 @@ void QGraphicsItem::setCursor(const QCursor &cursor)
d_ptr->hasCursor = 1;
if (d_ptr->scene) {
d_ptr->scene->d_func()->allItemsUseDefaultCursor = false;
- foreach (QGraphicsView *view, d_ptr->scene->views()) {
+ const auto views = d_ptr->scene->views();
+ for (QGraphicsView *view : views) {
view->viewport()->setMouseTracking(true);
// Note: Some of this logic is duplicated in QGraphicsView's mouse events.
if (view->underMouse()) {
- foreach (QGraphicsItem *itemUnderCursor, view->items(view->mapFromGlobal(QCursor::pos()))) {
+ const auto itemsUnderCursor = view->items(view->mapFromGlobal(QCursor::pos()));
+ for (QGraphicsItem *itemUnderCursor : itemsUnderCursor) {
if (itemUnderCursor->hasCursor()) {
QMetaObject::invokeMethod(view, "_q_setViewportCursor",
Q_ARG(QCursor, itemUnderCursor->cursor()));
@@ -2210,7 +2289,8 @@ void QGraphicsItem::unsetCursor()
d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraCursor);
d_ptr->hasCursor = 0;
if (d_ptr->scene) {
- foreach (QGraphicsView *view, d_ptr->scene->views()) {
+ const auto views = d_ptr->scene->views();
+ for (QGraphicsView *view : views) {
if (view->underMouse() && view->itemAt(view->mapFromGlobal(QCursor::pos())) == this) {
QMetaObject::invokeMethod(view, "_q_unsetViewportCursor");
break;
@@ -2846,7 +2926,8 @@ QRectF QGraphicsItemPrivate::effectiveBoundingRect(const QRectF &rect) const
return effect->boundingRectFor(rect);
QRectF sceneRect = q->mapRectToScene(rect);
QRectF sceneEffectRect;
- foreach (QGraphicsView *view, scene->views()) {
+ const auto views = scene->views();
+ for (QGraphicsView *view : views) {
QRectF deviceRect = view->d_func()->mapRectFromScene(sceneRect);
QRect deviceEffectRect = effect->boundingRectFor(deviceRect).toAlignedRect();
sceneEffectRect |= view->d_func()->mapRectToScene(deviceEffectRect);
@@ -5140,7 +5221,8 @@ bool QGraphicsItem::isObscured(const QRectF &rect) const
QRectF br = boundingRect();
QRectF testRect = rect.isNull() ? br : rect;
- foreach (QGraphicsItem *item, d->scene->items(mapToScene(br), Qt::IntersectsItemBoundingRect)) {
+ const auto items = d->scene->items(mapToScene(br), Qt::IntersectsItemBoundingRect);
+ for (QGraphicsItem *item : items) {
if (item == this)
break;
if (qt_QGraphicsItem_isObscured(this, item, testRect))
@@ -5262,7 +5344,8 @@ QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) c
QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity);
QRegion r;
QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0));
- foreach (const QRect &rect, QRegion( colorMask ).rects()) {
+ const auto rects = QRegion(colorMask).rects();
+ for (const QRect &rect : rects) {
QRect xrect = unscale.mapRect(rect).translated(deviceRect.topLeft() - QPoint(pad, pad));
r += xrect.adjusted(-1, -1, 1, 1) & deviceRect;
}
@@ -6523,7 +6606,8 @@ bool QGraphicsItem::isUnderMouse() const
return false;
QPoint cursorPos = QCursor::pos();
- foreach (QGraphicsView *view, d->scene->views()) {
+ const auto views = d->scene->views();
+ for (QGraphicsView *view : views) {
if (contains(mapFromScene(view->mapToScene(view->mapFromGlobal(cursorPos)))))
return true;
}
diff --git a/src/widgets/graphicsview/qgraphicsitem_p.h b/src/widgets/graphicsview/qgraphicsitem_p.h
index fe4bac12bc..a8d4e950b5 100644
--- a/src/widgets/graphicsview/qgraphicsitem_p.h
+++ b/src/widgets/graphicsview/qgraphicsitem_p.h
@@ -168,77 +168,8 @@ public:
AncestorContainsChildren = 0x10
};
- inline QGraphicsItemPrivate()
- : z(0),
- opacity(1.),
- scene(0),
- parent(0),
- transformData(0),
- graphicsEffect(0),
- index(-1),
- siblingIndex(-1),
- itemDepth(-1),
- focusProxy(0),
- subFocusItem(0),
- focusScopeItem(0),
- imHints(Qt::ImhNone),
- panelModality(QGraphicsItem::NonModal),
- acceptedMouseButtons(0x1f),
- visible(1),
- explicitlyHidden(0),
- enabled(1),
- explicitlyDisabled(0),
- selected(0),
- acceptsHover(0),
- acceptDrops(0),
- isMemberOfGroup(0),
- handlesChildEvents(0),
- itemDiscovered(0),
- hasCursor(0),
- ancestorFlags(0),
- cacheMode(0),
- hasBoundingRegionGranularity(0),
- isWidget(0),
- dirty(0),
- dirtyChildren(0),
- localCollisionHack(0),
- inSetPosHelper(0),
- needSortChildren(0),
- allChildrenDirty(0),
- fullUpdatePending(0),
- flags(0),
- paintedViewBoundingRectsNeedRepaint(0),
- dirtySceneTransform(1),
- geometryChanged(1),
- inDestructor(0),
- isObject(0),
- ignoreVisible(0),
- ignoreOpacity(0),
- acceptTouchEvents(0),
- acceptedTouchBeginEvent(0),
- filtersDescendantEvents(0),
- sceneTransformTranslateOnly(0),
- notifyBoundingRectChanged(0),
- notifyInvalidated(0),
- mouseSetsFocus(1),
- explicitActivate(0),
- wantsActive(0),
- holesInSiblingIndex(0),
- sequentialOrdering(1),
- updateDueToGraphicsEffect(0),
- scenePosDescendants(0),
- pendingPolish(0),
- mayHaveChildWithGraphicsEffect(0),
- isDeclarativeItem(0),
- sendParentChangeNotification(0),
- dirtyChildrenBoundingRect(1),
- globalStackingOrder(-1),
- q_ptr(0)
- {
- }
-
- inline virtual ~QGraphicsItemPrivate()
- { }
+ QGraphicsItemPrivate();
+ virtual ~QGraphicsItemPrivate();
static const QGraphicsItemPrivate *get(const QGraphicsItem *item)
{
@@ -354,7 +285,7 @@ public:
struct ExtraStruct {
ExtraStruct() {} // for QVector, don't use
- ExtraStruct(Extra type, QVariant value)
+ ExtraStruct(Extra type, const QVariant &value)
: type(type), value(value)
{ }
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
index 88bed7cf0e..ea9fc0a0d5 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -187,6 +187,31 @@ Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets();
/*!
\internal
*/
+QGraphicsProxyWidgetPrivate::QGraphicsProxyWidgetPrivate()
+ : QGraphicsWidgetPrivate(),
+ dragDropWidget(nullptr),
+ posChangeMode(NoMode),
+ sizeChangeMode(NoMode),
+ visibleChangeMode(NoMode),
+ enabledChangeMode(NoMode),
+ styleChangeMode(NoMode),
+ paletteChangeMode(NoMode),
+ tooltipChangeMode(NoMode),
+ focusFromWidgetToProxy(false),
+ proxyIsGivingFocus(false)
+{
+}
+
+/*!
+ \internal
+*/
+QGraphicsProxyWidgetPrivate::~QGraphicsProxyWidgetPrivate()
+{
+}
+
+/*!
+ \internal
+*/
void QGraphicsProxyWidgetPrivate::init()
{
Q_Q(QGraphicsProxyWidget);
@@ -570,7 +595,8 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto
resolvePalette(inheritedPaletteResolveMask);
widget->update();
- foreach (QGraphicsItem *child, q->childItems()) {
+ const auto childItems = q->childItems();
+ for (QGraphicsItem *child : childItems) {
if (child->d_ptr->isProxyWidget()) {
QGraphicsProxyWidget *childProxy = static_cast<QGraphicsProxyWidget *>(child);
QWidget * parent = childProxy->widget();
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget_p.h b/src/widgets/graphicsview/qgraphicsproxywidget_p.h
index c0e0d73aa9..a3386c78cb 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget_p.h
+++ b/src/widgets/graphicsview/qgraphicsproxywidget_p.h
@@ -56,17 +56,9 @@ class Q_AUTOTEST_EXPORT QGraphicsProxyWidgetPrivate : public QGraphicsWidgetPriv
{
Q_DECLARE_PUBLIC(QGraphicsProxyWidget)
public:
- QGraphicsProxyWidgetPrivate()
- : dragDropWidget(0),
- posChangeMode(NoMode),
- sizeChangeMode(NoMode),
- visibleChangeMode(NoMode),
- enabledChangeMode(NoMode),
- styleChangeMode(NoMode),
- paletteChangeMode(NoMode),
- tooltipChangeMode(NoMode),
- focusFromWidgetToProxy(0)
- { }
+ QGraphicsProxyWidgetPrivate();
+ ~QGraphicsProxyWidgetPrivate();
+
void init();
void sendWidgetMouseEvent(QGraphicsSceneMouseEvent *event);
void sendWidgetMouseEvent(QGraphicsSceneHoverEvent *event);
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
index ad58aeb488..80c0aa1a30 100644
--- a/src/widgets/graphicsview/qgraphicsscene.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -232,6 +232,7 @@
#include <QtGui/qpainter.h>
#include <QtGui/qpixmapcache.h>
#include <QtGui/qpolygon.h>
+#include <QtGui/qtouchdevice.h>
#include <QtWidgets/qstyleoption.h>
#include <QtWidgets/qtooltip.h>
#include <QtGui/qtransform.h>
@@ -755,8 +756,9 @@ void QGraphicsScenePrivate::setActivePanelHelper(QGraphicsItem *item, bool durin
q->sendEvent(activePanel, &event);
} else if (panel && !duringActivationEvent) {
// Deactivate the scene if changing activation to a panel.
+ const auto items = q->items();
QEvent event(QEvent::WindowDeactivate);
- foreach (QGraphicsItem *item, q->items()) {
+ for (QGraphicsItem *item : items) {
if (item->isVisible() && !item->isPanel() && !item->parentItem())
q->sendEvent(item, &event);
}
@@ -790,9 +792,10 @@ void QGraphicsScenePrivate::setActivePanelHelper(QGraphicsItem *item, bool durin
} while (fw != panel);
}
} else if (q->isActive()) {
+ const auto items = q->items();
// Activate the scene
QEvent event(QEvent::WindowActivate);
- foreach (QGraphicsItem *item, q->items()) {
+ for (QGraphicsItem *item : items) {
if (item->isVisible() && !item->isPanel() && !item->parentItem())
q->sendEvent(item, &event);
}
@@ -1544,7 +1547,8 @@ void QGraphicsScenePrivate::updateFont(const QFont &font)
// Resolve the fonts of all top-level widget items, or widget items
// whose parent is not a widget.
- foreach (QGraphicsItem *item, q->items()) {
+ const auto items = q->items();
+ for (QGraphicsItem *item : items) {
if (!item->parentItem()) {
// Resolvefont for an item is a noop operation, but
// every item can be a widget, or can have a widget
@@ -1600,7 +1604,8 @@ void QGraphicsScenePrivate::updatePalette(const QPalette &palette)
// Resolve the palettes of all top-level widget items, or widget items
// whose parent is not a widget.
- foreach (QGraphicsItem *item, q->items()) {
+ const auto items = q->items();
+ for (QGraphicsItem *item : items) {
if (!item->parentItem()) {
// ResolvePalette for an item is a noop operation, but
// every item can be a widget, or can have a widget
@@ -1946,7 +1951,8 @@ QRectF QGraphicsScene::itemsBoundingRect() const
{
// Does not take untransformable items into account.
QRectF boundingRect;
- foreach (QGraphicsItem *item, items())
+ const auto items_ = items();
+ for (QGraphicsItem *item : items_)
boundingRect |= item->sceneBoundingRect();
return boundingRect;
}
@@ -2115,7 +2121,8 @@ QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item,
// Does not support ItemIgnoresTransformations.
QList<QGraphicsItem *> tmp;
- foreach (QGraphicsItem *itemInVicinity, d->index->estimateItems(item->sceneBoundingRect(), Qt::DescendingOrder)) {
+ const auto itemsInVicinity = d->index->estimateItems(item->sceneBoundingRect(), Qt::DescendingOrder);
+ for (QGraphicsItem *itemInVicinity : itemsInVicinity) {
if (item != itemInVicinity && item->collidesWithItem(itemInVicinity, mode))
tmp << itemInVicinity;
}
@@ -2302,7 +2309,8 @@ void QGraphicsScene::setSelectionArea(const QPainterPath &path,
bool changed = false;
// Set all items in path to selected.
- foreach (QGraphicsItem *item, items(path, mode, Qt::DescendingOrder, deviceTransform)) {
+ const auto items = this->items(path, mode, Qt::DescendingOrder, deviceTransform);
+ for (QGraphicsItem *item : items) {
if (item->flags() & QGraphicsItem::ItemIsSelectable) {
if (!item->isSelected())
changed = true;
@@ -2429,7 +2437,7 @@ QGraphicsItemGroup *QGraphicsScene::createItemGroup(const QList<QGraphicsItem *>
QGraphicsItemGroup *group = new QGraphicsItemGroup(commonAncestor);
if (!commonAncestor)
addItem(group);
- foreach (QGraphicsItem *item, items)
+ for (QGraphicsItem *item : items)
group->addToGroup(item);
return group;
}
@@ -2443,7 +2451,8 @@ QGraphicsItemGroup *QGraphicsScene::createItemGroup(const QList<QGraphicsItem *>
*/
void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
{
- foreach (QGraphicsItem *item, group->childItems())
+ const auto items = group->childItems();
+ for (QGraphicsItem *item : items)
group->removeFromGroup(item);
removeItem(group);
delete group;
@@ -2558,7 +2567,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
}
#ifndef QT_NO_GESTURES
- foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
+ const auto gestures = item->d_ptr->gestureContext.keys(); // FIXME: iterate over hash directly?
+ for (Qt::GestureType gesture : gestures)
d->grabGesture(item, gesture);
#endif
@@ -3129,7 +3139,8 @@ void QGraphicsScene::setForegroundBrush(const QBrush &brush)
{
Q_D(QGraphicsScene);
d->foregroundBrush = brush;
- foreach (QGraphicsView *view, views())
+ const auto views_ = views();
+ for (QGraphicsView *view : views_)
view->viewport()->update();
update();
}
@@ -3237,7 +3248,8 @@ void QGraphicsScene::update(const QRectF &rect)
*/
void QGraphicsScene::invalidate(const QRectF &rect, SceneLayers layers)
{
- foreach (QGraphicsView *view, views())
+ const auto views_ = views();
+ for (QGraphicsView *view : views_)
view->invalidateScene(rect, layers);
update(rect);
}
@@ -3278,7 +3290,8 @@ QList <QGraphicsView *> QGraphicsScene::views() const
void QGraphicsScene::advance()
{
for (int i = 0; i < 2; ++i) {
- foreach (QGraphicsItem *item, items())
+ const auto items_ = items();
+ for (QGraphicsItem *item : items_)
item->advance(i);
}
}
@@ -3433,7 +3446,8 @@ bool QGraphicsScene::event(QEvent *event)
} else {
// Activate all toplevel items.
QEvent event(QEvent::WindowActivate);
- foreach (QGraphicsItem *item, items()) {
+ const auto items_ = items();
+ for (QGraphicsItem *item : items_) {
if (item->isVisible() && !item->isPanel() && !item->parentItem())
sendEvent(item, &event);
}
@@ -3451,7 +3465,8 @@ bool QGraphicsScene::event(QEvent *event)
} else {
// Activate all toplevel items.
QEvent event(QEvent::WindowDeactivate);
- foreach (QGraphicsItem *item, items()) {
+ const auto items_ = items();
+ for (QGraphicsItem *item : items_) {
if (item->isVisible() && !item->isPanel() && !item->parentItem())
sendEvent(item, &event);
}
@@ -3546,9 +3561,10 @@ void QGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMen
// Send the event to all items at this position until one item accepts the
// event.
- foreach (QGraphicsItem *item, d->itemsAtPosition(contextMenuEvent->screenPos(),
- contextMenuEvent->scenePos(),
- contextMenuEvent->widget())) {
+ const auto items = d->itemsAtPosition(contextMenuEvent->screenPos(),
+ contextMenuEvent->scenePos(),
+ contextMenuEvent->widget());
+ for (QGraphicsItem *item : items) {
contextMenuEvent->setPos(item->d_ptr->genericMapFromScene(contextMenuEvent->scenePos(),
contextMenuEvent->widget()));
contextMenuEvent->accept();
@@ -3604,9 +3620,10 @@ void QGraphicsScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
// Find the topmost enabled items under the cursor. They are all
// candidates for accepting drag & drop events.
- foreach (QGraphicsItem *item, d->itemsAtPosition(event->screenPos(),
- event->scenePos(),
- event->widget())) {
+ const auto items = d->itemsAtPosition(event->screenPos(),
+ event->scenePos(),
+ event->widget());
+ for (QGraphicsItem *item : items) {
if (!item->isEnabled() || !item->acceptDrops())
continue;
@@ -3869,15 +3886,15 @@ bool QGraphicsScenePrivate::dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEv
QList<QGraphicsItem *> parents;
QGraphicsItem *parent = item;
while (parent && parent != commonAncestorItem) {
- parents.prepend(parent);
+ parents.append(parent);
if (parent->isPanel()) {
// Stop at the panel - we don't deliver beyond this point.
break;
}
parent = parent->parentItem();
}
- for (int i = 0; i < parents.size(); ++i) {
- parent = parents.at(i);
+ for (auto it = parents.crbegin(), end = parents.crend(); it != end; ++it) {
+ QGraphicsItem *parent = *it;
hoverItems << parent;
if (itemAcceptsHoverEvents_helper(parent))
sendHoverEvent(QEvent::GraphicsSceneHoverEnter, parent, hoverEvent);
@@ -4132,9 +4149,9 @@ void QGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
void QGraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent)
{
Q_D(QGraphicsScene);
- QList<QGraphicsItem *> wheelCandidates = d->itemsAtPosition(wheelEvent->screenPos(),
- wheelEvent->scenePos(),
- wheelEvent->widget());
+ const QList<QGraphicsItem *> wheelCandidates = d->itemsAtPosition(wheelEvent->screenPos(),
+ wheelEvent->scenePos(),
+ wheelEvent->widget());
#ifdef Q_DEAD_CODE_FROM_QT4_MAC
// On Mac, ignore the event if the first item under the mouse is not the last opened
@@ -4156,7 +4173,7 @@ void QGraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent)
#endif
bool hasSetFocus = false;
- foreach (QGraphicsItem *item, wheelCandidates) {
+ for (QGraphicsItem *item : wheelCandidates) {
if (!hasSetFocus && item->isEnabled()
&& ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) {
if (item->isWidget() && static_cast<QGraphicsWidget *>(item)->focusPolicy() == Qt::WheelFocus) {
@@ -4634,7 +4651,8 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
for (int i = 0; i < exposed.size(); ++i)
br |= exposed.at(i);
QTransform pixmapToItem = itemToPixmap.inverted();
- foreach (const QRect &r, scrollExposure.rects())
+ const auto rects = scrollExposure.rects();
+ for (const QRect &r : rects)
br |= pixmapToItem.mapRect(r);
}
styleOptionTmp = *option;
@@ -5563,7 +5581,8 @@ void QGraphicsScene::setStyle(QStyle *style)
QApplication::sendEvent(this, &event);
// Notify all widgets that don't have a style explicitly set.
- foreach (QGraphicsItem *item, items()) {
+ const auto items_ = items();
+ for (QGraphicsItem *item : items_) {
if (item->isWidget()) {
QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
if (!widget->testAttribute(Qt::WA_SetStyle))
@@ -5727,18 +5746,16 @@ void QGraphicsScene::setActiveWindow(QGraphicsWidget *widget)
// Raise
if (panel) {
- QList<QGraphicsItem *> siblingWindows;
QGraphicsItem *parent = panel->parentItem();
// Raise ### inefficient for toplevels
- foreach (QGraphicsItem *sibling, parent ? parent->childItems() : items()) {
- if (sibling != panel && sibling->isWindow())
- siblingWindows << sibling;
- }
// Find the highest z value.
qreal z = panel->zValue();
- for (int i = 0; i < siblingWindows.size(); ++i)
- z = qMax(z, siblingWindows.at(i)->zValue());
+ const auto siblings = parent ? parent->childItems() : items();
+ for (QGraphicsItem *sibling : siblings) {
+ if (sibling != panel && sibling->isWindow())
+ z = qMax(z, sibling->zValue());
+ }
// This will probably never overflow.
const qreal litt = qreal(0.001);
@@ -5821,7 +5838,8 @@ void QGraphicsScenePrivate::addView(QGraphicsView *view)
{
views << view;
#ifndef QT_NO_GESTURES
- foreach (Qt::GestureType gesture, grabbedGestures.keys())
+ const auto gestures = grabbedGestures.keys();
+ for (Qt::GestureType gesture : gestures)
view->viewport()->grabGesture(gesture);
#endif
}
@@ -5833,14 +5851,11 @@ void QGraphicsScenePrivate::removeView(QGraphicsView *view)
void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent)
{
- QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
- for (int i = 0; i < touchPoints.count(); ++i) {
- QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
+ for (auto &touchPoint : touchEvent->_touchPoints) {
touchPoint.setRect(item->mapFromScene(touchPoint.sceneRect()).boundingRect());
touchPoint.setStartPos(item->d_ptr->genericMapFromScene(touchPoint.startScenePos(), static_cast<QWidget *>(touchEvent->target())));
touchPoint.setLastPos(item->d_ptr->genericMapFromScene(touchPoint.lastScenePos(), static_cast<QWidget *>(touchEvent->target())));
}
- touchEvent->setTouchPoints(touchPoints);
}
int QGraphicsScenePrivate::findClosestTouchPointId(const QPointF &scenePos)
@@ -6166,7 +6181,7 @@ void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &ges
QSet<QGesture *> *conflicts)
{
QSet<QGesture *> normalGestures; // that are not in conflicted state.
- foreach (QGesture *gesture, gestures) {
+ for (QGesture *gesture : gestures) {
if (!gesture->hasHotSpot())
continue;
const Qt::GestureType gestureType = gesture->gestureType();
@@ -6214,7 +6229,7 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
if (!graphicsView)
return;
- QList<QGesture *> allGestures = event->gestures();
+ const QList<QGesture *> allGestures = event->gestures();
DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
<< "Gestures:" << allGestures;
@@ -6222,7 +6237,7 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
QPoint delta = viewport->mapFromGlobal(QPoint());
QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y())
* graphicsView->viewportTransform().inverted();
- foreach (QGesture *gesture, allGestures) {
+ for (QGesture *gesture : allGestures) {
// cache scene coordinates of the hot spot
if (gesture->hasHotSpot()) {
gesture->d_func()->sceneHotSpot = toScene.map(gesture->hotSpot());
@@ -6257,7 +6272,7 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
QPointer<QGraphicsObject> item = cachedTargetItems.at(i);
// get gestures to deliver to the current item
- QSet<QGesture *> gestures = conflictedGestures & cachedItemGestures.value(item.data());
+ const QSet<QGesture *> gestures = conflictedGestures & cachedItemGestures.value(item.data());
if (gestures.isEmpty())
continue;
@@ -6270,11 +6285,11 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
ev.setWidget(event->widget());
// mark event and individual gestures as ignored
ev.ignore();
- foreach(QGesture *g, gestures)
+ for (QGesture *g : gestures)
ev.setAccepted(g, false);
sendEvent(item.data(), &ev);
// mark all accepted gestures to deliver them as normal gesture events
- foreach (QGesture *g, gestures) {
+ for (QGesture *g : gestures) {
if (ev.isAccepted() || ev.isAccepted(g)) {
conflictedGestures.remove(g);
// mark the item as a gesture target
@@ -6309,7 +6324,8 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
QGraphicsObject *item = cachedTargetItems.at(i);
// get gestures to deliver to the current item
- foreach (QGesture *g, cachedItemGestures.value(item)) {
+ const auto gestures = cachedItemGestures.value(item);
+ for (QGesture *g : gestures) {
if (!gestureTargets.contains(g)) {
gestureTargets.insert(g, item);
normalGestures.remove(g);
@@ -6323,7 +6339,7 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
// deliver all gesture events
QSet<QGesture *> undeliveredGestures;
QSet<QGesture *> parentPropagatedGestures;
- foreach (QGesture *gesture, allGestures) {
+ for (QGesture *gesture : allGestures) {
if (QGraphicsObject *target = gestureTargets.value(gesture, 0)) {
cachedItemGestures[target].insert(gesture);
cachedTargetItems.append(target);
@@ -6435,7 +6451,7 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
}
// forget about targets for gestures that have ended
- foreach (QGesture *g, allGestures) {
+ for (QGesture *g : allGestures) {
switch (g->state()) {
case Qt::GestureFinished:
case Qt::GestureCanceled:
@@ -6495,32 +6511,33 @@ void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original)
}
Q_ASSERT(target);
- QList<QGesture *> list = gestures.toList();
+ const QList<QGesture *> list = gestures.toList();
QGestureEvent ev(list);
sendEvent(target, &ev);
- foreach (QGesture *g, list) {
- if (ev.isAccepted() || ev.isAccepted(g))
- gestures.remove(g);
- }
+ if (!ev.isAccepted()) {
+ for (QGesture *g : list) {
- foreach (QGesture *g, gestures) {
- if (!g->hasHotSpot())
- continue;
+ if (ev.isAccepted(g))
+ continue;
- QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), g->d_func()->sceneHotSpot, 0);
- for (int j = 0; j < items.size(); ++j) {
- QGraphicsObject *item = items.at(j)->toGraphicsObject();
- if (!item)
+ if (!g->hasHotSpot())
continue;
- QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
- if (d->gestureContext.contains(g->gestureType())) {
- QList<QGesture *> list;
- list << g;
- QGestureEvent ev(list);
- sendEvent(item, &ev);
- if (ev.isAccepted() || ev.isAccepted(g))
- break; // successfully delivered
+
+ QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), g->d_func()->sceneHotSpot, 0);
+ for (int j = 0; j < items.size(); ++j) {
+ QGraphicsObject *item = items.at(j)->toGraphicsObject();
+ if (!item)
+ continue;
+ QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
+ if (d->gestureContext.contains(g->gestureType())) {
+ QList<QGesture *> list;
+ list << g;
+ QGestureEvent ev(list);
+ sendEvent(item, &ev);
+ if (ev.isAccepted() || ev.isAccepted(g))
+ break; // successfully delivered
+ }
}
}
}
diff --git a/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
index ce43b1332d..47d599278a 100644
--- a/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
+++ b/src/widgets/graphicsview/qgraphicsscenebsptreeindex.cpp
@@ -77,6 +77,8 @@
#include <QtCore/qmath.h>
#include <QtCore/qdebug.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
static inline int intmaxlog(int n)
@@ -545,23 +547,18 @@ QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) co
Q_D(const QGraphicsSceneBspTreeIndex);
const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->purgeRemovedItems();
QList<QGraphicsItem *> itemList;
+ itemList.reserve(d->indexedItems.size() + d->unindexedItems.size());
+
+ // Rebuild the list of items to avoid holes. ### We could also just
+ // compress the item lists at this point.
+ QGraphicsItem *null = nullptr; // work-around for (at least) MSVC 2012 emitting
+ // warning C4100 for its own header <algorithm>
+ // when passing nullptr directly to remove_copy:
+ std::remove_copy(d->indexedItems.cbegin(), d->indexedItems.cend(),
+ std::back_inserter(itemList), null);
+ std::remove_copy(d->unindexedItems.cbegin(), d->unindexedItems.cend(),
+ std::back_inserter(itemList), null);
- // If freeItemIndexes is empty, we know there are no holes in indexedItems and
- // unindexedItems.
- if (d->freeItemIndexes.isEmpty()) {
- if (d->unindexedItems.isEmpty()) {
- itemList = d->indexedItems;
- } else {
- itemList = d->indexedItems + d->unindexedItems;
- }
- } else {
- // Rebuild the list of items to avoid holes. ### We could also just
- // compress the item lists at this point.
- foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) {
- if (item)
- itemList << item;
- }
- }
d->sortItems(&itemList, order, d->sortCacheEnabled);
return itemList;
}
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index ac8cd45f9e..ad4733145a 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -799,7 +799,8 @@ void QGraphicsViewPrivate::_q_setViewportCursor(const QCursor &cursor)
void QGraphicsViewPrivate::_q_unsetViewportCursor()
{
Q_Q(QGraphicsView);
- foreach (QGraphicsItem *item, q->items(lastMouseEvent.pos())) {
+ const auto items = q->items(lastMouseEvent.pos());
+ for (QGraphicsItem *item : items) {
if (item->hasCursor()) {
_q_setViewportCursor(item->cursor());
return;
@@ -1139,7 +1140,8 @@ QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedReg
// the expose region, convert it to a path, and then search for items
// using QGraphicsScene::items(QPainterPath);
QRegion adjustedRegion;
- foreach (const QRect &r, exposedRegion.rects())
+ const auto rects = exposedRegion.rects();
+ for (const QRect &r : rects)
adjustedRegion += r.adjusted(-1, -1, 1, 1);
const QPainterPath exposedScenePath(q->mapToScene(qt_regionToPath(adjustedRegion)));
@@ -2465,7 +2467,7 @@ QPolygonF QGraphicsView::mapToScene(const QPolygon &polygon) const
{
QPolygonF poly;
poly.reserve(polygon.count());
- foreach (const QPoint &point, polygon)
+ for (const QPoint &point : polygon)
poly << mapToScene(point);
return poly;
}
@@ -2561,7 +2563,7 @@ QPolygon QGraphicsView::mapFromScene(const QPolygonF &polygon) const
{
QPolygon poly;
poly.reserve(polygon.count());
- foreach (const QPointF &point, polygon)
+ for (const QPointF &point : polygon)
poly << mapFromScene(point);
return poly;
}
@@ -2694,7 +2696,7 @@ void QGraphicsView::updateScene(const QList<QRectF> &rects)
QTransform transform = viewportTransform();
// Convert scene rects to viewport rects.
- foreach (const QRectF &rect, rects) {
+ for (const QRectF &rect : rects) {
QRect xrect = transform.mapRect(rect).toAlignedRect();
if (!(d->optimizationFlags & DontAdjustForAntialiasing))
xrect.adjust(-2, -2, 2, 2);
@@ -2791,7 +2793,8 @@ void QGraphicsView::setupViewport(QWidget *widget)
#ifndef QT_NO_GESTURES
if (d->scene) {
- foreach (Qt::GestureType gesture, d->scene->d_func()->grabbedGestures.keys())
+ const auto gestures = d->scene->d_func()->grabbedGestures.keys();
+ for (Qt::GestureType gesture : gestures)
widget->grabGesture(gesture);
}
#endif
diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp
index 8ffb60411c..db1cdd42ab 100644
--- a/src/widgets/graphicsview/qgraphicswidget.cpp
+++ b/src/widgets/graphicsview/qgraphicswidget.cpp
@@ -251,7 +251,8 @@ QGraphicsWidget::~QGraphicsWidget()
//we check if we have a layout previously
if (d->layout) {
QGraphicsLayout *temp = d->layout;
- foreach (QGraphicsItem * item, childItems()) {
+ const auto items = childItems();
+ for (QGraphicsItem *item : items) {
// In case of a custom layout which doesn't remove and delete items, we ensure that
// the parent layout item does not point to the deleted layout. This code is here to
// avoid regression from 4.4 to 4.5, because according to 4.5 docs it is not really needed.
@@ -2056,7 +2057,11 @@ void QGraphicsWidget::insertAction(QAction *before, QAction *action)
\sa removeAction(), QMenu, insertAction(), QWidget::insertActions()
*/
+#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
+void QGraphicsWidget::insertActions(QAction *before, const QList<QAction *> &actions)
+#else
void QGraphicsWidget::insertActions(QAction *before, QList<QAction *> actions)
+#endif
{
for (int i = 0; i < actions.count(); ++i)
insertAction(before, actions.at(i));
diff --git a/src/widgets/graphicsview/qgraphicswidget.h b/src/widgets/graphicsview/qgraphicswidget.h
index 0878e020bc..f922e80782 100644
--- a/src/widgets/graphicsview/qgraphicswidget.h
+++ b/src/widgets/graphicsview/qgraphicswidget.h
@@ -139,11 +139,12 @@ public:
void addAction(QAction *action);
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
void addActions(const QList<QAction*> &actions);
+ void insertActions(QAction *before, const QList<QAction*> &actions);
#else
void addActions(QList<QAction*> actions);
+ void insertActions(QAction *before, QList<QAction*> actions);
#endif
void insertAction(QAction *before, QAction *action);
- void insertActions(QAction *before, QList<QAction*> actions);
void removeAction(QAction *action);
QList<QAction*> actions() const;
#endif
diff --git a/src/widgets/graphicsview/qgraphicswidget_p.cpp b/src/widgets/graphicsview/qgraphicswidget_p.cpp
index e9ab6dffec..f70862fbf3 100644
--- a/src/widgets/graphicsview/qgraphicswidget_p.cpp
+++ b/src/widgets/graphicsview/qgraphicswidget_p.cpp
@@ -86,6 +86,25 @@ qreal QGraphicsWidgetPrivate::titleBarHeight(const QStyleOptionTitleBar &options
/*!
\internal
*/
+QGraphicsWidgetPrivate::QGraphicsWidgetPrivate()
+ : margins(nullptr),
+ layout(nullptr),
+ inheritedPaletteResolveMask(0),
+ inheritedFontResolveMask(0),
+ inSetGeometry(false),
+ polished(false),
+ inSetPos(false),
+ autoFillBackground(false),
+ focusPolicy(Qt::NoFocus),
+ focusNext(nullptr),
+ focusPrev(nullptr),
+ windowFlags(),
+ windowData(nullptr),
+ setWindowFrameMargins(false),
+ windowFrameMargins(nullptr)
+{
+}
+
QGraphicsWidgetPrivate::~QGraphicsWidgetPrivate()
{
// Remove any lazily allocated data
diff --git a/src/widgets/graphicsview/qgraphicswidget_p.h b/src/widgets/graphicsview/qgraphicswidget_p.h
index 7054dfcc2b..bca30deb9b 100644
--- a/src/widgets/graphicsview/qgraphicswidget_p.h
+++ b/src/widgets/graphicsview/qgraphicswidget_p.h
@@ -64,23 +64,7 @@ class QGraphicsWidgetPrivate : public QGraphicsItemPrivate
{
Q_DECLARE_PUBLIC(QGraphicsWidget)
public:
- QGraphicsWidgetPrivate()
- : margins(0),
- layout(0),
- inheritedPaletteResolveMask(0),
- inheritedFontResolveMask(0),
- inSetGeometry(0),
- polished(0),
- inSetPos(0),
- autoFillBackground(0),
- focusPolicy(Qt::NoFocus),
- focusNext(0),
- focusPrev(0),
- windowFlags(0),
- windowData(0),
- setWindowFrameMargins(false),
- windowFrameMargins(0)
- { }
+ QGraphicsWidgetPrivate();
virtual ~QGraphicsWidgetPrivate();
void init(QGraphicsItem *parentItem, Qt::WindowFlags wFlags);
diff --git a/src/widgets/graphicsview/qsimplex_p.cpp b/src/widgets/graphicsview/qsimplex_p.cpp
index b827ab1400..d4e2e2f922 100644
--- a/src/widgets/graphicsview/qsimplex_p.cpp
+++ b/src/widgets/graphicsview/qsimplex_p.cpp
@@ -153,9 +153,11 @@ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> &newConstraints)
// "variables" is a list that provides a stable, indexed list of all variables
// used in this problem.
QSet<QSimplexVariable *> variablesSet;
- for (int i = 0; i < constraints.size(); ++i)
- variablesSet += \
- QSet<QSimplexVariable *>::fromList(constraints[i]->variables.keys());
+ for (int i = 0; i < constraints.size(); ++i) {
+ const auto &v = constraints.at(i)->variables;
+ for (auto it = v.cbegin(), end = v.cend(); it != end; ++it)
+ variablesSet.insert(it.key());
+ }
variables = variablesSet.toList();
// Set Variables reverse mapping
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index ad7be840d0..edfb5c0f57 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -54,6 +54,7 @@
#include <private/qabstractitemview_p.h>
#include <private/qabstractitemmodel_p.h>
#include <private/qguiapplication_p.h>
+#include <private/qscrollbar_p.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
#endif
@@ -427,6 +428,11 @@ void QAbstractItemViewPrivate::_q_scrollerStateChanged()
\since 4.2
\enum QAbstractItemView::ScrollMode
+ Describes how the scrollbar should behave. When setting the scroll mode
+ to ScrollPerPixel the single step size will adjust automatically unless
+ it was set explicitly using \l{QAbstractSlider::}{setSingleStep()}.
+ The automatic adjustment can be restored by setting the single step size to -1.
+
\value ScrollPerItem The view will scroll the contents one item at a time.
\value ScrollPerPixel The view will scroll the contents one pixel at a time.
*/
@@ -758,7 +764,7 @@ void QAbstractItemView::setSelectionModel(QItemSelectionModel *selectionModel)
Q_ASSERT(selectionModel);
Q_D(QAbstractItemView);
- if (selectionModel->model() != d->model) {
+ if (Q_UNLIKELY(selectionModel->model() != d->model)) {
qWarning("QAbstractItemView::setSelectionModel() failed: "
"Trying to set a selection model, which works on "
"a different model than the view.");
@@ -1113,7 +1119,7 @@ void QAbstractItemView::reset()
void QAbstractItemView::setRootIndex(const QModelIndex &index)
{
Q_D(QAbstractItemView);
- if (index.isValid() && index.model() != d->model) {
+ if (Q_UNLIKELY(index.isValid() && index.model() != d->model)) {
qWarning("QAbstractItemView::setRootIndex failed : index must be from the currently set model");
return;
}
@@ -1166,9 +1172,9 @@ void QAbstractItemView::selectAll()
void QAbstractItemView::edit(const QModelIndex &index)
{
Q_D(QAbstractItemView);
- if (!d->isIndexValid(index))
+ if (Q_UNLIKELY(!d->isIndexValid(index)))
qWarning("edit: index was invalid");
- if (!edit(index, AllEditTriggers, 0))
+ if (Q_UNLIKELY(!edit(index, AllEditTriggers, 0)))
qWarning("edit: editing failed");
}
@@ -1235,6 +1241,10 @@ void QAbstractItemView::setVerticalScrollMode(ScrollMode mode)
return;
QModelIndex topLeft = indexAt(QPoint(0, 0));
d->verticalScrollMode = mode;
+ if (mode == ScrollPerItem)
+ verticalScrollBar()->d_func()->itemviewChangeSingleStep(1); // setSingleStep(-1) => step with 1
+ else
+ verticalScrollBar()->setSingleStep(-1); // Ensure that the view can update single step
updateGeometries(); // update the scroll bars
scrollTo(topLeft, QAbstractItemView::PositionAtTop);
}
@@ -1257,7 +1267,13 @@ QAbstractItemView::ScrollMode QAbstractItemView::verticalScrollMode() const
void QAbstractItemView::setHorizontalScrollMode(ScrollMode mode)
{
Q_D(QAbstractItemView);
+ if (mode == d->horizontalScrollMode)
+ return;
d->horizontalScrollMode = mode;
+ if (mode == ScrollPerItem)
+ horizontalScrollBar()->d_func()->itemviewChangeSingleStep(1); // setSingleStep(-1) => step with 1
+ else
+ horizontalScrollBar()->setSingleStep(-1); // Ensure that the view can update single step
updateGeometries(); // update the scroll bars
}
@@ -4274,9 +4290,8 @@ QModelIndex QAbstractItemViewPrivate::indexForEditor(QWidget *editor) const
void QAbstractItemViewPrivate::removeEditor(QWidget *editor)
{
- QEditorIndexHash::iterator it = editorIndexHash.find(editor);
- if (it != editorIndexHash.end())
- {
+ const auto it = editorIndexHash.constFind(editor);
+ if (it != editorIndexHash.cend()) {
indexEditorHash.remove(it.value());
editorIndexHash.erase(it);
}
@@ -4335,11 +4350,11 @@ QItemViewPaintPairs QAbstractItemViewPrivate::draggablePaintPairs(const QModelIn
QRect &rect = *r;
const QRect viewportRect = viewport->rect();
QItemViewPaintPairs ret;
- for (int i = 0; i < indexes.count(); ++i) {
- const QModelIndex &index = indexes.at(i);
+ for (const auto &index : indexes) {
const QRect current = q->visualRect(index);
if (current.intersects(viewportRect)) {
- ret += qMakePair(current, index);
+ QItemViewPaintPair p = { current, index };
+ ret += p;
rect |= current;
}
}
@@ -4359,8 +4374,8 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,
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());
- const QModelIndex &current = paintPairs.at(j).second;
+ option.rect = paintPairs.at(j).rect.translated(-r->topLeft());
+ const QModelIndex &current = paintPairs.at(j).index;
adjustViewOptionsForIndex(&option, current);
delegateForIndex(current)->paint(&painter, option, current);
}
diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h
index ff1848b149..e32c5dad2f 100644
--- a/src/widgets/itemviews/qabstractitemview.h
+++ b/src/widgets/itemviews/qabstractitemview.h
@@ -362,6 +362,7 @@ private:
friend class QTreeViewPrivate; // needed to compile with MSVC
friend class QListModeViewBase;
friend class QListViewPrivate;
+ friend class QAbstractSlider;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractItemView::EditTriggers)
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
index bb88b25652..2b28d8db84 100644
--- a/src/widgets/itemviews/qabstractitemview_p.h
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -73,7 +73,13 @@ struct QEditorInfo {
typedef QHash<QWidget *, QPersistentModelIndex> QEditorIndexHash;
typedef QHash<QPersistentModelIndex, QEditorInfo> QIndexEditorHash;
-typedef QPair<QRect, QModelIndex> QItemViewPaintPair;
+struct QItemViewPaintPair {
+ QRect rect;
+ QModelIndex index;
+};
+template <>
+class QTypeInfo<QItemViewPaintPair> : public QTypeInfoMerger<QItemViewPaintPair, QRect, QModelIndex> {};
+
typedef QVector<QItemViewPaintPair> QItemViewPaintPairs;
class QEmptyModel : public QAbstractItemModel
@@ -165,21 +171,21 @@ public:
virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const;
inline bool canDrop(QDropEvent *event) {
- QModelIndex index;
- int col = -1;
- int row = -1;
const QMimeData *mime = event->mimeData();
// Drag enter event shall always be accepted, if mime type and action match.
// Whether the data can actually be dropped will be checked in drag move.
- if (event->type() == QEvent::DragEnter) {
+ if (event->type() == QEvent::DragEnter && (event->dropAction() & model->supportedDropActions())) {
const QStringList modelTypes = model->mimeTypes();
- for (int i = 0; i < modelTypes.count(); ++i)
- if (mime->hasFormat(modelTypes.at(i))
- && (event->dropAction() & model->supportedDropActions()))
+ for (const auto &modelType : modelTypes) {
+ if (mime->hasFormat(modelType))
return true;
+ }
}
+ QModelIndex index;
+ int col = -1;
+ int row = -1;
if (dropOn(event, &row, &col, &index)) {
return model->canDropMimeData(mime,
dragDropMode == QAbstractItemView::InternalMove ? Qt::MoveAction : event->dropAction(),
diff --git a/src/widgets/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp
index 0c157c940f..8a7ab3c63c 100644
--- a/src/widgets/itemviews/qdirmodel.cpp
+++ b/src/widgets/itemviews/qdirmodel.cpp
@@ -34,7 +34,6 @@
#include "qdirmodel.h"
#ifndef QT_NO_DIRMODEL
-#include <qstack.h>
#include <qfile.h>
#include <qfilesystemmodel.h>
#include <qurl.h>
@@ -49,6 +48,9 @@
#include <private/qabstractitemmodel_p.h>
#include <qdebug.h>
+#include <stack>
+#include <vector>
+
/*!
\enum QDirModel::Roles
\value FileIconRole
@@ -163,14 +165,15 @@ void QDirModelPrivate::clear(QDirNode *parent) const
void QDirModelPrivate::invalidate()
{
- QStack<const QDirNode*> nodes;
+ std::stack<const QDirNode*, std::vector<const QDirNode*> > nodes;
nodes.push(&root);
while (!nodes.empty()) {
- const QDirNode *current = nodes.pop();
+ const QDirNode *current = nodes.top();
+ nodes.pop();
current->stat = false;
- const QVector<QDirNode> children = current->children;
- for (int i = 0; i < children.count(); ++i)
- nodes.push(&children.at(i));
+ const QVector<QDirNode> &children = current->children;
+ for (const auto &child : children)
+ nodes.push(&child);
}
}
@@ -1022,7 +1025,7 @@ bool QDirModel::rmdir(const QModelIndex &index)
return false;
QDirModelPrivate::QDirNode *n = d_func()->node(index);
- if (!n->info.isDir()) {
+ if (Q_UNLIKELY(!n->info.isDir())) {
qWarning("rmdir: the node is not a directory");
return false;
}
@@ -1172,7 +1175,7 @@ QDirModelPrivate::QDirNode *QDirModelPrivate::node(int row, QDirNode *parent) co
if (isDir && !p->populated)
populate(p); // will also resolve symlinks
- if (row >= p->children.count()) {
+ if (Q_UNLIKELY(row >= p->children.count())) {
qWarning("node: the row does not exist");
return 0;
}
diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp
index f43bcd5d5a..18b9755477 100644
--- a/src/widgets/itemviews/qfileiconprovider.cpp
+++ b/src/widgets/itemviews/qfileiconprovider.cpp
@@ -52,10 +52,6 @@
# endif
#endif
-#if defined(Q_OS_UNIX) && !defined(QT_NO_STYLE_GTK)
-# include <private/qgtkstyle_p_p.h>
-#endif
-
QT_BEGIN_NAMESPACE
static bool isCacheable(const QFileInfo &fi);
@@ -358,15 +354,6 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const
{
Q_D(const QFileIconProvider);
-#if defined(Q_OS_UNIX) && !defined(QT_NO_STYLE_GTK)
- const QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment();
- if (desktopEnvironment != QByteArrayLiteral("KDE")) {
- QIcon gtkIcon = QGtkStylePrivate::getFilesystemIcon(info);
- if (!gtkIcon.isNull())
- return gtkIcon;
- }
-#endif
-
QIcon retIcon = d->getIcon(info);
if (!retIcon.isNull())
return retIcon;
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 338627c79f..24b31f9eaf 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -753,9 +753,6 @@ void QHeaderView::moveSection(int from, int to)
return;
}
- if (stretchLastSection() && to == d->lastVisibleVisualIndex())
- d->lastSectionSize = sectionSize(from);
-
d->initializeIndexMapping();
int *visualIndices = d->visualIndices.data();
@@ -788,6 +785,12 @@ void QHeaderView::moveSection(int from, int to)
d->viewport->update();
emit sectionMoved(logical, from, to);
+
+ if (stretchLastSection()) {
+ const int lastSectionVisualIdx = visualIndex(d->lastSectionLogicalIdx);
+ if (from >= lastSectionVisualIdx || to >= lastSectionVisualIdx)
+ d->maybeRestorePrevLastSectionAndStretchLast();
+ }
}
/*!
@@ -839,6 +842,12 @@ void QHeaderView::swapSections(int first, int second)
d->viewport->update();
emit sectionMoved(firstLogical, first, second);
emit sectionMoved(secondLogical, second, first);
+
+ if (stretchLastSection()) {
+ const int lastSectionVisualIdx = visualIndex(d->lastSectionLogicalIdx);
+ if (first >= lastSectionVisualIdx || second >= lastSectionVisualIdx)
+ d->maybeRestorePrevLastSectionAndStretchLast();
+ }
}
/*!
@@ -877,7 +886,7 @@ void QHeaderView::resizeSection(int logical, int size)
d->executePostedLayout();
d->invalidateCachedSizeHint();
- if (stretchLastSection() && visual == d->lastVisibleVisualIndex())
+ if (stretchLastSection() && logical == d->lastSectionLogicalIdx)
d->lastSectionSize = size;
d->createSectionItems(visual, visual, size, d->headerSectionResizeMode(visual));
@@ -1000,11 +1009,16 @@ void QHeaderView::setSectionHidden(int logicalIndex, bool hide)
if (hide == d->isVisualIndexHidden(visual))
return;
if (hide) {
+ const bool isHidingLastSection = (stretchLastSection() && logicalIndex == d->lastSectionLogicalIdx);
+ if (isHidingLastSection)
+ d->restoreSizeOnPrevLastSection(); // Restore here/now to get the right restore size.
int size = d->headerSectionSize(visual);
if (!d->hasAutoResizeSections())
resizeSection(logicalIndex, 0);
d->hiddenSectionSize.insert(logicalIndex, size);
d->setVisualIndexHidden(visual, true);
+ if (isHidingLastSection)
+ d->setNewLastSection(d->lastVisibleVisualIndex());
if (d->hasAutoResizeSections())
d->doDelayedResizeSections();
} else {
@@ -1012,6 +1026,12 @@ void QHeaderView::setSectionHidden(int logicalIndex, bool hide)
d->hiddenSectionSize.remove(logicalIndex);
d->setVisualIndexHidden(visual, false);
resizeSection(logicalIndex, size);
+
+ const bool newLastSection = (stretchLastSection() && visual > visualIndex(d->lastSectionLogicalIdx));
+ if (newLastSection) {
+ d->restoreSizeOnPrevLastSection();
+ d->setNewLastSection(visual);
+ }
}
}
@@ -1473,13 +1493,17 @@ bool QHeaderView::stretchLastSection() const
void QHeaderView::setStretchLastSection(bool stretch)
{
Q_D(QHeaderView);
+ const bool changedStretchMode = (d->stretchLastSection != stretch);
d->stretchLastSection = stretch;
if (d->state != QHeaderViewPrivate::NoState)
return;
- if (stretch)
+ if (stretch) {
+ d->setNewLastSection(d->lastVisibleVisualIndex());
resizeSections();
- else if (count())
- resizeSection(count() - 1, d->defaultSectionSize);
+ } else {
+ if (changedStretchMode)
+ d->restoreSizeOnPrevLastSection();
+ }
}
/*!
@@ -1834,6 +1858,21 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
int insertAt = logicalFirst;
int insertCount = logicalLast - logicalFirst + 1;
+ bool lastSectionActualChange = false;
+ if (stretchLastSection()) {
+
+ int visualIndexForStretch = d->lastSectionLogicalIdx;
+ if (d->lastSectionLogicalIdx >= 0 && d->lastSectionLogicalIdx < d->visualIndices.size())
+ visualIndexForStretch = d->visualIndices[d->lastSectionLogicalIdx]; // We cannot call visualIndex since it executes executePostedLayout()
+ // and it is likely to bypass initializeSections() and we may end up here again. Doing the insert twice.
+
+ if (d->lastSectionLogicalIdx < 0 || insertAt >= visualIndexForStretch)
+ lastSectionActualChange = true;
+
+ if (d->lastSectionLogicalIdx >= logicalFirst)
+ d->lastSectionLogicalIdx += insertCount; // We do not want to emit resize before we have fixed the count
+ }
+
QHeaderViewPrivate::SectionItem section(d->defaultSectionSize, d->globalResizeMode);
d->sectionStartposRecalc = true;
@@ -1890,6 +1929,9 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
d->doDelayedResizeSections();
emit sectionCountChanged(oldCount, count());
+ if (lastSectionActualChange)
+ d->maybeRestorePrevLastSectionAndStretchLast();
+
// if the new sections were not updated by resizing, we need to update now
if (!d->hasAutoResizeSections())
d->viewport->update();
@@ -2000,6 +2042,16 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
clear();
invalidateCachedSizeHint();
emit q->sectionCountChanged(oldCount, q->count());
+
+ if (q->stretchLastSection()) {
+ const bool lastSectionRemoved = lastSectionLogicalIdx >= logicalFirst && lastSectionLogicalIdx <= logicalLast;
+ if (lastSectionRemoved)
+ setNewLastSection(lastVisibleVisualIndex());
+ else
+ lastSectionLogicalIdx = logicalIndex(lastVisibleVisualIndex()); // Just update the last log index.
+ doDelayedResizeSections();
+ }
+
viewport->update();
}
@@ -2078,8 +2130,8 @@ void QHeaderView::initializeSections()
} else if (newCount != oldCount) {
const int min = qBound(0, oldCount, newCount - 1);
initializeSections(min, newCount - 1);
- if (stretchLastSection()) // we've already gotten the size hint
- d->lastSectionSize = sectionSize(logicalIndex(d->sectionCount() - 1));
+ if (stretchLastSection()) // we've already gotten the size hint
+ d->maybeRestorePrevLastSectionAndStretchLast();
//make sure we update the hidden sections
if (newCount < oldCount)
@@ -2960,8 +3012,7 @@ QRegion QHeaderView::visualRegionForSelection(const QItemSelection &selection) c
int right = 0;
int rangeLeft, rangeRight;
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange r = selection.at(i);
+ for (const auto &r : selection) {
if (r.parent().isValid() || !r.isValid())
continue; // we only know about toplevel items and we don't want invalid ranges
// FIXME an item inside the range may be the leftmost or rightmost
@@ -2994,8 +3045,7 @@ QRegion QHeaderView::visualRegionForSelection(const QItemSelection &selection) c
int bottom = 0;
int rangeTop, rangeBottom;
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange r = selection.at(i);
+ for (const auto &r : selection) {
if (r.parent().isValid() || !r.isValid())
continue; // we only know about toplevel items
// FIXME an item inside the range may be the leftmost or rightmost
@@ -3173,6 +3223,42 @@ int QHeaderViewPrivate::lastVisibleVisualIndex() const
return -1;
}
+void QHeaderViewPrivate::restoreSizeOnPrevLastSection()
+{
+ Q_Q(QHeaderView);
+ if (lastSectionLogicalIdx < 0)
+ return;
+ int resizeLogIdx = lastSectionLogicalIdx;
+ lastSectionLogicalIdx = -1; // We do not want resize to catch it as the last section.
+ q->resizeSection(resizeLogIdx, lastSectionSize);
+}
+
+void QHeaderViewPrivate::setNewLastSection(int visualIndexForLastSection)
+{
+ Q_Q(QHeaderView);
+ lastSectionSize = -1;
+ lastSectionLogicalIdx = q->logicalIndex(visualIndexForLastSection);
+ lastSectionSize = headerSectionSize(visualIndexForLastSection); // pick size directly since ...
+ // q->sectionSize(lastSectionLogicalIdx) may do delayed resize and stretch it before we get the value.
+}
+
+void QHeaderViewPrivate::maybeRestorePrevLastSectionAndStretchLast()
+{
+ Q_Q(const QHeaderView);
+ if (!q->stretchLastSection())
+ return;
+
+ int nowLastVisualSection = lastVisibleVisualIndex();
+ if (lastSectionLogicalIdx == q->logicalIndex(nowLastVisualSection))
+ return;
+
+ // restore old last section.
+ restoreSizeOnPrevLastSection();
+ setNewLastSection(nowLastVisualSection);
+ doDelayedResizeSections(); // Do stretch of last section soon (but not now).
+}
+
+
/*!
\internal
Go through and resize all of the sections applying stretchLastSection,
@@ -3201,13 +3287,12 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
resizeRecursionBlock = true;
invalidateCachedSizeHint();
-
- const int lastVisibleSection = lastVisibleVisualIndex();
+ const int lastSectionVisualIdx = q->visualIndex(lastSectionLogicalIdx);
// find stretchLastSection if we have it
int stretchSection = -1;
if (stretchLastSection && !useGlobalMode)
- stretchSection = lastVisibleVisualIndex();
+ stretchSection = lastSectionVisualIdx;
// count up the number of stretched sections and how much space left for them
int lengthToStretch = (orientation == Qt::Horizontal ? viewport->width() : viewport->height());
@@ -3276,7 +3361,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
? QHeaderView::Stretch
: newSectionResizeMode);
if (resizeMode == QHeaderView::Stretch && stretchSectionLength != -1) {
- if (i == lastVisibleSection)
+ if (i == lastSectionVisualIdx)
newSectionLength = qMax(stretchSectionLength, lastSectionSize);
else
newSectionLength = stretchSectionLength;
@@ -3665,10 +3750,12 @@ void QHeaderViewPrivate::write(QDataStream &out) const
out << sectionItems;
out << resizeContentsPrecision;
out << customDefaultSectionSize;
+ out << lastSectionSize;
}
bool QHeaderViewPrivate::read(QDataStream &in)
{
+ Q_Q(QHeaderView);
int orient, order, align, global;
int sortIndicatorSectionIn;
bool sortIndicatorShownIn;
@@ -3687,7 +3774,6 @@ bool QHeaderViewPrivate::read(QDataStream &in)
int minimumSectionSizeIn;
QVector<SectionItem> sectionItemsIn;
-
in >> orient;
in >> order;
@@ -3780,6 +3866,18 @@ bool QHeaderViewPrivate::read(QDataStream &in)
updateDefaultSectionSizeFromStyle();
}
+ lastSectionSize = -1;
+ int inLastSectionSize;
+ in >> inLastSectionSize;
+ if (in.status() == QDataStream::Ok)
+ lastSectionSize = inLastSectionSize;
+
+ lastSectionLogicalIdx = -1;
+ if (stretchLastSection) {
+ lastSectionLogicalIdx = q->logicalIndex(lastVisibleVisualIndex());
+ doDelayedResizeSections();
+ }
+
return true;
}
diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h
index 7f92d2a81b..d1982d4777 100644
--- a/src/widgets/itemviews/qheaderview_p.h
+++ b/src/widgets/itemviews/qheaderview_p.h
@@ -90,6 +90,7 @@ public:
minimumSectionSize(-1),
maximumSectionSize(-1),
lastSectionSize(0),
+ lastSectionLogicalIdx(-1), // Only trust when we stretch last section
sectionIndicatorOffset(0),
sectionIndicator(0),
globalResizeMode(QHeaderView::Interactive),
@@ -99,6 +100,9 @@ public:
int lastVisibleVisualIndex() const;
+ void restoreSizeOnPrevLastSection();
+ void setNewLastSection(int visualIndexForLastSection);
+ void maybeRestorePrevLastSectionAndStretchLast();
int sectionHandleAt(int position);
void setupSectionIndicator(int section, int position);
void updateSectionIndicator(int section, int position);
@@ -281,7 +285,8 @@ public:
int defaultSectionSize;
int minimumSectionSize;
int maximumSectionSize;
- int lastSectionSize; // $$$
+ int lastSectionSize;
+ int lastSectionLogicalIdx; // Only trust if we stretch LastSection
int sectionIndicatorOffset;
Qt::Alignment defaultAlignment;
QLabel *sectionIndicator;
@@ -327,8 +332,8 @@ public:
inline int headerLength() const { // for debugging
int len = 0;
- for (int i = 0; i < sectionItems.count(); ++i)
- len += sectionItems.at(i).size;
+ for (const auto &section : sectionItems)
+ len += section.size;
return len;
}
diff --git a/src/widgets/itemviews/qitemeditorfactory.cpp b/src/widgets/itemviews/qitemeditorfactory.cpp
index e966c83fe7..3287d5dc99 100644
--- a/src/widgets/itemviews/qitemeditorfactory.cpp
+++ b/src/widgets/itemviews/qitemeditorfactory.cpp
@@ -47,6 +47,7 @@
#include <qapplication.h>
#include <qdebug.h>
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -197,12 +198,12 @@ QItemEditorFactory::~QItemEditorFactory()
*/
void QItemEditorFactory::registerEditor(int userType, QItemEditorCreatorBase *creator)
{
- QHash<int, QItemEditorCreatorBase *>::iterator it = creatorMap.find(userType);
- if (it != creatorMap.end()) {
+ const auto it = creatorMap.constFind(userType);
+ if (it != creatorMap.cend()) {
QItemEditorCreatorBase *oldCreator = it.value();
Q_ASSERT(oldCreator);
creatorMap.erase(it);
- if (!creatorMap.values().contains(oldCreator))
+ if (std::find(creatorMap.cbegin(), creatorMap.cend(), oldCreator) == creatorMap.cend())
delete oldCreator; // if it is no more in use we can delete it
}
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index 9c79509874..6e432a9ad7 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -46,11 +46,14 @@
#include <qscrollbar.h>
#include <qrubberband.h>
#include <private/qlistview_p.h>
+#include <private/qscrollbar_p.h>
#include <qdebug.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
#endif
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
@@ -392,7 +395,7 @@ int QListView::spacing() const
void QListView::setBatchSize(int batchSize)
{
Q_D(QListView);
- if (batchSize <= 0) {
+ if (Q_UNLIKELY(batchSize <= 0)) {
qWarning("Invalid batchSize (%d)", batchSize);
return;
}
@@ -649,12 +652,13 @@ QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList
QRect &rect = *r;
const QRect viewportRect = viewport->rect();
QItemViewPaintPairs ret;
- const QSet<QModelIndex> visibleIndexes = intersectingSet(viewportRect.translated(q->horizontalOffset(), q->verticalOffset())).toList().toSet();
- for (int i = 0; i < indexes.count(); ++i) {
- const QModelIndex &index = indexes.at(i);
- if (visibleIndexes.contains(index)) {
+ QVector<QModelIndex> visibleIndexes = intersectingSet(viewportRect.translated(q->horizontalOffset(), q->verticalOffset()));
+ std::sort(visibleIndexes.begin(), visibleIndexes.end());
+ for (const auto &index : indexes) {
+ if (std::binary_search(visibleIndexes.cbegin(), visibleIndexes.cend(), index)) {
const QRect current = q->visualRect(index);
- ret += qMakePair(current, index);
+ QItemViewPaintPair p = { current, index };
+ ret += p;
rect |= current;
}
}
@@ -1396,16 +1400,16 @@ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) con
int c = d->column;
QRegion selectionRegion;
const QRect &viewportRect = d->viewport->rect();
- for (int i = 0; i < selection.count(); ++i) {
- if (!selection.at(i).isValid())
+ for (const auto &elem : selection) {
+ if (!elem.isValid())
continue;
- QModelIndex parent = selection.at(i).topLeft().parent();
+ QModelIndex parent = elem.topLeft().parent();
//we only display the children of the root in a listview
//we're not interested in the other model indexes
if (parent != d->root)
continue;
- int t = selection.at(i).topLeft().row();
- int b = selection.at(i).bottomRight().row();
+ int t = elem.topLeft().row();
+ int b = elem.bottomRight().row();
if (d->viewMode == IconMode || d->isWrapping()) { // in non-static mode, we have to go through all selected items
for (int r = t; r <= b; ++r) {
const QRect &rect = visualRect(d->model->index(r, c, parent));
@@ -1842,6 +1846,16 @@ bool QListViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QMo
}
#endif
+void QListViewPrivate::removeCurrentAndDisabled(QVector<QModelIndex> *indexes, const QModelIndex &current) const
+{
+ auto isCurrentOrDisabled = [=](const QModelIndex &index) {
+ return !isIndexEnabled(index) || index == current;
+ };
+ indexes->erase(std::remove_if(indexes->begin(), indexes->end(),
+ isCurrentOrDisabled),
+ indexes->end());
+}
+
/*
* Common ListView Implementation
*/
@@ -1867,7 +1881,7 @@ void QCommonListViewBase::paintDragDrop(QPainter *painter)
void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
{
- horizontalScrollBar()->setSingleStep(step.width() + spacing());
+ horizontalScrollBar()->d_func()->itemviewChangeSingleStep(step.width() + spacing());
horizontalScrollBar()->setPageStep(viewport()->width());
// If both scroll bars are set to auto, we might end up in a situation with enough space
@@ -1897,7 +1911,7 @@ void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step)
void QCommonListViewBase::updateVerticalScrollBar(const QSize &step)
{
- verticalScrollBar()->setSingleStep(step.height() + spacing());
+ verticalScrollBar()->d_func()->itemviewChangeSingleStep(step.height() + spacing());
verticalScrollBar()->setPageStep(viewport()->height());
// If both scroll bars are set to auto, we might end up in a situation with enough space
@@ -2769,9 +2783,8 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
}
QPoint start = dd->pressedPosition;
QPoint delta = (dd->movement == QListView::Snap ? snapToGrid(end) - snapToGrid(start) : end - start);
- QList<QModelIndex> indexes = dd->selectionModel->selectedIndexes();
- for (int i = 0; i < indexes.count(); ++i) {
- QModelIndex index = indexes.at(i);
+ const QList<QModelIndex> indexes = dd->selectionModel->selectedIndexes();
+ for (const auto &index : indexes) {
QRect rect = dd->rectForIndex(index);
viewport()->update(dd->mapToViewport(rect, false));
QPoint dest = rect.topLeft() + delta;
diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h
index 62fa45e640..2aa34256d2 100644
--- a/src/widgets/itemviews/qlistview_p.h
+++ b/src/widgets/itemviews/qlistview_p.h
@@ -64,9 +64,6 @@ class QListViewItem
public:
inline QListViewItem()
: x(-1), y(-1), w(0), h(0), indexHint(-1), visited(0xffff) {}
- inline QListViewItem(const QListViewItem &other)
- : x(other.x), y(other.y), w(other.w), h(other.h),
- indexHint(other.indexHint), visited(other.visited) {}
inline QListViewItem(QRect r, int i)
: x(r.x()), y(r.y()), w(qMin(r.width(), SHRT_MAX)), h(qMin(r.height(), SHRT_MAX)),
indexHint(i), visited(0xffff) {}
@@ -375,15 +372,7 @@ public:
}
inline bool isHiddenOrDisabled(int row) const { return isHidden(row) || !isIndexEnabled(modelIndex(row)); }
- inline void removeCurrentAndDisabled(QVector<QModelIndex> *indexes, const QModelIndex &current) const {
- QVector<QModelIndex>::iterator it = indexes->begin();
- while (it != indexes->end()) {
- if (!isIndexEnabled(*it) || (*it) == current)
- indexes->erase(it);
- else
- ++it;
- }
- }
+ void removeCurrentAndDisabled(QVector<QModelIndex> *indexes, const QModelIndex &current) const;
void scrollElasticBandBy(int dx, int dy);
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index d4d22c8bef..275fc2a1f1 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -1908,7 +1908,7 @@ QList<QListWidgetItem*> QListWidget::items(const QMimeData *data) const
}
/*!
- Returns the QModelIndex assocated with the given \a item.
+ Returns the QModelIndex associated with the given \a item.
*/
QModelIndex QListWidget::indexFromItem(QListWidgetItem *item) const
@@ -1918,7 +1918,7 @@ QModelIndex QListWidget::indexFromItem(QListWidgetItem *item) const
}
/*!
- Returns a pointer to the QListWidgetItem assocated with the given \a index.
+ Returns a pointer to the QListWidgetItem associated with the given \a index.
*/
QListWidgetItem *QListWidget::itemFromIndex(const QModelIndex &index) const
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index ee0d41ce15..88090f1e45 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -46,6 +46,7 @@
#include <qabstractbutton.h>
#include <private/qtableview_p.h>
#include <private/qheaderview_p.h>
+#include <private/qscrollbar_p.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
#endif
@@ -661,7 +662,7 @@ void QTableViewPrivate::trimHiddenSelections(QItemSelectionRange *range) const
*/
void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan)
{
- if (row < 0 || column < 0 || rowSpan <= 0 || columnSpan <= 0) {
+ if (Q_UNLIKELY(row < 0 || column < 0 || rowSpan <= 0 || columnSpan <= 0)) {
qWarning("QTableView::setSpan: invalid span given: (%d, %d, %d, %d)",
row, column, rowSpan, columnSpan);
return;
@@ -680,7 +681,7 @@ void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan
sp->m_right = column + columnSpan - 1;
spans.updateSpan(sp, old_height);
return;
- } else if (rowSpan == 1 && columnSpan == 1) {
+ } else if (Q_UNLIKELY(rowSpan == 1 && columnSpan == 1)) {
qWarning("QTableView::setSpan: single cell span won't be added");
return;
}
@@ -1369,9 +1370,6 @@ void QTableView::paintEvent(QPaintEvent *event)
uint x = horizontalHeader->length() - horizontalHeader->offset() - (rightToLeft ? 0 : 1);
uint y = verticalHeader->length() - verticalHeader->offset() - 1;
- const QRegion region = event->region().translated(offset);
- const QVector<QRect> rects = region.rects();
-
//firstVisualRow is the visual index of the first visible row. lastVisualRow is the visual index of the last visible Row.
//same goes for ...VisualColumn
int firstVisualRow = qMax(verticalHeader->visualIndexAt(0),0);
@@ -1390,13 +1388,15 @@ void QTableView::paintEvent(QPaintEvent *event)
QBitArray drawn((lastVisualRow - firstVisualRow + 1) * (lastVisualColumn - firstVisualColumn + 1));
+ const QRegion region = event->region().translated(offset);
+
if (d->hasSpans()) {
d->drawAndClipSpans(region, &painter, option, &drawn,
firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn);
}
- for (int i = 0; i < rects.size(); ++i) {
- QRect dirtyArea = rects.at(i);
+ const QVector<QRect> rects = region.rects();
+ for (auto dirtyArea : rects) {
dirtyArea.setBottom(qMin(dirtyArea.bottom(), int(y)));
if (rightToLeft) {
dirtyArea.setLeft(qMax(dirtyArea.left(), d->viewport->width() - int(x)));
@@ -1951,8 +1951,7 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co
bool horizontalMoved = horizontalHeader()->sectionsMoved();
if ((verticalMoved && horizontalMoved) || (d->hasSpans() && (verticalMoved || horizontalMoved))) {
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange range = selection.at(i);
+ for (const auto &range : selection) {
if (range.parent() != d->root || !range.isValid())
continue;
for (int r = range.top(); r <= range.bottom(); ++r)
@@ -1963,8 +1962,7 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co
}
}
} else if (horizontalMoved) {
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange range = selection.at(i);
+ for (const auto &range : selection) {
if (range.parent() != d->root || !range.isValid())
continue;
int top = rowViewportPosition(range.top());
@@ -1979,8 +1977,7 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co
}
}
} else if (verticalMoved) {
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange range = selection.at(i);
+ for (const auto &range : selection) {
if (range.parent() != d->root || !range.isValid())
continue;
int left = columnViewportPosition(range.left());
@@ -1996,8 +1993,7 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co
}
} else { // nothing moved
const int gridAdjust = showGrid() ? 1 : 0;
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange range = selection.at(i);
+ for (auto range : selection) {
if (range.parent() != d->root || !range.isValid())
continue;
d->trimHiddenSelections(&range);
@@ -2166,7 +2162,7 @@ void QTableView::updateGeometries()
} else { // ScrollPerPixel
horizontalScrollBar()->setPageStep(vsize.width());
horizontalScrollBar()->setRange(0, horizontalLength - vsize.width());
- horizontalScrollBar()->setSingleStep(qMax(vsize.width() / (columnsInViewport + 1), 2));
+ horizontalScrollBar()->d_func()->itemviewChangeSingleStep(qMax(vsize.width() / (columnsInViewport + 1), 2));
}
// vertical scroll bar
@@ -2194,7 +2190,7 @@ void QTableView::updateGeometries()
} else { // ScrollPerPixel
verticalScrollBar()->setPageStep(vsize.height());
verticalScrollBar()->setRange(0, verticalLength - vsize.height());
- verticalScrollBar()->setSingleStep(qMax(vsize.height() / (rowsInViewport + 1), 2));
+ verticalScrollBar()->d_func()->itemviewChangeSingleStep(qMax(vsize.height() / (rowsInViewport + 1), 2));
}
d->geometryRecursionBlock = false;
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index cd38f4b282..6238835f04 100644
--- a/src/widgets/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
@@ -1388,9 +1388,10 @@ void QTableWidgetItem::setData(int role, const QVariant &value)
QVariant QTableWidgetItem::data(int role) const
{
role = (role == Qt::EditRole ? Qt::DisplayRole : role);
- for (int i = 0; i < values.count(); ++i)
- if (values.at(i).role == role)
- return values.at(i).value;
+ for (const auto &value : values) {
+ if (value.role == role)
+ return value.value;
+ }
return QVariant();
}
@@ -1958,7 +1959,7 @@ void QTableWidget::setItem(int row, int column, QTableWidgetItem *item)
{
Q_D(QTableWidget);
if (item) {
- if (item->view != 0) {
+ if (Q_UNLIKELY(item->view)) {
qWarning("QTableWidget: cannot insert an item that is already owned by another QTableWidget");
} else {
item->view = this;
@@ -2359,10 +2360,9 @@ QList<QTableWidgetSelectionRange> QTableWidget::selectedRanges() const
QList<QTableWidgetItem*> QTableWidget::selectedItems() const
{
Q_D(const QTableWidget);
- QModelIndexList indexes = selectionModel()->selectedIndexes();
+ const QModelIndexList indexes = selectionModel()->selectedIndexes();
QList<QTableWidgetItem*> items;
- for (int i = 0; i < indexes.count(); ++i) {
- QModelIndex index = indexes.at(i);
+ for (const auto &index : indexes) {
if (isIndexHidden(index))
continue;
QTableWidgetItem *item = d->tableModel()->item(index);
@@ -2639,7 +2639,7 @@ QList<QTableWidgetItem*> QTableWidget::items(const QMimeData *data) const
}
/*!
- Returns the QModelIndex assocated with the given \a item.
+ Returns the QModelIndex associated with the given \a item.
*/
QModelIndex QTableWidget::indexFromItem(QTableWidgetItem *item) const
@@ -2649,7 +2649,7 @@ QModelIndex QTableWidget::indexFromItem(QTableWidgetItem *item) const
}
/*!
- Returns a pointer to the QTableWidgetItem assocated with the given \a index.
+ Returns a pointer to the QTableWidgetItem associated with the given \a index.
*/
QTableWidgetItem *QTableWidget::itemFromIndex(const QModelIndex &index) const
@@ -2682,22 +2682,21 @@ void QTableWidget::dropEvent(QDropEvent *event) {
int col = -1;
int row = -1;
if (d->dropOn(event, &row, &col, &topIndex)) {
- QModelIndexList indexes = selectedIndexes();
+ const QModelIndexList indexes = selectedIndexes();
int top = INT_MAX;
int left = INT_MAX;
- for (int i = 0; i < indexes.count(); ++i) {
- top = qMin(indexes.at(i).row(), top);
- left = qMin(indexes.at(i).column(), left);
+ for (const auto &index : indexes) {
+ top = qMin(index.row(), top);
+ left = qMin(index.column(), left);
}
QList<QTableWidgetItem *> taken;
const int indexesCount = indexes.count();
taken.reserve(indexesCount);
- for (int i = 0; i < indexesCount; ++i)
- taken.append(takeItem(indexes.at(i).row(), indexes.at(i).column()));
+ for (const auto &index : indexes)
+ taken.append(takeItem(index.row(), index.column()));
- for (int i = 0; i < indexes.count(); ++i) {
- QModelIndex index = indexes.at(i);
+ for (const auto &index : indexes) {
int r = index.row() - top + topIndex.row();
int c = index.column() - left + topIndex.column();
setItem(r, c, taken.takeFirst());
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 57092a7cdc..b11c54ffb8 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -45,6 +45,7 @@
#include <qpen.h>
#include <qdebug.h>
#include <QMetaMethod>
+#include <private/qscrollbar_p.h>
#ifndef QT_NO_ACCESSIBILITY
#include <qaccessible.h>
#endif
@@ -2392,8 +2393,7 @@ QRegion QTreeView::visualRegionForSelection(const QItemSelection &selection) con
QRegion selectionRegion;
const QRect &viewportRect = d->viewport->rect();
- for (int i = 0; i < selection.count(); ++i) {
- QItemSelectionRange range = selection.at(i);
+ for (const auto &range : selection) {
if (!range.isValid())
continue;
QModelIndex parent = range.parent();
@@ -3698,7 +3698,7 @@ void QTreeViewPrivate::updateScrollBars()
}
vbar->setRange(0, contentsHeight - viewportSize.height());
vbar->setPageStep(viewportSize.height());
- vbar->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));
+ vbar->d_func()->itemviewChangeSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));
}
const int columnCount = header->count();
@@ -3724,7 +3724,7 @@ void QTreeViewPrivate::updateScrollBars()
viewportSize = maxSize;
hbar->setPageStep(viewportSize.width());
hbar->setRange(0, qMax(horizontalLength - viewportSize.width(), 0));
- hbar->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));
+ hbar->d_func()->itemviewChangeSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));
}
}
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index 676893ebf0..9dbf7df5fb 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -725,9 +725,9 @@ QMimeData *QTreeModel::internalMimeData() const
QMimeData *QTreeModel::mimeData(const QModelIndexList &indexes) const
{
QList<QTreeWidgetItem*> items;
- for (int i = 0; i < indexes.count(); ++i) {
- if (indexes.at(i).column() == 0) // only one item per row
- items << item(indexes.at(i));
+ for (const auto &index : indexes) {
+ if (index.column() == 0) // only one item per row
+ items << item(index);
}
// cachedIndexes is a little hack to avoid copying from QModelIndexList to
@@ -1735,7 +1735,7 @@ void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
default:
if (column < values.count()) {
bool found = false;
- QVector<QWidgetItemData> column_values = values.at(column);
+ const QVector<QWidgetItemData> column_values = values.at(column);
for (int i = 0; i < column_values.count(); ++i) {
if (column_values.at(i).role == role) {
if (column_values.at(i).value == value)
@@ -1785,9 +1785,10 @@ QVariant QTreeWidgetItem::data(int column, int role) const
default:
if (column >= 0 && column < values.size()) {
const QVector<QWidgetItemData> &column_values = values.at(column);
- for (int i = 0; i < column_values.count(); ++i)
- if (column_values.at(i).role == role)
- return column_values.at(i).value;
+ for (const auto &column_value : column_values) {
+ if (column_value.role == role)
+ return column_value.value;
+ }
}
}
return QVariant();
@@ -2136,8 +2137,8 @@ QVariant QTreeWidgetItem::childrenCheckState(int column) const
return QVariant();
bool checkedChildren = false;
bool uncheckedChildren = false;
- for (int i = 0; i < children.count(); ++i) {
- QVariant value = children.at(i)->data(column, Qt::CheckStateRole);
+ for (const auto *child : children) {
+ QVariant value = child->data(column, Qt::CheckStateRole);
if (!value.isValid())
return QVariant();
@@ -3018,13 +3019,13 @@ void QTreeWidget::setItemSelected(const QTreeWidgetItem *item, bool select)
QList<QTreeWidgetItem*> QTreeWidget::selectedItems() const
{
Q_D(const QTreeWidget);
- QModelIndexList indexes = selectionModel()->selectedIndexes();
+ const QModelIndexList indexes = selectionModel()->selectedIndexes();
QList<QTreeWidgetItem*> items;
items.reserve(indexes.count());
QSet<QTreeWidgetItem *> seen;
seen.reserve(indexes.count());
- for (int i = 0; i < indexes.count(); ++i) {
- QTreeWidgetItem *item = d->item(indexes.at(i));
+ for (const auto &index : indexes) {
+ QTreeWidgetItem *item = d->item(index);
if (isItemHidden(item) || seen.contains(item))
continue;
seen.insert(item);
@@ -3278,16 +3279,15 @@ QMimeData *QTreeWidget::mimeData(const QList<QTreeWidgetItem*> items) const
Q_D(const QTreeWidget);
if (d->treeModel()->cachedIndexes.isEmpty()) {
QList<QModelIndex> indexes;
- for (int i = 0; i < items.count(); ++i) {
- QTreeWidgetItem *item = items.at(i);
- if (!item) {
+ for (const auto *item : items) {
+ if (Q_UNLIKELY(!item)) {
qWarning("QTreeWidget::mimeData: Null-item passed");
return 0;
}
for (int c = 0; c < item->values.count(); ++c) {
const QModelIndex index = indexFromItem(item, c);
- if (!index.isValid()) {
+ if (Q_UNLIKELY(!index.isValid())) {
qWarning() << "QTreeWidget::mimeData: No index associated with item :" << item;
return 0;
}
@@ -3340,18 +3340,29 @@ QList<QTreeWidgetItem*> QTreeWidget::items(const QMimeData *data) const
}
/*!
- Returns the QModelIndex assocated with the given \a item in the given \a column.
+ Returns the QModelIndex associated with the given \a item in the given \a column.
+
+ \note In Qt versions prior to 5.7, this function took a non-\c{const} \a item.
\sa itemFromIndex(), topLevelItem()
*/
-QModelIndex QTreeWidget::indexFromItem(QTreeWidgetItem *item, int column) const
+QModelIndex QTreeWidget::indexFromItem(const QTreeWidgetItem *item, int column) const
{
Q_D(const QTreeWidget);
return d->index(item, column);
}
/*!
- Returns a pointer to the QTreeWidgetItem assocated with the given \a index.
+ \overload
+ \internal
+*/
+QModelIndex QTreeWidget::indexFromItem(QTreeWidgetItem *item, int column) const
+{
+ return indexFromItem(const_cast<const QTreeWidgetItem *>(item), column);
+}
+
+/*!
+ Returns a pointer to the QTreeWidgetItem associated with the given \a index.
\sa indexFromItem()
*/
@@ -3371,12 +3382,12 @@ void QTreeWidget::dropEvent(QDropEvent *event) {
int col = -1;
int row = -1;
if (d->dropOn(event, &row, &col, &topIndex)) {
- QList<QModelIndex> idxs = selectedIndexes();
+ const QList<QModelIndex> idxs = selectedIndexes();
QList<QPersistentModelIndex> indexes;
const int indexesCount = idxs.count();
indexes.reserve(indexesCount);
- for (int i = 0; i < indexesCount; i++)
- indexes.append(idxs.at(i));
+ for (const auto &idx : idxs)
+ indexes.append(idx);
if (indexes.contains(topIndex))
return;
@@ -3386,12 +3397,12 @@ void QTreeWidget::dropEvent(QDropEvent *event) {
// Remove the items
QList<QTreeWidgetItem *> taken;
- for (int i = 0; i < indexes.count(); ++i) {
- QTreeWidgetItem *parent = itemFromIndex(indexes.at(i));
+ for (const auto &index : indexes) {
+ QTreeWidgetItem *parent = itemFromIndex(index);
if (!parent || !parent->parent()) {
- taken.append(takeTopLevelItem(indexes.at(i).row()));
+ taken.append(takeTopLevelItem(index.row()));
} else {
- taken.append(parent->parent()->takeChild(indexes.at(i).row()));
+ taken.append(parent->parent()->takeChild(index.row()));
}
}
diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h
index 995528fe37..e39593c6c1 100644
--- a/src/widgets/itemviews/qtreewidget.h
+++ b/src/widgets/itemviews/qtreewidget.h
@@ -350,7 +350,8 @@ protected:
virtual Qt::DropActions supportedDropActions() const;
QList<QTreeWidgetItem*> items(const QMimeData *data) const;
- QModelIndex indexFromItem(QTreeWidgetItem *item, int column = 0) const;
+ QModelIndex indexFromItem(const QTreeWidgetItem *item, int column = 0) const;
+ QModelIndex indexFromItem(QTreeWidgetItem *item, int column = 0) const; // ### Qt 6: remove
QTreeWidgetItem *itemFromIndex(const QModelIndex &index) const;
void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE;
diff --git a/src/widgets/itemviews/qwidgetitemdata_p.h b/src/widgets/itemviews/qwidgetitemdata_p.h
index d8c1fc2ff7..82427b338a 100644
--- a/src/widgets/itemviews/qwidgetitemdata_p.h
+++ b/src/widgets/itemviews/qwidgetitemdata_p.h
@@ -53,7 +53,7 @@ class QWidgetItemData
{
public:
inline QWidgetItemData() : role(-1) {}
- inline QWidgetItemData(int r, QVariant v) : role(r), value(v) {}
+ inline QWidgetItemData(int r, const QVariant &v) : role(r), value(v) {}
int role;
QVariant value;
inline bool operator==(const QWidgetItemData &other) const { return role == other.role && value == other.value; }
diff --git a/src/widgets/kernel/mac.pri b/src/widgets/kernel/mac.pri
index 4c507ae80e..8c694c5e05 100644
--- a/src/widgets/kernel/mac.pri
+++ b/src/widgets/kernel/mac.pri
@@ -1,4 +1,4 @@
-!x11:mac:!ios {
- LIBS_PRIVATE += -framework Carbon -framework Cocoa -lz
+!x11:osx {
+ LIBS_PRIVATE += -framework AppKit -lz
*-mwerks:INCLUDEPATH += compat
}
diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp
index 2c4e4d3125..66e8e5379f 100644
--- a/src/widgets/kernel/qaction.cpp
+++ b/src/widgets/kernel/qaction.cpp
@@ -45,7 +45,7 @@
#include <private/qmenu_p.h>
#define QAPP_CHECK(functionName) \
- if (!qApp) { \
+ if (Q_UNLIKELY(!qApp)) { \
qWarning("QAction: Initialize QApplication before calling '" functionName "'."); \
return; \
}
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index e20e820f12..aa2ac25c25 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -65,6 +65,7 @@
#include <QtGui/qstylehints.h>
#include <QtGui/qinputmethod.h>
#include <QtGui/private/qwindow_p.h>
+#include <QtGui/qtouchdevice.h>
#include <qpa/qplatformtheme.h>
#ifndef QT_NO_WHATSTHIS
#include <QtWidgets/QWhatsThis>
@@ -1124,9 +1125,9 @@ QStyle *QApplication::style()
QStyle *&app_style = QApplicationPrivate::app_style;
app_style = QStyleFactory::create(style);
if (!app_style) {
- QStringList styles = QStyleFactory::keys();
- for (int i = 0; i < styles.size(); ++i) {
- if ((app_style = QStyleFactory::create(styles.at(i))))
+ const QStringList styles = QStyleFactory::keys();
+ for (const auto &style : styles) {
+ if ((app_style = QStyleFactory::create(style)))
break;
}
}
@@ -1367,7 +1368,7 @@ int QApplication::colorSpec()
void QApplication::setColorSpec(int spec)
{
- if (qApp)
+ if (Q_UNLIKELY(qApp))
qWarning("QApplication::setColorSpec: This function must be "
"called before the QApplication object is created");
QApplicationPrivate::app_cspec = spec;
@@ -1741,8 +1742,7 @@ void QApplicationPrivate::notifyWindowIconChanged()
QWindowList windowList = QGuiApplication::topLevelWindows();
// send to all top-level QWidgets
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
+ for (auto *w : list) {
windowList.removeOne(w->windowHandle());
QCoreApplication::sendEvent(w, &ev);
}
@@ -1904,9 +1904,9 @@ bool QApplicationPrivate::tryCloseAllWidgetWindows(QWindowList *processedWindows
processedWindows->append(window);
}
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
+retry:
+ const QWidgetList list = QApplication::topLevelWidgets();
+ for (auto *w : list) {
if (w->isVisible() && w->windowType() != Qt::Desktop &&
!w->testAttribute(Qt::WA_DontShowOnScreen) && !w->data->is_closing) {
QWindow *window = w->windowHandle();
@@ -1914,8 +1914,7 @@ bool QApplicationPrivate::tryCloseAllWidgetWindows(QWindowList *processedWindows
return false;
if (window)
processedWindows->append(window);
- list = QApplication::topLevelWidgets();
- i = -1;
+ goto retry;
}
}
return true;
@@ -1994,9 +1993,8 @@ bool QApplication::event(QEvent *e)
ce->accept();
closeAllWindows();
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
+ const QWidgetList list = topLevelWidgets();
+ for (auto *w : list) {
if (w->isVisible() && !(w->windowType() == Qt::Desktop) && !(w->windowType() == Qt::Popup) &&
(!(w->windowType() == Qt::Dialog) || !w->parentWidget())) {
ce->ignore();
@@ -2010,9 +2008,8 @@ bool QApplication::event(QEvent *e)
} else if (e->type() == QEvent::LocaleChange) {
// on Windows the event propagation is taken care by the
// WM_SETTINGCHANGE event handler.
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
+ const QWidgetList list = topLevelWidgets();
+ for (auto *w : list) {
if (!(w->windowType() == Qt::Desktop)) {
if (!w->testAttribute(Qt::WA_SetLocale))
w->d_func()->setLocale_helper(QLocale(), true);
@@ -2056,9 +2053,8 @@ bool QApplication::event(QEvent *e)
}
if(e->type() == QEvent::LanguageChange) {
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
+ const QWidgetList list = topLevelWidgets();
+ for (auto *w : list) {
if (!(w->windowType() == Qt::Desktop))
postEvent(w, new QEvent(QEvent::LanguageChange));
}
@@ -2084,8 +2080,7 @@ void QApplicationPrivate::notifyLayoutDirectionChange()
QWindowList windowList = QGuiApplication::topLevelWindows();
// send to all top-level QWidgets
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
+ for (auto *w : list) {
windowList.removeAll(w->windowHandle());
QEvent ev(QEvent::ApplicationLayoutDirectionChange);
QCoreApplication::sendEvent(w, &ev);
@@ -2136,9 +2131,8 @@ void QApplication::setActiveWindow(QWidget* act)
if (QApplicationPrivate::active_window) {
if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
+ const QWidgetList list = topLevelWidgets();
+ for (auto *w : list) {
if (w->isVisible() && w->isActiveWindow())
toBeDeactivated.append(w);
}
@@ -2159,9 +2153,8 @@ void QApplication::setActiveWindow(QWidget* act)
if (QApplicationPrivate::active_window) {
if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
- QWidgetList list = topLevelWidgets();
- for (int i = 0; i < list.size(); ++i) {
- QWidget *w = list.at(i);
+ const QWidgetList list = topLevelWidgets();
+ for (auto *w : list) {
if (w->isVisible() && w->isActiveWindow())
toBeActivated.append(w);
}
@@ -2319,7 +2312,6 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, con
return;
#endif
- QWidget* w ;
if ((!enter && !leave) || (enter == leave))
return;
#ifdef ALIEN_DEBUG
@@ -2330,25 +2322,25 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, con
bool sameWindow = leave && enter && leave->window() == enter->window();
if (leave && !sameWindow) {
- w = leave;
+ auto *w = leave;
do {
leaveList.append(w);
} while (!w->isWindow() && (w = w->parentWidget()));
}
if (enter && !sameWindow) {
- w = enter;
+ auto *w = enter;
do {
- enterList.prepend(w);
+ enterList.append(w);
} while (!w->isWindow() && (w = w->parentWidget()));
}
if (sameWindow) {
int enterDepth = 0;
int leaveDepth = 0;
- w = enter;
- while (!w->isWindow() && (w = w->parentWidget()))
+ auto *e = enter;
+ while (!e->isWindow() && (e = e->parentWidget()))
enterDepth++;
- w = leave;
- while (!w->isWindow() && (w = w->parentWidget()))
+ auto *l = leave;
+ while (!l->isWindow() && (l = l->parentWidget()))
leaveDepth++;
QWidget* wenter = enter;
QWidget* wleave = leave;
@@ -2365,21 +2357,16 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, con
wleave = wleave->parentWidget();
}
- w = leave;
- while (w != wleave) {
+ for (auto *w = leave; w != wleave; w = w->parentWidget())
leaveList.append(w);
- w = w->parentWidget();
- }
- w = enter;
- while (w != wenter) {
- enterList.prepend(w);
- w = w->parentWidget();
- }
+
+ for (auto *w = enter; w != wenter; w = w->parentWidget())
+ enterList.append(w);
}
QEvent leaveEvent(QEvent::Leave);
for (int i = 0; i < leaveList.size(); ++i) {
- w = leaveList.at(i);
+ auto *w = leaveList.at(i);
if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
QApplication::sendEvent(w, &leaveEvent);
if (w->testAttribute(Qt::WA_Hover) &&
@@ -2396,9 +2383,9 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, con
const QPoint globalPos = qIsInf(globalPosF.x())
? QPoint(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX)
: globalPosF.toPoint();
- const QPoint windowPos = enterList.front()->window()->mapFromGlobal(globalPos);
- for (int i = 0; i < enterList.size(); ++i) {
- w = enterList.at(i);
+ const QPoint windowPos = enterList.back()->window()->mapFromGlobal(globalPos);
+ for (auto it = enterList.crbegin(), end = enterList.crend(); it != end; ++it) {
+ auto *w = *it;
if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
const QPointF localPos = w->mapFromGlobal(globalPos);
QEnterEvent enterEvent(localPos, windowPos, globalPosF);
@@ -2421,7 +2408,7 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, con
// This is not required on Windows as the cursor is reset on every single mouse move.
QWidget *parentOfLeavingCursor = 0;
for (int i = 0; i < leaveList.size(); ++i) {
- w = leaveList.at(i);
+ auto *w = leaveList.at(i);
if (!isAlien(w))
break;
if (w->testAttribute(Qt::WA_SetCursor)) {
@@ -2486,7 +2473,7 @@ bool QApplicationPrivate::isBlockedByModal(QWidget *widget)
bool QApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blockingWindow) const
{
QWindow *unused = 0;
- if (!window) {
+ if (Q_UNLIKELY(!window)) {
qWarning().nospace() << "window == 0 passed.";
return false;
}
@@ -3008,7 +2995,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
if (QApplicationPrivate::is_app_closing)
return true;
- if (receiver == 0) { // serious error
+ if (Q_UNLIKELY(!receiver)) { // serious error
qWarning("QApplication::notify: Unexpected null receiver");
return true;
}
@@ -3257,7 +3244,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QObject *obj = d->extraData->eventFilters.at(i);
if (!obj)
continue;
- if (obj->d_func()->threadData != w->d_func()->threadData) {
+ if (Q_UNLIKELY(obj->d_func()->threadData != w->d_func()->threadData)) {
qWarning("QApplication: Object event filter cannot be in a different thread.");
continue;
}
@@ -4129,7 +4116,7 @@ bool QApplication::isEffectEnabled(Qt::UIEffect effect)
*/
void QApplication::beep()
{
- QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), "beep");
+ QGuiApplicationPrivate::platformIntegration()->beep();
}
/*!
diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp
index 2ddd025239..e85c6504a7 100644
--- a/src/widgets/kernel/qdesktopwidget.cpp
+++ b/src/widgets/kernel/qdesktopwidget.cpp
@@ -49,7 +49,7 @@ int QDesktopScreenWidget::screenNumber() const
const QRect QDesktopWidget::screenGeometry(const QWidget *widget) const
{
- if (!widget) {
+ if (Q_UNLIKELY(!widget)) {
qWarning("QDesktopWidget::screenGeometry(): Attempt "
"to get the screen geometry of a null widget");
return QRect();
@@ -62,7 +62,7 @@ const QRect QDesktopWidget::screenGeometry(const QWidget *widget) const
const QRect QDesktopWidget::availableGeometry(const QWidget *widget) const
{
- if (!widget) {
+ if (Q_UNLIKELY(!widget)) {
qWarning("QDesktopWidget::availableGeometry(): Attempt "
"to get the available geometry of a null widget");
return QRect();
diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp
index a7f9021c42..464d09cde1 100644
--- a/src/widgets/kernel/qformlayout.cpp
+++ b/src/widgets/kernel/qformlayout.cpp
@@ -945,7 +945,7 @@ void QFormLayoutPrivate::setItem(int row, QFormLayout::ItemRole role, QLayoutIte
{
const bool fullRow = role == QFormLayout::SpanningRole;
const int column = role == QFormLayout::SpanningRole ? 1 : static_cast<int>(role);
- if (uint(row) >= uint(m_matrix.rowCount()) || uint(column) > 1U) {
+ if (Q_UNLIKELY(uint(row) >= uint(m_matrix.rowCount()) || uint(column) > 1U)) {
qWarning("QFormLayoutPrivate::setItem: Invalid cell (%d, %d)", row, column);
return;
}
@@ -953,7 +953,7 @@ void QFormLayoutPrivate::setItem(int row, QFormLayout::ItemRole role, QLayoutIte
if (!item)
return;
- if (m_matrix(row, column)) {
+ if (Q_UNLIKELY(m_matrix(row, column))) {
qWarning("QFormLayoutPrivate::setItem: Cell (%d, %d) already occupied", row, column);
return;
}
@@ -1000,7 +1000,7 @@ QLayoutItem* QFormLayoutPrivate::replaceAt(int index, QLayoutItem *newitem)
if (!newitem)
return 0;
const int storageIndex = storageIndexFromLayoutItem(m_matrix, m_things.value(index));
- if (storageIndex == -1) {
+ if (Q_UNLIKELY(storageIndex == -1)) {
// ### Qt6 - fix warning too when this class becomes public
qWarning("QFormLayoutPrivate::replaceAt: Invalid index %d", index);
return 0;
@@ -1414,7 +1414,7 @@ QLayoutItem *QFormLayout::takeAt(int index)
Q_D(QFormLayout);
const int storageIndex = storageIndexFromLayoutItem(d->m_matrix, d->m_things.value(index));
- if (storageIndex == -1) {
+ if (Q_UNLIKELY(storageIndex == -1)) {
qWarning("QFormLayout::takeAt: Invalid index %d", index);
return 0;
}
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index fb2914d53a..2bf5eece64 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -106,7 +106,7 @@ QGestureManager::QGestureManager(QObject *parent)
QGestureManager::~QGestureManager()
{
- qDeleteAll(m_recognizers.values());
+ qDeleteAll(m_recognizers);
foreach (QGestureRecognizer *recognizer, m_obsoleteGestures.keys()) {
qDeleteAll(m_obsoleteGestures.value(recognizer));
delete recognizer;
@@ -117,7 +117,7 @@ QGestureManager::~QGestureManager()
Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
{
QGesture *dummy = recognizer->create(0);
- if (!dummy) {
+ if (Q_UNLIKELY(!dummy)) {
qWarning("QGestureManager::registerGestureRecognizer: "
"the recognizer fails to create a gesture object, skipping registration.");
return Qt::GestureType(0);
@@ -640,17 +640,17 @@ void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures,
Q_ASSERT(gestureType != Qt::CustomGesture);
Q_UNUSED(gestureType);
- if (target) {
+ if (Q_UNLIKELY(!target)) {
+ qCDebug(lcGestureManager) << "QGestureManager::deliverEvent: could not find the target for gesture"
+ << gesture->gestureType();
+ qWarning("QGestureManager::deliverEvent: could not find the target for gesture");
+ undeliveredGestures->insert(gesture);
+ } else {
if (gesture->state() == Qt::GestureStarted) {
startedGestures.insert(gesture);
} else {
normalStartedGestures[target].append(gesture);
}
- } else {
- qCDebug(lcGestureManager) << "QGestureManager::deliverEvent: could not find the target for gesture"
- << gesture->gestureType();
- qWarning("QGestureManager::deliverEvent: could not find the target for gesture");
- undeliveredGestures->insert(gesture);
}
}
diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp
index 85898ae86c..f3272731d9 100644
--- a/src/widgets/kernel/qgridlayout.cpp
+++ b/src/widgets/kernel/qgridlayout.cpp
@@ -557,9 +557,9 @@ void QGridLayoutPrivate::add(QGridBox *box, int row, int col)
void QGridLayoutPrivate::add(QGridBox *box, int row1, int row2, int col1, int col2)
{
- if (row2 >= 0 && row2 < row1)
+ if (Q_UNLIKELY(row2 >= 0 && row2 < row1))
qWarning("QGridLayout: Multi-cell fromRow greater than toRow");
- if (col2 >= 0 && col2 < col1)
+ if (Q_UNLIKELY(col2 >= 0 && col2 < col1))
qWarning("QGridLayout: Multi-cell fromCol greater than toCol");
if (row1 == row2 && col1 == col2) {
add(box, row1, col1);
@@ -1435,7 +1435,7 @@ void QGridLayout::addWidget(QWidget *widget, int row, int column, Qt::Alignment
Q_D(QGridLayout);
if (!d->checkWidget(widget))
return;
- if (row < 0 || column < 0) {
+ if (Q_UNLIKELY(row < 0 || column < 0)) {
qWarning("QGridLayout: Cannot add %s/%s to %s/%s at row %d column %d",
widget->metaObject()->className(), widget->objectName().toLocal8Bit().data(),
metaObject()->className(), objectName().toLocal8Bit().data(), row, column);
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index e74f17b6f7..eec60b14d0 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -129,11 +129,11 @@ QLayout::QLayout(QLayoutPrivate &dd, QLayout *lay, QWidget *w)
if (lay) {
lay->addItem(this);
} else if (w) {
- if (w->layout()) {
- qWarning("QLayout: Attempting to add QLayout \"%s\" to %s \"%s\", which"
+ if (Q_UNLIKELY(w->layout())) {
+ qWarning("QLayout: Attempting to add QLayout \"%ls\" to %s \"%ls\", which"
" already has a layout",
- qPrintable(QObject::objectName()), w->metaObject()->className(),
- w->objectName().toLocal8Bit().data());
+ qUtf16Printable(QObject::objectName()), w->metaObject()->className(),
+ qUtf16Printable(w->objectName()));
setParent(0);
} else {
d->topLevel = true;
@@ -469,7 +469,7 @@ QWidget *QLayout::parentWidget() const
if (!d->topLevel) {
if (parent()) {
QLayout *parentLayout = qobject_cast<QLayout*>(parent());
- if (!parentLayout) {
+ if (Q_UNLIKELY(!parentLayout)) {
qWarning("QLayout::parentWidget: A layout can only have another layout as a parent.");
return 0;
}
@@ -776,9 +776,9 @@ QLayout::~QLayout()
*/
void QLayout::addChildLayout(QLayout *l)
{
- if (l->parent()) {
- qWarning("QLayout::addChildLayout: layout \"%s\" already has a parent",
- l->objectName().toLocal8Bit().data());
+ if (Q_UNLIKELY(l->parent())) {
+ qWarning("QLayout::addChildLayout: layout \"%ls\" already has a parent",
+ qUtf16Printable(l->objectName()));
return;
}
l->setParent(this);
@@ -826,9 +826,9 @@ void QLayoutPrivate::reparentChildWidgets(QWidget *mw)
if (QWidget *w = item->widget()) {
QWidget *pw = w->parentWidget();
#ifdef QT_DEBUG
- if (pw && pw != mw && layoutDebug()) {
- qWarning("QLayout::addChildLayout: widget %s \"%s\" in wrong parent; moved to correct parent",
- w->metaObject()->className(), w->objectName().toLocal8Bit().data());
+ if (Q_UNLIKELY(pw && pw != mw && layoutDebug())) {
+ qWarning("QLayout::addChildLayout: widget %s \"%ls\" in wrong parent; moved to correct parent",
+ w->metaObject()->className(), qUtf16Printable(w->objectName()));
}
#endif
bool needShow = mwVisible && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide));
@@ -849,15 +849,15 @@ void QLayoutPrivate::reparentChildWidgets(QWidget *mw)
bool QLayoutPrivate::checkWidget(QWidget *widget) const
{
Q_Q(const QLayout);
- if (!widget) {
- qWarning("QLayout: Cannot add a null widget to %s/%s", q->metaObject()->className(),
- qPrintable(q->objectName()));
+ if (Q_UNLIKELY(!widget)) {
+ qWarning("QLayout: Cannot add a null widget to %s/%ls", q->metaObject()->className(),
+ qUtf16Printable(q->objectName()));
return false;
}
- if (widget == q->parentWidget()) {
- qWarning("QLayout: Cannot add parent widget %s/%s to its child layout %s/%s",
- widget->metaObject()->className(), qPrintable(widget->objectName()),
- q->metaObject()->className(), qPrintable(q->objectName()));
+ if (Q_UNLIKELY(widget == q->parentWidget())) {
+ qWarning("QLayout: Cannot add parent widget %s/%ls to its child layout %s/%ls",
+ widget->metaObject()->className(), qUtf16Printable(widget->objectName()),
+ q->metaObject()->className(), qUtf16Printable(q->objectName()));
return false;
}
return true;
@@ -870,14 +870,14 @@ bool QLayoutPrivate::checkWidget(QWidget *widget) const
bool QLayoutPrivate::checkLayout(QLayout *otherLayout) const
{
Q_Q(const QLayout);
- if (!otherLayout) {
- qWarning("QLayout: Cannot add a null layout to %s/%s", q->metaObject()->className(),
- qPrintable(q->objectName()));
+ if (Q_UNLIKELY(!otherLayout)) {
+ qWarning("QLayout: Cannot add a null layout to %s/%ls",
+ q->metaObject()->className(), qUtf16Printable(q->objectName()));
return false;
}
- if (otherLayout == q) {
- qWarning("QLayout: Cannot add layout %s/%s to itself", q->metaObject()->className(),
- qPrintable(q->objectName()));
+ if (Q_UNLIKELY(otherLayout == q)) {
+ qWarning("QLayout: Cannot add layout %s/%ls to itself",
+ q->metaObject()->className(), qUtf16Printable(q->objectName()));
return false;
}
return true;
@@ -902,17 +902,17 @@ void QLayout::addChildWidget(QWidget *w)
QLayout *l = pw->layout();
if (l && removeWidgetRecursively(l, w)) {
#ifdef QT_DEBUG
- if (layoutDebug())
- qWarning("QLayout::addChildWidget: %s \"%s\" is already in a layout; moved to new layout",
- w->metaObject()->className(), w->objectName().toLocal8Bit().data());
+ if (Q_UNLIKELY(layoutDebug()))
+ qWarning("QLayout::addChildWidget: %s \"%ls\" is already in a layout; moved to new layout",
+ w->metaObject()->className(), qUtf16Printable(w->objectName()));
#endif
}
}
if (pw && mw && pw != mw) {
#ifdef QT_DEBUG
- if (layoutDebug())
- qWarning("QLayout::addChildWidget: %s \"%s\" in wrong parent; moved to correct parent",
- w->metaObject()->className(), w->objectName().toLocal8Bit().data());
+ if (Q_UNLIKELY(layoutDebug()))
+ qWarning("QLayout::addChildWidget: %s \"%ls\" in wrong parent; moved to correct parent",
+ w->metaObject()->className(), qUtf16Printable(w->objectName()));
#endif
pw = 0;
}
@@ -1064,9 +1064,9 @@ bool QLayout::activate()
if (d->activated)
return false;
QWidget *mw = static_cast<QWidget*>(parent());
- if (mw == 0) {
- qWarning("QLayout::activate: %s \"%s\" does not have a main widget",
- QObject::metaObject()->className(), QObject::objectName().toLocal8Bit().data());
+ if (Q_UNLIKELY(!mw)) {
+ qWarning("QLayout::activate: %s \"%ls\" does not have a main widget",
+ metaObject()->className(), qUtf16Printable(objectName()));
return false;
}
activateRecursiveHelper(this);
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index a80db3f60b..7051f970ff 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -740,7 +740,7 @@ void QOpenGLWidgetPrivate::initialize()
// texture usable by the underlying window's backingstore.
QWidget *tlw = q->window();
QOpenGLContext *shareContext = get(tlw)->shareContext();
- if (!shareContext) {
+ if (Q_UNLIKELY(!shareContext)) {
qWarning("QOpenGLWidget: Cannot be used without a context shared with the toplevel.");
return;
}
@@ -756,7 +756,7 @@ void QOpenGLWidgetPrivate::initialize()
ctx->setShareContext(shareContext);
ctx->setFormat(requestedFormat);
ctx->setScreen(shareContext->screen());
- if (!ctx->create()) {
+ if (Q_UNLIKELY(!ctx->create())) {
qWarning("QOpenGLWidget: Failed to create context");
return;
}
@@ -782,7 +782,7 @@ void QOpenGLWidgetPrivate::initialize()
surface->setScreen(ctx->screen());
surface->create();
- if (!ctx->makeCurrent(surface)) {
+ if (Q_UNLIKELY(!ctx->makeCurrent(surface))) {
qWarning("QOpenGLWidget: Failed to make context current");
return;
}
@@ -915,10 +915,10 @@ QOpenGLWidget::QOpenGLWidget(QWidget *parent, Qt::WindowFlags f)
: QWidget(*(new QOpenGLWidgetPrivate), parent, f)
{
Q_D(QOpenGLWidget);
- if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::RasterGLSurface))
- d->setRenderToTexture();
- else
+ if (Q_UNLIKELY(!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::RasterGLSurface)))
qWarning("QOpenGLWidget is not supported on this platform.");
+ else
+ d->setRenderToTexture();
}
/*!
@@ -984,7 +984,7 @@ void QOpenGLWidget::setFormat(const QSurfaceFormat &format)
{
Q_UNUSED(format);
Q_D(QOpenGLWidget);
- if (d->initialized) {
+ if (Q_UNLIKELY(d->initialized)) {
qWarning("QOpenGLWidget: Already initialized, setting the format has no effect");
return;
}
diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp
index c08c4eeb32..55b57c5c57 100644
--- a/src/widgets/kernel/qshortcut.cpp
+++ b/src/widgets/kernel/qshortcut.cpp
@@ -49,7 +49,7 @@
QT_BEGIN_NAMESPACE
#define QAPP_CHECK(functionName) \
- if (!qApp) { \
+ if (Q_UNLIKELY(!qApp)) { \
qWarning("QShortcut: Initialize QApplication before calling '" functionName "'."); \
return; \
}
@@ -410,7 +410,7 @@ public:
void QShortcutPrivate::redoGrab(QShortcutMap &map)
{
Q_Q(QShortcut);
- if (!parent) {
+ if (Q_UNLIKELY(!parent)) {
qWarning("QShortcut: No widget parent defined");
return;
}
diff --git a/src/widgets/kernel/qstackedlayout.cpp b/src/widgets/kernel/qstackedlayout.cpp
index 957b6f09b5..b76e92bc35 100644
--- a/src/widgets/kernel/qstackedlayout.cpp
+++ b/src/widgets/kernel/qstackedlayout.cpp
@@ -57,7 +57,7 @@ QLayoutItem* QStackedLayoutPrivate::replaceAt(int idx, QLayoutItem *newitem)
if (idx < 0 || idx >= list.size() || !newitem)
return 0;
QWidget *wdg = newitem->widget();
- if (!wdg) {
+ if (Q_UNLIKELY(!wdg)) {
qWarning("QStackedLayout::replaceAt: Only widgets can be added");
return 0;
}
@@ -367,7 +367,7 @@ int QStackedLayout::currentIndex() const
void QStackedLayout::setCurrentWidget(QWidget *widget)
{
int index = indexOf(widget);
- if (index == -1) {
+ if (Q_UNLIKELY(index == -1)) {
qWarning("QStackedLayout::setCurrentWidget: Widget %p not contained in stack", widget);
return;
}
@@ -420,12 +420,12 @@ int QStackedLayout::count() const
void QStackedLayout::addItem(QLayoutItem *item)
{
QWidget *widget = item->widget();
- if (widget) {
- addWidget(widget);
- delete item;
- } else {
+ if (Q_UNLIKELY(!widget)) {
qWarning("QStackedLayout::addItem: Only widgets can be added");
+ return;
}
+ addWidget(widget);
+ delete item;
}
/*!
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index 51bf6e4684..39a58d60dc 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -264,12 +264,12 @@ void QTipLabel::hideTipImmediately()
void QTipLabel::setTipRect(QWidget *w, const QRect &r)
{
- if (!r.isNull() && !w)
+ if (Q_UNLIKELY(!r.isNull() && !w)) {
qWarning("QToolTip::setTipRect: Cannot pass null widget if rect is set");
- else{
- widget = w;
- rect = r;
+ return;
}
+ widget = w;
+ rect = r;
}
void QTipLabel::timerEvent(QTimerEvent *e)
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 229cfc0f85..2f436b11af 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -290,7 +290,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
, qd_hd(0)
#endif
{
- if (!qApp) {
+ if (Q_UNLIKELY(!qApp)) {
qFatal("QWidget: Must construct a QApplication before a QWidget");
return;
}
@@ -300,7 +300,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
// This allows incompatible versions to be loaded, possibly for testing.
Q_UNUSED(version);
#else
- if (version != QObjectPrivateVersion)
+ if (Q_UNLIKELY(version != QObjectPrivateVersion))
qFatal("Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)",
version, QObjectPrivateVersion);
#endif
@@ -1117,7 +1117,7 @@ void QWidgetPrivate::adjustFlags(Qt::WindowFlags &flags, QWidget *w)
void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
{
Q_Q(QWidget);
- if (!qobject_cast<QApplication *>(QCoreApplication::instance()))
+ if (Q_UNLIKELY(!qobject_cast<QApplication *>(QCoreApplication::instance())))
qFatal("QWidget: Cannot create a QWidget without QApplication");
Q_ASSERT(allWidgets);
@@ -1532,7 +1532,7 @@ QWidget::~QWidget()
d->data.in_destructor = true;
#if defined (QT_CHECK_STATE)
- if (paintingActive())
+ if (Q_UNLIKELY(paintingActive()))
qWarning("QWidget: %s (%s) deleted while being painted", className(), name());
#endif
@@ -1987,11 +1987,14 @@ void QWidgetPrivate::propagatePaletteChange()
}
int mask = data.pal.resolve() | inheritedPaletteResolveMask;
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
QEvent pc(QEvent::PaletteChange);
QApplication::sendEvent(q, &pc);
for (int i = 0; i < children.size(); ++i) {
QWidget *w = qobject_cast<QWidget*>(children.at(i));
- if (w && !w->testAttribute(Qt::WA_StyleSheet)
+ if (w && (!w->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
&& (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) {
QWidgetPrivate *wd = w->d_func();
wd->inheritedPaletteResolveMask = mask;
@@ -3291,7 +3294,7 @@ void QWidget::addActions(QList<QAction*> actions)
*/
void QWidget::insertAction(QAction *before, QAction *action)
{
- if(!action) {
+ if (Q_UNLIKELY(!action)) {
qWarning("QWidget::insertAction: Attempt to insert null action");
return;
}
@@ -3323,7 +3326,11 @@ void QWidget::insertAction(QAction *before, QAction *action)
\sa removeAction(), QMenu, insertAction(), contextMenuPolicy
*/
+#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
+void QWidget::insertActions(QAction *before, const QList<QAction*> &actions)
+#else
void QWidget::insertActions(QAction *before, QList<QAction*> actions)
+#endif
{
for(int i = 0; i < actions.count(); ++i)
insertAction(before, actions.at(i));
@@ -3937,7 +3944,7 @@ bool QWidgetPrivate::setMinimumSize_helper(int &minw, int &minh)
mw = 0;
if (mh == QWIDGETSIZE_MAX)
mh = 0;
- if (minw > QWIDGETSIZE_MAX || minh > QWIDGETSIZE_MAX) {
+ if (Q_UNLIKELY(minw > QWIDGETSIZE_MAX || minh > QWIDGETSIZE_MAX)) {
qWarning("QWidget::setMinimumSize: (%s/%s) "
"The largest allowed size is (%d,%d)",
q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
@@ -3945,7 +3952,7 @@ bool QWidgetPrivate::setMinimumSize_helper(int &minw, int &minh)
minw = mw = qMin<int>(minw, QWIDGETSIZE_MAX);
minh = mh = qMin<int>(minh, QWIDGETSIZE_MAX);
}
- if (minw < 0 || minh < 0) {
+ if (Q_UNLIKELY(minw < 0 || minh < 0)) {
qWarning("QWidget::setMinimumSize: (%s/%s) Negative sizes (%d,%d) "
"are not possible",
q->objectName().toLocal8Bit().data(), q->metaObject()->className(), minw, minh);
@@ -4019,7 +4026,7 @@ void QWidget::setMinimumSize(int minw, int minh)
bool QWidgetPrivate::setMaximumSize_helper(int &maxw, int &maxh)
{
Q_Q(QWidget);
- if (maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX) {
+ if (Q_UNLIKELY(maxw > QWIDGETSIZE_MAX || maxh > QWIDGETSIZE_MAX)) {
qWarning("QWidget::setMaximumSize: (%s/%s) "
"The largest allowed size is (%d,%d)",
q->objectName().toLocal8Bit().data(), q->metaObject()->className(), QWIDGETSIZE_MAX,
@@ -4027,7 +4034,7 @@ bool QWidgetPrivate::setMaximumSize_helper(int &maxw, int &maxh)
maxw = qMin<int>(maxw, QWIDGETSIZE_MAX);
maxh = qMin<int>(maxh, QWIDGETSIZE_MAX);
}
- if (maxw < 0 || maxh < 0) {
+ if (Q_UNLIKELY(maxw < 0 || maxh < 0)) {
qWarning("QWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) "
"are not possible",
q->objectName().toLocal8Bit().data(), q->metaObject()->className(), maxw, maxh);
@@ -4576,15 +4583,19 @@ void QWidget::setPalette(const QPalette &palette)
QPalette QWidgetPrivate::naturalWidgetPalette(uint inheritedMask) const
{
Q_Q(const QWidget);
+
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
QPalette naturalPalette = QApplication::palette(q);
- if (!q->testAttribute(Qt::WA_StyleSheet)
+ if ((!q->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
&& (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
#ifndef QT_NO_GRAPHICSVIEW
|| (extra && extra->proxyWidget)
#endif //QT_NO_GRAPHICSVIEW
)) {
if (QWidget *p = q->parentWidget()) {
- if (!p->testAttribute(Qt::WA_StyleSheet)) {
+ if (!p->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
if (!naturalPalette.isCopyOf(QApplication::palette())) {
QPalette inheritedPalette = p->palette();
inheritedPalette.resolve(inheritedMask);
@@ -4720,15 +4731,19 @@ void QWidget::setFont(const QFont &font)
QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const
{
Q_Q(const QWidget);
+
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
QFont naturalFont = QApplication::font(q);
- if (!q->testAttribute(Qt::WA_StyleSheet)
+ if ((!q->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles)
&& (!q->isWindow() || q->testAttribute(Qt::WA_WindowPropagation)
#ifndef QT_NO_GRAPHICSVIEW
|| (extra && extra->proxyWidget)
#endif //QT_NO_GRAPHICSVIEW
)) {
if (QWidget *p = q->parentWidget()) {
- if (!p->testAttribute(Qt::WA_StyleSheet)) {
+ if (!p->testAttribute(Qt::WA_StyleSheet) || useStyleSheetPropagationInWidgetStyles) {
if (!naturalFont.isCopyOf(QApplication::font())) {
if (inheritedMask != 0) {
QFont inheritedFont = p->font();
@@ -4784,6 +4799,8 @@ void QWidgetPrivate::updateFont(const QFont &font)
#ifndef QT_NO_STYLE_STYLESHEET
const QStyleSheetStyle* cssStyle;
cssStyle = extra ? qobject_cast<const QStyleSheetStyle*>(extra->style) : 0;
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
#endif
data.fnt = QFont(font, q);
@@ -4808,7 +4825,7 @@ void QWidgetPrivate::updateFont(const QFont &font)
if (w) {
if (0) {
#ifndef QT_NO_STYLE_STYLESHEET
- } else if (w->testAttribute(Qt::WA_StyleSheet)) {
+ } else if (!useStyleSheetPropagationInWidgetStyles && w->testAttribute(Qt::WA_StyleSheet)) {
// Style sheets follow a different font propagation scheme.
if (cssStyle)
cssStyle->updateStyleSheetFont(w);
@@ -4823,7 +4840,7 @@ void QWidgetPrivate::updateFont(const QFont &font)
}
#ifndef QT_NO_STYLE_STYLESHEET
- if (cssStyle) {
+ if (!useStyleSheetPropagationInWidgetStyles && cssStyle) {
cssStyle->updateStyleSheetFont(q);
}
#endif
@@ -5005,7 +5022,7 @@ void QWidgetPrivate::unsetCursor_sys()
qt_qpa_set_cursor(q, false);
}
-static inline void applyCursor(QWidget *w, QCursor c)
+static inline void applyCursor(QWidget *w, const QCursor &c)
{
if (QWindow *window = w->windowHandle())
window->setCursor(c);
@@ -5118,12 +5135,12 @@ void QWidget::render(QPaintDevice *target, const QPoint &targetOffset,
void QWidget::render(QPainter *painter, const QPoint &targetOffset,
const QRegion &sourceRegion, RenderFlags renderFlags)
{
- if (!painter) {
+ if (Q_UNLIKELY(!painter)) {
qWarning("QWidget::render: Null pointer to painter");
return;
}
- if (!painter->isActive()) {
+ if (Q_UNLIKELY(!painter->isActive())) {
qWarning("QWidget::render: Cannot render with an inactive painter");
return;
}
@@ -5177,9 +5194,9 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
d->render(target, targetOffset, toBePainted, renderFlags);
// Restore system clip, viewport and transform.
- enginePriv->systemClip = oldSystemClip;
enginePriv->setSystemViewport(oldSystemViewport);
enginePriv->setSystemTransform(oldTransform);
+ enginePriv->systemClip = oldSystemClip;
// Restore shared painter.
d->setSharedPainter(oldPainter);
@@ -5512,7 +5529,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
if (!toBePainted.isEmpty()) {
if (!onScreen || alsoOnScreen) {
//update the "in paint event" flag
- if (q->testAttribute(Qt::WA_WState_InPaintEvent))
+ if (Q_UNLIKELY(q->testAttribute(Qt::WA_WState_InPaintEvent)))
qWarning("QWidget::repaint: Recursive repaint detected");
q->setAttribute(Qt::WA_WState_InPaintEvent);
@@ -5623,7 +5640,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
setSystemClip(pdev, QRegion());
}
q->setAttribute(Qt::WA_WState_InPaintEvent, false);
- if (q->paintingActive())
+ if (Q_UNLIKELY(q->paintingActive()))
qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
if (paintEngine && paintEngine->autoDestruct()) {
@@ -5672,7 +5689,7 @@ void QWidgetPrivate::sendPaintEvent(const QRegion &toBePainted)
void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
const QRegion &sourceRegion, QWidget::RenderFlags renderFlags)
{
- if (!target) {
+ if (Q_UNLIKELY(!target)) {
qWarning("QWidget::render: null pointer to paint device");
return;
}
@@ -5806,7 +5823,7 @@ QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) con
if (system != Qt::DeviceCoordinates)
return m_widget->rect();
- if (!context) {
+ if (Q_UNLIKELY(!context)) {
// Device coordinates without context not yet supported.
qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
return QRectF();
@@ -5838,7 +5855,7 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
QGraphicsEffect::PixmapPadMode mode) const
{
const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
- if (!context && deviceCoordinates) {
+ if (Q_UNLIKELY(!context && deviceCoordinates)) {
// Device coordinates without context not yet supported.
qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
return QPixmap();
@@ -6371,7 +6388,7 @@ void QWidget::setFocusProxy(QWidget * w)
return;
for (QWidget* fp = w; fp; fp = fp->focusProxy()) {
- if (fp == this) {
+ if (Q_UNLIKELY(fp == this)) {
qWarning("QWidget: %s (%s) already in focus proxy chain", metaObject()->className(), objectName().toLocal8Bit().constData());
return;
}
@@ -6885,7 +6902,7 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
if (!first || !second || first->focusPolicy() == Qt::NoFocus || second->focusPolicy() == Qt::NoFocus)
return;
- if (first->window() != second->window()) {
+ if (Q_UNLIKELY(first->window() != second->window())) {
qWarning("QWidget::setTabOrder: 'first' and 'second' must be in the same window");
return;
}
@@ -10042,12 +10059,12 @@ QLayout *QWidget::layout() const
void QWidget::setLayout(QLayout *l)
{
- if (!l) {
+ if (Q_UNLIKELY(!l)) {
qWarning("QWidget::setLayout: Cannot set layout to 0");
return;
}
if (layout()) {
- if (layout() != l)
+ if (Q_UNLIKELY(layout() != l))
qWarning("QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", which already has a"
" layout", l->objectName().toLocal8Bit().data(), metaObject()->className(),
objectName().toLocal8Bit().data());
@@ -10489,7 +10506,11 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
d->reparentFocusWidgets(oldtlw);
setAttribute(Qt::WA_Resized, resized);
- if (!testAttribute(Qt::WA_StyleSheet)
+
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
+ if (!useStyleSheetPropagationInWidgetStyles && !testAttribute(Qt::WA_StyleSheet)
&& (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) {
d->resolveFont();
d->resolvePalette();
@@ -11388,7 +11409,7 @@ void QWidgetPrivate::setWindowModified_helper()
return;
bool on = q->testAttribute(Qt::WA_WindowModified);
if (!platformWindow->setWindowModified(on)) {
- if (!q->windowTitle().contains(QLatin1String("[*]")) && on)
+ if (Q_UNLIKELY(on && !q->windowTitle().contains(QLatin1String("[*]"))))
qWarning("QWidget::setWindowModified: The window title does not contain a '[*]' placeholder");
setWindowTitle_helper(q->windowTitle());
setWindowIconText_helper(q->windowIconText());
@@ -12138,7 +12159,7 @@ QOpenGLContext *QWidgetPrivate::shareContext() const
#ifdef QT_NO_OPENGL
return 0;
#else
- if (!extra || !extra->topextra || !extra->topextra->window) {
+ if (Q_UNLIKELY(!extra || !extra->topextra || !extra->topextra->window)) {
qWarning("Asking for share context for widget that does not have a window handle");
return 0;
}
diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h
index a56f6e1133..638c962e68 100644
--- a/src/widgets/kernel/qwidget.h
+++ b/src/widgets/kernel/qwidget.h
@@ -541,11 +541,12 @@ public:
void addAction(QAction *action);
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
void addActions(const QList<QAction*> &actions);
+ void insertActions(const QAction *before, const QList<QAction*> &actions);
#else
void addActions(QList<QAction*> actions);
+ void insertActions(QAction *before, QList<QAction*> actions);
#endif
void insertAction(QAction *before, QAction *action);
- void insertActions(QAction *before, QList<QAction*> actions);
void removeAction(QAction *action);
QList<QAction*> actions() const;
#endif
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 3f7f9291b6..63419ea093 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -1606,7 +1606,7 @@ void QWidgetPrivate::repaint_sys(const QRegion &rgn)
QWidgetBackingStore::unflushPaint(q, toBePainted);
#endif
- if (q->paintingActive())
+ if (Q_UNLIKELY(q->paintingActive()))
qWarning("QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent");
}
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 3637b76aa9..e65c2c8bef 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -283,7 +283,7 @@ bool QWidgetWindow::event(QEvent *event)
case QEvent::ContextMenu:
handleContextMenuEvent(static_cast<QContextMenuEvent *>(event));
return true;
-#endif
+#endif // QT_NO_CONTEXTMENU
// Handing show events to widgets (see below) here would cause them to be triggered twice
case QEvent::Show:
@@ -510,8 +510,12 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
popupEvent = popupChild;
QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
QApplication::sendSpontaneousEvent(popupEvent, &e);
-#endif
}
+#else
+ Q_UNUSED(contextMenuTrigger)
+ Q_UNUSED(oldOpenPopupCount)
+ }
+#endif
if (releaseAfter) {
qt_button_down = 0;
@@ -794,7 +798,7 @@ void QWidgetWindow::handleDragLeaveEvent(QDragLeaveEvent *event)
void QWidgetWindow::handleDropEvent(QDropEvent *event)
{
- if (m_dragTarget.isNull()) {
+ if (Q_UNLIKELY(m_dragTarget.isNull())) {
qWarning() << m_widget << ": No drag target set.";
event->ignore();
return;
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index 3885431b05..98a3330822 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -193,7 +193,7 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt:
: QWidget(*new QWindowContainerPrivate, parent, flags)
{
Q_D(QWindowContainer);
- if (!embeddedWindow) {
+ if (Q_UNLIKELY(!embeddedWindow)) {
qWarning("QWindowContainer: embedded window cannot be null");
return;
}
diff --git a/src/widgets/styles/qandroidstyle.cpp b/src/widgets/styles/qandroidstyle.cpp
index 4489f36ab7..9a0e4ba32a 100644
--- a/src/widgets/styles/qandroidstyle.cpp
+++ b/src/widgets/styles/qandroidstyle.cpp
@@ -84,7 +84,7 @@ QAndroidStyle::QAndroidStyle()
++objectIterator) {
QString key = objectIterator.key();
QJsonValue value = objectIterator.value();
- if (!value.isObject()) {
+ if (Q_UNLIKELY(!value.isObject())) {
qWarning("Style.json structure is unrecognized.");
continue;
}
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 355a3d2c3f..f639e4a082 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -552,18 +552,31 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
case PE_IndicatorTabTear:
if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
bool rtl = tab->direction == Qt::RightToLeft;
- QRect rect = tab->rect;
+ const bool horizontal = tab->rect.height() > tab->rect.width();
+ const int margin = 4;
QPainterPath path;
- rect.setTop(rect.top() + ((tab->state & State_Selected) ? 1 : 3));
- rect.setBottom(rect.bottom() - ((tab->state & State_Selected) ? 0 : 2));
+ if (horizontal) {
+ QRect rect = tab->rect.adjusted(rtl ? margin : 0, 0, rtl ? 1 : -margin, 0);
+ rect.setTop(rect.top() + ((tab->state & State_Selected) ? 1 : 3));
+ rect.setBottom(rect.bottom() - ((tab->state & State_Selected) ? 0 : 2));
- path.moveTo(QPoint(rtl ? rect.right() : rect.left(), rect.top()));
- int count = 4;
- for(int jags = 1; jags <= count; ++jags, rtl = !rtl)
- path.lineTo(QPoint(rtl ? rect.left() : rect.right(), rect.top() + jags * rect.height()/count));
+ path.moveTo(QPoint(rtl ? rect.right() : rect.left(), rect.top()));
+ int count = 4;
+ for (int jags = 1; jags <= count; ++jags, rtl = !rtl)
+ path.lineTo(QPoint(rtl ? rect.left() : rect.right(), rect.top() + jags * rect.height()/count));
+ } else {
+ QRect rect = tab->rect.adjusted(0, 0, 0, -margin);
+ rect.setLeft(rect.left() + ((tab->state & State_Selected) ? 1 : 3));
+ rect.setRight(rect.right() - ((tab->state & State_Selected) ? 0 : 2));
+
+ path.moveTo(QPoint(rect.left(), rect.top()));
+ int count = 4;
+ for (int jags = 1; jags <= count; ++jags, rtl = !rtl)
+ path.lineTo(QPoint(rect.left() + jags * rect.width()/count, rtl ? rect.top() : rect.bottom()));
+ }
- p->setPen(QPen(tab->palette.light(), qreal(.8)));
+ p->setPen(QPen(tab->palette.dark(), qreal(.8)));
p->setBrush(tab->palette.background());
p->setRenderHint(QPainter::Antialiasing);
p->drawPath(path);
@@ -2780,13 +2793,13 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
case QTabBar::TriangularNorth:
case QTabBar::RoundedSouth:
case QTabBar::TriangularSouth:
- r.setRect(tab->rect.left(), tab->rect.top(), 4, opt->rect.height());
+ r.setRect(tab->rect.left(), tab->rect.top(), 8, opt->rect.height());
break;
case QTabBar::RoundedWest:
case QTabBar::TriangularWest:
case QTabBar::RoundedEast:
case QTabBar::TriangularEast:
- r.setRect(tab->rect.left(), tab->rect.top(), opt->rect.width(), 4);
+ r.setRect(tab->rect.left(), tab->rect.top(), opt->rect.width(), 8);
break;
default:
break;
@@ -2794,6 +2807,23 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
r = visualRect(opt->direction, opt->rect, r);
}
break;
+ case SE_TabBarScrollLeftButton: {
+ const bool vertical = opt->rect.width() < opt->rect.height();
+ const Qt::LayoutDirection ld = widget->layoutDirection();
+ const int buttonWidth = qMax(pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width());
+ const int buttonOverlap = pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, 0, widget);
+
+ r = vertical ? QRect(0, opt->rect.height() - (buttonWidth * 2) + buttonOverlap, opt->rect.width(), buttonWidth)
+ : QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - (buttonWidth * 2) + buttonOverlap, 0, buttonWidth, opt->rect.height()));
+ break; }
+ case SE_TabBarScrollRightButton: {
+ const bool vertical = opt->rect.width() < opt->rect.height();
+ const Qt::LayoutDirection ld = widget->layoutDirection();
+ const int buttonWidth = qMax(pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, widget), QApplication::globalStrut().width());
+
+ r = vertical ? QRect(0, opt->rect.height() - buttonWidth, opt->rect.width(), buttonWidth)
+ : QStyle::visualRect(ld, opt->rect, QRect(opt->rect.width() - buttonWidth, 0, buttonWidth, opt->rect.height()));
+ break; }
#endif
case SE_TreeViewDisclosureItem:
r = opt->rect;
@@ -5567,6 +5597,11 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
case SP_FileLinkIcon:
case SP_DesktopIcon:
case SP_ComputerIcon:
+ case SP_VistaShield:
+ case SP_MessageBoxInformation:
+ case SP_MessageBoxWarning:
+ case SP_MessageBoxCritical:
+ case SP_MessageBoxQuestion:
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
for (int size = 16 ; size <= 32 ; size += 16) {
@@ -5590,13 +5625,6 @@ QIcon QCommonStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption
}
}
break;
- case SP_VistaShield:
- if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
- QPlatformTheme::StandardPixmap sp = static_cast<QPlatformTheme::StandardPixmap>(standardIcon);
- QPixmap pixmap = theme->standardPixmap(sp, QSizeF(32, 32));
- icon.addPixmap(pixmap);
- }
- break;
default:
break;
}
diff --git a/src/widgets/styles/qdrawutil.cpp b/src/widgets/styles/qdrawutil.cpp
index 2a4d392413..d50f04bbb8 100644
--- a/src/widgets/styles/qdrawutil.cpp
+++ b/src/widgets/styles/qdrawutil.cpp
@@ -87,7 +87,7 @@ void qDrawShadeLine(QPainter *p, int x1, int y1, int x2, int y2,
const QPalette &pal, bool sunken,
int lineWidth, int midLineWidth)
{
- if (!(p && lineWidth >= 0 && midLineWidth >= 0)) {
+ if (Q_UNLIKELY(!p || lineWidth < 0 || midLineWidth < 0)) {
qWarning("qDrawShadeLine: Invalid parameters");
return;
}
@@ -203,7 +203,7 @@ void qDrawShadeRect(QPainter *p, int x, int y, int w, int h,
{
if (w == 0 || h == 0)
return;
- if (! (w > 0 && h > 0 && lineWidth >= 0 && midLineWidth >= 0)) {
+ if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0 || midLineWidth < 0)) {
qWarning("qDrawShadeRect: Invalid parameters");
return;
}
@@ -303,7 +303,7 @@ void qDrawShadePanel(QPainter *p, int x, int y, int w, int h,
{
if (w == 0 || h == 0)
return;
- if (!(w > 0 && h > 0 && lineWidth >= 0)) {
+ if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
qWarning("qDrawShadePanel: Invalid parameters");
}
QColor shade = pal.dark().color();
@@ -509,7 +509,7 @@ void qDrawPlainRect(QPainter *p, int x, int y, int w, int h, const QColor &c,
{
if (w == 0 || h == 0)
return;
- if (!(w > 0 && h > 0 && lineWidth >= 0)) {
+ if (Q_UNLIKELY(w < 0 || h < 0 || lineWidth < 0)) {
qWarning("qDrawPlainRect: Invalid parameters");
}
QPen oldPen = p->pen();
diff --git a/src/widgets/styles/qgtk2painter.cpp b/src/widgets/styles/qgtk2painter.cpp
deleted file mode 100644
index ea8afbc93c..0000000000
--- a/src/widgets/styles/qgtk2painter.cpp
+++ /dev/null
@@ -1,699 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgtk2painter_p.h"
-
-#include <QtCore/qglobal.h>
-#if !defined(QT_NO_STYLE_GTK)
-
-// This class is primarily a wrapper around the gtk painter functions
-// and takes care of converting all such calls into cached Qt pixmaps.
-
-#include <private/qgtkstyle_p_p.h>
-#include <private/qhexstring_p.h>
-#include <QtWidgets/QWidget>
-#include <QtGui/QPixmapCache>
-#include <QtCore/QLibrary>
-
-QT_BEGIN_NAMESPACE
-
-typedef GdkPixbuf* (*Ptr_gdk_pixbuf_get_from_drawable) (GdkPixbuf *, GdkDrawable *, GdkColormap *, int, int, int, int, int, int);
-typedef GdkPixmap* (*Ptr_gdk_pixmap_new) (GdkDrawable *, gint, gint, gint);
-typedef void (*Ptr_gdk_draw_rectangle) (GdkDrawable *, GdkGC *, gboolean, gint, gint, gint, gint);
-typedef void (*Ptr_gdk_drawable_unref)(GdkDrawable *);
-
-typedef void (*Ptr_gtk_paint_check) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_box) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_box_gap) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint , gint, GtkPositionType, gint, gint);
-typedef void (*Ptr_gtk_paint_resize_grip) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, GdkWindowEdge, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_focus) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_shadow) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_slider) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint, GtkOrientation);
-typedef void (*Ptr_gtk_paint_expander) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , GtkExpanderStyle );
-typedef void (*Ptr_gtk_paint_handle) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint, GtkOrientation);
-typedef void (*Ptr_gtk_paint_arrow) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, GtkArrowType, gboolean, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_option) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_flat_box) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint , gint , gint , gint);
-typedef void (*Ptr_gtk_paint_extension) (GtkStyle *, GdkWindow *, GtkStateType, GtkShadowType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint, gint, GtkPositionType);
-typedef void (*Ptr_gtk_paint_hline) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint y);
-typedef void (*Ptr_gtk_paint_vline) (GtkStyle *, GdkWindow *, GtkStateType, const GdkRectangle *, GtkWidget *, const gchar *, gint, gint, gint);
-
-namespace QGtk2PainterPrivate {
- static Ptr_gdk_pixmap_new gdk_pixmap_new = 0;
- static Ptr_gdk_pixbuf_get_from_drawable gdk_pixbuf_get_from_drawable = 0;
- static Ptr_gdk_draw_rectangle gdk_draw_rectangle = 0;
- static Ptr_gdk_drawable_unref gdk_drawable_unref = 0;
-
- static Ptr_gtk_paint_check gtk_paint_check = 0;
- static Ptr_gtk_paint_box gtk_paint_box = 0;
- static Ptr_gtk_paint_box_gap gtk_paint_box_gap = 0;
- static Ptr_gtk_paint_flat_box gtk_paint_flat_box = 0;
- static Ptr_gtk_paint_option gtk_paint_option = 0;
- static Ptr_gtk_paint_extension gtk_paint_extension = 0;
- static Ptr_gtk_paint_slider gtk_paint_slider = 0;
- static Ptr_gtk_paint_shadow gtk_paint_shadow = 0;
- static Ptr_gtk_paint_resize_grip gtk_paint_resize_grip = 0;
- static Ptr_gtk_paint_focus gtk_paint_focus = 0;
- static Ptr_gtk_paint_arrow gtk_paint_arrow = 0;
- static Ptr_gtk_paint_handle gtk_paint_handle = 0;
- static Ptr_gtk_paint_expander gtk_paint_expander = 0;
- static Ptr_gtk_paint_vline gtk_paint_vline = 0;
- static Ptr_gtk_paint_hline gtk_paint_hline = 0;
-}
-
-static void initGtk()
-{
-#ifndef QT_NO_LIBRARY
- static bool initialized = false;
- if (!initialized) {
- // enforce the "0" suffix, so we'll open libgtk-x11-2.0.so.0
- QLibrary libgtk(QLS("gtk-x11-2.0"), 0, 0);
-
- QGtk2PainterPrivate::gdk_pixmap_new = (Ptr_gdk_pixmap_new)libgtk.resolve("gdk_pixmap_new");
- QGtk2PainterPrivate::gdk_pixbuf_get_from_drawable = (Ptr_gdk_pixbuf_get_from_drawable)libgtk.resolve("gdk_pixbuf_get_from_drawable");
- QGtk2PainterPrivate::gdk_draw_rectangle = (Ptr_gdk_draw_rectangle)libgtk.resolve("gdk_draw_rectangle");
- QGtk2PainterPrivate::gdk_drawable_unref = (Ptr_gdk_drawable_unref)libgtk.resolve("gdk_drawable_unref");
-
- QGtk2PainterPrivate::gtk_paint_check = (Ptr_gtk_paint_check)libgtk.resolve("gtk_paint_check");
- QGtk2PainterPrivate::gtk_paint_box = (Ptr_gtk_paint_box)libgtk.resolve("gtk_paint_box");
- QGtk2PainterPrivate::gtk_paint_flat_box = (Ptr_gtk_paint_flat_box)libgtk.resolve("gtk_paint_flat_box");
- QGtk2PainterPrivate::gtk_paint_check = (Ptr_gtk_paint_check)libgtk.resolve("gtk_paint_check");
- QGtk2PainterPrivate::gtk_paint_box = (Ptr_gtk_paint_box)libgtk.resolve("gtk_paint_box");
- QGtk2PainterPrivate::gtk_paint_resize_grip = (Ptr_gtk_paint_resize_grip)libgtk.resolve("gtk_paint_resize_grip");
- QGtk2PainterPrivate::gtk_paint_focus = (Ptr_gtk_paint_focus)libgtk.resolve("gtk_paint_focus");
- QGtk2PainterPrivate::gtk_paint_shadow = (Ptr_gtk_paint_shadow)libgtk.resolve("gtk_paint_shadow");
- QGtk2PainterPrivate::gtk_paint_slider = (Ptr_gtk_paint_slider)libgtk.resolve("gtk_paint_slider");
- QGtk2PainterPrivate::gtk_paint_expander = (Ptr_gtk_paint_expander)libgtk.resolve("gtk_paint_expander");
- QGtk2PainterPrivate::gtk_paint_handle = (Ptr_gtk_paint_handle)libgtk.resolve("gtk_paint_handle");
- QGtk2PainterPrivate::gtk_paint_option = (Ptr_gtk_paint_option)libgtk.resolve("gtk_paint_option");
- QGtk2PainterPrivate::gtk_paint_arrow = (Ptr_gtk_paint_arrow)libgtk.resolve("gtk_paint_arrow");
- QGtk2PainterPrivate::gtk_paint_box_gap = (Ptr_gtk_paint_box_gap)libgtk.resolve("gtk_paint_box_gap");
- QGtk2PainterPrivate::gtk_paint_extension = (Ptr_gtk_paint_extension)libgtk.resolve("gtk_paint_extension");
- QGtk2PainterPrivate::gtk_paint_hline = (Ptr_gtk_paint_hline)libgtk.resolve("gtk_paint_hline");
- QGtk2PainterPrivate::gtk_paint_vline = (Ptr_gtk_paint_vline)libgtk.resolve("gtk_paint_vline");
-
- initialized = true;
- }
-#endif // !QT_NO_LIBRARY
-}
-
-// To recover alpha we apply the gtk painting function two times to
-// white, and black window backgrounds. This can be used to
-// recover the premultiplied alpha channel
-QPixmap QGtk2Painter::renderTheme(uchar *bdata, uchar *wdata, const QRect &rect) const
-{
- const int bytecount = rect.width() * rect.height() * 4;
- for (int index = 0; index < bytecount ; index += 4) {
- uchar val = bdata[index + GTK_BLUE];
- if (m_alpha) {
- int alphaval = qMax(bdata[index + GTK_BLUE] - wdata[index + GTK_BLUE],
- bdata[index + GTK_GREEN] - wdata[index + GTK_GREEN]);
- alphaval = qMax(alphaval, bdata[index + GTK_RED] - wdata[index + GTK_RED]) + 255;
- bdata[index + QT_ALPHA] = alphaval;
- }
- bdata[index + QT_RED] = bdata[index + GTK_RED];
- bdata[index + QT_GREEN] = bdata[index + GTK_GREEN];
- bdata[index + QT_BLUE] = val;
- }
- QImage converted((const uchar*)bdata, rect.width(), rect.height(), m_alpha ?
- QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
-
- if (m_hflipped || m_vflipped) {
- return QPixmap::fromImage(converted.mirrored(m_hflipped, m_vflipped));
- } else {
- // on raster graphicssystem we need to do a copy here, because
- // we intend to deallocate the qimage bits shortly after...
- return QPixmap::fromImage(converted.copy());
- }
-}
-
-// This macro is responsible for painting any GtkStyle painting function onto a QPixmap
-#define DRAW_TO_CACHE(draw_func) \
- if (rect.width() > QWIDGETSIZE_MAX || rect.height() > QWIDGETSIZE_MAX) \
- return; \
- QRect pixmapRect(0, 0, rect.width(), rect.height()); \
- { \
- GdkPixmap *pixmap = QGtk2PainterPrivate::gdk_pixmap_new((GdkDrawable*)(m_window->window), \
- rect.width(), rect.height(), -1); \
- if (!pixmap) \
- return; \
- style = QGtkStylePrivate::gtk_style_attach (style, m_window->window); \
- QGtk2PainterPrivate::gdk_draw_rectangle(pixmap, m_alpha ? style->black_gc : *style->bg_gc, \
- true, 0, 0, rect.width(), rect.height()); \
- draw_func; \
- GdkPixbuf *imgb = QGtkStylePrivate::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, \
- rect.width(), rect.height()); \
- if (!imgb) \
- return; \
- imgb = QGtk2PainterPrivate::gdk_pixbuf_get_from_drawable(imgb, pixmap, NULL, 0, 0, 0, 0, \
- rect.width(), rect.height()); \
- uchar* bdata = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(imgb); \
- if (m_alpha) { \
- QGtk2PainterPrivate::gdk_draw_rectangle(pixmap, style->white_gc, true, 0, 0, \
- rect.width(), rect.height()); \
- draw_func; \
- GdkPixbuf *imgw = QGtkStylePrivate::gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, \
- rect.width(), rect.height()); \
- if (!imgw) \
- return; \
- imgw = QGtk2PainterPrivate::gdk_pixbuf_get_from_drawable(imgw, pixmap, NULL, 0, 0, 0, 0,\
- rect.width(), rect.height()); \
- uchar* wdata = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(imgw); \
- cache = renderTheme(bdata, wdata, rect); \
- QGtkStylePrivate::gdk_pixbuf_unref(imgw); \
- } else { \
- cache = renderTheme(bdata, 0, rect); \
- } \
- QGtk2PainterPrivate::gdk_drawable_unref(pixmap); \
- QGtkStylePrivate::gdk_pixbuf_unref(imgb); \
- }
-
-QGtk2Painter::QGtk2Painter() : QGtkPainter(), m_window(QGtkStylePrivate::gtkWidget("GtkWindow"))
-{
- initGtk();
-}
-
-// Note currently painted without alpha for performance reasons
-void QGtk2Painter::paintBoxGap(GtkWidget *gtkWidget, const gchar* part,
- const QRect &paintRect, GtkStateType state,
- GtkShadowType shadow, GtkPositionType gap_side,
- gint x, gint width,
- GtkStyle *style)
-{
- if (!paintRect.isValid())
- return;
-
- QPixmap cache;
- QRect rect = paintRect;
-
- // To avoid exhausting cache on large tabframes we cheat a bit by
- // tiling the center part.
-
- const int maxHeight = 256;
- const int border = 16;
- if (rect.height() > maxHeight && (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM))
- rect.setHeight(2 * border + 1);
-
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget)
- % HexString<uchar>(gap_side)
- % HexString<gint>(width)
- % HexString<gint>(x);
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_box_gap (style,
- pixmap,
- state,
- shadow,
- NULL,
- gtkWidget,
- (const gchar*)part,
- 0, 0,
- rect.width(),
- rect.height(),
- gap_side,
- x,
- width));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- if (rect.size() != paintRect.size()) {
- // We assume we can stretch the middle tab part
- // Note: the side effect of this is that pinstripe patterns will get fuzzy
- const QSize size = cache.size();
- // top part
- m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top(),
- paintRect.width(), border), cache,
- QRect(0, 0, size.width(), border));
-
- // tiled center part
- QPixmap tilePart(cache.width(), 1);
- QPainter scanLinePainter(&tilePart);
- scanLinePainter.drawPixmap(QRect(0, 0, tilePart.width(), tilePart.height()), cache, QRect(0, border, size.width(), 1));
- scanLinePainter.end();
- m_painter->drawTiledPixmap(QRect(paintRect.left(), paintRect.top() + border,
- paintRect.width(), paintRect.height() - 2*border), tilePart);
-
- // bottom part
- m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top() + paintRect.height() - border,
- paintRect.width(), border), cache,
- QRect(0, size.height() - border, size.width(), border));
- } else
- m_painter->drawPixmap(paintRect.topLeft(), cache);
-}
-
-void QGtk2Painter::paintBox(GtkWidget *gtkWidget, const gchar* part,
- const QRect &paintRect, GtkStateType state,
- GtkShadowType shadow, GtkStyle *style,
- const QString &pmKey)
-{
- if (!paintRect.isValid())
- return;
-
- QPixmap cache;
- QRect rect = paintRect;
-
- // To avoid exhausting cache on large tabframes we cheat a bit by
- // tiling the center part.
-
- const int maxHeight = 256;
- const int maxArea = 256*512;
- const int border = 32;
- if (rect.height() > maxHeight && (rect.width()*rect.height() > maxArea))
- rect.setHeight(2 * border + 1);
-
- QString pixmapName = uniqueName(QLS(part), state, shadow,
- rect.size(), gtkWidget) % pmKey;
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_box (style,
- pixmap,
- state,
- shadow,
- NULL,
- gtkWidget,
- part,
- 0, 0,
- rect.width(),
- rect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- if (rect.size() != paintRect.size()) {
- // We assume we can stretch the middle tab part
- // Note: the side effect of this is that pinstripe patterns will get fuzzy
- const QSize size = cache.size();
- // top part
- m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top(),
- paintRect.width(), border), cache,
- QRect(0, 0, size.width(), border));
-
- // tiled center part
- QPixmap tilePart(cache.width(), 1);
- QPainter scanLinePainter(&tilePart);
- scanLinePainter.drawPixmap(QRect(0, 0, tilePart.width(), tilePart.height()), cache, QRect(0, border, size.width(), 1));
- scanLinePainter.end();
- m_painter->drawTiledPixmap(QRect(paintRect.left(), paintRect.top() + border,
- paintRect.width(), paintRect.height() - 2*border), tilePart);
-
- // bottom part
- m_painter->drawPixmap(QRect(paintRect.left(), paintRect.top() + paintRect.height() - border,
- paintRect.width(), border), cache,
- QRect(0, size.height() - border, size.width(), border));
- } else
- m_painter->drawPixmap(paintRect.topLeft(), cache);
-}
-
-void QGtk2Painter::paintHline(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkStyle *style, int x1, int x2, int y,
- const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
- % HexString<int>(x1)
- % HexString<int>(x2)
- % HexString<int>(y)
- % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_hline (style,
- pixmap,
- state,
- NULL,
- gtkWidget,
- part,
- x1, x2, y));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtk2Painter::paintVline(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkStyle *style, int y1, int y2, int x,
- const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
- % HexString<int>(y1)
- % HexString<int>(y2)
- % HexString<int>(x)
- % pmKey;
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_vline (style,
- pixmap,
- state,
- NULL,
- gtkWidget,
- part,
- y1, y2,
- x));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtk2Painter::paintExpander(GtkWidget *gtkWidget,
- const gchar* part, const QRect &rect,
- GtkStateType state, GtkExpanderStyle expander_state,
- GtkStyle *style, const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget)
- % HexString<uchar>(expander_state)
- % pmKey;
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_expander (style, pixmap,
- state, NULL,
- gtkWidget, part,
- rect.width()/2,
- rect.height()/2,
- expander_state));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtk2Painter::paintFocus(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkStyle *style, const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_focus (style, pixmap, state, NULL,
- gtkWidget,
- part,
- 0, 0,
- rect.width(),
- rect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtk2Painter::paintResizeGrip(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkShadowType shadow, GdkWindowEdge edge,
- GtkStyle *style, const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_resize_grip (style, pixmap, state,
- NULL, gtkWidget,
- part, edge, 0, 0,
- rect.width(),
- rect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtk2Painter::paintArrow(GtkWidget *gtkWidget, const gchar* part,
- const QRect &arrowrect, GtkArrowType arrow_type,
- GtkStateType state, GtkShadowType shadow,
- gboolean fill, GtkStyle *style, const QString &pmKey)
-{
- QRect rect = m_cliprect.isValid() ? m_cliprect : arrowrect;
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size())
- % HexString<uchar>(arrow_type)
- % pmKey;
-
- GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
- int xOffset = m_cliprect.isValid() ? arrowrect.x() - m_cliprect.x() : 0;
- int yOffset = m_cliprect.isValid() ? arrowrect.y() - m_cliprect.y() : 0;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_arrow (style, pixmap, state, shadow,
- &gtkCliprect,
- gtkWidget,
- part,
- arrow_type, fill,
- xOffset, yOffset,
- arrowrect.width(),
- arrowrect.height()))
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtk2Painter::paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow,
- GtkOrientation orientation, GtkStyle *style)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size())
- % HexString<uchar>(orientation);
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_handle (style,
- pixmap,
- state,
- shadow,
- NULL,
- gtkWidget,
- part, 0, 0,
- rect.width(),
- rect.height(),
- orientation));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtk2Painter::paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, GtkOrientation orientation,
- const QString &pmKey)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_slider (style,
- pixmap,
- state,
- shadow,
- NULL,
- gtkWidget,
- part,
- 0, 0,
- rect.width(),
- rect.height(),
- orientation));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-
-void QGtk2Painter::paintShadow(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkShadowType shadow, GtkStyle *style,
- const QString &pmKey)
-
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_shadow(style, pixmap, state, shadow, NULL,
- gtkWidget, part, 0, 0, rect.width(), rect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtk2Painter::paintFlatBox(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state,
- GtkShadowType shadow, GtkStyle *style,
- const QString &pmKey)
-{
- if (!rect.isValid())
- return;
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_flat_box (style,
- pixmap,
- state,
- shadow,
- NULL,
- gtkWidget,
- part, 0, 0,
- rect.width(),
- rect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtk2Painter::paintExtention(GtkWidget *gtkWidget,
- const gchar *part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow,
- GtkPositionType gap_pos, GtkStyle *style)
-{
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget)
- % HexString<uchar>(gap_pos);
-
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_extension (style, pixmap, state, shadow,
- NULL, gtkWidget,
- (const gchar*)part, 0, 0,
- rect.width(),
- rect.height(),
- gap_pos));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtk2Painter::paintOption(GtkWidget *gtkWidget, const QRect &radiorect,
- GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, const QString &detail)
-
-{
- QRect rect = m_cliprect.isValid() ? m_cliprect : radiorect;
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(detail, state, shadow, rect.size());
- GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
- int xOffset = m_cliprect.isValid() ? radiorect.x() - m_cliprect.x() : 0;
- int yOffset = m_cliprect.isValid() ? radiorect.y() - m_cliprect.y() : 0;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_option(style, pixmap,
- state, shadow,
- &gtkCliprect,
- gtkWidget,
- detail.toLatin1(),
- xOffset, yOffset,
- radiorect.width(),
- radiorect.height()));
-
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-void QGtk2Painter::paintCheckbox(GtkWidget *gtkWidget, const QRect &checkrect,
- GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, const QString &detail)
-
-{
- QRect rect = m_cliprect.isValid() ? m_cliprect : checkrect;
- if (!rect.isValid())
- return;
-
- QPixmap cache;
- QString pixmapName = uniqueName(detail, state, shadow, rect.size());
- GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()};
- int xOffset = m_cliprect.isValid() ? checkrect.x() - m_cliprect.x() : 0;
- int yOffset = m_cliprect.isValid() ? checkrect.y() - m_cliprect.y() : 0;
- if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) {
- DRAW_TO_CACHE(QGtk2PainterPrivate::gtk_paint_check (style,
- pixmap,
- state,
- shadow,
- &gtkCliprect,
- gtkWidget,
- detail.toLatin1(),
- xOffset, yOffset,
- checkrect.width(),
- checkrect.height()));
- if (m_usePixmapCache)
- QPixmapCache::insert(pixmapName, cache);
- }
-
- m_painter->drawPixmap(rect.topLeft(), cache);
-}
-
-QT_END_NAMESPACE
-
-#endif //!defined(QT_NO_STYLE_GTK)
diff --git a/src/widgets/styles/qgtk2painter_p.h b/src/widgets/styles/qgtk2painter_p.h
deleted file mode 100644
index 1e489b5bf9..0000000000
--- a/src/widgets/styles/qgtk2painter_p.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGTK2PAINTER_P_H
-#define QGTK2PAINTER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#if !defined(QT_NO_STYLE_GTK)
-
-#include <private/qgtkpainter_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGtk2Painter : public QGtkPainter
-{
-public:
- QGtk2Painter();
-
- void paintBoxGap(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow, GtkPositionType gap_side, gint x,
- gint width, GtkStyle *style) Q_DECL_OVERRIDE;
- void paintBox(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style,
- const QString &pmKey = QString()) Q_DECL_OVERRIDE;
- void paintHline(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
- int x1, int x2, int y, const QString &pmKey = QString()) Q_DECL_OVERRIDE;
- void paintVline(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
- int y1, int y2, int x, const QString &pmKey = QString()) Q_DECL_OVERRIDE;
- void paintExpander(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state,
- GtkExpanderStyle expander_state, GtkStyle *style, const QString &pmKey = QString()) Q_DECL_OVERRIDE;
- void paintFocus(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
- const QString &pmKey = QString()) Q_DECL_OVERRIDE;
- void paintResizeGrip(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GdkWindowEdge edge, GtkStyle *style, const QString &pmKey = QString()) Q_DECL_OVERRIDE;
- void paintArrow(GtkWidget *gtkWidget, const gchar* part, const QRect &arrowrect, GtkArrowType arrow_type, GtkStateType state, GtkShadowType shadow,
- gboolean fill, GtkStyle *style, const QString &pmKey = QString()) Q_DECL_OVERRIDE;
- void paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow, GtkOrientation orientation, GtkStyle *style) Q_DECL_OVERRIDE;
- void paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, GtkOrientation orientation, const QString &pmKey = QString()) Q_DECL_OVERRIDE;
- void paintShadow(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, const QString &pmKey = QString()) Q_DECL_OVERRIDE;
- void paintFlatBox(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString & = QString()) Q_DECL_OVERRIDE;
- void paintExtention(GtkWidget *gtkWidget, const gchar *part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GtkPositionType gap_pos, GtkStyle *style) Q_DECL_OVERRIDE;
- void paintOption(GtkWidget *gtkWidget, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString &detail) Q_DECL_OVERRIDE;
- void paintCheckbox(GtkWidget *gtkWidget, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString &detail) Q_DECL_OVERRIDE;
-
-private:
- QPixmap renderTheme(uchar *bdata, uchar *wdata, const QRect &rect) const;
-
- GtkWidget *m_window;
-};
-
-QT_END_NAMESPACE
-
-#endif //!defined(QT_NO_STYLE_QGTK)
-
-#endif // QGTK2PAINTER_P_H
diff --git a/src/widgets/styles/qgtkpainter_p.h b/src/widgets/styles/qgtkpainter_p.h
deleted file mode 100644
index bfe97ccaef..0000000000
--- a/src/widgets/styles/qgtkpainter_p.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGTKPAINTER_H
-#define QGTKPAINTER_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#if !defined(QT_NO_STYLE_GTK)
-
-#include <private/qgtkglobal_p.h>
-#include <QtCore/qsize.h>
-#include <QtCore/qrect.h>
-#include <QtCore/qpoint.h>
-#include <QtGui/qpixmap.h>
-#include <QtGui/qpainter.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGtkPainter
-{
-public:
- QGtkPainter();
- virtual ~QGtkPainter();
-
- void reset(QPainter *painter = 0);
-
- void setAlphaSupport(bool value) { m_alpha = value; }
- void setClipRect(const QRect &rect) { m_cliprect = rect; }
- void setFlipHorizontal(bool value) { m_hflipped = value; }
- void setFlipVertical(bool value) { m_vflipped = value; }
- void setUsePixmapCache(bool value) { m_usePixmapCache = value; }
-
- virtual void paintBoxGap(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow, GtkPositionType gap_side, gint x,
- gint width, GtkStyle *style) = 0;
- virtual void paintBox(GtkWidget *gtkWidget, const gchar* part,
- const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style,
- const QString &pmKey = QString()) = 0;
- virtual void paintHline(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
- int x1, int x2, int y, const QString &pmKey = QString()) = 0;
- virtual void paintVline(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
- int y1, int y2, int x, const QString &pmKey = QString()) = 0;
- virtual void paintExpander(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state,
- GtkExpanderStyle expander_state, GtkStyle *style, const QString &pmKey = QString()) = 0;
- virtual void paintFocus(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkStyle *style,
- const QString &pmKey = QString()) = 0;
- virtual void paintResizeGrip(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GdkWindowEdge edge, GtkStyle *style, const QString &pmKey = QString()) = 0;
- virtual void paintArrow(GtkWidget *gtkWidget, const gchar* part, const QRect &arrowrect, GtkArrowType arrow_type, GtkStateType state, GtkShadowType shadow,
- gboolean fill, GtkStyle *style, const QString &pmKey = QString()) = 0;
- virtual void paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRect &rect,
- GtkStateType state, GtkShadowType shadow, GtkOrientation orientation, GtkStyle *style) = 0;
- virtual void paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, GtkOrientation orientation, const QString &pmKey = QString()) = 0;
- virtual void paintShadow(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GtkStyle *style, const QString &pmKey = QString()) = 0;
- virtual void paintFlatBox(GtkWidget *gtkWidget, const gchar* part, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString & = QString()) = 0;
- virtual void paintExtention(GtkWidget *gtkWidget, const gchar *part, const QRect &rect, GtkStateType state, GtkShadowType shadow,
- GtkPositionType gap_pos, GtkStyle *style) = 0;
- virtual void paintOption(GtkWidget *gtkWidget, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString &detail) = 0;
- virtual void paintCheckbox(GtkWidget *gtkWidget, const QRect &rect, GtkStateType state, GtkShadowType shadow, GtkStyle *style, const QString &detail) = 0;
-
-protected:
- static QString uniqueName(const QString &key, GtkStateType state, GtkShadowType shadow, const QSize &size, GtkWidget *widget = 0);
-
- QPainter *m_painter;
- bool m_alpha;
- bool m_hflipped;
- bool m_vflipped;
- bool m_usePixmapCache;
- QRect m_cliprect;
-};
-
-QT_END_NAMESPACE
-
-#endif //!defined(QT_NO_STYLE_QGTK)
-
-#endif // QGTKPAINTER_H
diff --git a/src/widgets/styles/qgtkstyle.cpp b/src/widgets/styles/qgtkstyle.cpp
deleted file mode 100644
index 7ed0dce91d..0000000000
--- a/src/widgets/styles/qgtkstyle.cpp
+++ /dev/null
@@ -1,4257 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include "qgtkstyle_p.h"
-
-#if !defined(QT_NO_STYLE_GTK)
-
-#include <private/qapplication_p.h>
-#include <QtCore/QLibrary>
-#include <QtCore/QSettings>
-#include <QtWidgets/QDialogButtonBox>
-#include <QtWidgets/QStatusBar>
-#include <QtWidgets/QLineEdit>
-#include <QtWidgets/QWidget>
-#include <QtWidgets/QListView>
-#include <QtWidgets/QApplication>
-#include <QtWidgets/QStyleOption>
-#include <QtWidgets/QPushButton>
-#include <QtGui/QPainter>
-#include <QtWidgets/QMainWindow>
-#include <QtWidgets/QToolBar>
-#include <QtWidgets/QHeaderView>
-#include <QtWidgets/QMenuBar>
-#include <QtWidgets/QComboBox>
-#include <QtWidgets/QSpinBox>
-#include <QtWidgets/QScrollBar>
-#include <QtWidgets/QAbstractButton>
-#include <QtWidgets/QToolButton>
-#include <QtWidgets/QGroupBox>
-#include <QtWidgets/QRadioButton>
-#include <QtWidgets/QCheckBox>
-#include <QtWidgets/QTreeView>
-#include <QtWidgets/QStyledItemDelegate>
-#include <QtWidgets/QWizard>
-
-#include <qpixmapcache.h>
-#include <private/qstyleanimation_p.h>
-#undef signals // Collides with GTK stymbols
-#include <private/qgtkpainter_p.h>
-#include <private/qstylehelper_p.h>
-#include <private/qgtkstyle_p_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static GtkStateType qt_gtk_state(const QStyleOption *option)
-{
- GtkStateType state = GTK_STATE_NORMAL;
- if (!(option->state & QStyle::State_Enabled))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & QStyle::State_MouseOver)
- state = GTK_STATE_PRELIGHT;
-
- return state;
-}
-
-static QPixmap qt_gtk_get_icon(const char* iconName, GtkIconSize size = GTK_ICON_SIZE_BUTTON)
-{
- GtkStyle *style = QGtkStylePrivate::gtkStyle();
- GtkIconSet* iconSet = QGtkStylePrivate::gtk_icon_factory_lookup_default (iconName);
- GdkPixbuf* icon = QGtkStylePrivate::gtk_icon_set_render_icon(iconSet,
- style,
- GTK_TEXT_DIR_LTR,
- GTK_STATE_NORMAL,
- size,
- NULL,
- "button");
- uchar* data = (uchar*)QGtkStylePrivate::gdk_pixbuf_get_pixels(icon);
- int width = QGtkStylePrivate::gdk_pixbuf_get_width(icon);
- int height = QGtkStylePrivate::gdk_pixbuf_get_height(icon);
- QImage converted(width, height, QImage::Format_ARGB32);
- uchar* tdata = (uchar*)converted.bits();
-
- for ( int index = 0 ; index < height * width*4 ; index +=4 ) {
- //int index = y * rowstride + x;
- tdata[index + QT_RED] = data[index + GTK_RED];
- tdata[index + QT_GREEN] = data[index + GTK_GREEN];
- tdata[index + QT_BLUE] = data[index + GTK_BLUE];
- tdata[index + QT_ALPHA] = data[index + GTK_ALPHA];
- }
-
- QGtkStylePrivate::gdk_pixbuf_unref(icon);
-
- // should we free iconset?
- return QPixmap::fromImage(converted);
-}
-
-static void qt_gtk_draw_mdibutton(QPainter *painter, const QStyleOptionTitleBar *option, const QRect &tmp, bool hover, bool sunken)
-{
- QColor dark;
- dark.setHsv(option->palette.button().color().hue(),
- qMin(255, (int)(option->palette.button().color().saturation()*1.9)),
- qMin(255, (int)(option->palette.button().color().value()*0.7)));
-
- QColor highlight = option->palette.highlight().color();
-
- bool active = (option->titleBarState & QStyle::State_Active);
- QColor titleBarHighlight(255, 255, 255, 60);
-
- if (sunken)
- painter->fillRect(tmp.adjusted(1, 1, -1, -1), option->palette.highlight().color().darker(120));
- else if (hover)
- painter->fillRect(tmp.adjusted(1, 1, -1, -1), QColor(255, 255, 255, 20));
-
- QColor mdiButtonGradientStartColor;
- QColor mdiButtonGradientStopColor;
-
- mdiButtonGradientStartColor = QColor(0, 0, 0, 40);
- mdiButtonGradientStopColor = QColor(255, 255, 255, 60);
-
- if (sunken)
- titleBarHighlight = highlight.darker(130);
-
- QLinearGradient gradient(tmp.center().x(), tmp.top(), tmp.center().x(), tmp.bottom());
- gradient.setColorAt(0, mdiButtonGradientStartColor);
- gradient.setColorAt(1, mdiButtonGradientStopColor);
- QColor mdiButtonBorderColor(active ? option->palette.highlight().color().darker(180): dark.darker(110));
-
- painter->setPen(QPen(mdiButtonBorderColor, 1));
- const QLine lines[4] = {
- QLine(tmp.left() + 2, tmp.top(), tmp.right() - 2, tmp.top()),
- QLine(tmp.left() + 2, tmp.bottom(), tmp.right() - 2, tmp.bottom()),
- QLine(tmp.left(), tmp.top() + 2, tmp.left(), tmp.bottom() - 2),
- QLine(tmp.right(), tmp.top() + 2, tmp.right(), tmp.bottom() - 2)
- };
- painter->drawLines(lines, 4);
- const QPoint points[4] = {
- QPoint(tmp.left() + 1, tmp.top() + 1),
- QPoint(tmp.right() - 1, tmp.top() + 1),
- QPoint(tmp.left() + 1, tmp.bottom() - 1),
- QPoint(tmp.right() - 1, tmp.bottom() - 1)
- };
- painter->drawPoints(points, 4);
-
- painter->setPen(titleBarHighlight);
- painter->drawLine(tmp.left() + 2, tmp.top() + 1, tmp.right() - 2, tmp.top() + 1);
- painter->drawLine(tmp.left() + 1, tmp.top() + 2, tmp.left() + 1, tmp.bottom() - 2);
-
- painter->setPen(QPen(gradient, 1));
- painter->drawLine(tmp.right() + 1, tmp.top() + 2, tmp.right() + 1, tmp.bottom() - 2);
- painter->drawPoint(tmp.right() , tmp.top() + 1);
-
- painter->drawLine(tmp.left() + 2, tmp.bottom() + 1, tmp.right() - 2, tmp.bottom() + 1);
- painter->drawPoint(tmp.left() + 1, tmp.bottom());
- painter->drawPoint(tmp.right() - 1, tmp.bottom());
- painter->drawPoint(tmp.right() , tmp.bottom() - 1);
-}
-
-static const char * const dock_widget_close_xpm[] =
- {
- "11 13 5 1",
- " c None",
- ". c #D5CFCB",
- "+ c #6C6A67",
- "@ c #6C6A67",
- "$ c #B5B0AC",
- " ",
- " @@@@@@@@@ ",
- "@+ +@",
- "@ +@ @+ @",
- "@ @@@ @@@ @",
- "@ @@@@@ @",
- "@ @@@ @",
- "@ @@@@@ @",
- "@ @@@ @@@ @",
- "@ +@ @+ @",
- "@+ +@",
- " @@@@@@@@@ ",
- " "
- };
-
-static const char * const dock_widget_restore_xpm[] =
- {
- "11 13 5 1",
- " c None",
- ". c #D5CFCB",
- "+ c #6C6A67",
- "@ c #6C6A67",
- "# c #6C6A67",
- " ",
- " @@@@@@@@@ ",
- "@+ +@",
- "@ #@@@# @",
- "@ @ @ @",
- "@ #@@@# @ @",
- "@ @ @ @ @",
- "@ @ @@@ @",
- "@ @ @ @",
- "@ #@@@@ @",
- "@+ +@",
- " @@@@@@@@@ ",
- " "
- };
-
-static const char * const qt_titlebar_context_help[] = {
- "10 10 3 1",
- " c None",
- "# c #000000",
- "+ c #444444",
- " +####+ ",
- " ### ### ",
- " ## ## ",
- " +##+ ",
- " +## ",
- " ## ",
- " ## ",
- " ",
- " ## ",
- " ## "};
-
-static const char * const qt_scrollbar_button_arrow_up[] = {
- "7 4 2 1",
- " c None",
- "* c #BFBFBF",
- " * ",
- " *** ",
- " ***** ",
- "*******"};
-
-static const char * const qt_scrollbar_button_arrow_down[] = {
- "7 4 2 1",
- " c None",
- "* c #BFBFBF",
- "*******",
- " ***** ",
- " *** ",
- " * "};
-
-static const int groupBoxBottomMargin = 2; // space below the groupbox
-static const int groupBoxTitleMargin = 6; // space between contents and title
-static const int groupBoxTopMargin = 2;
-
-/*!
- Returns the configuration string for \a value.
- Returns \a fallback if \a value is not found.
- */
-QString QGtkStyle::getGConfString(const QString &value, const QString &fallback)
-{
- return QGtkStylePrivate::getGConfString(value, fallback);
-}
-
-/*!
- Returns the configuration boolean for \a key.
- Returns \a fallback if \a key is not found.
- */
-bool QGtkStyle::getGConfBool(const QString &key, bool fallback)
-{
- return QGtkStylePrivate::getGConfBool(key, fallback);
-}
-
-static QColor mergedColors(const QColor &colorA, const QColor &colorB, int factor = 50)
-{
- const int maxFactor = 100;
- QColor tmp = colorA;
- tmp.setRed((tmp.red() * factor) / maxFactor + (colorB.red() * (maxFactor - factor)) / maxFactor);
- tmp.setGreen((tmp.green() * factor) / maxFactor + (colorB.green() * (maxFactor - factor)) / maxFactor);
- tmp.setBlue((tmp.blue() * factor) / maxFactor + (colorB.blue() * (maxFactor - factor)) / maxFactor);
- return tmp;
-}
-
-static GdkColor fromQColor(const QColor &color)
-{
- GdkColor retval;
- retval.pixel = 0;
- retval.red = color.red() * 255;
- retval.green = color.green() * 255;
- retval.blue = color.blue() * 255;
- return retval;
-}
-
-/*!
- \class QGtkStyle
- \brief The QGtkStyle class provides a widget style rendered by GTK+
- \since 4.5
-
- \internal
- \inmodule QtWidgets
-
- The QGtkStyle style provides a look and feel that integrates well
- into GTK-based desktop environments such as the XFCe and GNOME.
-
- It does this by making use of the GTK+ theme engine, ensuring
- that Qt applications look and feel native on these platforms.
-
- Note: The style requires GTK+ version 2.18 or later.
- The Qt3-based "Qt" GTK+ theme engine will not work with QGtkStyle.
-
- \sa QWindowsXPStyle, QMacStyle, QWindowsStyle, QFusionStyle
-*/
-
-/*!
- Constructs a QGtkStyle object.
-*/
-QGtkStyle::QGtkStyle()
- : QCommonStyle(*new QGtkStylePrivate)
-{
- Q_D(QGtkStyle);
- d->init();
-}
-
-/*!
- \internal
-
- Constructs a QGtkStyle object.
-*/
-QGtkStyle::QGtkStyle(QGtkStylePrivate &dd)
- : QCommonStyle(dd)
-{
- Q_D(QGtkStyle);
- d->init();
-}
-
-
-/*!
- Destroys the QGtkStyle object.
-*/
-QGtkStyle::~QGtkStyle()
-{
-}
-
-/*!
- \reimp
-*/
-QPalette QGtkStyle::standardPalette() const
-{
- Q_D(const QGtkStyle);
-
- QPalette palette = QCommonStyle::standardPalette();
- if (d->isThemeAvailable()) {
- GtkStyle *style = d->gtkStyle();
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- GtkWidget *gtkEntry = d->getTextColorWidget();
- GdkColor gdkBg, gdkBase, gdkText, gdkForeground, gdkSbg, gdkSfg, gdkaSbg, gdkaSfg;
- QColor bg, base, text, fg, highlight, highlightText, inactiveHighlight, inactiveHighlightedTExt;
- gdkBg = style->bg[GTK_STATE_NORMAL];
- gdkForeground = d->gtk_widget_get_style(gtkButton)->fg[GTK_STATE_NORMAL];
-
- // Our base and selected color is primarily used for text
- // so we assume a gtkEntry will have the most correct value
- GtkStyle *gtkEntryStyle = d->gtk_widget_get_style(gtkEntry);
- gdkBase = gtkEntryStyle->base[GTK_STATE_NORMAL];
- gdkText = gtkEntryStyle->text[GTK_STATE_NORMAL];
- gdkSbg = gtkEntryStyle->base[GTK_STATE_SELECTED];
- gdkSfg = gtkEntryStyle->text[GTK_STATE_SELECTED];
-
- // The ACTIVE base color is really used for inactive windows
- gdkaSbg = gtkEntryStyle->base[GTK_STATE_ACTIVE];
- gdkaSfg = gtkEntryStyle->text[GTK_STATE_ACTIVE];
-
- bg = QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
- text = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- fg = QColor(gdkForeground.red>>8, gdkForeground.green>>8, gdkForeground.blue>>8);
- base = QColor(gdkBase.red>>8, gdkBase.green>>8, gdkBase.blue>>8);
- highlight = QColor(gdkSbg.red>>8, gdkSbg.green>>8, gdkSbg.blue>>8);
- highlightText = QColor(gdkSfg.red>>8, gdkSfg.green>>8, gdkSfg.blue>>8);
- inactiveHighlight = QColor(gdkaSbg.red>>8, gdkaSbg.green>>8, gdkaSbg.blue>>8);
- inactiveHighlightedTExt = QColor(gdkaSfg.red>>8, gdkaSfg.green>>8, gdkaSfg.blue>>8);
-
- palette.setColor(QPalette::HighlightedText, highlightText);
-
-
- palette.setColor(QPalette::Light, bg.lighter(125));
- palette.setColor(QPalette::Shadow, bg.darker(130));
- palette.setColor(QPalette::Dark, bg.darker(120));
- palette.setColor(QPalette::Text, text);
- palette.setColor(QPalette::WindowText, fg);
- palette.setColor(QPalette::ButtonText, fg);
- palette.setColor(QPalette::Base, base);
-
- QColor alternateRowColor = palette.base().color().lighter(93); // ref gtkstyle.c draw_flat_box
- GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
- GdkColor *gtkAltBase = NULL;
- d->gtk_widget_style_get(gtkTreeView, "odd-row-color", &gtkAltBase, NULL);
- if (gtkAltBase) {
- alternateRowColor = QColor(gtkAltBase->red>>8, gtkAltBase->green>>8, gtkAltBase->blue>>8);
- d->gdk_color_free(gtkAltBase);
- }
- palette.setColor(QPalette::AlternateBase, alternateRowColor);
-
- palette.setColor(QPalette::Window, bg);
- palette.setColor(QPalette::Button, bg);
- palette.setColor(QPalette::Background, bg);
- QColor disabled((fg.red() + bg.red()) / 2,
- (fg.green() + bg.green())/ 2,
- (fg.blue() + bg.blue()) / 2);
- palette.setColor(QPalette::Disabled, QPalette::Text, disabled);
- palette.setColor(QPalette::Disabled, QPalette::WindowText, disabled);
- palette.setColor(QPalette::Disabled, QPalette::Foreground, disabled);
- palette.setColor(QPalette::Disabled, QPalette::ButtonText, disabled);
- palette.setColor(QPalette::Highlight, highlight);
- // calculate disabled colors by removing saturation
- highlight.setHsv(highlight.hue(), 0, highlight.value(), highlight.alpha());
- highlightText.setHsv(highlightText.hue(), 0, highlightText.value(), highlightText.alpha());
- palette.setColor(QPalette::Disabled, QPalette::Highlight, highlight);
- palette.setColor(QPalette::Disabled, QPalette::HighlightedText, highlightText);
-
- palette.setColor(QPalette::Inactive, QPalette::HighlightedText, inactiveHighlightedTExt);
- palette.setColor(QPalette::Inactive, QPalette::Highlight, inactiveHighlight);
-
- style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "gtk-tooltips", "GtkWindow",
- d->gtk_window_get_type());
- if (style) {
- gdkText = style->fg[GTK_STATE_NORMAL];
- text = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- palette.setColor(QPalette::ToolTipText, text);
- }
- }
- return palette;
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::polish(QPalette &palette)
-{
- Q_D(QGtkStyle);
-
- if (!d->isThemeAvailable())
- QCommonStyle::polish(palette);
- else
- palette = palette.resolve(standardPalette());
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::polish(QApplication *app)
-{
- Q_D(QGtkStyle);
-
- QCommonStyle::polish(app);
- // Custom fonts and palettes with QtConfig are intentionally
- // not supported as these should be entirely determined by
- // current Gtk settings
- if (app->desktopSettingsAware() && d->isThemeAvailable()) {
- QApplicationPrivate::setSystemPalette(standardPalette());
- QApplicationPrivate::setSystemFont(d->getThemeFont());
- d->applyCustomPaletteHash();
- if (!d->isKDE4Session())
- qApp->installEventFilter(&d->filter);
- }
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::unpolish(QApplication *app)
-{
- Q_D(QGtkStyle);
-
- QCommonStyle::unpolish(app);
- QPixmapCache::clear();
-
- if (app->desktopSettingsAware() && d->isThemeAvailable() && !d->isKDE4Session())
- qApp->removeEventFilter(&d->filter);
-}
-
-/*!
- \reimp
-*/
-
-void QGtkStyle::polish(QWidget *widget)
-{
- Q_D(QGtkStyle);
-
- QCommonStyle::polish(widget);
- if (!d->isThemeAvailable())
- return;
- if (qobject_cast<QAbstractButton*>(widget)
- || qobject_cast<QToolButton*>(widget)
- || qobject_cast<QComboBox*>(widget)
- || qobject_cast<QGroupBox*>(widget)
- || qobject_cast<QScrollBar*>(widget)
- || qobject_cast<QSlider*>(widget)
- || qobject_cast<QAbstractSpinBox*>(widget)
- || qobject_cast<QSpinBox*>(widget)
- || qobject_cast<QHeaderView*>(widget))
- widget->setAttribute(Qt::WA_Hover);
-#ifndef QT_NO_TREEVIEW
- else if (QTreeView *tree = qobject_cast<QTreeView *> (widget))
- tree->viewport()->setAttribute(Qt::WA_Hover);
-#endif
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::unpolish(QWidget *widget)
-{
- QCommonStyle::unpolish(widget);
-}
-
-/*!
- \reimp
-*/
-int QGtkStyle::pixelMetric(PixelMetric metric,
- const QStyleOption *option,
- const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable())
- return QCommonStyle::pixelMetric(metric, option, widget);
-
- switch (metric) {
- case PM_DefaultFrameWidth:
- if (qobject_cast<const QFrame*>(widget)) {
- if (GtkStyle *style =
- d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(),
- "*.GtkScrolledWindow",
- "*.GtkScrolledWindow",
- d->gtk_window_get_type()))
- return qMax(style->xthickness, style->ythickness);
- }
- return 2;
-
- case PM_MenuButtonIndicator:
- return 20;
-
- case PM_TabBarBaseOverlap:
- return 1;
-
- case PM_ToolBarSeparatorExtent:
- return 11;
-
- case PM_ToolBarFrameWidth:
- return 1;
-
- case PM_ToolBarItemSpacing:
- return 0;
-
- case PM_ButtonShiftHorizontal: {
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- guint horizontal_shift;
- d->gtk_widget_style_get(gtkButton, "child-displacement-x", &horizontal_shift, NULL);
- return horizontal_shift;
- }
-
- case PM_ButtonShiftVertical: {
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- guint vertical_shift;
- d->gtk_widget_style_get(gtkButton, "child-displacement-y", &vertical_shift, NULL);
- return vertical_shift;
- }
-
- case PM_MenuBarPanelWidth:
- return 0;
-
- case PM_MenuPanelWidth: {
- GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
- guint horizontal_padding = 0;
- // horizontal-padding is used by Maemo to get thicker borders
- if (!d->gtk_check_version(2, 10, 0))
- d->gtk_widget_style_get(gtkMenu, "horizontal-padding", &horizontal_padding, NULL);
- int padding = qMax<int>(d->gtk_widget_get_style(gtkMenu)->xthickness, horizontal_padding);
- return padding;
- }
-
- case PM_ButtonIconSize: {
- int retVal = 24;
- GtkSettings *settings = d->gtk_settings_get_default();
- gchararray icon_sizes;
- g_object_get(settings, "gtk-icon-sizes", &icon_sizes, NULL);
- QStringList values = QString(QLS(icon_sizes)).split(QLatin1Char(':'));
- g_free(icon_sizes);
- QChar splitChar(QLatin1Char(','));
- foreach (const QString &value, values) {
- if (value.startsWith(QLS("gtk-button="))) {
- QString iconSize = value.right(value.size() - 11);
-
- if (iconSize.contains(splitChar))
- retVal = iconSize.split(splitChar)[0].toInt();
- break;
- }
- }
- return retVal;
- }
-
- case PM_MenuVMargin:
-
- case PM_MenuHMargin:
- return 0;
-
- case PM_DockWidgetTitleMargin:
- return 0;
-
- case PM_DockWidgetTitleBarButtonMargin:
- return 5;
-
- case PM_TabBarTabVSpace:
- return 12;
-
- case PM_TabBarTabHSpace:
- return 14;
-
- case PM_TabBarTabShiftVertical:
- return 2;
-
- case PM_ToolBarHandleExtent:
- return 9;
-
- case PM_SplitterWidth:
- return 6;
-
- case PM_SliderThickness:
- case PM_SliderControlThickness: {
- GtkWidget *gtkScale = d->gtkWidget("GtkHScale");
- gint val;
- d->gtk_widget_style_get(gtkScale, "slider-width", &val, NULL);
- if (metric == PM_SliderControlThickness)
- return val + 2*d->gtk_widget_get_style(gtkScale)->ythickness;
- return val;
- }
-
- case PM_ScrollBarExtent: {
- gint sliderLength;
- gint trough_border;
- GtkWidget *hScrollbar = d->gtkWidget("GtkHScrollbar");
- d->gtk_widget_style_get(hScrollbar,
- "trough-border", &trough_border,
- "slider-width", &sliderLength,
- NULL);
- return sliderLength + trough_border*2;
- }
-
- case PM_ScrollBarSliderMin:
- return 34;
-
- case PM_SliderLength:
- gint val;
- d->gtk_widget_style_get(d->gtkWidget("GtkHScale"), "slider-length", &val, NULL);
- return val;
-
- case PM_ExclusiveIndicatorWidth:
- case PM_ExclusiveIndicatorHeight:
- case PM_IndicatorWidth:
- case PM_IndicatorHeight: {
- GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
- gint size, spacing;
- d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, "indicator-size", &size, NULL);
- return size + 2 * spacing;
- }
-
- case PM_MenuBarVMargin: {
- GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
- return qMax(0, d->gtk_widget_get_style(gtkMenubar)->ythickness);
- }
- case PM_ScrollView_ScrollBarSpacing:
- {
- gint spacing = 3;
- GtkWidget *gtkScrollWindow = d->gtkWidget("GtkScrolledWindow");
- Q_ASSERT(gtkScrollWindow);
- d->gtk_widget_style_get(gtkScrollWindow, "scrollbar-spacing", &spacing, NULL);
- return spacing;
- }
- case PM_SubMenuOverlap: {
- gint offset = 0;
- GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
- d->gtk_widget_style_get(gtkMenu, "horizontal-offset", &offset, NULL);
- return offset;
- }
- case PM_ToolTipLabelFrameWidth:
- return 2;
- case PM_ButtonDefaultIndicator:
- return 0;
- case PM_ListViewIconSize:
- return 24;
- case PM_DialogButtonsSeparator:
- return 6;
- case PM_TitleBarHeight:
- return 24;
- case PM_SpinBoxFrameWidth:
- return 3;
- case PM_MenuBarItemSpacing:
- return 6;
- case PM_MenuBarHMargin:
- return 0;
- case PM_ToolBarItemMargin:
- return 1;
- case PM_SmallIconSize:
- return 16;
- case PM_MaximumDragDistance:
- return -1;
- case PM_TabCloseIndicatorWidth:
- case PM_TabCloseIndicatorHeight:
- return 20;
- default:
- return QCommonStyle::pixelMetric(metric, option, widget);
- }
-}
-
-/*!
- \reimp
-*/
-int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget,
-
- QStyleHintReturn *returnData = 0) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable())
- return QCommonStyle::styleHint(hint, option, widget, returnData);
-
- switch (hint) {
- case SH_ItemView_ChangeHighlightOnFocus:
- return true;
- case SH_ScrollBar_MiddleClickAbsolutePosition:
- return true;
- case SH_Menu_AllowActiveAndDisabled:
- return false;
- case SH_MainWindow_SpaceBelowMenuBar:
- return false;
- case SH_MenuBar_MouseTracking:
- return true;
- case SH_Menu_MouseTracking:
- return true;
- case SH_TitleBar_AutoRaise:
- return true;
- case SH_TitleBar_NoBorder:
- return true;
- case SH_ItemView_ShowDecorationSelected:
- return true;
- case SH_Table_GridLineColor:
- if (option)
- return option->palette.background().color().darker(120).rgb();
- break;
- case SH_WindowFrame_Mask:
- if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(returnData)) {
- //left rounded corner
- mask->region = option->rect;
- mask->region -= QRect(option->rect.left(), option->rect.top(), 5, 1);
- mask->region -= QRect(option->rect.left(), option->rect.top() + 1, 3, 1);
- mask->region -= QRect(option->rect.left(), option->rect.top() + 2, 2, 1);
- mask->region -= QRect(option->rect.left(), option->rect.top() + 3, 1, 2);
-
- //right rounded corner
- mask->region -= QRect(option->rect.right() - 4, option->rect.top(), 5, 1);
- mask->region -= QRect(option->rect.right() - 2, option->rect.top() + 1, 3, 1);
- mask->region -= QRect(option->rect.right() - 1, option->rect.top() + 2, 2, 1);
- mask->region -= QRect(option->rect.right() , option->rect.top() + 3, 1, 2);
- }
- return QCommonStyle::styleHint(hint, option, widget, returnData);
- case SH_MessageBox_TextInteractionFlags:
- return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse;
- case SH_MessageBox_CenterButtons:
- return false;
-#ifndef QT_NO_WIZARD
- case SH_WizardStyle:
- return QWizard::ClassicStyle;
-#endif
- case SH_ItemView_ArrowKeysNavigateIntoChildren:
- return false;
- case SH_DialogButtonLayout: {
- int ret = QDialogButtonBox::GnomeLayout;
- gboolean alternateOrder = 0;
- GtkSettings *settings = d->gtk_settings_get_default();
- g_object_get(settings, "gtk-alternative-button-order", &alternateOrder, NULL);
-
- if (alternateOrder)
- ret = QDialogButtonBox::WinLayout;
-
- return ret;
- }
- break;
-
- case SH_ToolButtonStyle:
- {
- if (d->isKDE4Session())
- return QCommonStyle::styleHint(hint, option, widget, returnData);
- GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
- GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS;
- g_object_get(gtkToolbar, "toolbar-style", &toolbar_style, NULL);
- switch (toolbar_style) {
- case GTK_TOOLBAR_TEXT:
- return Qt::ToolButtonTextOnly;
- case GTK_TOOLBAR_BOTH:
- return Qt::ToolButtonTextUnderIcon;
- case GTK_TOOLBAR_BOTH_HORIZ:
- return Qt::ToolButtonTextBesideIcon;
- case GTK_TOOLBAR_ICONS:
- default:
- return Qt::ToolButtonIconOnly;
- }
- }
- break;
- case SH_SpinControls_DisableOnBounds:
- return int(true);
-
- case SH_DitherDisabledText:
- return int(false);
-
- case SH_ComboBox_Popup: {
- GtkWidget *gtkComboBox = d->gtkWidget("GtkComboBox");
- gboolean appears_as_list;
- d->gtk_widget_style_get((GtkWidget*)gtkComboBox, "appears-as-list", &appears_as_list, NULL);
- return appears_as_list ? 0 : 1;
- }
-
- case SH_MenuBar_AltKeyNavigation:
- return int(false);
-
- case SH_EtchDisabledText:
- return int(false);
-
- case SH_Menu_SubMenuPopupDelay: {
- gint delay = 225;
- GtkSettings *settings = d->gtk_settings_get_default();
- g_object_get(settings, "gtk-menu-popup-delay", &delay, NULL);
- return delay;
- }
-
- case SH_ScrollView_FrameOnlyAroundContents: {
- gboolean scrollbars_within_bevel = false;
- if (widget && widget->isWindow())
- scrollbars_within_bevel = true;
- else if (!d->gtk_check_version(2, 12, 0)) {
- GtkWidget *gtkScrollWindow = d->gtkWidget("GtkScrolledWindow");
- d->gtk_widget_style_get(gtkScrollWindow, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL);
- }
- return !scrollbars_within_bevel;
- }
-
- case SH_DialogButtonBox_ButtonsHaveIcons: {
- static bool buttonsHaveIcons = d->getGConfBool(QLS("/desktop/gnome/interface/buttons_have_icons"));
- return buttonsHaveIcons;
- }
-
- case SH_UnderlineShortcut: {
- gboolean underlineShortcut = true;
- if (!d->gtk_check_version(2, 12, 0)) {
- GtkSettings *settings = d->gtk_settings_get_default();
- g_object_get(settings, "gtk-enable-mnemonics", &underlineShortcut, NULL);
- }
- return underlineShortcut;
- }
-
- default:
- break;
- }
- return QCommonStyle::styleHint(hint, option, widget, returnData);
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::drawPrimitive(PrimitiveElement element,
- const QStyleOption *option,
- QPainter *painter,
- const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable()) {
- QCommonStyle::drawPrimitive(element, option, painter, widget);
- return;
- }
-
- GtkStyle* style = d->gtkStyle();
- QGtkPainter* gtkPainter = d->gtkPainter(painter);
-
- switch (element) {
- case PE_Frame: {
- if (widget && widget->inherits("QComboBoxPrivateContainer")){
- QStyleOption copy = *option;
- copy.state |= State_Raised;
- proxy()->drawPrimitive(PE_PanelMenu, &copy, painter, widget);
- break;
- }
- // Drawing the entire itemview frame is very expensive, especially on the native X11 engine
- // Instead we cheat a bit and draw a border image without the center part, hence only scaling
- // thin rectangular images
- const int pmSize = 64;
- const int border = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget);
- const QString pmKey = QLatin1String("windowframe") % HexString<uint>(option->state);
-
- QPixmap pixmap;
- QRect pmRect(QPoint(0,0), QSize(pmSize, pmSize));
-
- // Only draw through style once
- if (!QPixmapCache::find(pmKey, pixmap)) {
- pixmap = QPixmap(pmSize, pmSize);
- pixmap.fill(Qt::transparent);
- QPainter pmPainter(&pixmap);
- gtkPainter->reset(&pmPainter);
- gtkPainter->setUsePixmapCache(false); // Don't cache twice
-
- GtkShadowType shadow_type = GTK_SHADOW_NONE;
- if (option->state & State_Sunken)
- shadow_type = GTK_SHADOW_IN;
- else if (option->state & State_Raised)
- shadow_type = GTK_SHADOW_OUT;
-
- GtkStyle *style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(),
- "*.GtkScrolledWindow", "*.GtkScrolledWindow", d->gtk_window_get_type());
- if (style)
- gtkPainter->paintShadow(d->gtkWidget("GtkFrame"), "viewport", pmRect,
- option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
- shadow_type, style);
- QPixmapCache::insert(pmKey, pixmap);
- gtkPainter->reset(painter);
- }
-
- QRect rect = option->rect;
- const int rw = rect.width() - border;
- const int rh = rect.height() - border;
- const int pw = pmRect.width() - border;
- const int ph = pmRect.height() - border;
-
- // Sidelines
- painter->drawPixmap(rect.adjusted(border, 0, -border, -rh), pixmap, pmRect.adjusted(border, 0, -border,-ph));
- painter->drawPixmap(rect.adjusted(border, rh, -border, 0), pixmap, pmRect.adjusted(border, ph,-border,0));
- painter->drawPixmap(rect.adjusted(0, border, -rw, -border), pixmap, pmRect.adjusted(0, border, -pw, -border));
- painter->drawPixmap(rect.adjusted(rw, border, 0, -border), pixmap, pmRect.adjusted(pw, border, 0, -border));
-
- // Corners
- painter->drawPixmap(rect.adjusted(0, 0, -rw, -rh), pixmap, pmRect.adjusted(0, 0, -pw,-ph));
- painter->drawPixmap(rect.adjusted(rw, 0, 0, -rh), pixmap, pmRect.adjusted(pw, 0, 0,-ph));
- painter->drawPixmap(rect.adjusted(0, rh, -rw, 0), pixmap, pmRect.adjusted(0, ph, -pw,0));
- painter->drawPixmap(rect.adjusted(rw, rh, 0, 0), pixmap, pmRect.adjusted(pw, ph, 0,0));
- }
- break;
- case PE_FrameWindow:
- painter->save();
- {
- QRect rect= option->rect;
- painter->setPen(QPen(option->palette.dark().color().darker(150), 0));
- painter->drawRect(option->rect.adjusted(0, 0, -1, -1));
- painter->setPen(QPen(option->palette.light(), 0));
- painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1),
- QPoint(rect.left() + 1, rect.bottom() - 1));
- painter->setPen(QPen(option->palette.background().color().darker(120), 0));
- painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1),
- QPoint(rect.right() - 2, rect.bottom() - 1));
- painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1),
- QPoint(rect.right() - 1, rect.bottom() - 1));
- }
- painter->restore();
- break;
-
- case PE_PanelTipLabel: {
- GtkWidget *gtkWindow = d->gtkWidget("GtkWindow"); // The Murrine Engine currently assumes a widget is passed
- style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "gtk-tooltips", "GtkWindow",
- d->gtk_window_get_type());
- gtkPainter->paintFlatBox(gtkWindow, "tooltip", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, style);
- }
- break;
-
- case PE_PanelStatusBar: {
- if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
- option->palette.resolve() & (1 << QPalette::Window)) {
- // Respect custom palette
- painter->fillRect(option->rect, option->palette.window());
- break;
- }
- GtkShadowType shadow_type;
- GtkWidget *gtkStatusbarFrame = d->gtkWidget("GtkStatusbar.GtkFrame");
- d->gtk_widget_style_get(d->gtk_widget_get_parent(gtkStatusbarFrame), "shadow-type", &shadow_type, NULL);
- gtkPainter->paintShadow(gtkStatusbarFrame, "frame", option->rect, GTK_STATE_NORMAL,
- shadow_type, d->gtk_widget_get_style(gtkStatusbarFrame));
- }
- break;
-
- case PE_IndicatorHeaderArrow:
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
- GtkWidget *gtkTreeHeader = d->gtkWidget("GtkTreeView.GtkButton");
- GtkStateType state = qt_gtk_state(option);
- style = d->gtk_widget_get_style(gtkTreeHeader);
- GtkArrowType type = GTK_ARROW_UP;
- // This sorting indicator inversion is intentional, and follows the GNOME HIG.
- // See http://library.gnome.org/devel/hig-book/stable/controls-lists.html.en#controls-lists-sortable
- if (header->sortIndicator & QStyleOptionHeader::SortUp)
- type = GTK_ARROW_UP;
- else if (header->sortIndicator & QStyleOptionHeader::SortDown)
- type = GTK_ARROW_DOWN;
-
- gtkPainter->paintArrow(gtkTreeHeader, "button", option->rect.adjusted(1, 1, -1, -1), type, state,
- GTK_SHADOW_NONE, false, style);
- }
- break;
-
- case PE_FrameDefaultButton: // fall through
- case PE_FrameFocusRect: {
- QRect frameRect = option->rect.adjusted(1, 1, -2, -2); // ### this mess should move to subcontrolrect
- if (qobject_cast<const QAbstractItemView*>(widget)) {
- // Don't draw anything
- } else if (qobject_cast<const QTabBar*>(widget)) {
- GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
- style = d->gtk_widget_get_style(gtkNotebook);
- gtkPainter->paintFocus(gtkNotebook, "tab", frameRect.adjusted(-1, 1, 1, 1), GTK_STATE_ACTIVE, style);
- } else {
- GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton");
- gtkPainter->paintFocus(gtkRadioButton, "radiobutton", frameRect, GTK_STATE_ACTIVE, style);
- }
- }
- break;
-
- case PE_IndicatorBranch:
- if (option->state & State_Children) {
- QRect rect = option->rect;
- rect = QRect(0, 0, 12, 12);
- rect.moveCenter(option->rect.center());
- rect.translate(2, 0);
- GtkExpanderStyle openState = GTK_EXPANDER_EXPANDED;
- GtkExpanderStyle closedState = GTK_EXPANDER_COLLAPSED;
- GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
-
- GtkStateType state = GTK_STATE_NORMAL;
- if (!(option->state & State_Enabled))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & State_MouseOver)
- state = GTK_STATE_PRELIGHT;
-
- gtkPainter->paintExpander(gtkTreeView, "treeview", rect, state,
- option->state & State_Open ? openState : closedState , d->gtk_widget_get_style(gtkTreeView));
- }
- break;
-
- case PE_PanelItemViewRow:
- // This primitive is only used to draw selection behind selected expander arrows.
- // We try not to decorate the tree branch background unless you inherit from StyledItemDelegate
- // The reason for this is that a lot of code that relies on custom item delegates will look odd having
- // a gradient on the branch but a flat shaded color on the item itself.
- QCommonStyle::drawPrimitive(element, option, painter, widget);
- if (!(option->state & State_Selected)) {
- break;
- } else {
- if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(widget)) {
- if (!qobject_cast<QStyledItemDelegate*>(view->itemDelegate()))
- break;
- }
- } // fall through
-
- case PE_PanelItemViewItem:
- if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) {
- uint resolve_mask = vopt->palette.resolve();
- if (vopt->backgroundBrush.style() != Qt::NoBrush
- || (resolve_mask & (1 << QPalette::Base)))
- {
- QPointF oldBO = painter->brushOrigin();
- painter->setBrushOrigin(vopt->rect.topLeft());
- painter->fillRect(vopt->rect, vopt->backgroundBrush);
- painter->setBrushOrigin(oldBO);
- if (!(option->state & State_Selected))
- break;
- }
- if (GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView")) {
- const char *detail = "cell_even_ruled";
- if (vopt && vopt->features & QStyleOptionViewItem::Alternate)
- detail = "cell_odd_ruled";
- bool isActive = option->state & State_Active;
- QString key;
- if (isActive ) {
- // Required for active/non-active window appearance
- key = QLS("a");
- QGtkStylePrivate::gtkWidgetSetFocus(gtkTreeView, true);
- }
- bool isEnabled = (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled));
- gtkPainter->paintFlatBox(gtkTreeView, detail, option->rect,
- option->state & State_Selected ? GTK_STATE_SELECTED :
- isEnabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
- GTK_SHADOW_OUT, d->gtk_widget_get_style(gtkTreeView), key);
- if (isActive )
- QGtkStylePrivate::gtkWidgetSetFocus(gtkTreeView, false);
- }
- }
- break;
- case PE_IndicatorToolBarSeparator:
- {
- const int margin = 6;
- GtkWidget *gtkSeparator = d->gtkWidget("GtkToolbar.GtkSeparatorToolItem");
- if (option->state & State_Horizontal) {
- const int offset = option->rect.width()/2;
- QRect rect = option->rect.adjusted(offset, margin, 0, -margin);
- painter->setPen(QPen(option->palette.background().color().darker(110)));
- gtkPainter->paintVline(gtkSeparator, "vseparator",
- rect, GTK_STATE_NORMAL, d->gtk_widget_get_style(gtkSeparator),
- 0, rect.height(), 0);
- } else { //Draw vertical separator
- const int offset = option->rect.height()/2;
- QRect rect = option->rect.adjusted(margin, offset, -margin, 0);
- painter->setPen(QPen(option->palette.background().color().darker(110)));
- gtkPainter->paintHline(gtkSeparator, "hseparator",
- rect, GTK_STATE_NORMAL, d->gtk_widget_get_style(gtkSeparator),
- 0, rect.width(), 0);
- }
- }
- break;
-
- case PE_IndicatorToolBarHandle: {
- GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
- GtkShadowType shadow_type;
- d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
- //Note when the toolbar is horizontal, the handle is vertical
- painter->setClipRect(option->rect);
- gtkPainter->paintHandle(gtkToolbar, "toolbar", option->rect.adjusted(-1, -1 ,0 ,1),
- GTK_STATE_NORMAL, shadow_type, !(option->state & State_Horizontal) ?
- GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, d->gtk_widget_get_style(gtkToolbar));
- }
- break;
-
- case PE_IndicatorArrowUp:
- case PE_IndicatorArrowDown:
- case PE_IndicatorArrowLeft:
- case PE_IndicatorArrowRight: {
-
-
- GtkArrowType type = GTK_ARROW_UP;
-
- switch (element) {
-
- case PE_IndicatorArrowDown:
- type = GTK_ARROW_DOWN;
- break;
-
- case PE_IndicatorArrowLeft:
- type = GTK_ARROW_LEFT;
- break;
-
- case PE_IndicatorArrowRight:
- type = GTK_ARROW_RIGHT;
- break;
-
- default:
- break;
- }
- int size = qMin(option->rect.height(), option->rect.width());
- int border = (size > 9) ? (size/4) : 0; //Allow small arrows to have exact dimensions
- int bsx = 0, bsy = 0;
- if (option->state & State_Sunken) {
- bsx = proxy()->pixelMetric(PM_ButtonShiftHorizontal);
- bsy = proxy()->pixelMetric(PM_ButtonShiftVertical);
- }
- QRect arrowRect = option->rect.adjusted(border + bsx, border + bsy, -border + bsx, -border + bsy);
- GtkShadowType shadow = option->state & State_Sunken ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
- GtkStateType state = qt_gtk_state(option);
-
- QColor arrowColor = option->palette.buttonText().color();
- GtkWidget *gtkArrow = d->gtkWidget("GtkArrow");
- GdkColor color = fromQColor(arrowColor);
- d->gtk_widget_modify_fg (gtkArrow, state, &color);
- gtkPainter->paintArrow(gtkArrow, "button", arrowRect,
- type, state, shadow, false, d->gtk_widget_get_style(gtkArrow),
- QString::number(arrowColor.rgba(), 16));
- // Passing NULL will revert the color change
- d->gtk_widget_modify_fg (gtkArrow, state, NULL);
- }
- break;
-
- case PE_FrameGroupBox:
- // Do nothing here, the GNOME groupboxes are flat
- break;
-
- case PE_PanelMenu: {
- GtkWidget *gtkMenu = d->gtkWidget("GtkMenu");
- gtkPainter->setAlphaSupport(false); // Note, alpha disabled for performance reasons
- gtkPainter->paintBox(gtkMenu, "menu", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, d->gtk_widget_get_style(gtkMenu), QString());
- }
- break;
-
- case PE_FrameMenu:
- //This is actually done by PE_Widget due to a clipping issue
- //Otherwise Menu items will not be able to span the entire menu width
-
- // This is only used by floating tool bars
- if (qobject_cast<const QToolBar *>(widget)) {
- GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
- gtkPainter->paintBox(gtkMenubar, "toolbar", option->rect,
- GTK_STATE_NORMAL, GTK_SHADOW_OUT, style);
- gtkPainter->paintBox(gtkMenubar, "menu", option->rect,
- GTK_STATE_NORMAL, GTK_SHADOW_OUT, style);
- }
- break;
-
- case PE_FrameLineEdit: {
- GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
-
-
- gboolean interior_focus;
- gint focus_line_width;
- QRect rect = option->rect;
- d->gtk_widget_style_get(gtkEntry,
- "interior-focus", &interior_focus,
- "focus-line-width", &focus_line_width, NULL);
-
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=405421 for info about this hack
- g_object_set_data(G_OBJECT(gtkEntry), "transparent-bg-hint", GINT_TO_POINTER(true));
-
- if (!interior_focus && option->state & State_HasFocus)
- rect.adjust(focus_line_width, focus_line_width, -focus_line_width, -focus_line_width);
-
- if (option->state & State_HasFocus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkEntry, true);
- gtkPainter->paintShadow(gtkEntry, "entry", rect, option->state & State_Enabled ?
- GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
- GTK_SHADOW_IN, d->gtk_widget_get_style(gtkEntry),
- option->state & State_HasFocus ? QLS("focus") : QString());
- if (!interior_focus && option->state & State_HasFocus)
- gtkPainter->paintShadow(gtkEntry, "entry", option->rect, option->state & State_Enabled ?
- GTK_STATE_ACTIVE : GTK_STATE_INSENSITIVE,
- GTK_SHADOW_IN, d->gtk_widget_get_style(gtkEntry), QLS("GtkEntryShadowIn"));
-
- if (option->state & State_HasFocus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkEntry, false);
- }
- break;
-
- case PE_PanelLineEdit:
- if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
- if (panel->lineWidth > 0)
- proxy()->drawPrimitive(PE_FrameLineEdit, option, painter, widget);
- uint resolve_mask = option->palette.resolve();
- GtkStyle *gtkEntryStyle = d->gtk_widget_get_style(gtkEntry);
- QRect textRect = option->rect.adjusted(gtkEntryStyle->xthickness, gtkEntryStyle->ythickness,
- -gtkEntryStyle->xthickness, -gtkEntryStyle->ythickness);
-
- if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
- resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
- painter->fillRect(textRect, option->palette.base());
- else
- gtkPainter->paintFlatBox(gtkEntry, "entry_bg", textRect,
- option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, gtkEntryStyle);
- }
- break;
-
- case PE_FrameTabWidget:
- if (const QStyleOptionTabWidgetFrame *frame = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option)) {
- GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
- style = d->gtk_widget_get_style(gtkNotebook);
- gtkPainter->setAlphaSupport(false);
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = GTK_STATE_NORMAL; // Only state supported by gtknotebook
- bool reverse = (option->direction == Qt::RightToLeft);
- QGtkStylePrivate::gtk_widget_set_direction(gtkNotebook, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- if (const QStyleOptionTabWidgetFrameV2 *tabframe = qstyleoption_cast<const QStyleOptionTabWidgetFrameV2*>(option)) {
- GtkPositionType frameType = GTK_POS_TOP;
- QTabBar::Shape shape = frame->shape;
- int gapStart = 0;
- int gapSize = 0;
- if (shape == QTabBar::RoundedNorth || shape == QTabBar::RoundedSouth) {
- frameType = (shape == QTabBar::RoundedNorth) ? GTK_POS_TOP : GTK_POS_BOTTOM;
- gapStart = tabframe->selectedTabRect.left();
- gapSize = tabframe->selectedTabRect.width();
- } else {
- frameType = (shape == QTabBar::RoundedWest) ? GTK_POS_LEFT : GTK_POS_RIGHT;
- gapStart = tabframe->selectedTabRect.y();
- gapSize = tabframe->selectedTabRect.height();
- }
- gtkPainter->paintBoxGap(gtkNotebook, "notebook", option->rect, state, shadow, frameType,
- gapStart, gapSize, style);
- break; // done
- }
-
- // Note this is only the fallback option
- gtkPainter->paintBox(gtkNotebook, "notebook", option->rect, state, shadow, style);
- }
- break;
-
- case PE_PanelButtonCommand:
- case PE_PanelButtonTool: {
- bool isDefault = false;
- bool isTool = (element == PE_PanelButtonTool);
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton*>(option))
- isDefault = btn->features & QStyleOptionButton::DefaultButton;
-
- // don't draw a frame for tool buttons that have the autoRaise flag and are not enabled or on
- if (isTool && !(option->state & State_Enabled || option->state & State_On) && (option->state & State_AutoRaise))
- break;
- // don't draw a frame for dock widget buttons, unless we are hovering
- if (widget && widget->inherits("QDockWidgetTitleButton") && !(option->state & State_MouseOver))
- break;
-
- GtkStateType state = qt_gtk_state(option);
- if (option->state & State_On || option->state & State_Sunken)
- state = GTK_STATE_ACTIVE;
- GtkWidget *gtkButton = isTool ? d->gtkWidget("GtkToolButton.GtkButton") : d->gtkWidget("GtkButton");
- gint focusWidth, focusPad;
- gboolean interiorFocus = false;
- d->gtk_widget_style_get (gtkButton,
- "focus-line-width", &focusWidth,
- "focus-padding", &focusPad,
- "interior-focus", &interiorFocus, NULL);
-
- style = d->gtk_widget_get_style(gtkButton);
-
- QRect buttonRect = option->rect;
-
- QString key;
- if (isDefault) {
- key += QLS("def");
- QGtkStylePrivate::gtk_widget_set_can_default(gtkButton, true);
- QGtkStylePrivate::gtk_window_set_default((GtkWindow*)QGtkStylePrivate::gtk_widget_get_toplevel(gtkButton), gtkButton);
- gtkPainter->paintBox(gtkButton, "buttondefault", buttonRect, state, GTK_SHADOW_IN,
- style, isDefault ? QLS("d") : QString());
- }
-
- bool hasFocus = option->state & State_HasFocus;
-
- if (hasFocus) {
- key += QLS("def");
- QGtkStylePrivate::gtkWidgetSetFocus(gtkButton, true);
- }
-
- if (!interiorFocus)
- buttonRect = buttonRect.adjusted(focusWidth, focusWidth, -focusWidth, -focusWidth);
-
- GtkShadowType shadow = (option->state & State_Sunken || option->state & State_On ) ?
- GTK_SHADOW_IN : GTK_SHADOW_OUT;
-
- gtkPainter->paintBox(gtkButton, "button", buttonRect, state, shadow,
- style, key);
- if (isDefault)
- QGtkStylePrivate::gtk_window_set_default((GtkWindow*)QGtkStylePrivate::gtk_widget_get_toplevel(gtkButton), 0);
- if (hasFocus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkButton, false);
- }
- break;
-
- case PE_IndicatorRadioButton: {
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = qt_gtk_state(option);
-
- if (option->state & State_Sunken)
- state = GTK_STATE_ACTIVE;
-
- if (option->state & State_NoChange)
- shadow = GTK_SHADOW_ETCHED_IN;
- else if (option->state & State_On)
- shadow = GTK_SHADOW_IN;
- else
- shadow = GTK_SHADOW_OUT;
-
- GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton");
- gint spacing;
- d->gtk_widget_style_get(gtkRadioButton, "indicator-spacing", &spacing, NULL);
- QRect buttonRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
- gtkPainter->setClipRect(option->rect);
- // ### Note: Ubuntulooks breaks when the proper widget is passed
- // Murrine engine requires a widget not to get RGBA check - warnings
- GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
- QString key(QLS("radiobutton"));
- if (option->state & State_HasFocus) { // Themes such as Nodoka check this flag
- key += QLatin1Char('f');
- QGtkStylePrivate::gtkWidgetSetFocus(gtkCheckButton, true);
- }
- gtkPainter->paintOption(gtkCheckButton , buttonRect, state, shadow, d->gtk_widget_get_style(gtkRadioButton), key);
- if (option->state & State_HasFocus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkCheckButton, false);
- }
- break;
-
- case PE_IndicatorCheckBox: {
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = qt_gtk_state(option);
-
- if (option->state & State_Sunken)
- state = GTK_STATE_ACTIVE;
-
- if (option->state & State_NoChange)
- shadow = GTK_SHADOW_ETCHED_IN;
- else if (option->state & State_On)
- shadow = GTK_SHADOW_IN;
- else
- shadow = GTK_SHADOW_OUT;
-
- int spacing;
-
- GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
- QString key(QLS("checkbutton"));
- if (option->state & State_HasFocus) { // Themes such as Nodoka checks this flag
- key += QLatin1Char('f');
- QGtkStylePrivate::gtkWidgetSetFocus(gtkCheckButton, true);
- }
-
- // Some styles such as aero-clone assume they can paint in the spacing area
- gtkPainter->setClipRect(option->rect);
-
- d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, NULL);
-
- QRect checkRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing);
-
- gtkPainter->paintCheckbox(gtkCheckButton, checkRect, state, shadow, d->gtk_widget_get_style(gtkCheckButton),
- key);
- if (option->state & State_HasFocus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkCheckButton, false);
-
- }
- break;
-
-#ifndef QT_NO_TABBAR
-
- case PE_FrameTabBarBase:
- if (const QStyleOptionTabBarBase *tbb
- = qstyleoption_cast<const QStyleOptionTabBarBase *>(option)) {
- QRect tabRect = tbb->rect;
- painter->save();
- painter->setPen(QPen(option->palette.dark().color().dark(110), 0));
- switch (tbb->shape) {
-
- case QTabBar::RoundedNorth:
- painter->drawLine(tabRect.topLeft(), tabRect.topRight());
- break;
-
- case QTabBar::RoundedWest:
- painter->drawLine(tabRect.left(), tabRect.top(), tabRect.left(), tabRect.bottom());
- break;
-
- case QTabBar::RoundedSouth:
- painter->drawLine(tbb->rect.left(), tbb->rect.bottom(),
- tabRect.right(), tabRect.bottom());
- break;
-
- case QTabBar::RoundedEast:
- painter->drawLine(tabRect.topRight(), tabRect.bottomRight());
- break;
-
- case QTabBar::TriangularNorth:
- case QTabBar::TriangularEast:
- case QTabBar::TriangularWest:
- case QTabBar::TriangularSouth:
- painter->restore();
- QCommonStyle::drawPrimitive(element, option, painter, widget);
- return;
- }
-
- painter->restore();
- }
- return;
-
-#endif // QT_NO_TABBAR
-
- case PE_Widget:
- break;
-
- default:
- QCommonStyle::drawPrimitive(element, option, painter, widget);
- }
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
-
- QPainter *painter, const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable()) {
- QCommonStyle::drawComplexControl(control, option, painter, widget);
- return;
- }
-
- GtkStyle* style = d->gtkStyle();
- QGtkPainter* gtkPainter = d->gtkPainter(painter);
- QColor button = option->palette.button().color();
- QColor dark;
- QColor grooveColor;
- QColor darkOutline;
- dark.setHsv(button.hue(),
- qMin(255, (int)(button.saturation()*1.9)),
- qMin(255, (int)(button.value()*0.7)));
- grooveColor.setHsv(button.hue(),
- qMin(255, (int)(button.saturation()*2.6)),
- qMin(255, (int)(button.value()*0.9)));
- darkOutline.setHsv(button.hue(),
- qMin(255, (int)(button.saturation()*3.0)),
- qMin(255, (int)(button.value()*0.6)));
-
- QColor alphaCornerColor;
-
- if (widget)
- alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), darkOutline);
- else
- alphaCornerColor = mergedColors(option->palette.background().color(), darkOutline);
-
- switch (control) {
-
- case CC_TitleBar:
- painter->save();
- if (const QStyleOptionTitleBar *titleBar = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
- // Since this is drawn by metacity and not Gtk we
- // have to do custom drawing
-
- GdkColor gdkBg = style->bg[GTK_STATE_SELECTED];
- QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
-
- const int buttonMargin = 5;
- bool active = (titleBar->titleBarState & State_Active);
- QRect fullRect = titleBar->rect;
- QPalette palette = option->palette;
- QColor highlight = bgColor;
-
- QColor titleBarFrameBorder(active ? highlight.darker(180): dark.darker(110));
- QColor titleBarHighlight(active ? highlight.lighter(120): palette.background().color().lighter(120));
- QColor textColor(active ? 0xffffff : 0xff000000);
- QColor textAlphaColor(active ? 0xffffff : 0xff000000 );
-
- {
- // Fill title bar gradient
- QColor titlebarColor = QColor(active ? highlight: palette.background().color());
- QLinearGradient gradient(option->rect.center().x(), option->rect.top(),
- option->rect.center().x(), option->rect.bottom());
-
- gradient.setColorAt(0, titlebarColor.lighter(114));
- gradient.setColorAt(0.5, titlebarColor.lighter(102));
- gradient.setColorAt(0.51, titlebarColor.darker(104));
- gradient.setColorAt(1, titlebarColor);
- painter->fillRect(option->rect.adjusted(1, 1, -1, 0), gradient);
-
- // Frame and rounded corners
- painter->setPen(titleBarFrameBorder);
-
- // top outline
- painter->drawLine(fullRect.left() + 5, fullRect.top(), fullRect.right() - 5, fullRect.top());
- painter->drawLine(fullRect.left(), fullRect.top() + 4, fullRect.left(), fullRect.bottom());
- const QPoint points[5] = {
- QPoint(fullRect.left() + 4, fullRect.top() + 1),
- QPoint(fullRect.left() + 3, fullRect.top() + 1),
- QPoint(fullRect.left() + 2, fullRect.top() + 2),
- QPoint(fullRect.left() + 1, fullRect.top() + 3),
- QPoint(fullRect.left() + 1, fullRect.top() + 4)
- };
- painter->drawPoints(points, 5);
-
- painter->drawLine(fullRect.right(), fullRect.top() + 4, fullRect.right(), fullRect.bottom());
- const QPoint points2[5] = {
- QPoint(fullRect.right() - 3, fullRect.top() + 1),
- QPoint(fullRect.right() - 4, fullRect.top() + 1),
- QPoint(fullRect.right() - 2, fullRect.top() + 2),
- QPoint(fullRect.right() - 1, fullRect.top() + 3),
- QPoint(fullRect.right() - 1, fullRect.top() + 4)
- };
- painter->drawPoints(points2, 5);
-
- // draw bottomline
- painter->drawLine(fullRect.right(), fullRect.bottom(), fullRect.left(), fullRect.bottom());
-
- // top highlight
- painter->setPen(titleBarHighlight);
- painter->drawLine(fullRect.left() + 6, fullRect.top() + 1, fullRect.right() - 6, fullRect.top() + 1);
- }
- // draw title
- QRect textRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarLabel, widget);
- QFont font = painter->font();
- font.setBold(true);
- painter->setFont(font);
- painter->setPen(active? (titleBar->palette.text().color().lighter(120)) :
- titleBar->palette.text().color() );
- // Note workspace also does elliding but it does not use the correct font
- QString title = QFontMetrics(font).elidedText(titleBar->text, Qt::ElideRight, textRect.width() - 14);
- painter->drawText(textRect.adjusted(1, 1, 1, 1), title, QTextOption(Qt::AlignHCenter | Qt::AlignVCenter));
- painter->setPen(Qt::white);
- if (active)
- painter->drawText(textRect, title, QTextOption(Qt::AlignHCenter | Qt::AlignVCenter));
- // min button
- if ((titleBar->subControls & SC_TitleBarMinButton) && (titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
- !(titleBar->titleBarState& Qt::WindowMinimized)) {
- QRect minButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMinButton, widget);
- if (minButtonRect.isValid()) {
- bool hover = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_MouseOver);
- bool sunken = (titleBar->activeSubControls & SC_TitleBarMinButton) && (titleBar->state & State_Sunken);
- qt_gtk_draw_mdibutton(painter, titleBar, minButtonRect, hover, sunken);
- QRect minButtonIconRect = minButtonRect.adjusted(buttonMargin ,buttonMargin , -buttonMargin, -buttonMargin);
- painter->setPen(textColor);
- painter->drawLine(minButtonIconRect.center().x() - 2, minButtonIconRect.center().y() + 3,
- minButtonIconRect.center().x() + 3, minButtonIconRect.center().y() + 3);
- painter->drawLine(minButtonIconRect.center().x() - 2, minButtonIconRect.center().y() + 4,
- minButtonIconRect.center().x() + 3, minButtonIconRect.center().y() + 4);
- painter->setPen(textAlphaColor);
- painter->drawLine(minButtonIconRect.center().x() - 3, minButtonIconRect.center().y() + 3,
- minButtonIconRect.center().x() - 3, minButtonIconRect.center().y() + 4);
- painter->drawLine(minButtonIconRect.center().x() + 4, minButtonIconRect.center().y() + 3,
- minButtonIconRect.center().x() + 4, minButtonIconRect.center().y() + 4);
- }
- }
- // max button
- if ((titleBar->subControls & SC_TitleBarMaxButton) && (titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
- !(titleBar->titleBarState & Qt::WindowMaximized)) {
- QRect maxButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarMaxButton, widget);
- if (maxButtonRect.isValid()) {
- bool hover = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_MouseOver);
- bool sunken = (titleBar->activeSubControls & SC_TitleBarMaxButton) && (titleBar->state & State_Sunken);
- qt_gtk_draw_mdibutton(painter, titleBar, maxButtonRect, hover, sunken);
-
- QRect maxButtonIconRect = maxButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
-
- painter->setPen(textColor);
- painter->drawRect(maxButtonIconRect.adjusted(0, 0, -1, -1));
- painter->drawLine(maxButtonIconRect.left() + 1, maxButtonIconRect.top() + 1,
- maxButtonIconRect.right() - 1, maxButtonIconRect.top() + 1);
- painter->setPen(textAlphaColor);
- const QPoint points[4] = {
- maxButtonIconRect.topLeft(),
- maxButtonIconRect.topRight(),
- maxButtonIconRect.bottomLeft(),
- maxButtonIconRect.bottomRight()
- };
- painter->drawPoints(points, 4);
- }
- }
-
- // close button
- if ((titleBar->subControls & SC_TitleBarCloseButton) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
- QRect closeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarCloseButton, widget);
- if (closeButtonRect.isValid()) {
- bool hover = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_MouseOver);
- bool sunken = (titleBar->activeSubControls & SC_TitleBarCloseButton) && (titleBar->state & State_Sunken);
- qt_gtk_draw_mdibutton(painter, titleBar, closeButtonRect, hover, sunken);
- QRect closeIconRect = closeButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
- painter->setPen(textAlphaColor);
- const QLine lines[4] = {
- QLine(closeIconRect.left() + 1, closeIconRect.top(),
- closeIconRect.right(), closeIconRect.bottom() - 1),
- QLine(closeIconRect.left(), closeIconRect.top() + 1,
- closeIconRect.right() - 1, closeIconRect.bottom()),
- QLine(closeIconRect.right() - 1, closeIconRect.top(),
- closeIconRect.left(), closeIconRect.bottom() - 1),
- QLine(closeIconRect.right(), closeIconRect.top() + 1,
- closeIconRect.left() + 1, closeIconRect.bottom())
- };
- painter->drawLines(lines, 4);
- const QPoint points[4] = {
- closeIconRect.topLeft(),
- closeIconRect.topRight(),
- closeIconRect.bottomLeft(),
- closeIconRect.bottomRight()
- };
- painter->drawPoints(points, 4);
-
- painter->setPen(textColor);
- painter->drawLine(closeIconRect.left() + 1, closeIconRect.top() + 1,
- closeIconRect.right() - 1, closeIconRect.bottom() - 1);
- painter->drawLine(closeIconRect.left() + 1, closeIconRect.bottom() - 1,
- closeIconRect.right() - 1, closeIconRect.top() + 1);
- }
- }
-
- // normalize button
- if ((titleBar->subControls & SC_TitleBarNormalButton) &&
- (((titleBar->titleBarFlags & Qt::WindowMinimizeButtonHint) &&
- (titleBar->titleBarState & Qt::WindowMinimized)) ||
- ((titleBar->titleBarFlags & Qt::WindowMaximizeButtonHint) &&
- (titleBar->titleBarState & Qt::WindowMaximized)))) {
- QRect normalButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarNormalButton, widget);
- if (normalButtonRect.isValid()) {
-
- bool hover = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_MouseOver);
- bool sunken = (titleBar->activeSubControls & SC_TitleBarNormalButton) && (titleBar->state & State_Sunken);
- QRect normalButtonIconRect = normalButtonRect.adjusted(buttonMargin, buttonMargin, -buttonMargin, -buttonMargin);
- qt_gtk_draw_mdibutton(painter, titleBar, normalButtonRect, hover, sunken);
-
- QRect frontWindowRect = normalButtonIconRect.adjusted(0, 3, -3, 0);
- painter->setPen(textColor);
- painter->drawRect(frontWindowRect.adjusted(0, 0, -1, -1));
- painter->drawLine(frontWindowRect.left() + 1, frontWindowRect.top() + 1,
- frontWindowRect.right() - 1, frontWindowRect.top() + 1);
- painter->setPen(textAlphaColor);
- const QPoint points[4] = {
- frontWindowRect.topLeft(),
- frontWindowRect.topRight(),
- frontWindowRect.bottomLeft(),
- frontWindowRect.bottomRight()
- };
- painter->drawPoints(points, 4);
-
- QRect backWindowRect = normalButtonIconRect.adjusted(3, 0, 0, -3);
- QRegion clipRegion = backWindowRect;
- clipRegion -= frontWindowRect;
- painter->save();
- painter->setClipRegion(clipRegion);
- painter->setPen(textColor);
- painter->drawRect(backWindowRect.adjusted(0, 0, -1, -1));
- painter->drawLine(backWindowRect.left() + 1, backWindowRect.top() + 1,
- backWindowRect.right() - 1, backWindowRect.top() + 1);
- painter->setPen(textAlphaColor);
- const QPoint points2[4] = {
- backWindowRect.topLeft(),
- backWindowRect.topRight(),
- backWindowRect.bottomLeft(),
- backWindowRect.bottomRight()
- };
- painter->drawPoints(points2, 4);
- painter->restore();
- }
- }
-
- // context help button
- if (titleBar->subControls & SC_TitleBarContextHelpButton
- && (titleBar->titleBarFlags & Qt::WindowContextHelpButtonHint)) {
- QRect contextHelpButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarContextHelpButton, widget);
- if (contextHelpButtonRect.isValid()) {
- bool hover = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_MouseOver);
- bool sunken = (titleBar->activeSubControls & SC_TitleBarContextHelpButton) && (titleBar->state & State_Sunken);
- qt_gtk_draw_mdibutton(painter, titleBar, contextHelpButtonRect, hover, sunken);
-
- QColor blend;
- QImage image(qt_titlebar_context_help);
- QColor alpha = textColor;
- alpha.setAlpha(128);
- image.setColor(1, textColor.rgba());
- image.setColor(2, alpha.rgba());
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
- painter->drawImage(contextHelpButtonRect.adjusted(4, 4, -4, -4), image);
- }
- }
-
- // shade button
- if (titleBar->subControls & SC_TitleBarShadeButton && (titleBar->titleBarFlags & Qt::WindowShadeButtonHint)) {
- QRect shadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarShadeButton, widget);
- if (shadeButtonRect.isValid()) {
- bool hover = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_MouseOver);
- bool sunken = (titleBar->activeSubControls & SC_TitleBarShadeButton) && (titleBar->state & State_Sunken);
- qt_gtk_draw_mdibutton(painter, titleBar, shadeButtonRect, hover, sunken);
- QImage image(qt_scrollbar_button_arrow_up);
- image.setColor(1, textColor.rgba());
- painter->drawImage(shadeButtonRect.adjusted(5, 7, -5, -7), image);
- }
- }
-
- // unshade button
- if (titleBar->subControls & SC_TitleBarUnshadeButton && (titleBar->titleBarFlags & Qt::WindowShadeButtonHint)) {
- QRect unshadeButtonRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarUnshadeButton, widget);
- if (unshadeButtonRect.isValid()) {
- bool hover = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_MouseOver);
- bool sunken = (titleBar->activeSubControls & SC_TitleBarUnshadeButton) && (titleBar->state & State_Sunken);
- qt_gtk_draw_mdibutton(painter, titleBar, unshadeButtonRect, hover, sunken);
- QImage image(qt_scrollbar_button_arrow_down);
- image.setColor(1, textColor.rgba());
- painter->drawImage(unshadeButtonRect.adjusted(5, 7, -5, -7), image);
- }
- }
-
- if ((titleBar->subControls & SC_TitleBarSysMenu) && (titleBar->titleBarFlags & Qt::WindowSystemMenuHint)) {
- QRect iconRect = proxy()->subControlRect(CC_TitleBar, titleBar, SC_TitleBarSysMenu, widget);
- if (iconRect.isValid()) {
- if (!titleBar->icon.isNull()) {
- titleBar->icon.paint(painter, iconRect);
- } else {
- QStyleOption tool(0);
- tool.palette = titleBar->palette;
- QPixmap pm = proxy()->standardIcon(SP_TitleBarMenuButton, &tool, widget).pixmap(16, 16);
- tool.rect = iconRect;
- painter->save();
- proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pm);
- painter->restore();
- }
- }
- }
- }
- painter->restore();
- break;
-
-#ifndef QT_NO_GROUPBOX
-
- case CC_GroupBox:
- painter->save();
-
- if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
- QRect textRect = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxLabel, widget);
- QRect checkBoxRect = proxy()->subControlRect(CC_GroupBox, groupBox, SC_GroupBoxCheckBox, widget);
- // Draw title
-
- if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) {
- // Draw prelight background
- GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton");
-
- if (option->state & State_MouseOver) {
- QRect bgRect = textRect | checkBoxRect;
- gtkPainter->paintFlatBox(gtkCheckButton, "checkbutton", bgRect.adjusted(0, 0, 0, -2),
- GTK_STATE_PRELIGHT, GTK_SHADOW_ETCHED_OUT, d->gtk_widget_get_style(gtkCheckButton));
- }
-
- if (!groupBox->text.isEmpty()) {
- int alignment = int(groupBox->textAlignment);
- if (!proxy()->styleHint(QStyle::SH_UnderlineShortcut, option, widget))
- alignment |= Qt::TextHideMnemonic;
- QColor textColor = groupBox->textColor; // Note: custom textColor is currently ignored
- int labelState = GTK_STATE_INSENSITIVE;
-
- if (option->state & State_Enabled)
- labelState = (option->state & State_MouseOver) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
-
- GdkColor gdkText = d->gtk_widget_get_style(gtkCheckButton)->fg[labelState];
- textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- painter->setPen(textColor);
- QFont font = painter->font();
- font.setBold(true);
- painter->setFont(font);
- painter->drawText(textRect, Qt::TextShowMnemonic | Qt::AlignLeft| alignment, groupBox->text);
-
- if (option->state & State_HasFocus)
- gtkPainter->paintFocus(gtkCheckButton, "checkbutton", textRect.adjusted(-4, -1, 0, -3), GTK_STATE_ACTIVE, style);
- }
- }
-
- if (groupBox->subControls & SC_GroupBoxCheckBox) {
- QStyleOptionButton box;
- box.QStyleOption::operator=(*groupBox);
- box.rect = checkBoxRect;
- proxy()->drawPrimitive(PE_IndicatorCheckBox, &box, painter, widget);
- }
- }
-
- painter->restore();
- break;
-#endif // QT_NO_GROUPBOX
-
-#ifndef QT_NO_COMBOBOX
-
- case CC_ComboBox:
- // See: http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/GtkComboBox
- // and http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/GtkComboBoxEntry
- if (const QStyleOptionComboBox *comboBox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- bool sunken = comboBox->state & State_On; // play dead, if combobox has no items
- BEGIN_STYLE_PIXMAPCACHE(QString::fromLatin1("cb-%0-%1").arg(sunken).arg(comboBox->editable));
- gtkPainter->reset(p);
- gtkPainter->setUsePixmapCache(false); // cached externally
-
- bool isEnabled = (comboBox->state & State_Enabled);
- bool focus = isEnabled && (comboBox->state & State_HasFocus);
- GtkStateType state = qt_gtk_state(option);
- int appears_as_list = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, comboBox, widget);
- QStyleOptionComboBox comboBoxCopy = *comboBox;
- comboBoxCopy.rect = option->rect;
-
- bool reverse = (option->direction == Qt::RightToLeft);
- QRect rect = option->rect;
- QRect arrowButtonRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy,
- SC_ComboBoxArrow, widget);
-
- GtkShadowType shadow = (option->state & State_Sunken || option->state & State_On ) ?
- GTK_SHADOW_IN : GTK_SHADOW_OUT;
- const QHashableLatin1Literal comboBoxPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry") : QHashableLatin1Literal("GtkComboBox");
-
- // We use the gtk widget to position arrows and separators for us
- GtkWidget *gtkCombo = d->gtkWidget(comboBoxPath);
- GtkAllocation geometry = {0, 0, option->rect.width(), option->rect.height()};
- d->gtk_widget_set_direction(gtkCombo, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- d->gtk_widget_size_allocate(gtkCombo, &geometry);
-
- QHashableLatin1Literal buttonPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton")
- : QHashableLatin1Literal("GtkComboBox.GtkToggleButton");
- GtkWidget *gtkToggleButton = d->gtkWidget(buttonPath);
- d->gtk_widget_set_direction(gtkToggleButton, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- if (gtkToggleButton && (appears_as_list || comboBox->editable)) {
- if (focus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkToggleButton, true);
- // Draw the combo box as a line edit with a button next to it
- if (comboBox->editable || appears_as_list) {
- GtkStateType frameState = (state == GTK_STATE_PRELIGHT) ? GTK_STATE_NORMAL : state;
- QHashableLatin1Literal entryPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkEntry") : QHashableLatin1Literal("GtkComboBox.GtkFrame");
- GtkWidget *gtkEntry = d->gtkWidget(entryPath);
- d->gtk_widget_set_direction(gtkEntry, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- QRect frameRect = option->rect;
-
- if (reverse)
- frameRect.setLeft(arrowButtonRect.right());
- else
- frameRect.setRight(arrowButtonRect.left());
-
- // Fill the line edit background
- // We could have used flat_box with "entry_bg" but that is probably not worth the overhead
- uint resolve_mask = option->palette.resolve();
- GtkStyle *gtkEntryStyle = d->gtk_widget_get_style(gtkEntry);
- QRect contentRect = frameRect.adjusted(gtkEntryStyle->xthickness, gtkEntryStyle->ythickness,
- -gtkEntryStyle->xthickness, -gtkEntryStyle->ythickness);
- // Required for inner blue highlight with clearlooks
- if (focus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkEntry, true);
-
- if (widget && widget->testAttribute(Qt::WA_SetPalette) &&
- resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
- p->fillRect(contentRect, option->palette.base().color());
- else {
- gtkPainter->paintFlatBox(gtkEntry, "entry_bg", contentRect,
- option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE,
- GTK_SHADOW_NONE, gtkEntryStyle, entryPath.toString() + QString::number(focus));
- }
-
- gtkPainter->paintShadow(gtkEntry, comboBox->editable ? "entry" : "frame", frameRect, frameState,
- GTK_SHADOW_IN, gtkEntryStyle, entryPath.toString() +
- QString::number(focus) + QString::number(comboBox->editable) +
- QString::number(option->direction));
- if (focus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkEntry, false);
- }
-
- GtkStateType buttonState = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled))
- buttonState = GTK_STATE_INSENSITIVE;
- else if (option->state & State_Sunken || option->state & State_On)
- buttonState = GTK_STATE_ACTIVE;
- else if (option->state & State_MouseOver && comboBox->activeSubControls & SC_ComboBoxArrow)
- buttonState = GTK_STATE_PRELIGHT;
-
- Q_ASSERT(gtkToggleButton);
- gtkPainter->paintBox(gtkToggleButton, "button", arrowButtonRect, buttonState,
- shadow, d->gtk_widget_get_style(gtkToggleButton), buttonPath.toString() +
- QString::number(focus) + QString::number(option->direction));
- if (focus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkToggleButton, false);
- } else {
- // Draw combo box as a button
- QRect buttonRect = option->rect;
- GtkStyle *gtkToggleButtonStyle = d->gtk_widget_get_style(gtkToggleButton);
-
- if (focus) // Clearlooks actually check the widget for the default state
- QGtkStylePrivate::gtkWidgetSetFocus(gtkToggleButton, true);
- gtkPainter->paintBox(gtkToggleButton, "button",
- buttonRect, state,
- shadow, gtkToggleButtonStyle,
- buttonPath.toString() + QString::number(focus));
- if (focus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkToggleButton, false);
-
-
- // Draw the separator between label and arrows
- QHashableLatin1Literal vSeparatorPath = comboBox->editable
- ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkHBox.GtkVSeparator")
- : QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkHBox.GtkVSeparator");
-
- if (GtkWidget *gtkVSeparator = d->gtkWidget(vSeparatorPath)) {
- GtkAllocation allocation;
- d->gtk_widget_get_allocation(gtkVSeparator, &allocation);
- QRect vLineRect(allocation.x, allocation.y, allocation.width, allocation.height);
-
- gtkPainter->paintVline(gtkVSeparator, "vseparator",
- vLineRect, state, d->gtk_widget_get_style(gtkVSeparator),
- 0, vLineRect.height(), 0, vSeparatorPath.toString());
-
-
- gint interiorFocus = true;
- d->gtk_widget_style_get(gtkToggleButton, "interior-focus", &interiorFocus, NULL);
- int xt = interiorFocus ? gtkToggleButtonStyle->xthickness : 0;
- int yt = interiorFocus ? gtkToggleButtonStyle->ythickness : 0;
- if (focus && ((option->state & State_KeyboardFocusChange) || styleHint(SH_UnderlineShortcut, option, widget)))
- gtkPainter->paintFocus(gtkToggleButton, "button",
- option->rect.adjusted(xt, yt, -xt, -yt),
- option->state & State_Sunken ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
- gtkToggleButtonStyle);
- }
- }
-
- if (comboBox->subControls & SC_ComboBoxArrow) {
- if (!isEnabled)
- state = GTK_STATE_INSENSITIVE;
- else if (sunken)
- state = GTK_STATE_ACTIVE;
- else if (option->state & State_MouseOver)
- state = GTK_STATE_PRELIGHT;
- else
- state = GTK_STATE_NORMAL;
-
- QHashableLatin1Literal arrowPath("");
- if (comboBox->editable) {
- if (appears_as_list)
- arrowPath = QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkArrow");
- else
- arrowPath = QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkHBox.GtkArrow");
- } else {
- if (appears_as_list)
- arrowPath = QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkArrow");
- else
- arrowPath = QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkHBox.GtkArrow");
- }
-
- GtkWidget *gtkArrow = d->gtkWidget(arrowPath);
- gfloat scale = 0.7;
- gint minSize = 15;
- QRect arrowWidgetRect;
-
- if (gtkArrow && !d->gtk_check_version(2, 12, 0)) {
- d->gtk_widget_style_get(gtkArrow, "arrow-scaling", &scale, NULL);
- d->gtk_widget_style_get(gtkCombo, "arrow-size", &minSize, NULL);
- }
- if (gtkArrow) {
- GtkAllocation allocation;
- d->gtk_widget_get_allocation(gtkArrow, &allocation);
- arrowWidgetRect = QRect(allocation.x, allocation.y, allocation.width, allocation.height);
- style = d->gtk_widget_get_style(gtkArrow);
- }
-
- // Note that for some reason the arrow-size is not properly respected with Hildon
- // Hence we enforce the minimum "arrow-size" ourselves
- int arrowSize = qMax(qMin(rect.height() - d->gtk_widget_get_style(gtkCombo)->ythickness * 2, minSize),
- qMin(arrowWidgetRect.width(), arrowWidgetRect.height()));
- QRect arrowRect(0, 0, static_cast<int>(arrowSize * scale), static_cast<int>(arrowSize * scale));
-
- arrowRect.moveCenter(arrowWidgetRect.center());
-
- if (sunken) {
- int xoff, yoff;
- const QHashableLatin1Literal toggleButtonPath = comboBox->editable
- ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton")
- : QHashableLatin1Literal("GtkComboBox.GtkToggleButton");
-
- GtkWidget *gtkButton = d->gtkWidget(toggleButtonPath);
- d->gtk_widget_style_get(gtkButton, "child-displacement-x", &xoff, NULL);
- d->gtk_widget_style_get(gtkButton, "child-displacement-y", &yoff, NULL);
- arrowRect = arrowRect.adjusted(xoff, yoff, xoff, yoff);
- }
-
- // Some styles such as Nimbus paint outside the arrowRect
- // hence we have provide the whole widget as the cliprect
- if (gtkArrow) {
- gtkPainter->setClipRect(option->rect);
- gtkPainter->paintArrow(gtkArrow, "arrow", arrowRect,
- GTK_ARROW_DOWN, state, GTK_SHADOW_NONE, true,
- style, arrowPath.toString() + QString::number(option->direction));
- }
- }
- END_STYLE_PIXMAPCACHE;
- }
- break;
-#endif // QT_NO_COMBOBOX
-#ifndef QT_NO_TOOLBUTTON
-
- case CC_ToolButton:
- if (const QStyleOptionToolButton *toolbutton
- = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
- QRect button, menuarea;
- button = proxy()->subControlRect(control, toolbutton, SC_ToolButton, widget);
- menuarea = proxy()->subControlRect(control, toolbutton, SC_ToolButtonMenu, widget);
- State bflags = toolbutton->state & ~(State_Sunken | State_MouseOver);
-
- if (bflags & State_AutoRaise)
- if (!(bflags & State_MouseOver))
- bflags &= ~State_Raised;
-
- State mflags = bflags;
-
- if (toolbutton->state & State_Sunken) {
- if (toolbutton->activeSubControls & SC_ToolButton)
- bflags |= State_Sunken;
- if (toolbutton->activeSubControls & SC_ToolButtonMenu)
- mflags |= State_Sunken;
- } else if (toolbutton->state & State_MouseOver) {
- if (toolbutton->activeSubControls & SC_ToolButton)
- bflags |= State_MouseOver;
- if (toolbutton->activeSubControls & SC_ToolButtonMenu)
- mflags |= State_MouseOver;
- }
-
- QStyleOption tool(0);
-
- tool.palette = toolbutton->palette;
-
- if (toolbutton->subControls & SC_ToolButton) {
- if (bflags & (State_Sunken | State_On | State_Raised | State_MouseOver)) {
- tool.rect = button;
- tool.state = bflags;
- proxy()->drawPrimitive(PE_PanelButtonTool, &tool, painter, widget);
- }
- }
-
- bool drawMenuArrow = toolbutton->features & QStyleOptionToolButton::HasMenu &&
- !(toolbutton->features & QStyleOptionToolButton::MenuButtonPopup);
- int popupArrowSize = drawMenuArrow ? 7 : 0;
-
- if (toolbutton->state & State_HasFocus) {
- QStyleOptionFocusRect fr;
- fr.QStyleOption::operator=(*toolbutton);
- fr.rect = proxy()->subControlRect(CC_ToolButton, toolbutton, SC_ToolButton, widget);
- fr.rect.adjust(1, 1, -1, -1);
- proxy()->drawPrimitive(PE_FrameFocusRect, &fr, painter, widget);
- }
-
- QStyleOptionToolButton label = *toolbutton;
- label.state = bflags;
- GtkWidget *gtkButton = d->gtkWidget("GtkToolButton.GtkButton");
- QPalette pal = toolbutton->palette;
- if (option->state & State_Enabled &&
- option->state & State_MouseOver && !(widget && widget->testAttribute(Qt::WA_SetPalette))) {
- GdkColor gdkText = d->gtk_widget_get_style(gtkButton)->fg[GTK_STATE_PRELIGHT];
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- pal.setBrush(QPalette::All, QPalette::ButtonText, textColor);
- label.palette = pal;
- }
- label.rect = button.adjusted(style->xthickness, style->ythickness,
- -style->xthickness - popupArrowSize, -style->ythickness);
- proxy()->drawControl(CE_ToolButtonLabel, &label, painter, widget);
-
- if (toolbutton->subControls & SC_ToolButtonMenu) {
- tool.rect = menuarea;
- tool.state = mflags;
- if ((mflags & State_Enabled && (mflags & (State_Sunken | State_Raised | State_MouseOver))) || !(mflags & State_AutoRaise))
- proxy()->drawPrimitive(PE_IndicatorButtonDropDown, &tool, painter, widget);
-
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, painter, widget);
-
- } else if (drawMenuArrow) {
- QRect ir = toolbutton->rect;
- QStyleOptionToolButton newBtn = *toolbutton;
- newBtn.rect = QRect(ir.right() - popupArrowSize - style->xthickness - 3, ir.height()/2 - 1, popupArrowSize, popupArrowSize);
- proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, painter, widget);
- }
- }
- break;
-
-#endif // QT_NO_TOOLBUTTON
-#ifndef QT_NO_SCROLLBAR
-
- case CC_ScrollBar:
- if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- GtkWidget *gtkHScrollBar = d->gtkWidget("GtkHScrollbar");
- GtkWidget *gtkVScrollBar = d->gtkWidget("GtkVScrollbar");
-
- // Fill background in case the scrollbar is partially transparent
- painter->fillRect(option->rect, option->palette.background());
-
- QRect rect = scrollBar->rect;
- QRect scrollBarSubLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSubLine, widget);
- QRect scrollBarAddLine = proxy()->subControlRect(control, scrollBar, SC_ScrollBarAddLine, widget);
- QRect scrollBarSlider = proxy()->subControlRect(control, scrollBar, SC_ScrollBarSlider, widget);
- QRect grooveRect = proxy()->subControlRect(control, scrollBar, SC_ScrollBarGroove, widget);
- bool horizontal = scrollBar->orientation == Qt::Horizontal;
- GtkWidget * scrollbarWidget = horizontal ? gtkHScrollBar : gtkVScrollBar;
- style = d->gtk_widget_get_style(scrollbarWidget);
- gboolean trough_under_steppers = true;
- gboolean trough_side_details = false;
- gboolean activate_slider = false;
- gboolean stepper_size = 14;
- gint trough_border = 1;
- if (!d->gtk_check_version(2, 10, 0)) {
- d->gtk_widget_style_get((GtkWidget*)(scrollbarWidget),
- "trough-border", &trough_border,
- "trough-side-details", &trough_side_details,
- "trough-under-steppers", &trough_under_steppers,
- "activate-slider", &activate_slider,
- "stepper-size", &stepper_size, NULL);
- }
- if (trough_under_steppers) {
- scrollBarAddLine.adjust(trough_border, trough_border, -trough_border, -trough_border);
- scrollBarSubLine.adjust(trough_border, trough_border, -trough_border, -trough_border);
- scrollBarSlider.adjust(horizontal ? -trough_border : 0, horizontal ? 0 : -trough_border,
- horizontal ? trough_border : 0, horizontal ? 0 : trough_border);
- }
-
- // Some styles check the position of scrollbars in order to determine
- // if lines should be painted when the scrollbar is in max or min positions.
- int maximum = 2;
- int fakePos = 0;
- bool reverse = (option->direction == Qt::RightToLeft);
- if (scrollBar->minimum == scrollBar->maximum)
- maximum = 0;
- if (scrollBar->sliderPosition == scrollBar->maximum)
- fakePos = maximum;
- else if (scrollBar->sliderPosition > scrollBar->minimum)
- fakePos = maximum - 1;
-
-
- GtkRange *range = (GtkRange*)(horizontal ? gtkHScrollBar : gtkVScrollBar);
- GtkAdjustment *adjustment = 0;
-
- if (d->gtk_adjustment_configure)
- adjustment = d->gtk_range_get_adjustment(range);
- if (adjustment) {
- d->gtk_adjustment_configure(adjustment, fakePos, 0, maximum, 0, 0, 0);
- } else {
- adjustment = (GtkAdjustment*)d->gtk_adjustment_new(fakePos, 0, maximum, 0, 0, 0);
- d->gtk_range_set_adjustment(range, adjustment);
- }
-
- if (scrollBar->subControls & SC_ScrollBarGroove) {
- GtkStateType state = GTK_STATE_ACTIVE;
-
- if (!(option->state & State_Enabled))
- state = GTK_STATE_INSENSITIVE;
-
- if (trough_under_steppers)
- grooveRect = option->rect;
-
- gtkPainter->paintBox(scrollbarWidget, "trough", grooveRect, state, GTK_SHADOW_IN, style);
- }
-
- //paint slider
- if (scrollBar->subControls & SC_ScrollBarSlider) {
- GtkStateType state = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled))
- state = GTK_STATE_INSENSITIVE;
- else if (activate_slider &&
- option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarSlider))
- state = GTK_STATE_ACTIVE;
- else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarSlider))
- state = GTK_STATE_PRELIGHT;
-
- GtkShadowType shadow = GTK_SHADOW_OUT;
-
- if (trough_under_steppers) {
- if (!horizontal)
- scrollBarSlider.adjust(trough_border, 0, -trough_border, 0);
- else
- scrollBarSlider.adjust(0, trough_border, 0, -trough_border);
- }
-
- gtkPainter->paintSlider(scrollbarWidget, "slider", scrollBarSlider, state, shadow, style,
- horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, QString(QLS("%0%1")).arg(fakePos).arg(maximum));
- }
-
- if (scrollBar->subControls & SC_ScrollBarAddLine) {
- GtkAllocation vAllocation;
- vAllocation.y = scrollBarAddLine.top();
- vAllocation.height = scrollBarAddLine.height() - rect.height() + 6;
- d->gtk_widget_set_allocation(gtkVScrollBar, &vAllocation);
-
- GtkAllocation hAllocation;
- hAllocation.x = scrollBarAddLine.right();
- hAllocation.width = scrollBarAddLine.width() - rect.width();
- d->gtk_widget_set_allocation(gtkHScrollBar, &hAllocation);
-
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled) || (fakePos == maximum))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarAddLine)) {
- state = GTK_STATE_ACTIVE;
- shadow = GTK_SHADOW_IN;
-
- } else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarAddLine))
- state = GTK_STATE_PRELIGHT;
-
- gtkPainter->paintBox(scrollbarWidget,
- horizontal ? "hscrollbar" : "vscrollbar", scrollBarAddLine,
- state, shadow, style, QLS("add"));
-
- gtkPainter->paintArrow(scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarAddLine.adjusted(4, 4, -4, -4),
- horizontal ? (reverse ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT) :
- GTK_ARROW_DOWN, state, GTK_SHADOW_NONE, false, style);
- }
-
- if (scrollBar->subControls & SC_ScrollBarSubLine) {
- GtkAllocation vAllocation;
- vAllocation.y = 0;
- vAllocation.height = scrollBarSubLine.height();
- d->gtk_widget_set_allocation(gtkVScrollBar, &vAllocation);
-
- GtkAllocation hAllocation;
- hAllocation.x = 0;
- hAllocation.width = scrollBarSubLine.width();
- d->gtk_widget_set_allocation(gtkHScrollBar, &hAllocation);
-
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled) || (fakePos == 0))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & State_Sunken && (scrollBar->activeSubControls & SC_ScrollBarSubLine)) {
- shadow = GTK_SHADOW_IN;
- state = GTK_STATE_ACTIVE;
-
- } else if (option->state & State_MouseOver && (scrollBar->activeSubControls & SC_ScrollBarSubLine))
- state = GTK_STATE_PRELIGHT;
-
- gtkPainter->paintBox(scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarSubLine,
- state, shadow, style, QLS("sub"));
-
- gtkPainter->paintArrow(scrollbarWidget, horizontal ? "hscrollbar" : "vscrollbar", scrollBarSubLine.adjusted(4, 4, -4, -4),
- horizontal ? (reverse ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT) :
- GTK_ARROW_UP, state, GTK_SHADOW_NONE, false, style);
- }
- }
- break;
-
-#endif //QT_NO_SCROLLBAR
-#ifndef QT_NO_SPINBOX
-
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
-
- GtkWidget *gtkSpinButton = spinBox->buttonSymbols == QAbstractSpinBox::NoButtons
- ? d->gtkWidget("GtkEntry")
- : d->gtkWidget("GtkSpinButton");
- bool isEnabled = (spinBox->state & State_Enabled);
- bool hover = isEnabled && (spinBox->state & State_MouseOver);
- bool sunken = (spinBox->state & State_Sunken);
- bool upIsActive = (spinBox->activeSubControls == SC_SpinBoxUp);
- bool downIsActive = (spinBox->activeSubControls == SC_SpinBoxDown);
- bool reverse = (spinBox->direction == Qt::RightToLeft);
-
- QRect editArea = option->rect;
- QRect editRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxEditField, widget);
- QRect upRect, downRect, buttonRect;
- if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) {
- upRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxUp, widget);
- downRect = proxy()->subControlRect(CC_SpinBox, option, SC_SpinBoxDown, widget);
-
- //### Move this to subControlRect
- upRect.setTop(option->rect.top());
-
- if (reverse)
- upRect.setLeft(option->rect.left());
- else
- upRect.setRight(option->rect.right());
-
- downRect.setBottom(option->rect.bottom());
-
- if (reverse)
- downRect.setLeft(option->rect.left());
- else
- downRect.setRight(option->rect.right());
-
- buttonRect = upRect | downRect;
-
- if (reverse)
- editArea.setLeft(upRect.right());
- else
- editArea.setRight(upRect.left());
- }
- if (spinBox->frame) {
- GtkStateType state = qt_gtk_state(option);
-
- if (!(option->state & State_Enabled))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & State_HasFocus)
- state = GTK_STATE_NORMAL;
- else if (state == GTK_STATE_PRELIGHT)
- state = GTK_STATE_NORMAL;
-
- style = d->gtk_widget_get_style(gtkSpinButton);
-
-
- QString key;
-
- if (option->state & State_HasFocus) {
- key += QLatin1Char('f');
- QGtkStylePrivate::gtkWidgetSetFocus(gtkSpinButton, true);
- }
-
- uint resolve_mask = option->palette.resolve();
-
- if (resolve_mask & (1 << QPalette::Base)) // Palette overridden by user
- painter->fillRect(editRect, option->palette.base().color());
- else
- gtkPainter->paintFlatBox(gtkSpinButton, "entry_bg", editArea.adjusted(style->xthickness, style->ythickness,
- -style->xthickness, -style->ythickness),
- option->state & State_Enabled ?
- GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, style, key);
-
- gtkPainter->paintShadow(gtkSpinButton, "entry", editArea, state, GTK_SHADOW_IN, d->gtk_widget_get_style(gtkSpinButton), key);
- if (spinBox->buttonSymbols != QAbstractSpinBox::NoButtons) {
- gtkPainter->paintBox(gtkSpinButton, "spinbutton", buttonRect, state, GTK_SHADOW_IN, style, key);
-
- upRect.setSize(downRect.size());
- if (!(option->state & State_Enabled))
- gtkPainter->paintBox(gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key);
- else if (upIsActive && sunken)
- gtkPainter->paintBox(gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key);
- else if (upIsActive && hover)
- gtkPainter->paintBox(gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key);
- else
- gtkPainter->paintBox(gtkSpinButton, "spinbutton_up", upRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key);
-
- if (!(option->state & State_Enabled))
- gtkPainter->paintBox(gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_INSENSITIVE, GTK_SHADOW_IN, style, key);
- else if (downIsActive && sunken)
- gtkPainter->paintBox(gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_ACTIVE, GTK_SHADOW_IN, style, key);
- else if (downIsActive && hover)
- gtkPainter->paintBox(gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style, key);
- else
- gtkPainter->paintBox(gtkSpinButton, "spinbutton_down", downRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style, key);
-
- if (option->state & State_HasFocus)
- QGtkStylePrivate::gtkWidgetSetFocus(gtkSpinButton, false);
- }
- }
-
- if (spinBox->buttonSymbols == QAbstractSpinBox::PlusMinus) {
- int centerX = upRect.center().x();
- int centerY = upRect.center().y();
- // plus/minus
-
- if (spinBox->activeSubControls == SC_SpinBoxUp && sunken) {
- painter->drawLine(1 + centerX - 2, 1 + centerY, 1 + centerX + 2, 1 + centerY);
- painter->drawLine(1 + centerX, 1 + centerY - 2, 1 + centerX, 1 + centerY + 2);
-
- } else {
- painter->drawLine(centerX - 2, centerY, centerX + 2, centerY);
- painter->drawLine(centerX, centerY - 2, centerX, centerY + 2);
- }
- centerX = downRect.center().x();
- centerY = downRect.center().y();
-
- if (spinBox->activeSubControls == SC_SpinBoxDown && sunken) {
- painter->drawLine(1 + centerX - 2, 1 + centerY, 1 + centerX + 2, 1 + centerY);
- } else {
- painter->drawLine(centerX - 2, centerY, centerX + 2, centerY);
- }
-
- } else if (spinBox->buttonSymbols == QAbstractSpinBox::UpDownArrows) {
- int size = d->getSpinboxArrowSize();
- int w = size / 2 - 1;
- w -= w % 2 - 1; // force odd
- int h = (w + 1)/2;
- QRect arrowRect(0, 0, w, h);
- arrowRect.moveCenter(upRect.center());
- // arrows
- GtkStateType state = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled) || !(spinBox->stepEnabled & QAbstractSpinBox::StepUpEnabled))
- state = GTK_STATE_INSENSITIVE;
-
- gtkPainter->paintArrow(gtkSpinButton, "spinbutton", arrowRect, GTK_ARROW_UP, state,
- GTK_SHADOW_NONE, false, style);
-
- arrowRect.moveCenter(downRect.center());
-
- if (!(option->state & State_Enabled) || !(spinBox->stepEnabled & QAbstractSpinBox::StepDownEnabled))
- state = GTK_STATE_INSENSITIVE;
-
- gtkPainter->paintArrow(gtkSpinButton, "spinbutton", arrowRect, GTK_ARROW_DOWN, state,
- GTK_SHADOW_NONE, false, style);
- }
- }
- break;
-
-#endif // QT_NO_SPINBOX
-
-#ifndef QT_NO_SLIDER
-
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- GtkWidget *hScaleWidget = d->gtkWidget("GtkHScale");
- GtkWidget *vScaleWidget = d->gtkWidget("GtkVScale");
-
- QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget);
- QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget);
-
- bool horizontal = slider->orientation == Qt::Horizontal;
- bool ticksAbove = slider->tickPosition & QSlider::TicksAbove;
- bool ticksBelow = slider->tickPosition & QSlider::TicksBelow;
-
- QBrush oldBrush = painter->brush();
- QPen oldPen = painter->pen();
-
- QColor shadowAlpha(Qt::black);
- shadowAlpha.setAlpha(10);
- QColor highlightAlpha(Qt::white);
- highlightAlpha.setAlpha(80);
-
- QGtkStylePrivate::gtk_widget_set_direction(hScaleWidget, slider->upsideDown ?
- GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- GtkWidget *scaleWidget = horizontal ? hScaleWidget : vScaleWidget;
- style = d->gtk_widget_get_style(scaleWidget);
-
- if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
-
- GtkRange *range = (GtkRange*)scaleWidget;
- GtkAdjustment *adjustment = 0;
- if (d->gtk_adjustment_configure)
- adjustment = d->gtk_range_get_adjustment(range);
- if (adjustment) {
- d->gtk_adjustment_configure(adjustment,
- slider->sliderPosition,
- slider->minimum,
- slider->maximum,
- slider->singleStep,
- slider->singleStep,
- slider->pageStep);
- } else {
- adjustment = (GtkAdjustment*)d->gtk_adjustment_new(slider->sliderPosition,
- slider->minimum,
- slider->maximum,
- slider->singleStep,
- slider->singleStep,
- slider->pageStep);
- d->gtk_range_set_adjustment(range, adjustment);
- }
-
- int outerSize;
- d->gtk_range_set_inverted(range, !horizontal);
- d->gtk_widget_style_get(scaleWidget, "trough-border", &outerSize, NULL);
- outerSize++;
-
- GtkStateType state = qt_gtk_state(option);
- int focusFrameMargin = 2;
- QRect grooveRect = option->rect.adjusted(focusFrameMargin, outerSize + focusFrameMargin,
- -focusFrameMargin, -outerSize - focusFrameMargin);
-
- gboolean trough_side_details = false; // Indicates if the upper or lower scale background differs
- if (!d->gtk_check_version(2, 10, 0))
- d->gtk_widget_style_get((GtkWidget*)(scaleWidget), "trough-side-details", &trough_side_details, NULL);
-
- if (!trough_side_details) {
- gtkPainter->paintBox(scaleWidget, "trough", grooveRect, state,
- GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
- } else {
- QRect upperGroove = grooveRect;
- QRect lowerGroove = grooveRect;
-
- if (horizontal) {
- if (slider->upsideDown) {
- lowerGroove.setLeft(handle.center().x());
- upperGroove.setRight(handle.center().x());
- } else {
- upperGroove.setLeft(handle.center().x());
- lowerGroove.setRight(handle.center().x());
- }
- } else {
- if (!slider->upsideDown) {
- lowerGroove.setBottom(handle.center().y());
- upperGroove.setTop(handle.center().y());
- } else {
- upperGroove.setBottom(handle.center().y());
- lowerGroove.setTop(handle.center().y());
- }
- }
-
- gtkPainter->paintBox(scaleWidget, "trough-upper", upperGroove, state,
- GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
- gtkPainter->paintBox(scaleWidget, "trough-lower", lowerGroove, state,
- GTK_SHADOW_IN, style, QString(QLS("p%0")).arg(slider->sliderPosition));
- }
- }
-
- if (option->subControls & SC_SliderTickmarks) {
- painter->setPen(darkOutline);
- int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
- int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, widget);
- int interval = slider->tickInterval;
-
- if (interval <= 0) {
- interval = slider->singleStep;
-
- if (QStyle::sliderPositionFromValue(slider->minimum, slider->maximum, interval,
- available)
- - QStyle::sliderPositionFromValue(slider->minimum, slider->maximum,
- 0, available) < 3)
- interval = slider->pageStep;
- }
-
- if (interval <= 0)
- interval = 1;
-
- int v = slider->minimum;
- int len = proxy()->pixelMetric(PM_SliderLength, slider, widget);
- while (v <= slider->maximum + 1) {
- if (v == slider->maximum + 1 && interval == 1)
- break;
- const int v_ = qMin(v, slider->maximum);
- int pos = sliderPositionFromValue(slider->minimum, slider->maximum,
- v_, (horizontal
- ? slider->rect.width()
- : slider->rect.height()) - len,
- slider->upsideDown) + len / 2;
- int extra = 2 - ((v_ == slider->minimum || v_ == slider->maximum) ? 1 : 0);
- if (horizontal) {
- if (ticksAbove)
- painter->drawLine(pos, slider->rect.top() + extra,
- pos, slider->rect.top() + tickSize);
- if (ticksBelow)
- painter->drawLine(pos, slider->rect.bottom() - extra,
- pos, slider->rect.bottom() - tickSize);
-
- } else {
- if (ticksAbove)
- painter->drawLine(slider->rect.left() + extra, pos,
- slider->rect.left() + tickSize, pos);
- if (ticksBelow)
- painter->drawLine(slider->rect.right() - extra, pos,
- slider->rect.right() - tickSize, pos);
- }
-
- // In the case where maximum is max int
- int nextInterval = v + interval;
- if (nextInterval < v)
- break;
- v = nextInterval;
- }
- }
-
- // Draw slider handle
- if (option->subControls & SC_SliderHandle) {
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = GTK_STATE_NORMAL;
-
- if (!(option->state & State_Enabled))
- state = GTK_STATE_INSENSITIVE;
- else if (option->state & State_MouseOver && option->activeSubControls & SC_SliderHandle)
- state = GTK_STATE_PRELIGHT;
-
- bool horizontal = option->state & State_Horizontal;
-
- if (slider->state & State_HasFocus) {
- QStyleOptionFocusRect fropt;
- fropt.QStyleOption::operator=(*slider);
- fropt.rect = slider->rect.adjusted(-1, -1 ,1, 1);
-
- if (horizontal) {
- fropt.rect.setTop(handle.top() - 3);
- fropt.rect.setBottom(handle.bottom() + 4);
-
- } else {
- fropt.rect.setLeft(handle.left() - 3);
- fropt.rect.setRight(handle.right() + 3);
- }
- proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
- }
- gtkPainter->paintSlider(scaleWidget, horizontal ? "hscale" : "vscale", handle, state, shadow, style,
- horizontal ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
- }
- painter->setBrush(oldBrush);
- painter->setPen(oldPen);
- }
- break;
- case CC_Dial:
- if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(option))
- QStyleHelper::drawDial(dial, painter);
- break;
-
-#endif // QT_NO_SLIDER
-
- default:
- QCommonStyle::drawComplexControl(control, option, painter, widget);
-
- break;
- }
-}
-
-
-/*!
- \reimp
-*/
-void QGtkStyle::drawControl(ControlElement element,
- const QStyleOption *option,
- QPainter *painter,
- const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable()) {
- QCommonStyle::drawControl(element, option, painter, widget);
- return;
- }
-
- GtkStyle* style = d->gtkStyle();
- QGtkPainter* gtkPainter = d->gtkPainter(painter);
-
- switch (element) {
- case CE_ProgressBarLabel:
- if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
- GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
- if (!gtkProgressBar)
- return;
-
- QRect leftRect;
- QRect rect = bar->rect;
- GtkStyle *gtkProgressBarStyle = d->gtk_widget_get_style(gtkProgressBar);
- GdkColor gdkText = gtkProgressBarStyle->fg[GTK_STATE_NORMAL];
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- gdkText = gtkProgressBarStyle->fg[GTK_STATE_PRELIGHT];
- QColor alternateTextColor= QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
-
- painter->save();
- bool vertical = false, inverted = false;
- if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
- vertical = (bar2->orientation == Qt::Vertical);
- inverted = bar2->invertedAppearance;
- }
- if (vertical)
- rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height
- const int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) * rect.width() /
- qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum);
- if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width())
- leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height());
- if (vertical)
- leftRect.translate(rect.width() - progressIndicatorPos, 0);
-
- bool flip = (!vertical && (((bar->direction == Qt::RightToLeft) && !inverted) ||
- ((bar->direction == Qt::LeftToRight) && inverted)));
-
- QRegion rightRect = rect;
- rightRect = rightRect.subtracted(leftRect);
- painter->setClipRegion(rightRect);
- painter->setPen(flip ? alternateTextColor : textColor);
- painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
- if (!leftRect.isNull()) {
- painter->setPen(flip ? textColor : alternateTextColor);
- painter->setClipRect(leftRect);
- painter->drawText(rect, bar->text, QTextOption(Qt::AlignAbsolute | Qt::AlignHCenter | Qt::AlignVCenter));
- }
- painter->restore();
- }
- break;
- case CE_PushButtonLabel:
- if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- QRect ir = button->rect;
- uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic;
- QPoint buttonShift;
-
- if (option->state & State_Sunken)
- buttonShift = QPoint(pixelMetric(PM_ButtonShiftHorizontal, option, widget),
- proxy()->pixelMetric(PM_ButtonShiftVertical, option, widget));
-
- if (proxy()->styleHint(SH_UnderlineShortcut, button, widget))
- tf |= Qt::TextShowMnemonic;
- else
- tf |= Qt::TextHideMnemonic;
-
- if (!button->icon.isNull()) {
- //Center both icon and text
- QPoint point;
-
- QIcon::Mode mode = button->state & State_Enabled ? QIcon::Normal : QIcon::Disabled;
- if (mode == QIcon::Normal && button->state & State_HasFocus)
- mode = QIcon::Active;
-
- QIcon::State state = QIcon::Off;
-
- if (button->state & State_On)
- state = QIcon::On;
-
- QPixmap pixmap = button->icon.pixmap(button->iconSize, mode, state);
- int w = pixmap.width();
- int h = pixmap.height();
-
- if (!button->text.isEmpty())
- w += button->fontMetrics.boundingRect(option->rect, tf, button->text).width() + 4;
-
- point = QPoint(ir.x() + ir.width() / 2 - w / 2,
- ir.y() + ir.height() / 2 - h / 2);
-
- if (button->direction == Qt::RightToLeft)
- point.rx() += pixmap.width();
-
- painter->drawPixmap(visualPos(button->direction, button->rect, point + buttonShift), pixmap);
-
- if (button->direction == Qt::RightToLeft)
- ir.translate(-point.x() - 2, 0);
- else
- ir.translate(point.x() + pixmap.width() + 2, 0);
-
- // left-align text if there is
- if (!button->text.isEmpty())
- tf |= Qt::AlignLeft;
-
- } else {
- tf |= Qt::AlignHCenter;
- }
-
- ir.translate(buttonShift);
-
- if (button->features & QStyleOptionButton::HasMenu)
- ir = ir.adjusted(0, 0, -pixelMetric(PM_MenuButtonIndicator, button, widget), 0);
-
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- QPalette pal = button->palette;
- int labelState = GTK_STATE_INSENSITIVE;
- if (option->state & State_Enabled)
- labelState = (option->state & State_MouseOver && !(option->state & State_Sunken)) ?
- GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
-
- GdkColor gdkText = d->gtk_widget_get_style(gtkButton)->fg[labelState];
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- pal.setBrush(QPalette::ButtonText, textColor);
- proxy()->drawItemText(painter, ir, tf, pal, (button->state & State_Enabled),
- button->text, QPalette::ButtonText);
- }
- break;
-
- case CE_RadioButton: // Fall through
- case CE_CheckBox:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- bool isRadio = (element == CE_RadioButton);
-
- // Draw prelight background
- GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton");
-
- if (option->state & State_MouseOver) {
- gtkPainter->paintFlatBox(gtkRadioButton, "checkbutton", option->rect,
- GTK_STATE_PRELIGHT, GTK_SHADOW_ETCHED_OUT, d->gtk_widget_get_style(gtkRadioButton));
- }
-
- QStyleOptionButton subopt = *btn;
- subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator
- : SE_CheckBoxIndicator, btn, widget);
- proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox,
- &subopt, painter, widget);
- subopt.rect = subElementRect(isRadio ? SE_RadioButtonContents
- : SE_CheckBoxContents, btn, widget);
- // Get label text color
- QPalette pal = subopt.palette;
- int labelState = GTK_STATE_INSENSITIVE;
- if (option->state & State_Enabled)
- labelState = (option->state & State_MouseOver) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
-
- GdkColor gdkText = d->gtk_widget_get_style(gtkRadioButton)->fg[labelState];
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- pal.setBrush(QPalette::WindowText, textColor);
- subopt.palette = pal;
- proxy()->drawControl(isRadio ? CE_RadioButtonLabel : CE_CheckBoxLabel, &subopt, painter, widget);
-
- if (btn->state & State_HasFocus) {
- QStyleOptionFocusRect fropt;
- fropt.QStyleOption::operator=(*btn);
- fropt.rect = subElementRect(isRadio ? SE_RadioButtonFocusRect
- : SE_CheckBoxFocusRect, btn, widget);
- proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
- }
- }
- break;
-
-#ifndef QT_NO_COMBOBOX
-
- case CE_ComboBoxLabel:
- if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- QRect editRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxEditField, widget);
- bool appearsAsList = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, cb, widget);
- painter->save();
- painter->setClipRect(editRect);
-
- if (!cb->currentIcon.isNull()) {
- QIcon::Mode mode = cb->state & State_Enabled ? QIcon::Normal
- : QIcon::Disabled;
- QPixmap pixmap = cb->currentIcon.pixmap(cb->iconSize, mode);
- QRect iconRect(editRect);
- iconRect.setWidth(cb->iconSize.width() + 4);
-
- iconRect = alignedRect(cb->direction,
- Qt::AlignLeft | Qt::AlignVCenter,
- iconRect.size(), editRect);
-
- if (cb->editable)
- painter->fillRect(iconRect, option->palette.brush(QPalette::Base));
-
- proxy()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, pixmap);
-
- if (cb->direction == Qt::RightToLeft)
- editRect.translate(-4 - cb->iconSize.width(), 0);
- else
- editRect.translate(cb->iconSize.width() + 4, 0);
- }
-
- if (!cb->currentText.isEmpty() && !cb->editable) {
- GtkWidget *gtkCombo = d->gtkWidget("GtkComboBox");
- QPalette pal = cb->palette;
- int labelState = GTK_STATE_INSENSITIVE;
-
- if (option->state & State_Enabled)
- labelState = (option->state & State_MouseOver && !appearsAsList) ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL;
-
- GdkColor gdkText = d->gtk_widget_get_style(gtkCombo)->fg[labelState];
-
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
-
- pal.setBrush(QPalette::ButtonText, textColor);
-
- proxy()->drawItemText(painter, editRect.adjusted(1, 0, -1, 0),
- visualAlignment(cb->direction, Qt::AlignLeft | Qt::AlignVCenter),
- pal, cb->state & State_Enabled, cb->currentText, QPalette::ButtonText);
- }
-
- painter->restore();
- }
- break;
-
-#endif // QT_NO_COMBOBOX
-
- case CE_DockWidgetTitle:
- painter->save();
- if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(option)) {
- const QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(dwOpt);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
-
- QRect rect = dwOpt->rect;
- QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, option, widget).adjusted(-2, 0, -2, 0);
- QRect r = rect.adjusted(0, 0, -1, -1);
- if (verticalTitleBar)
- r.adjust(0, 0, 0, -1);
-
- if (verticalTitleBar) {
- QRect r = rect;
- r.setSize(r.size().transposed());
-
- titleRect = QRect(r.left() + rect.bottom()
- - titleRect.bottom(),
- r.top() + titleRect.left() - rect.left(),
- titleRect.height(), titleRect.width());
-
- painter->translate(r.left(), r.top() + r.width());
- painter->rotate(-90);
- painter->translate(-r.left(), -r.top());
-
- rect = r;
- }
-
- if (!dwOpt->title.isEmpty()) {
- QString titleText
- = painter->fontMetrics().elidedText(dwOpt->title,
- Qt::ElideRight, titleRect.width());
- proxy()->drawItemText(painter,
- titleRect,
- Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette,
- dwOpt->state & State_Enabled, titleText,
- QPalette::WindowText);
- }
- }
- painter->restore();
- break;
-
-
-
- case CE_HeaderSection:
- painter->save();
-
- // Draws the header in tables.
- if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) {
- Q_UNUSED(header);
- GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView");
- // Get the middle column
- GtkTreeViewColumn *column = d->gtk_tree_view_get_column((GtkTreeView*)gtkTreeView, 1);
- Q_ASSERT(column);
-
- GtkWidget *gtkTreeHeader = column->button;
- GtkStateType state = qt_gtk_state(option);
- GtkShadowType shadow = GTK_SHADOW_OUT;
-
- if (option->state & State_Sunken)
- shadow = GTK_SHADOW_IN;
-
- gtkPainter->paintBox(gtkTreeHeader, "button", option->rect.adjusted(-1, 0, 0, 0), state, shadow, d->gtk_widget_get_style(gtkTreeHeader));
- }
-
- painter->restore();
- break;
-
-#ifndef QT_NO_SIZEGRIP
-
- case CE_SizeGrip: {
- GtkWidget *gtkStatusbar = d->gtkWidget("GtkStatusbar.GtkFrame");
- GtkStyle *gtkStatusbarStyle = d->gtk_widget_get_style(gtkStatusbar);
- QRect gripRect = option->rect.adjusted(0, 0, -gtkStatusbarStyle->xthickness, -gtkStatusbarStyle->ythickness);
- gtkPainter->paintResizeGrip(gtkStatusbar, "statusbar", gripRect, GTK_STATE_NORMAL,
- GTK_SHADOW_OUT, option->direction == Qt::RightToLeft ?
- GDK_WINDOW_EDGE_SOUTH_WEST : GDK_WINDOW_EDGE_SOUTH_EAST,
- gtkStatusbarStyle);
- }
- break;
-
-#endif // QT_NO_SIZEGRIP
-
- case CE_MenuBarEmptyArea: {
- GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
- GdkColor gdkBg = d->gtk_widget_get_style(gtkMenubar)->bg[GTK_STATE_NORMAL]; // Theme can depend on transparency
- painter->fillRect(option->rect, QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8));
- if (widget) { // See CE_MenuBarItem
- QRect menuBarRect = widget->rect();
- QPixmap pixmap(menuBarRect.size());
- pixmap.fill(Qt::transparent);
- QPainter pmPainter(&pixmap);
- gtkPainter->reset(&pmPainter);
- GtkShadowType shadow_type;
- d->gtk_widget_style_get(gtkMenubar, "shadow-type", &shadow_type, NULL);
- gtkPainter->paintBox(gtkMenubar, "menubar", menuBarRect,
- GTK_STATE_NORMAL, shadow_type, d->gtk_widget_get_style(gtkMenubar));
- pmPainter.end();
- painter->drawPixmap(option->rect, pixmap, option->rect);
- gtkPainter->reset(painter);
- }
- }
- break;
-
- case CE_MenuBarItem:
- painter->save();
-
- if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- GtkWidget *gtkMenubarItem = d->gtkWidget("GtkMenuBar.GtkMenuItem");
- GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar");
-
- style = d->gtk_widget_get_style(gtkMenubarItem);
-
- if (widget) {
- // Since Qt does not currently allow filling the entire background
- // we use a hack for this by making a complete menubar each time and
- // paint with the correct offset inside it. Pixmap caching should resolve
- // most of the performance penalty.
- QRect menuBarRect = widget->rect();
- QPixmap pixmap(menuBarRect.size());
- pixmap.fill(Qt::transparent);
- QPainter pmPainter(&pixmap);
- gtkPainter->reset(&pmPainter);
- GtkShadowType shadow_type;
- d->gtk_widget_style_get(gtkMenubar, "shadow-type", &shadow_type, NULL);
- GdkColor gdkBg = d->gtk_widget_get_style(gtkMenubar)->bg[GTK_STATE_NORMAL]; // Theme can depend on transparency
- painter->fillRect(option->rect, QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8));
- gtkPainter->paintBox(gtkMenubar, "menubar", menuBarRect,
- GTK_STATE_NORMAL, shadow_type, d->gtk_widget_get_style(gtkMenubar));
- pmPainter.end();
- painter->drawPixmap(option->rect, pixmap, option->rect);
- gtkPainter->reset(painter);
- }
-
- QStyleOptionMenuItem item = *mbi;
- bool act = mbi->state & State_Selected && mbi->state & State_Sunken;
- bool dis = !(mbi->state & State_Enabled);
- item.rect = mbi->rect;
- GdkColor gdkText = style->fg[dis ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL];
- GdkColor gdkHText = style->fg[GTK_STATE_PRELIGHT];
- QColor normalTextColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- QColor highlightedTextColor = QColor(gdkHText.red>>8, gdkHText.green>>8, gdkHText.blue>>8);
- item.palette.setBrush(QPalette::HighlightedText, highlightedTextColor);
- item.palette.setBrush(QPalette::Text, normalTextColor);
- item.palette.setBrush(QPalette::ButtonText, normalTextColor);
- QCommonStyle::drawControl(element, &item, painter, widget);
-
- if (act) {
- GtkShadowType shadowType = GTK_SHADOW_NONE;
- d->gtk_widget_style_get (gtkMenubarItem, "selected-shadow-type", &shadowType, NULL);
- gtkPainter->paintBox(gtkMenubarItem, "menuitem", option->rect.adjusted(0, 0, 0, 3),
- GTK_STATE_PRELIGHT, shadowType, style);
- //draw text
- QPalette::ColorRole textRole = dis ? QPalette::Text : QPalette::HighlightedText;
- uint alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
-
- if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
- alignment |= Qt::TextHideMnemonic;
-
- proxy()->drawItemText(painter, item.rect, alignment, item.palette, mbi->state & State_Enabled, mbi->text, textRole);
- }
- }
- painter->restore();
- break;
-
- case CE_Splitter: {
- GtkWidget *gtkWindow = d->gtkWidget("GtkWindow"); // The Murrine Engine currently assumes a widget is passed
- gtkPainter->paintHandle(gtkWindow, "splitter", option->rect, qt_gtk_state(option), GTK_SHADOW_NONE,
- !(option->state & State_Horizontal) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL,
- style);
- }
- break;
-
-#ifndef QT_NO_TOOLBAR
-
- case CE_ToolBar:
- if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) {
- // Reserve the beveled appearance only for mainwindow toolbars
- if (!(widget && qobject_cast<const QMainWindow*> (widget->parentWidget())))
- break;
-
- QRect rect = option->rect;
- // There is a 1 pixel gap between toolbar lines in some styles (i.e Human)
- if (toolbar->positionWithinLine != QStyleOptionToolBar::End)
- rect.adjust(0, 0, 1, 0);
-
- GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar");
- GtkShadowType shadow_type = GTK_SHADOW_NONE;
- d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL);
- gtkPainter->paintBox(gtkToolbar, "toolbar", rect,
- GTK_STATE_NORMAL, shadow_type, d->gtk_widget_get_style(gtkToolbar));
- }
- break;
-
-#endif // QT_NO_TOOLBAR
-
- case CE_MenuItem:
- painter->save();
-
- // Draws one item in a popup menu.
- if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- const int windowsItemHMargin = 3; // menu item hor text margin
- const int windowsItemVMargin = 26; // menu item ver text margin
- GtkWidget *gtkMenuItem = menuItem->checked ? d->gtkWidget("GtkMenu.GtkCheckMenuItem") :
- d->gtkWidget("GtkMenu.GtkMenuItem");
-
- style = d->gtk_widget_get_style(gtkMenuItem);
- QColor shadow = option->palette.dark().color();
-
- if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
- GtkWidget *gtkMenuSeparator = d->gtkWidget("GtkMenu.GtkSeparatorMenuItem");
- painter->setPen(shadow.lighter(106));
- gboolean wide_separators = 0;
- gint separator_height = 0;
- guint horizontal_padding = 3;
- QRect separatorRect = option->rect;
- if (!d->gtk_check_version(2, 10, 0)) {
- d->gtk_widget_style_get(gtkMenuSeparator,
- "wide-separators", &wide_separators,
- "separator-height", &separator_height,
- "horizontal-padding", &horizontal_padding,
- NULL);
- }
- GtkStyle *gtkMenuSeparatorStyle = d->gtk_widget_get_style(gtkMenuSeparator);
- separatorRect.setHeight(option->rect.height() - 2 * gtkMenuSeparatorStyle->ythickness);
- separatorRect.setWidth(option->rect.width() - 2 * (horizontal_padding + gtkMenuSeparatorStyle->xthickness));
- separatorRect.moveCenter(option->rect.center());
- if (wide_separators)
- gtkPainter->paintBox(gtkMenuSeparator, "hseparator",
- separatorRect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, gtkMenuSeparatorStyle);
- else
- gtkPainter->paintHline(gtkMenuSeparator, "hseparator",
- separatorRect, GTK_STATE_NORMAL, gtkMenuSeparatorStyle,
- 0, option->rect.right() - 1, 1);
- painter->restore();
- break;
- }
-
- bool selected = menuItem->state & State_Selected && menuItem->state & State_Enabled;
-
- if (selected) {
- QRect rect = option->rect;
-#ifndef QT_NO_COMBOBOX
- if (qobject_cast<const QComboBox*>(widget))
- rect = option->rect;
-#endif
- gtkPainter->paintBox(gtkMenuItem, "menuitem", rect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style);
- }
-
- bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable;
- bool checked = menuItem->checked;
- bool enabled = menuItem->state & State_Enabled;
- bool ignoreCheckMark = false;
-
- gint checkSize;
- d->gtk_widget_style_get(d->gtkWidget("GtkMenu.GtkCheckMenuItem"), "indicator-size", &checkSize, NULL);
-
- int checkcol = qMax(menuItem->maxIconWidth, qMax(20, checkSize));
-
-#ifndef QT_NO_COMBOBOX
-
- if (qobject_cast<const QComboBox*>(widget) ||
- (option->styleObject && option->styleObject->property("_q_isComboBoxPopupItem").toBool()))
- ignoreCheckMark = true; // Ignore the checkmarks provided by the QComboMenuDelegate
-
-#endif
- if (!ignoreCheckMark) {
- // Check
- QRect checkRect(option->rect.left() + 7, option->rect.center().y() - checkSize/2 + 1, checkSize, checkSize);
- checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
-
- if (checkable && menuItem->icon.isNull()) {
- // Some themes such as aero-clone draw slightly outside the paint rect
- int spacing = 1; // ### Consider using gtkCheckBox : "indicator-spacing" instead
-
- if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
- // Radio button
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = qt_gtk_state(option);
-
- if (selected)
- state = GTK_STATE_PRELIGHT;
- if (checked)
- shadow = GTK_SHADOW_IN;
-
- gtkPainter->setClipRect(checkRect.adjusted(-spacing, -spacing, spacing, spacing));
- gtkPainter->paintOption(gtkMenuItem, checkRect.translated(-spacing, -spacing), state, shadow,
- style, QLS("option"));
- gtkPainter->setClipRect(QRect());
-
- } else {
- // Check box
- if (menuItem->icon.isNull()) {
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = qt_gtk_state(option);
-
- if (selected)
- state = GTK_STATE_PRELIGHT;
- if (checked)
- shadow = GTK_SHADOW_IN;
-
- gtkPainter->setClipRect(checkRect.adjusted(-spacing, -spacing, -spacing, -spacing));
- gtkPainter->paintCheckbox(gtkMenuItem, checkRect.translated(-spacing, -spacing), state, shadow,
- style, QLS("check"));
- gtkPainter->setClipRect(QRect());
- }
- }
- }
-
- } else {
- // Ignore checkmark
- if (menuItem->icon.isNull())
- checkcol = 0;
- else
- checkcol = menuItem->maxIconWidth;
- }
-
- bool dis = !(menuItem->state & State_Enabled);
- bool act = menuItem->state & State_Selected;
- const QStyleOption *opt = option;
- const QStyleOptionMenuItem *menuitem = menuItem;
- QPainter *p = painter;
- QRect vCheckRect = visualRect(opt->direction, menuitem->rect,
- QRect(menuitem->rect.x() + 3, menuitem->rect.y(),
- checkcol, menuitem->rect.height()));
-
- if (!menuItem->icon.isNull()) {
- QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal;
-
- if (act && !dis)
- mode = QIcon::Active;
-
- QPixmap pixmap;
- int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize, option, widget);
- QSize iconSize(smallIconSize, smallIconSize);
-
-#ifndef QT_NO_COMBOBOX
- if (const QComboBox *combo = qobject_cast<const QComboBox*>(widget))
- iconSize = combo->iconSize();
-
-#endif // QT_NO_COMBOBOX
- if (checked)
- pixmap = menuItem->icon.pixmap(iconSize, mode, QIcon::On);
- else
- pixmap = menuItem->icon.pixmap(iconSize, mode);
-
- const int pixw = pixmap.width() / pixmap.devicePixelRatio();
- const int pixh = pixmap.height() / pixmap.devicePixelRatio();
- QRect pmr(0, 0, pixw, pixh);
- pmr.moveCenter(vCheckRect.center() - QPoint(0, 1));
- painter->setPen(menuItem->palette.text().color());
- if (!ignoreCheckMark && checkable && checked) {
- QStyleOption opt = *option;
-
- if (act) {
- QColor activeColor = mergedColors(option->palette.background().color(),
- option->palette.highlight().color());
- opt.palette.setBrush(QPalette::Button, activeColor);
- }
- opt.state |= State_Sunken;
- opt.rect = vCheckRect;
- proxy()->drawPrimitive(PE_PanelButtonCommand, &opt, painter, widget);
- }
- painter->drawPixmap(pmr.topLeft(), pixmap);
- }
-
- GdkColor gdkText = style->fg[GTK_STATE_NORMAL];
- GdkColor gdkDText = style->fg[GTK_STATE_INSENSITIVE];
- GdkColor gdkHText = style->fg[GTK_STATE_PRELIGHT];
- uint resolve_mask = option->palette.resolve();
- QColor textColor = QColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- QColor disabledTextColor = QColor(gdkDText.red>>8, gdkDText.green>>8, gdkDText.blue>>8);
- if (resolve_mask & (1 << QPalette::ButtonText)) {
- textColor = option->palette.buttonText().color();
- disabledTextColor = option->palette.brush(QPalette::Disabled, QPalette::ButtonText).color();
- }
-
- QColor highlightedTextColor = QColor(gdkHText.red>>8, gdkHText.green>>8, gdkHText.blue>>8);
- if (resolve_mask & (1 << QPalette::HighlightedText)) {
- highlightedTextColor = option->palette.highlightedText().color();
- }
-
- if (selected)
- painter->setPen(highlightedTextColor);
- else
- painter->setPen(textColor);
-
- int x, y, w, h;
- menuitem->rect.getRect(&x, &y, &w, &h);
- int tab = menuitem->tabWidth;
- int xm = QGtkStylePrivate::menuItemFrame + checkcol + windowsItemHMargin;
- int xpos = menuitem->rect.x() + xm + 1;
- QRect textRect(xpos, y + windowsItemVMargin, w - xm - QGtkStylePrivate::menuRightBorder - tab + 1, h - 2 * windowsItemVMargin);
- QRect vTextRect = visualRect(opt->direction, menuitem->rect, textRect);
- QString s = menuitem->text;
-
- if (!s.isEmpty()) { // Draw text
- p->save();
- int t = s.indexOf(QLatin1Char('\t'));
- int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine;
-
- if (!proxy()->styleHint(SH_UnderlineShortcut, menuitem, widget))
- text_flags |= Qt::TextHideMnemonic;
-
- // Draw shortcut right aligned
- text_flags |= Qt::AlignRight;
-
- if (t >= 0) {
- int rightMargin = 12; // Hardcode for now
- QRect vShortcutRect = visualRect(opt->direction, menuitem->rect,
- QRect(textRect.topRight(), QPoint(menuitem->rect.right() - rightMargin, textRect.bottom())));
-
- if (dis)
- p->setPen(disabledTextColor);
- p->drawText(vShortcutRect, text_flags , s.mid(t + 1));
- s = s.left(t);
- }
-
- text_flags &= ~Qt::AlignRight;
- text_flags |= Qt::AlignLeft;
- QFont font = menuitem->font;
- if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
- font.setBold(true);
- p->setFont(font);
-
- if (dis)
- p->setPen(disabledTextColor);
- p->drawText(vTextRect, text_flags, s.left(t));
- p->restore();
- }
-
- // Arrow
- if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow
-
- QFontMetrics fm(menuitem->font);
- int arrow_size = fm.ascent() + fm.descent() - 2 * style->ythickness;
- gfloat arrow_scaling = 0.8;
- int extra = 0;
- if (!d->gtk_check_version(2, 16, 0)) {
- // "arrow-scaling" is actually hardcoded and fails on hardy (see gtk+-2.12/gtkmenuitem.c)
- // though the current documentation states otherwise
- d->gtk_widget_style_get(gtkMenuItem, "arrow-scaling", &arrow_scaling, NULL);
- // in versions < 2.16 ythickness was previously subtracted from the arrow_size
- extra = 2 * style->ythickness;
- }
-
- int horizontal_padding;
- d->gtk_widget_style_get(gtkMenuItem, "horizontal-padding", &horizontal_padding, NULL);
-
- const int dim = static_cast<int>(arrow_size * arrow_scaling) + extra;
- int xpos = menuItem->rect.left() + menuItem->rect.width() - horizontal_padding - dim;
- QRect vSubMenuRect = visualRect(option->direction, menuItem->rect,
- QRect(xpos, menuItem->rect.top() +
- menuItem->rect.height() / 2 - dim / 2, dim, dim));
- GtkStateType state = enabled ? (act ? GTK_STATE_PRELIGHT: GTK_STATE_NORMAL) : GTK_STATE_INSENSITIVE;
- GtkShadowType shadowType = (state == GTK_STATE_PRELIGHT) ? GTK_SHADOW_OUT : GTK_SHADOW_IN;
- gtkPainter->paintArrow(gtkMenuItem, "menuitem", vSubMenuRect, option->direction == Qt::RightToLeft ? GTK_ARROW_LEFT : GTK_ARROW_RIGHT, state,
- shadowType, false, style);
- }
- }
- painter->restore();
- break;
-
- case CE_PushButton:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget);
- QStyleOptionButton subopt = *btn;
- subopt.rect = subElementRect(SE_PushButtonContents, btn, widget);
- gint interiorFocus = true;
- d->gtk_widget_style_get(gtkButton, "interior-focus", &interiorFocus, NULL);
- GtkStyle *gtkButtonStyle = d->gtk_widget_get_style(gtkButton);
- int xt = interiorFocus ? gtkButtonStyle->xthickness : 0;
- int yt = interiorFocus ? gtkButtonStyle->ythickness : 0;
-
- if (btn->features & QStyleOptionButton::Flat && btn->state & State_HasFocus)
- // The normal button focus rect does not work well for flat buttons in Clearlooks
- proxy()->drawPrimitive(PE_FrameFocusRect, option, painter, widget);
- else if (btn->state & State_HasFocus)
- gtkPainter->paintFocus(gtkButton, "button",
- option->rect.adjusted(xt, yt, -xt, -yt),
- btn->state & State_Sunken ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
- gtkButtonStyle);
-
- proxy()->drawControl(CE_PushButtonLabel, &subopt, painter, widget);
- }
- break;
-
-#ifndef QT_NO_TABBAR
-
- case CE_TabBarTabShape:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
- GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook");
- style = d->gtk_widget_get_style(gtkNotebook);
-
- QRect rect = option->rect;
- GtkShadowType shadow = GTK_SHADOW_OUT;
- GtkStateType state = GTK_STATE_ACTIVE;
- if (tab->state & State_Selected)
- state = GTK_STATE_NORMAL;
-
- bool selected = (tab->state & State_Selected);
- bool first = false, last = false;
- if (widget) {
- // This is most accurate and avoids resizing tabs while moving
- first = tab->rect.left() == widget->rect().left();
- last = tab->rect.right() == widget->rect().right();
- } else if (option->direction == Qt::RightToLeft) {
- bool tmp = first;
- first = last;
- last = tmp;
- }
- int topIndent = 3;
- int bottomIndent = 1;
- int tabOverlap = 1;
- painter->save();
-
- switch (tab->shape) {
- case QTabBar::RoundedNorth:
- if (!selected)
- rect.adjust(first ? 0 : -tabOverlap, topIndent, last ? 0 : tabOverlap, -bottomIndent);
- gtkPainter->paintExtention(gtkNotebook, "tab", rect,
- state, shadow, GTK_POS_BOTTOM, style);
- break;
-
- case QTabBar::RoundedSouth:
- if (!selected)
- rect.adjust(first ? 0 : -tabOverlap, 0, last ? 0 : tabOverlap, -topIndent);
- gtkPainter->paintExtention(gtkNotebook, "tab", rect.adjusted(0, 1, 0, 0),
- state, shadow, GTK_POS_TOP, style);
- break;
-
- case QTabBar::RoundedWest:
- if (!selected)
- rect.adjust(topIndent, 0, -bottomIndent, 0);
- gtkPainter->paintExtention(gtkNotebook, "tab", rect, state, shadow, GTK_POS_RIGHT, style);
- break;
-
- case QTabBar::RoundedEast:
- if (!selected)
- rect.adjust(bottomIndent, 0, -topIndent, 0);
- gtkPainter->paintExtention(gtkNotebook, "tab", rect, state, shadow, GTK_POS_LEFT, style);
- break;
-
- default:
- QCommonStyle::drawControl(element, option, painter, widget);
- break;
- }
-
- painter->restore();
- }
-
- break;
-
-#endif //QT_NO_TABBAR
-
- case CE_ProgressBarGroove:
- if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
- Q_UNUSED(bar);
- GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
- GtkStateType state = qt_gtk_state(option);
- gtkPainter->paintBox(gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, d->gtk_widget_get_style(gtkProgressBar));
- }
-
- break;
-
- case CE_ProgressBarContents:
- if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
- GtkStateType state = option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE;
- GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar");
- style = d->gtk_widget_get_style(gtkProgressBar);
- gtkPainter->paintBox(gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, style);
- int xt = style->xthickness;
- int yt = style->ythickness;
- QRect rect = bar->rect.adjusted(xt, yt, -xt, -yt);
- bool vertical = false;
- bool inverted = false;
- bool indeterminate = (bar->minimum == 0 && bar->maximum == 0);
- // Get extra style options if version 2
-
- if (const QStyleOptionProgressBarV2 *bar2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) {
- vertical = (bar2->orientation == Qt::Vertical);
- inverted = bar2->invertedAppearance;
- }
-
- // If the orientation is vertical, we use a transform to rotate
- // the progress bar 90 degrees clockwise. This way we can use the
- // same rendering code for both orientations.
- if (vertical) {
- rect.translate(xt, -yt * 2);
- rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // Flip width and height
- QTransform m = QTransform::fromTranslate(rect.height(), 0);
- m.rotate(90.0);
- painter->setTransform(m);
- }
-
- int maxWidth = rect.width();
- int minWidth = 4;
-
- qint64 progress = (qint64)qMax(bar->progress, bar->minimum); // Workaround for bug in QProgressBar
- double vc6_workaround = ((progress - qint64(bar->minimum)) / double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth;
- int progressBarWidth = (int(vc6_workaround) > minWidth ) ? int(vc6_workaround) : minWidth;
- int width = indeterminate ? maxWidth : progressBarWidth;
- bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical;
-
- if (inverted)
- reverse = !reverse;
-
- int maximum = 2;
- int fakePos = 0;
- if (bar->minimum == bar->maximum)
- maximum = 0;
- if (bar->progress == bar->maximum)
- fakePos = maximum;
- else if (bar->progress > bar->minimum)
- fakePos = maximum - 1;
-
- QRect progressBar;
-
- if (!indeterminate) {
- if (!reverse)
- progressBar.setRect(rect.left(), rect.top(), width, rect.height());
- else
- progressBar.setRect(rect.right() - width, rect.top(), width, rect.height());
-#ifndef QT_NO_ANIMATION
- d->stopAnimation(option->styleObject);
-#endif
- } else {
- Q_D(const QGtkStyle);
- int slideWidth = ((rect.width() - 4) * 2) / 3;
- int step = 0;
-#ifndef QT_NO_ANIMATION
- if (QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(option->styleObject)))
- step = animation->progressStep(slideWidth);
- else
- d->startAnimation(new QProgressStyleAnimation(d->animationFps, option->styleObject));
-#endif
- progressBar.setRect(rect.left() + step, rect.top(), slideWidth / 2, rect.height());
- }
-
- QString key = QString(QLS("%0")).arg(fakePos);
- if (inverted) {
- key += QLatin1String("inv");
- gtkPainter->setFlipHorizontal(true);
- }
- gtkPainter->paintBox(gtkProgressBar, "bar", progressBar, GTK_STATE_SELECTED, GTK_SHADOW_OUT, style, key);
- }
-
- break;
-
- default:
- QCommonStyle::drawControl(element, option, painter, widget);
- }
-}
-
-/*!
- \reimp
-*/
-QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
- SubControl subControl, const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- QRect rect = QCommonStyle::subControlRect(control, option, subControl, widget);
- if (!d->isThemeAvailable())
- return QCommonStyle::subControlRect(control, option, subControl, widget);
-
- switch (control) {
- case CC_ScrollBar:
- break;
- case CC_Slider:
- if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
- int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, option, widget);
- switch (subControl) {
- case SC_SliderHandle: {
- if (slider->orientation == Qt::Horizontal) {
- rect.setHeight(proxy()->pixelMetric(PM_SliderThickness));
- rect.setWidth(proxy()->pixelMetric(PM_SliderLength));
- int centerY = slider->rect.center().y() - rect.height() / 2;
- if (slider->tickPosition & QSlider::TicksAbove)
- centerY += tickSize;
- if (slider->tickPosition & QSlider::TicksBelow)
- centerY -= tickSize;
- rect.moveTop(centerY);
- } else {
- rect.setWidth(proxy()->pixelMetric(PM_SliderThickness));
- rect.setHeight(proxy()->pixelMetric(PM_SliderLength));
- int centerX = slider->rect.center().x() - rect.width() / 2;
- if (slider->tickPosition & QSlider::TicksAbove)
- centerX += tickSize;
- if (slider->tickPosition & QSlider::TicksBelow)
- centerX -= tickSize;
- rect.moveLeft(centerX);
- }
- }
- break;
- case SC_SliderGroove: {
- QPoint grooveCenter = slider->rect.center();
- if (slider->orientation == Qt::Horizontal) {
- rect.setHeight(7);
- if (slider->tickPosition & QSlider::TicksAbove)
- grooveCenter.ry() += tickSize;
- if (slider->tickPosition & QSlider::TicksBelow)
- grooveCenter.ry() -= tickSize;
- } else {
- rect.setWidth(7);
- if (slider->tickPosition & QSlider::TicksAbove)
- grooveCenter.rx() += tickSize;
- if (slider->tickPosition & QSlider::TicksBelow)
- grooveCenter.rx() -= tickSize;
- }
- rect.moveCenter(grooveCenter);
- break;
- }
- default:
- break;
- }
- }
- break;
-
-#ifndef QT_NO_GROUPBOX
-
- case CC_GroupBox:
- if (const QStyleOptionGroupBox * groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
- rect = option->rect.adjusted(0, groupBoxTopMargin, 0, -groupBoxBottomMargin);
- int topMargin = 0;
- int topHeight = 0;
- topHeight = 10;
- QRect frameRect = rect;
- frameRect.setTop(topMargin);
-
- if (subControl == SC_GroupBoxFrame)
- return rect;
- else if (subControl == SC_GroupBoxContents) {
- int margin = 0;
- int leftMarginExtension = 8;
- return frameRect.adjusted(leftMarginExtension + margin, margin + topHeight + groupBoxTitleMargin, -margin, -margin);
- }
-
- QFontMetrics fontMetrics = option->fontMetrics;
- if (qobject_cast<const QGroupBox *>(widget)) {
- //Prepare metrics for a bold font
- QFont font = widget->font();
- font.setBold(true);
- fontMetrics = QFontMetrics(font);
-#ifndef QT_NO_ACCESSIBILITY
- } else if (QStyleHelper::isInstanceOf(groupBox->styleObject, QAccessible::Grouping)) {
- QVariant var = groupBox->styleObject->property("font");
- if (var.isValid() && var.canConvert<QFont>()) {
- QFont font = var.value<QFont>();
- font.setBold(true);
- fontMetrics = QFontMetrics(font);
- }
-#endif // QT_NO_ACCESSIBILITY
- }
-
- QSize textRect = fontMetrics.boundingRect(groupBox->text).size() + QSize(4, 4);
- int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
- int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
-
- if (subControl == SC_GroupBoxCheckBox) {
- rect.setWidth(indicatorWidth);
- rect.setHeight(indicatorHeight);
- rect.moveTop((textRect.height() - indicatorHeight) / 2);
-
- } else if (subControl == SC_GroupBoxLabel) {
- if (groupBox->subControls & SC_GroupBoxCheckBox)
- rect.adjust(indicatorWidth + 4, 0, 0, 0);
- rect.setSize(textRect);
- }
- rect = visualRect(option->direction, option->rect, rect);
- }
-
- return rect;
-
-#endif
-#ifndef QT_NO_SPINBOX
-
- case CC_SpinBox:
- if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) {
- GtkWidget *gtkSpinButton = d->gtkWidget("GtkSpinButton");
- int center = spinbox->rect.height() / 2;
- GtkStyle *gtkSpinButtonStyle = d->gtk_widget_get_style(gtkSpinButton);
- int xt = spinbox->frame ? gtkSpinButtonStyle->xthickness : 0;
- int yt = spinbox->frame ? gtkSpinButtonStyle->ythickness : 0;
- int y = yt;
-
- QSize bs;
- bs.setHeight(qMax(8, spinbox->rect.height()/2 - y));
- bs.setWidth(d->getSpinboxArrowSize());
- int x, lx, rx;
- x = spinbox->rect.width() - y - bs.width() + 2;
- lx = xt;
- rx = x - xt;
-
- switch (subControl) {
-
- case SC_SpinBoxUp:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
- return QRect();
- rect = QRect(x, xt, bs.width(), center - yt);
- break;
-
- case SC_SpinBoxDown:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
- return QRect();
- rect = QRect(x, center, bs.width(), spinbox->rect.bottom() - center - yt + 1);
- break;
-
- case SC_SpinBoxEditField:
- if (spinbox->buttonSymbols == QAbstractSpinBox::NoButtons)
- rect = QRect(lx, yt, spinbox->rect.width() - 2*xt, spinbox->rect.height() - 2*yt);
- else
- rect = QRect(lx, yt, rx - qMax(xt - 1, 0), spinbox->rect.height() - 2*yt);
- break;
-
- case SC_SpinBoxFrame:
- rect = spinbox->rect;
-
- default:
- break;
- }
-
- rect = visualRect(spinbox->direction, spinbox->rect, rect);
- }
-
- break;
-
-#endif // Qt_NO_SPINBOX
-#ifndef QT_NO_COMBOBOX
-
- case CC_TitleBar:
- if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(option)) {
- SubControl sc = subControl;
- QRect &ret = rect;
- const int indent = 3;
- const int controlTopMargin = 3;
- const int controlBottomMargin = 3;
- const int controlWidthMargin = 2;
- const int controlHeight = tb->rect.height() - controlTopMargin - controlBottomMargin ;
- const int delta = controlHeight + controlWidthMargin;
- int offset = 0;
-
- bool isMinimized = tb->titleBarState & Qt::WindowMinimized;
- bool isMaximized = tb->titleBarState & Qt::WindowMaximized;
-
- switch (sc) {
- case SC_TitleBarLabel:
- if (tb->titleBarFlags & (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)) {
- ret = tb->rect;
- if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
- ret.adjust(delta, 0, -delta, 0);
- if (tb->titleBarFlags & Qt::WindowMinimizeButtonHint)
- ret.adjust(0, 0, -delta, 0);
- if (tb->titleBarFlags & Qt::WindowMaximizeButtonHint)
- ret.adjust(0, 0, -delta, 0);
- if (tb->titleBarFlags & Qt::WindowShadeButtonHint)
- ret.adjust(0, 0, -delta, 0);
- if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
- ret.adjust(0, 0, -delta, 0);
- }
- break;
- case SC_TitleBarContextHelpButton:
- if (tb->titleBarFlags & Qt::WindowContextHelpButtonHint)
- offset += delta;
- case SC_TitleBarMinButton:
- if (!isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
- offset += delta;
- else if (sc == SC_TitleBarMinButton)
- break;
- case SC_TitleBarNormalButton:
- if (isMinimized && (tb->titleBarFlags & Qt::WindowMinimizeButtonHint))
- offset += delta;
- else if (isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
- offset += delta;
- else if (sc == SC_TitleBarNormalButton)
- break;
- case SC_TitleBarMaxButton:
- if (!isMaximized && (tb->titleBarFlags & Qt::WindowMaximizeButtonHint))
- offset += delta;
- else if (sc == SC_TitleBarMaxButton)
- break;
- case SC_TitleBarShadeButton:
- if (!isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
- offset += delta;
- else if (sc == SC_TitleBarShadeButton)
- break;
- case SC_TitleBarUnshadeButton:
- if (isMinimized && (tb->titleBarFlags & Qt::WindowShadeButtonHint))
- offset += delta;
- else if (sc == SC_TitleBarUnshadeButton)
- break;
- case SC_TitleBarCloseButton:
- if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
- offset += delta;
- else if (sc == SC_TitleBarCloseButton)
- break;
- ret.setRect(tb->rect.right() - indent - offset, tb->rect.top() + controlTopMargin,
- controlHeight, controlHeight);
- break;
- case SC_TitleBarSysMenu:
- if (tb->titleBarFlags & Qt::WindowSystemMenuHint) {
- ret.setRect(tb->rect.left() + controlWidthMargin + indent, tb->rect.top() + controlTopMargin,
- controlHeight, controlHeight);
- }
- break;
- default:
- break;
- }
- ret = visualRect(tb->direction, tb->rect, ret);
- }
- break;
- case CC_ComboBox:
- if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- // We employ the gtk widget to position arrows and separators for us
- GtkWidget *gtkCombo = box->editable ? d->gtkWidget("GtkComboBoxEntry")
- : d->gtkWidget("GtkComboBox");
- d->gtk_widget_set_direction(gtkCombo, (option->direction == Qt::RightToLeft) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
- GtkAllocation geometry = {0, 0, qMax(0, option->rect.width()), qMax(0, option->rect.height())};
- d->gtk_widget_size_allocate(gtkCombo, &geometry);
- int appears_as_list = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, option, widget);
- QHashableLatin1Literal arrowPath("GtkComboBoxEntry.GtkToggleButton");
- if (!box->editable) {
- if (appears_as_list)
- arrowPath = "GtkComboBox.GtkToggleButton";
- else
- arrowPath = "GtkComboBox.GtkToggleButton.GtkHBox.GtkArrow";
- }
-
- GtkWidget *arrowWidget = d->gtkWidget(arrowPath);
- if (!arrowWidget)
- return QCommonStyle::subControlRect(control, option, subControl, widget);
-
- GtkAllocation allocation;
- d->gtk_widget_get_allocation(arrowWidget, &allocation);
- QRect buttonRect(option->rect.left() + allocation.x,
- option->rect.top() + allocation.y,
- allocation.width, allocation.height);
-
- switch (subControl) {
-
- case SC_ComboBoxArrow: // Note: this indicates the arrowbutton for editable combos
- rect = buttonRect;
- break;
-
- case SC_ComboBoxEditField: {
- rect = visualRect(option->direction, option->rect, rect);
- int xMargin = box->editable ? 1 : 4, yMargin = 2;
- GtkStyle *gtkComboStyle = d->gtk_widget_get_style(gtkCombo);
- rect.setRect(option->rect.left() + gtkComboStyle->xthickness + xMargin,
- option->rect.top() + gtkComboStyle->ythickness + yMargin,
- option->rect.width() - buttonRect.width() - 2*(gtkComboStyle->xthickness + xMargin),
- option->rect.height() - 2*(gtkComboStyle->ythickness + yMargin));
- rect = visualRect(option->direction, option->rect, rect);
- break;
- }
-
- default:
- break;
- }
- }
-
- break;
-#endif // QT_NO_COMBOBOX
-
- default:
- break;
- }
-
- return rect;
-}
-
-/*!
- \reimp
-*/
-QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- QSize newSize = QCommonStyle::sizeFromContents(type, option, size, widget);
- if (!d->isThemeAvailable())
- return newSize;
-
- switch (type) {
- case CT_GroupBox:
- // Since we use a bold font we have to recalculate base width
- if (const QGroupBox *gb = qobject_cast<const QGroupBox*>(widget)) {
- QFont font = gb->font();
- font.setBold(true);
- QFontMetrics metrics(font);
- int baseWidth = metrics.width(gb->title()) + metrics.width(QLatin1Char(' '));
- if (gb->isCheckable()) {
- baseWidth += proxy()->pixelMetric(QStyle::PM_IndicatorWidth, option, widget);
- baseWidth += proxy()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, option, widget);
- }
- newSize.setWidth(qMax(baseWidth, newSize.width()));
- }
- newSize += QSize(4, 1 + groupBoxBottomMargin + groupBoxTopMargin + groupBoxTitleMargin); // Add some space below the groupbox
- break;
- case CT_ToolButton:
- if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) {
- GtkWidget *gtkButton = d->gtkWidget("GtkToolButton.GtkButton");
- GtkStyle *gtkButtonStyle = d->gtk_widget_get_style(gtkButton);
- newSize = size + QSize(2 * gtkButtonStyle->xthickness, 2 + 2 * gtkButtonStyle->ythickness);
- if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
- QSize minSize(0, 25);
- if (toolbutton->toolButtonStyle != Qt::ToolButtonTextOnly)
- minSize = toolbutton->iconSize + QSize(12, 12);
- newSize = newSize.expandedTo(minSize);
- }
-
- if (toolbutton->features & QStyleOptionToolButton::HasMenu)
- newSize += QSize(6, 0);
- }
- break;
- case CT_SpinBox:
- // QSpinBox does some nasty things that depends on CT_LineEdit
- newSize = newSize + QSize(0, -d->gtk_widget_get_style(d->gtkWidget("GtkSpinButton"))->ythickness * 2);
- break;
- case CT_RadioButton:
- case CT_CheckBox:
- newSize += QSize(0, 1);
- break;
- case CT_PushButton:
- if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- if (!btn->icon.isNull() && btn->iconSize.height() > 16)
- newSize -= QSize(0, 2); // From cleanlooksstyle
- newSize += QSize(0, 1);
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- gint focusPadding, focusWidth;
- d->gtk_widget_style_get(gtkButton, "focus-padding", &focusPadding, NULL);
- d->gtk_widget_style_get(gtkButton, "focus-line-width", &focusWidth, NULL);
- newSize = size;
- GtkStyle *gtkButtonStyle = d->gtk_widget_get_style(gtkButton);
- newSize += QSize(2*gtkButtonStyle->xthickness + 4, 2*gtkButtonStyle->ythickness);
- newSize += QSize(2*(focusWidth + focusPadding + 2), 2*(focusWidth + focusPadding));
-
- GtkWidget *gtkButtonBox = d->gtkWidget("GtkHButtonBox");
- gint minWidth = 85, minHeight = 0;
- d->gtk_widget_style_get(gtkButtonBox, "child-min-width", &minWidth,
- "child-min-height", &minHeight, NULL);
- if (!btn->text.isEmpty() && newSize.width() < minWidth)
- newSize.setWidth(minWidth);
- if (newSize.height() < minHeight)
- newSize.setHeight(minHeight);
- }
- break;
- case CT_Slider: {
- GtkWidget *gtkSlider = d->gtkWidget("GtkHScale");
- GtkStyle *gtkSliderStyle = d->gtk_widget_get_style(gtkSlider);
- newSize = size + QSize(2*gtkSliderStyle->xthickness, 2*gtkSliderStyle->ythickness); }
- break;
- case CT_LineEdit: {
- GtkWidget *gtkEntry = d->gtkWidget("GtkEntry");
- GtkStyle *gtkEntryStyle = d->gtk_widget_get_style(gtkEntry);
- newSize = size + QSize(2*gtkEntryStyle->xthickness, 2 + 2*gtkEntryStyle->ythickness); }
- break;
- case CT_ItemViewItem:
- newSize += QSize(0, 2);
- break;
- case CT_ComboBox:
- if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- GtkWidget *gtkCombo = d->gtkWidget("GtkComboBox");
- QRect arrowButtonRect = proxy()->subControlRect(CC_ComboBox, combo, SC_ComboBoxArrow, widget);
- GtkStyle *gtkComboStyle = d->gtk_widget_get_style(gtkCombo);
- newSize = size + QSize(12 + arrowButtonRect.width() + 2*gtkComboStyle->xthickness, 4 + 2*gtkComboStyle->ythickness);
-
- if (!(widget && qobject_cast<QToolBar *>(widget->parentWidget())))
- newSize += QSize(0, 2);
- }
- break;
- case CT_TabBarTab:
- if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) {
- if (!tab->icon.isNull())
- newSize += QSize(6, 0);
- }
- newSize += QSize(1, 1);
- break;
- case CT_MenuBarItem:
- newSize += QSize(QGtkStylePrivate::menuItemHMargin * 4, QGtkStylePrivate::menuItemVMargin * 2 + 2);
- break;
- case CT_SizeGrip:
- newSize += QSize(4, 4);
- break;
- case CT_MdiControls:
- if (const QStyleOptionComplex *styleOpt = qstyleoption_cast<const QStyleOptionComplex *>(option)) {
- int width = 0;
- if (styleOpt->subControls & SC_MdiMinButton)
- width += 19 + 1;
- if (styleOpt->subControls & SC_MdiNormalButton)
- width += 19 + 1;
- if (styleOpt->subControls & SC_MdiCloseButton)
- width += 19 + 1;
- newSize = QSize(width, 19);
- } else {
- newSize = QSize(60, 19);
- }
- break;
- case CT_MenuItem:
- if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
- int w = newSize.width();
- int maxpmw = menuItem->maxIconWidth;
- int tabSpacing = 20;
- if (menuItem->text.contains(QLatin1Char('\t')))
- w += tabSpacing;
- else if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu)
- w += 2 * QGtkStylePrivate::menuArrowHMargin;
- else if (menuItem->menuItemType == QStyleOptionMenuItem::DefaultItem) {
- // adjust the font and add the difference in size.
- // it would be better if the font could be adjusted in the initStyleOption qmenu func!!
- QFontMetrics fm(menuItem->font);
- QFont fontBold = menuItem->font;
- fontBold.setBold(true);
- QFontMetrics fmBold(fontBold);
- w += fmBold.width(menuItem->text) - fm.width(menuItem->text);
- }
-
- int checkcol = qMax<int>(maxpmw, QGtkStylePrivate::menuCheckMarkWidth); // Windows always shows a check column
- w += checkcol;
- w += int(QGtkStylePrivate::menuRightBorder) + 10;
-
- newSize.setWidth(w);
-
- int textMargin = 8;
- if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
- GtkWidget *gtkMenuSeparator = d->gtkWidget("GtkMenu.GtkSeparatorMenuItem");
- GtkRequisition sizeReq = {0, 0};
- d->gtk_widget_size_request(gtkMenuSeparator, &sizeReq);
- newSize = QSize(newSize.width(), sizeReq.height);
- break;
- }
-
- GtkWidget *gtkMenuItem = d->gtkWidget("GtkMenu.GtkCheckMenuItem");
- GtkStyle* style = d->gtk_widget_get_style(gtkMenuItem);
-
- // Note we get the perfect height for the default font since we
- // set a fake text label on the gtkMenuItem
- // But if custom fonts are used on the widget we need a minimum size
- GtkRequisition sizeReq = {0, 0};
- d->gtk_widget_size_request(gtkMenuItem, &sizeReq);
- newSize.setHeight(qMax(newSize.height() - 4, sizeReq.height));
- newSize += QSize(textMargin + style->xthickness - 1, 0);
-
- gint checkSize;
- d->gtk_widget_style_get(gtkMenuItem, "indicator-size", &checkSize, NULL);
- newSize.setWidth(newSize.width() + qMax(0, checkSize - 20));
- }
- break;
- default:
- break;
- }
-
- return newSize;
-}
-
-
-/*! \reimp */
-QPixmap QGtkStyle::standardPixmap(StandardPixmap sp, const QStyleOption *option,
- const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable())
- return QCommonStyle::standardPixmap(sp, option, widget);
-
- QPixmap pixmap;
- switch (sp) {
-
- case SP_TitleBarNormalButton: {
- QImage restoreButton(dock_widget_restore_xpm);
- QColor alphaCorner = restoreButton.color(2);
- alphaCorner.setAlpha(80);
- restoreButton.setColor(2, alphaCorner.rgba());
- alphaCorner.setAlpha(180);
- restoreButton.setColor(4, alphaCorner.rgba());
- return QPixmap::fromImage(restoreButton);
- }
- break;
-
- case SP_TitleBarCloseButton: // Fall through
- case SP_DockWidgetCloseButton: {
-
- QImage closeButton(dock_widget_close_xpm);
- QColor alphaCorner = closeButton.color(2);
- alphaCorner.setAlpha(80);
- closeButton.setColor(2, alphaCorner.rgba());
- return QPixmap::fromImage(closeButton);
- }
- break;
-
- case SP_DialogDiscardButton:
- return qt_gtk_get_icon(GTK_STOCK_DELETE);
- case SP_DialogOkButton:
- return qt_gtk_get_icon(GTK_STOCK_OK);
- case SP_DialogCancelButton:
- return qt_gtk_get_icon(GTK_STOCK_CANCEL);
- case SP_DialogYesButton:
- return qt_gtk_get_icon(GTK_STOCK_YES);
- case SP_DialogNoButton:
- return qt_gtk_get_icon(GTK_STOCK_NO);
- case SP_DialogOpenButton:
- return qt_gtk_get_icon(GTK_STOCK_OPEN);
- case SP_DialogCloseButton:
- return qt_gtk_get_icon(GTK_STOCK_CLOSE);
- case SP_DialogApplyButton:
- return qt_gtk_get_icon(GTK_STOCK_APPLY);
- case SP_DialogSaveButton:
- return qt_gtk_get_icon(GTK_STOCK_SAVE);
- case SP_MessageBoxWarning:
- return qt_gtk_get_icon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxQuestion:
- return qt_gtk_get_icon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxInformation:
- return qt_gtk_get_icon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxCritical:
- return qt_gtk_get_icon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
- default:
- return QCommonStyle::standardPixmap(sp, option, widget);
- }
- return pixmap;
-}
-
-/*!
- \reimp
-*/
-QIcon QGtkStyle::standardIcon(StandardPixmap standardIcon,
- const QStyleOption *option,
- const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- if (!d->isThemeAvailable())
- return QCommonStyle::standardIcon(standardIcon, option, widget);
- switch (standardIcon) {
- case SP_DialogDiscardButton:
- return qt_gtk_get_icon(GTK_STOCK_DELETE);
- case SP_DialogOkButton:
- return qt_gtk_get_icon(GTK_STOCK_OK);
- case SP_DialogCancelButton:
- return qt_gtk_get_icon(GTK_STOCK_CANCEL);
- case SP_DialogYesButton:
- return qt_gtk_get_icon(GTK_STOCK_YES);
- case SP_DialogNoButton:
- return qt_gtk_get_icon(GTK_STOCK_NO);
- case SP_DialogOpenButton:
- return qt_gtk_get_icon(GTK_STOCK_OPEN);
- case SP_DialogCloseButton:
- return qt_gtk_get_icon(GTK_STOCK_CLOSE);
- case SP_DialogApplyButton:
- return qt_gtk_get_icon(GTK_STOCK_APPLY);
- case SP_DialogSaveButton:
- return qt_gtk_get_icon(GTK_STOCK_SAVE);
- case SP_MessageBoxWarning:
- return qt_gtk_get_icon(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxQuestion:
- return qt_gtk_get_icon(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxInformation:
- return qt_gtk_get_icon(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
- case SP_MessageBoxCritical:
- return qt_gtk_get_icon(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
- default:
- return QCommonStyle::standardIcon(standardIcon, option, widget);
- }
-}
-
-
-/*! \reimp */
-QRect QGtkStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const
-{
- Q_D(const QGtkStyle);
-
- QRect r = QCommonStyle::subElementRect(element, option, widget);
- if (!d->isThemeAvailable())
- return r;
-
- switch (element) {
- case SE_PushButtonFocusRect:
- r.adjust(0, 1, 0, -1);
- break;
- case SE_DockWidgetTitleBarText: {
- const QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(option);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
- if (verticalTitleBar) {
- r.adjust(0, 0, 0, -4);
- } else {
- if (option->direction == Qt::LeftToRight)
- r.adjust(4, 0, 0, 0);
- else
- r.adjust(0, 0, -4, 0);
- }
-
- break;
- }
- case SE_ProgressBarLabel:
- case SE_ProgressBarContents:
- case SE_ProgressBarGroove:
- return option->rect;
- case SE_PushButtonContents:
- if (!d->gtk_check_version(2, 10, 0)) {
- GtkWidget *gtkButton = d->gtkWidget("GtkButton");
- GtkBorder *border = 0;
- d->gtk_widget_style_get(gtkButton, "inner-border", &border, NULL);
- if (border) {
- r = option->rect.adjusted(border->left, border->top, -border->right, -border->bottom);
- d->gtk_border_free(border);
- } else {
- r = option->rect.adjusted(1, 1, -1, -1);
- }
- r = visualRect(option->direction, option->rect, r);
- }
- break;
- default:
- break;
- }
-
- return r;
-}
-
-/*!
- \reimp
-*/
-QRect QGtkStyle::itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const
-{
- return QCommonStyle::itemPixmapRect(r, flags, pixmap);
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::drawItemPixmap(QPainter *painter, const QRect &rect,
- int alignment, const QPixmap &pixmap) const
-{
- QCommonStyle::drawItemPixmap(painter, rect, alignment, pixmap);
-}
-
-/*!
- \reimp
-*/
-QStyle::SubControl QGtkStyle::hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *w) const
-{
- return QCommonStyle::hitTestComplexControl(cc, opt, pt, w);
-}
-
-/*!
- \reimp
-*/
-QPixmap QGtkStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *opt) const
-{
- return QCommonStyle::generatedIconPixmap(iconMode, pixmap, opt);
-}
-
-/*!
- \reimp
-*/
-void QGtkStyle::drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
- bool enabled, const QString& text, QPalette::ColorRole textRole) const
-{
- return QCommonStyle::drawItemText(painter, rect, alignment, pal, enabled, text, textRole);
-}
-
-QT_END_NAMESPACE
-
-#endif //!defined(QT_NO_STYLE_QGTK)
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
deleted file mode 100644
index 00682c1c0f..0000000000
--- a/src/widgets/styles/qgtkstyle_p.cpp
+++ /dev/null
@@ -1,891 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgtkstyle_p_p.h"
-
-// This file is responsible for resolving all GTK functions we use
-// dynamically. This is done to avoid link-time dependancy on GTK
-// as well as crashes occurring due to usage of the GTK_QT engines
-//
-// Additionally we create a map of common GTK widgets that we can pass
-// to the GTK theme engine as many engines resort to querying the
-// actual widget pointers for details that are not covered by the
-// state flags
-
-#include <QtCore/qglobal.h>
-#if !defined(QT_NO_STYLE_GTK)
-
-#include <QtCore/QEvent>
-#include <QtCore/QFile>
-#include <QtCore/QStringList>
-#include <QtCore/QTextStream>
-#include <QtCore/QHash>
-#include <QtCore/QUrl>
-#include <QtCore/QLibrary>
-#include <QtCore/QDebug>
-
-#include <private/qgtk2painter_p.h>
-#include <private/qapplication_p.h>
-#include <private/qiconloader_p.h>
-#include <qpa/qplatformfontdatabase.h>
-
-#include <QtWidgets/QMenu>
-#include <QtWidgets/QStyle>
-#include <QtWidgets/QApplication>
-#include <QtGui/QPixmapCache>
-#include <QtWidgets/QStatusBar>
-#include <QtWidgets/QMenuBar>
-#include <QtWidgets/QToolBar>
-#include <QtWidgets/QToolButton>
-
-#ifndef Q_OS_MAC
-// X11 Includes:
-
-// the following is necessary to work around breakage in many versions
-// of XFree86's Xlib.h still in use
-// ### which versions?
-#if defined(_XLIB_H_) // crude hack, but...
-#error "cannot include <X11/Xlib.h> before this file"
-#endif
-#define XRegisterIMInstantiateCallback qt_XRegisterIMInstantiateCallback
-#define XUnregisterIMInstantiateCallback qt_XUnregisterIMInstantiateCallback
-#define XSetIMValues qt_XSetIMValues
-#include <X11/Xlib.h>
-#undef XRegisterIMInstantiateCallback
-#undef XUnregisterIMInstantiateCallback
-#undef XSetIMValues
-#endif
-
-QT_BEGIN_NAMESPACE
-
-Q_GLOBAL_STATIC(QGtkStyleUpdateScheduler, styleScheduler)
-
-Ptr_gtk_container_forall QGtkStylePrivate::gtk_container_forall = 0;
-Ptr_gtk_init QGtkStylePrivate::gtk_init = 0;
-Ptr_gtk_style_attach QGtkStylePrivate::gtk_style_attach = 0;
-Ptr_gtk_window_new QGtkStylePrivate::gtk_window_new = 0;
-Ptr_gtk_widget_destroy QGtkStylePrivate::gtk_widget_destroy = 0;
-Ptr_gtk_widget_realize QGtkStylePrivate::gtk_widget_realize = 0;
-Ptr_gtk_widget_set_default_direction QGtkStylePrivate::gtk_widget_set_default_direction = 0;
-Ptr_gtk_widget_modify_color QGtkStylePrivate::gtk_widget_modify_fg = 0;
-Ptr_gtk_widget_modify_color QGtkStylePrivate::gtk_widget_modify_bg = 0;
-Ptr_gtk_arrow_new QGtkStylePrivate::gtk_arrow_new = 0;
-Ptr_gtk_menu_item_new_with_label QGtkStylePrivate::gtk_menu_item_new_with_label = 0;
-Ptr_gtk_check_menu_item_new_with_label QGtkStylePrivate::gtk_check_menu_item_new_with_label = 0;
-Ptr_gtk_menu_bar_new QGtkStylePrivate::gtk_menu_bar_new = 0;
-Ptr_gtk_menu_new QGtkStylePrivate::gtk_menu_new = 0;
-Ptr_gtk_button_new QGtkStylePrivate::gtk_button_new = 0;
-Ptr_gtk_tool_button_new QGtkStylePrivate::gtk_tool_button_new = 0;
-Ptr_gtk_hbutton_box_new QGtkStylePrivate::gtk_hbutton_box_new = 0;
-Ptr_gtk_check_button_new QGtkStylePrivate::gtk_check_button_new = 0;
-Ptr_gtk_radio_button_new QGtkStylePrivate::gtk_radio_button_new = 0;
-Ptr_gtk_spin_button_new QGtkStylePrivate::gtk_spin_button_new = 0;
-Ptr_gtk_frame_new QGtkStylePrivate::gtk_frame_new = 0;
-Ptr_gtk_expander_new QGtkStylePrivate::gtk_expander_new = 0;
-Ptr_gtk_statusbar_new QGtkStylePrivate::gtk_statusbar_new = 0;
-Ptr_gtk_entry_new QGtkStylePrivate::gtk_entry_new = 0;
-Ptr_gtk_hscale_new QGtkStylePrivate::gtk_hscale_new = 0;
-Ptr_gtk_vscale_new QGtkStylePrivate::gtk_vscale_new = 0;
-Ptr_gtk_hscrollbar_new QGtkStylePrivate::gtk_hscrollbar_new = 0;
-Ptr_gtk_vscrollbar_new QGtkStylePrivate::gtk_vscrollbar_new = 0;
-Ptr_gtk_scrolled_window_new QGtkStylePrivate::gtk_scrolled_window_new = 0;
-Ptr_gtk_notebook_new QGtkStylePrivate::gtk_notebook_new = 0;
-Ptr_gtk_toolbar_new QGtkStylePrivate::gtk_toolbar_new = 0;
-Ptr_gtk_toolbar_insert QGtkStylePrivate::gtk_toolbar_insert = 0;
-Ptr_gtk_separator_tool_item_new QGtkStylePrivate::gtk_separator_tool_item_new = 0;
-Ptr_gtk_tree_view_new QGtkStylePrivate::gtk_tree_view_new = 0;
-Ptr_gtk_combo_box_new QGtkStylePrivate::gtk_combo_box_new = 0;
-Ptr_gtk_combo_box_entry_new QGtkStylePrivate::gtk_combo_box_entry_new = 0;
-Ptr_gtk_progress_bar_new QGtkStylePrivate::gtk_progress_bar_new = 0;
-Ptr_gtk_container_add QGtkStylePrivate::gtk_container_add = 0;
-Ptr_gtk_menu_shell_append QGtkStylePrivate::gtk_menu_shell_append = 0;
-Ptr_gtk_range_get_adjustment QGtkStylePrivate::gtk_range_get_adjustment = 0;
-Ptr_gtk_range_set_adjustment QGtkStylePrivate::gtk_range_set_adjustment = 0;
-Ptr_gtk_range_set_inverted QGtkStylePrivate::gtk_range_set_inverted = 0;
-Ptr_gtk_icon_factory_lookup_default QGtkStylePrivate::gtk_icon_factory_lookup_default = 0;
-Ptr_gtk_icon_theme_get_default QGtkStylePrivate::gtk_icon_theme_get_default = 0;
-Ptr_gtk_widget_get_style QGtkStylePrivate::gtk_widget_get_style = 0;
-Ptr_gtk_widget_style_get QGtkStylePrivate::gtk_widget_style_get = 0;
-Ptr_gtk_icon_set_render_icon QGtkStylePrivate::gtk_icon_set_render_icon = 0;
-Ptr_gtk_fixed_new QGtkStylePrivate::gtk_fixed_new = 0;
-Ptr_gtk_tree_view_column_new QGtkStylePrivate::gtk_tree_view_column_new = 0;
-Ptr_gtk_tree_view_get_column QGtkStylePrivate::gtk_tree_view_get_column = 0;
-Ptr_gtk_tree_view_append_column QGtkStylePrivate::gtk_tree_view_append_column = 0;
-Ptr_gtk_adjustment_configure QGtkStylePrivate::gtk_adjustment_configure = 0;
-Ptr_gtk_adjustment_new QGtkStylePrivate::gtk_adjustment_new = 0;
-Ptr_gtk_menu_item_set_submenu QGtkStylePrivate::gtk_menu_item_set_submenu = 0;
-Ptr_gtk_settings_get_default QGtkStylePrivate::gtk_settings_get_default = 0;
-Ptr_gtk_separator_menu_item_new QGtkStylePrivate::gtk_separator_menu_item_new = 0;
-Ptr_gtk_widget_size_allocate QGtkStylePrivate::gtk_widget_size_allocate = 0;
-Ptr_gtk_widget_size_request QGtkStylePrivate::gtk_widget_size_request = 0;
-Ptr_gtk_widget_set_direction QGtkStylePrivate::gtk_widget_set_direction = 0;
-Ptr_gtk_widget_path QGtkStylePrivate::gtk_widget_path = 0;
-Ptr_gtk_container_get_type QGtkStylePrivate::gtk_container_get_type = 0;
-Ptr_gtk_window_get_type QGtkStylePrivate::gtk_window_get_type = 0;
-Ptr_gtk_widget_get_type QGtkStylePrivate::gtk_widget_get_type = 0;
-Ptr_gtk_widget_get_parent QGtkStylePrivate::gtk_widget_get_parent = 0;
-Ptr_gtk_widget_is_toplevel QGtkStylePrivate::gtk_widget_is_toplevel = 0;
-Ptr_gtk_widget_get_toplevel QGtkStylePrivate::gtk_widget_get_toplevel = 0;
-Ptr_gtk_rc_get_style_by_paths QGtkStylePrivate::gtk_rc_get_style_by_paths = 0;
-Ptr_gtk_check_version QGtkStylePrivate::gtk_check_version = 0;
-Ptr_gtk_border_free QGtkStylePrivate::gtk_border_free = 0;
-Ptr_gtk_widget_get_allocation QGtkStylePrivate::gtk_widget_get_allocation = 0;
-Ptr_gtk_widget_set_allocation QGtkStylePrivate::gtk_widget_set_allocation = 0;
-Ptr_gtk_widget_set_can_default QGtkStylePrivate::gtk_widget_set_can_default = 0;
-Ptr_gtk_window_set_default QGtkStylePrivate::gtk_window_set_default = 0;
-
-Ptr_gdk_event_new QGtkStylePrivate::gdk_event_new = 0;
-Ptr_gdk_event_free QGtkStylePrivate::gdk_event_free = 0;
-Ptr_gtk_widget_send_focus_change QGtkStylePrivate::gtk_widget_send_focus_change = 0;
-
-Ptr_pango_font_description_get_size QGtkStylePrivate::pango_font_description_get_size = 0;
-Ptr_pango_font_description_get_weight QGtkStylePrivate::pango_font_description_get_weight = 0;
-Ptr_pango_font_description_get_family QGtkStylePrivate::pango_font_description_get_family = 0;
-Ptr_pango_font_description_get_style QGtkStylePrivate::pango_font_description_get_style = 0;
-
-Ptr_gdk_pixbuf_get_pixels QGtkStylePrivate::gdk_pixbuf_get_pixels = 0;
-Ptr_gdk_pixbuf_get_width QGtkStylePrivate::gdk_pixbuf_get_width = 0;
-Ptr_gdk_pixbuf_get_height QGtkStylePrivate::gdk_pixbuf_get_height = 0;
-Ptr_gdk_pixbuf_new QGtkStylePrivate::gdk_pixbuf_new = 0;
-Ptr_gdk_pixbuf_unref QGtkStylePrivate::gdk_pixbuf_unref = 0;
-Ptr_gdk_color_free QGtkStylePrivate::gdk_color_free = 0;
-Ptr_gdk_x11_window_set_user_time QGtkStylePrivate::gdk_x11_window_set_user_time = 0;
-Ptr_gdk_x11_drawable_get_xid QGtkStylePrivate::gdk_x11_drawable_get_xid = 0;
-Ptr_gdk_x11_drawable_get_xdisplay QGtkStylePrivate::gdk_x11_drawable_get_xdisplay = 0;
-
-Ptr_gconf_client_get_default QGtkStylePrivate::gconf_client_get_default = 0;
-Ptr_gconf_client_get_string QGtkStylePrivate::gconf_client_get_string = 0;
-Ptr_gconf_client_get_bool QGtkStylePrivate::gconf_client_get_bool = 0;
-
-Ptr_gnome_icon_lookup_sync QGtkStylePrivate::gnome_icon_lookup_sync = 0;
-Ptr_gnome_vfs_init QGtkStylePrivate::gnome_vfs_init = 0;
-
-#ifndef Q_OS_MAC
-typedef int (*x11ErrorHandler)(Display*, XErrorEvent*);
-#endif
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(QGtkStylePrivate*);
-
-QT_BEGIN_NAMESPACE
-
-static void gtkStyleSetCallback(GtkWidget*)
-{
- qRegisterMetaType<QGtkStylePrivate *>();
-
- // We have to let this function return and complete the event
- // loop to ensure that all gtk widgets have been styled before
- // updating
- QMetaObject::invokeMethod(styleScheduler(), "updateTheme", Qt::QueuedConnection);
-}
-
-static void update_toolbar_style(GtkWidget *gtkToolBar, GParamSpec *, gpointer)
-{
- GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS;
- g_object_get(gtkToolBar, "toolbar-style", &toolbar_style, NULL);
- QWidgetList widgets = QApplication::allWidgets();
- for (int i = 0; i < widgets.size(); ++i) {
- QWidget *widget = widgets.at(i);
- if (qobject_cast<QToolButton*>(widget)) {
- QEvent event(QEvent::StyleChange);
- QApplication::sendEvent(widget, &event);
- }
- }
-}
-
-static QHashableLatin1Literal classPath(GtkWidget *widget)
-{
- char *class_path;
- QGtkStylePrivate::gtk_widget_path (widget, NULL, &class_path, NULL);
-
- char *copy = class_path;
- if (strncmp(copy, "GtkWindow.", 10) == 0)
- copy += 10;
- if (strncmp(copy, "GtkFixed.", 9) == 0)
- copy += 9;
-
- copy = strdup(copy);
-
- g_free(class_path);
-
- return QHashableLatin1Literal::fromData(copy);
-}
-
-
-
-bool QGtkStyleFilter::eventFilter(QObject *obj, QEvent *e)
-{
- if (e->type() == QEvent::ApplicationPaletteChange) {
- // Only do this the first time since this will also
- // generate applicationPaletteChange events
- if (!qt_app_palettes_hash() || qt_app_palettes_hash()->isEmpty()) {
- stylePrivate->applyCustomPaletteHash();
- }
- }
- return QObject::eventFilter(obj, e);
-}
-
-QList<QGtkStylePrivate *> QGtkStylePrivate::instances;
-QGtkStylePrivate::WidgetMap *QGtkStylePrivate::widgetMap = 0;
-
-QGtkStylePrivate::QGtkStylePrivate()
- : QCommonStylePrivate()
- , filter(this)
-{
- instances.append(this);
- animationFps = 60;
-}
-
-QGtkStylePrivate::~QGtkStylePrivate()
-{
- instances.removeOne(this);
-}
-
-void QGtkStylePrivate::init()
-{
- resolveGtk();
- initGtkWidgets();
-}
-
-QGtkPainter* QGtkStylePrivate::gtkPainter(QPainter *painter)
-{
- // TODO: choose between gtk2 and gtk3
- static QGtk2Painter instance;
- instance.reset(painter);
- return &instance;
-}
-
-GtkWidget* QGtkStylePrivate::gtkWidget(const QHashableLatin1Literal &path)
-{
- GtkWidget *widget = gtkWidgetMap()->value(path);
- if (!widget) {
- // Theme might have rearranged widget internals
- widget = gtkWidgetMap()->value(path);
- }
- return widget;
-}
-
-GtkStyle* QGtkStylePrivate::gtkStyle(const QHashableLatin1Literal &path)
-{
- if (GtkWidget *w = gtkWidgetMap()->value(path))
- return QGtkStylePrivate::gtk_widget_get_style(w);
- return 0;
-}
-
-void QGtkStylePrivate::gtkWidgetSetFocus(GtkWidget *widget, bool focus)
-{
- if (QGtkStylePrivate::gtk_widget_send_focus_change) {
- GdkEvent *event = QGtkStylePrivate::gdk_event_new(GDK_FOCUS_CHANGE);
- event->focus_change.type = GDK_FOCUS_CHANGE;
- event->focus_change.in = focus;
- QGtkStylePrivate::gtk_widget_send_focus_change(widget, event);
- QGtkStylePrivate::gdk_event_free(event);
- } else {
-#if defined(GTK_WIDGET_SET_FLAGS) && defined(GTK_WIDGET_UNSET_FLAGS)
- if (focus)
- GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
- else
- GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
-#endif
- }
-}
-
-/*! \internal
- * Get references to gtk functions after we dynamically load the library.
- */
-void QGtkStylePrivate::resolveGtk() const
-{
-#ifndef QT_NO_LIBRARY
- // enforce the "0" suffix, so we'll open libgtk-x11-2.0.so.0
- QLibrary libgtk(QLS("gtk-x11-2.0"), 0, 0);
-
- gtk_init = (Ptr_gtk_init)libgtk.resolve("gtk_init");
- gtk_window_new = (Ptr_gtk_window_new)libgtk.resolve("gtk_window_new");
- gtk_style_attach = (Ptr_gtk_style_attach)libgtk.resolve("gtk_style_attach");
- gtk_widget_destroy = (Ptr_gtk_widget_destroy)libgtk.resolve("gtk_widget_destroy");
- gtk_widget_realize = (Ptr_gtk_widget_realize)libgtk.resolve("gtk_widget_realize");
-
- gdk_pixbuf_get_pixels = (Ptr_gdk_pixbuf_get_pixels)libgtk.resolve("gdk_pixbuf_get_pixels");
- gdk_pixbuf_get_width = (Ptr_gdk_pixbuf_get_width)libgtk.resolve("gdk_pixbuf_get_width");
- gdk_pixbuf_get_height = (Ptr_gdk_pixbuf_get_height)libgtk.resolve("gdk_pixbuf_get_height");
- gdk_pixbuf_new = (Ptr_gdk_pixbuf_new)libgtk.resolve("gdk_pixbuf_new");
- gdk_pixbuf_unref = (Ptr_gdk_pixbuf_unref)libgtk.resolve("gdk_pixbuf_unref");
- gdk_color_free = (Ptr_gdk_color_free)libgtk.resolve("gdk_color_free");
- gdk_x11_window_set_user_time = (Ptr_gdk_x11_window_set_user_time)libgtk.resolve("gdk_x11_window_set_user_time");
- gdk_x11_drawable_get_xid = (Ptr_gdk_x11_drawable_get_xid)libgtk.resolve("gdk_x11_drawable_get_xid");
- gdk_x11_drawable_get_xdisplay = (Ptr_gdk_x11_drawable_get_xdisplay)libgtk.resolve("gdk_x11_drawable_get_xdisplay");
-
- gtk_widget_set_default_direction = (Ptr_gtk_widget_set_default_direction)libgtk.resolve("gtk_widget_set_default_direction");
- gtk_widget_modify_fg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_fg");
- gtk_widget_modify_bg = (Ptr_gtk_widget_modify_color)libgtk.resolve("gtk_widget_modify_bg");
- gtk_arrow_new = (Ptr_gtk_arrow_new)libgtk.resolve("gtk_arrow_new");
- gtk_menu_item_new_with_label = (Ptr_gtk_menu_item_new_with_label)libgtk.resolve("gtk_menu_item_new_with_label");
- gtk_check_menu_item_new_with_label = (Ptr_gtk_check_menu_item_new_with_label)libgtk.resolve("gtk_check_menu_item_new_with_label");
- gtk_menu_bar_new = (Ptr_gtk_menu_bar_new)libgtk.resolve("gtk_menu_bar_new");
- gtk_menu_new = (Ptr_gtk_menu_new)libgtk.resolve("gtk_menu_new");
- gtk_toolbar_new = (Ptr_gtk_toolbar_new)libgtk.resolve("gtk_toolbar_new");
- gtk_separator_tool_item_new = (Ptr_gtk_separator_tool_item_new)libgtk.resolve("gtk_separator_tool_item_new");
- gtk_toolbar_insert = (Ptr_gtk_toolbar_insert)libgtk.resolve("gtk_toolbar_insert");
- gtk_button_new = (Ptr_gtk_button_new)libgtk.resolve("gtk_button_new");
- gtk_tool_button_new = (Ptr_gtk_tool_button_new)libgtk.resolve("gtk_tool_button_new");
- gtk_hbutton_box_new = (Ptr_gtk_hbutton_box_new)libgtk.resolve("gtk_hbutton_box_new");
- gtk_check_button_new = (Ptr_gtk_check_button_new)libgtk.resolve("gtk_check_button_new");
- gtk_radio_button_new = (Ptr_gtk_radio_button_new)libgtk.resolve("gtk_radio_button_new");
- gtk_notebook_new = (Ptr_gtk_notebook_new)libgtk.resolve("gtk_notebook_new");
- gtk_progress_bar_new = (Ptr_gtk_progress_bar_new)libgtk.resolve("gtk_progress_bar_new");
- gtk_spin_button_new = (Ptr_gtk_spin_button_new)libgtk.resolve("gtk_spin_button_new");
- gtk_hscale_new = (Ptr_gtk_hscale_new)libgtk.resolve("gtk_hscale_new");
- gtk_vscale_new = (Ptr_gtk_vscale_new)libgtk.resolve("gtk_vscale_new");
- gtk_hscrollbar_new = (Ptr_gtk_hscrollbar_new)libgtk.resolve("gtk_hscrollbar_new");
- gtk_vscrollbar_new = (Ptr_gtk_vscrollbar_new)libgtk.resolve("gtk_vscrollbar_new");
- gtk_scrolled_window_new = (Ptr_gtk_scrolled_window_new)libgtk.resolve("gtk_scrolled_window_new");
- gtk_menu_shell_append = (Ptr_gtk_menu_shell_append)libgtk.resolve("gtk_menu_shell_append");
- gtk_entry_new = (Ptr_gtk_entry_new)libgtk.resolve("gtk_entry_new");
- gtk_tree_view_new = (Ptr_gtk_tree_view_new)libgtk.resolve("gtk_tree_view_new");
- gtk_combo_box_new = (Ptr_gtk_combo_box_new)libgtk.resolve("gtk_combo_box_new");
- gtk_combo_box_entry_new = (Ptr_gtk_combo_box_entry_new)libgtk.resolve("gtk_combo_box_entry_new");
- gtk_range_get_adjustment = (Ptr_gtk_range_get_adjustment)libgtk.resolve("gtk_range_get_adjustment");
- gtk_range_set_adjustment = (Ptr_gtk_range_set_adjustment)libgtk.resolve("gtk_range_set_adjustment");
- gtk_range_set_inverted = (Ptr_gtk_range_set_inverted)libgtk.resolve("gtk_range_set_inverted");
- gtk_container_add = (Ptr_gtk_container_add)libgtk.resolve("gtk_container_add");
- gtk_icon_factory_lookup_default = (Ptr_gtk_icon_factory_lookup_default)libgtk.resolve("gtk_icon_factory_lookup_default");
- gtk_icon_theme_get_default = (Ptr_gtk_icon_theme_get_default)libgtk.resolve("gtk_icon_theme_get_default");
- gtk_widget_get_style = (Ptr_gtk_widget_get_style)libgtk.resolve("gtk_widget_get_style");
- gtk_widget_style_get = (Ptr_gtk_widget_style_get)libgtk.resolve("gtk_widget_style_get");
- gtk_icon_set_render_icon = (Ptr_gtk_icon_set_render_icon)libgtk.resolve("gtk_icon_set_render_icon");
- gtk_fixed_new = (Ptr_gtk_fixed_new)libgtk.resolve("gtk_fixed_new");
- gtk_tree_view_column_new = (Ptr_gtk_tree_view_column_new)libgtk.resolve("gtk_tree_view_column_new");
- gtk_tree_view_append_column= (Ptr_gtk_tree_view_append_column )libgtk.resolve("gtk_tree_view_append_column");
- gtk_tree_view_get_column = (Ptr_gtk_tree_view_get_column )libgtk.resolve("gtk_tree_view_get_column");
- gtk_adjustment_configure = (Ptr_gtk_adjustment_configure)libgtk.resolve("gtk_adjustment_configure");
- gtk_adjustment_new = (Ptr_gtk_adjustment_new)libgtk.resolve("gtk_adjustment_new");
- gtk_menu_item_set_submenu = (Ptr_gtk_menu_item_set_submenu)libgtk.resolve("gtk_menu_item_set_submenu");
- gtk_settings_get_default = (Ptr_gtk_settings_get_default)libgtk.resolve("gtk_settings_get_default");
- gtk_separator_menu_item_new = (Ptr_gtk_separator_menu_item_new)libgtk.resolve("gtk_separator_menu_item_new");
- gtk_frame_new = (Ptr_gtk_frame_new)libgtk.resolve("gtk_frame_new");
- gtk_expander_new = (Ptr_gtk_expander_new)libgtk.resolve("gtk_expander_new");
- gtk_statusbar_new = (Ptr_gtk_statusbar_new)libgtk.resolve("gtk_statusbar_new");
- gtk_container_forall = (Ptr_gtk_container_forall)libgtk.resolve("gtk_container_forall");
- gtk_widget_size_allocate =(Ptr_gtk_widget_size_allocate)libgtk.resolve("gtk_widget_size_allocate");
- gtk_widget_size_request =(Ptr_gtk_widget_size_request)libgtk.resolve("gtk_widget_size_request");
- gtk_widget_set_direction =(Ptr_gtk_widget_set_direction)libgtk.resolve("gtk_widget_set_direction");
- gtk_widget_path =(Ptr_gtk_widget_path)libgtk.resolve("gtk_widget_path");
- gtk_container_get_type =(Ptr_gtk_container_get_type)libgtk.resolve("gtk_container_get_type");
- gtk_window_get_type =(Ptr_gtk_window_get_type)libgtk.resolve("gtk_window_get_type");
- gtk_widget_get_type =(Ptr_gtk_widget_get_type)libgtk.resolve("gtk_widget_get_type");
- gtk_widget_get_parent =(Ptr_gtk_widget_get_parent)libgtk.resolve("gtk_widget_get_parent");
- gtk_widget_is_toplevel =(Ptr_gtk_widget_is_toplevel)libgtk.resolve("gtk_widget_is_toplevel");
- gtk_widget_get_toplevel =(Ptr_gtk_widget_get_toplevel)libgtk.resolve("gtk_widget_get_toplevel");
-
- gtk_rc_get_style_by_paths =(Ptr_gtk_rc_get_style_by_paths)libgtk.resolve("gtk_rc_get_style_by_paths");
- gtk_check_version =(Ptr_gtk_check_version)libgtk.resolve("gtk_check_version");
- gtk_border_free =(Ptr_gtk_border_free)libgtk.resolve("gtk_border_free");
- gtk_widget_get_allocation = (Ptr_gtk_widget_get_allocation)libgtk.resolve("gtk_widget_get_allocation");
- gtk_widget_set_allocation = (Ptr_gtk_widget_set_allocation)libgtk.resolve("gtk_widget_set_allocation");
-
- gtk_widget_set_can_default = (Ptr_gtk_widget_set_can_default)libgtk.resolve("gtk_widget_set_can_default");
- gtk_window_set_default = (Ptr_gtk_window_set_default)libgtk.resolve("gtk_window_set_default");
-
- gdk_event_new = (Ptr_gdk_event_new)libgtk.resolve("gdk_event_new");
- gdk_event_free = (Ptr_gdk_event_free)libgtk.resolve("gdk_event_free");
- gtk_widget_send_focus_change = (Ptr_gtk_widget_send_focus_change)libgtk.resolve("gtk_widget_send_focus_change");
-
- pango_font_description_get_size = (Ptr_pango_font_description_get_size)libgtk.resolve("pango_font_description_get_size");
- pango_font_description_get_weight = (Ptr_pango_font_description_get_weight)libgtk.resolve("pango_font_description_get_weight");
- pango_font_description_get_family = (Ptr_pango_font_description_get_family)libgtk.resolve("pango_font_description_get_family");
- pango_font_description_get_style = (Ptr_pango_font_description_get_style)libgtk.resolve("pango_font_description_get_style");
-
- gnome_icon_lookup_sync = (Ptr_gnome_icon_lookup_sync)QLibrary::resolve(QLS("gnomeui-2"), 0, "gnome_icon_lookup_sync");
- gnome_vfs_init= (Ptr_gnome_vfs_init)QLibrary::resolve(QLS("gnomevfs-2"), 0, "gnome_vfs_init");
-#endif // !QT_NO_LIBRARY
-}
-
-/* \internal
- * Initializes a number of gtk menu widgets.
- * The widgets are cached.
- */
-void QGtkStylePrivate::initGtkMenu() const
-{
- // Create menubar
- GtkWidget *gtkMenuBar = QGtkStylePrivate::gtk_menu_bar_new();
- setupGtkWidget(gtkMenuBar);
-
- GtkWidget *gtkMenuBarItem = QGtkStylePrivate::gtk_menu_item_new_with_label("X");
- gtk_menu_shell_append((GtkMenuShell*)(gtkMenuBar), gtkMenuBarItem);
- gtk_widget_realize(gtkMenuBarItem);
-
- // Create menu
- GtkWidget *gtkMenu = QGtkStylePrivate::gtk_menu_new();
- gtk_menu_item_set_submenu((GtkMenuItem*)(gtkMenuBarItem), gtkMenu);
- gtk_widget_realize(gtkMenu);
-
- GtkWidget *gtkMenuItem = QGtkStylePrivate::gtk_menu_item_new_with_label("X");
- gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuItem);
- gtk_widget_realize(gtkMenuItem);
-
- GtkWidget *gtkCheckMenuItem = QGtkStylePrivate::gtk_check_menu_item_new_with_label("X");
- gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkCheckMenuItem);
- gtk_widget_realize(gtkCheckMenuItem);
-
- GtkWidget *gtkMenuSeparator = QGtkStylePrivate::gtk_separator_menu_item_new();
- gtk_menu_shell_append((GtkMenuShell*)gtkMenu, gtkMenuSeparator);
-
- addAllSubWidgets(gtkMenuBar);
- addAllSubWidgets(gtkMenu);
-}
-
-
-void QGtkStylePrivate::initGtkTreeview() const
-{
- GtkWidget *gtkTreeView = gtk_tree_view_new();
- gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
- gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
- gtk_tree_view_append_column((GtkTreeView*)gtkTreeView, gtk_tree_view_column_new());
- addWidget(gtkTreeView);
-}
-
-
-/* \internal
- * Initializes a number of gtk widgets that we can later on use to determine some of our styles.
- * The widgets are cached.
- */
-void QGtkStylePrivate::initGtkWidgets() const
-{
- // From gtkmain.c
- uid_t ruid = getuid ();
- uid_t rgid = getgid ();
- uid_t euid = geteuid ();
- uid_t egid = getegid ();
- if (ruid != euid || rgid != egid) {
- qWarning("\nThis process is currently running setuid or setgid.\nGTK+ does not allow this "
- "therefore Qt cannot use the GTK+ integration.\nTry launching your app using \'gksudo\', "
- "\'kdesudo\' or a similar tool.\n\n"
- "See http://www.gtk.org/setuid.html for more information.\n");
- return;
- }
-
- if (QGtkStylePrivate::gtk_init) {
-#ifndef Q_OS_MAC
- // Gtk will set the Qt error handler so we have to reset it afterwards
- x11ErrorHandler qt_x_errhandler = XSetErrorHandler(0);
-#endif
- QGtkStylePrivate::gtk_init (NULL, NULL);
-#ifndef Q_OS_MAC
- XSetErrorHandler(qt_x_errhandler);
-#endif
-
- // make a window
- GtkWidget* gtkWindow = QGtkStylePrivate::gtk_window_new(GTK_WINDOW_POPUP);
- QGtkStylePrivate::gtk_widget_realize(gtkWindow);
- QHashableLatin1Literal widgetPath = QHashableLatin1Literal::fromData(strdup("GtkWindow"));
- removeWidgetFromMap(widgetPath);
- gtkWidgetMap()->insert(widgetPath, gtkWindow);
-
-
- // Make all other widgets. respect the text direction
- if (qApp->layoutDirection() == Qt::RightToLeft)
- QGtkStylePrivate::gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL);
-
- if (!gtkWidgetMap()->contains("GtkButton")) {
- GtkWidget *gtkButton = QGtkStylePrivate::gtk_button_new();
- addWidget(gtkButton);
- g_signal_connect(gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), 0);
- addWidget(QGtkStylePrivate::gtk_tool_button_new(NULL, "Qt"));
- addWidget(QGtkStylePrivate::gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE));
- addWidget(QGtkStylePrivate::gtk_hbutton_box_new());
- addWidget(QGtkStylePrivate::gtk_check_button_new());
- addWidget(QGtkStylePrivate::gtk_radio_button_new(NULL));
- addWidget(QGtkStylePrivate::gtk_combo_box_new());
- addWidget(QGtkStylePrivate::gtk_combo_box_entry_new());
- GtkWidget *entry = QGtkStylePrivate::gtk_entry_new();
- // gtk-im-context-none is supported in gtk+ since 2.19.5
- // and also exists in gtk3
- // http://git.gnome.org/browse/gtk+/tree/gtk/gtkimmulticontext.c?id=2.19.5#n33
- // reason that we don't use gtk-im-context-simple here is,
- // gtk-im-context-none has less overhead, and 2.19.5 is
- // relatively old. and even for older gtk+, it will fallback
- // to gtk-im-context-simple if gtk-im-context-none doesn't
- // exists.
- g_object_set(entry, "im-module", "gtk-im-context-none", NULL);
- addWidget(entry);
- addWidget(QGtkStylePrivate::gtk_frame_new(NULL));
- addWidget(QGtkStylePrivate::gtk_expander_new(""));
- addWidget(QGtkStylePrivate::gtk_statusbar_new());
- addWidget(QGtkStylePrivate::gtk_hscale_new((QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0))));
- addWidget(QGtkStylePrivate::gtk_hscrollbar_new(NULL));
- addWidget(QGtkStylePrivate::gtk_scrolled_window_new(NULL, NULL));
-
- initGtkMenu();
- addWidget(QGtkStylePrivate::gtk_notebook_new());
- addWidget(QGtkStylePrivate::gtk_progress_bar_new());
- addWidget(QGtkStylePrivate::gtk_spin_button_new((QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0)), 0.1, 3));
- GtkWidget *toolbar = gtk_toolbar_new();
- g_signal_connect (toolbar, "notify::toolbar-style", G_CALLBACK (update_toolbar_style), toolbar);
- gtk_toolbar_insert((GtkToolbar*)toolbar, gtk_separator_tool_item_new(), -1);
- addWidget(toolbar);
- initGtkTreeview();
- addWidget(gtk_vscale_new((QGtkStylePrivate::gtk_adjustment_new(1, 0, 1, 0, 0, 0))));
- addWidget(gtk_vscrollbar_new(NULL));
- }
- else // Rebuild map
- {
- // When styles change subwidgets can get rearranged
- // as with the combo box. We need to update the widget map
- // to reflect this;
- QHash<QHashableLatin1Literal, GtkWidget*> oldMap = *gtkWidgetMap();
- gtkWidgetMap()->clear();
- QHashIterator<QHashableLatin1Literal, GtkWidget*> it(oldMap);
- while (it.hasNext()) {
- it.next();
- if (!strchr(it.key().data(), '.')) {
- addAllSubWidgets(it.value());
- }
- free(const_cast<char *>(it.key().data()));
- }
- }
- } else {
- qWarning("QGtkStyle could not resolve GTK. Make sure you have installed the proper libraries.");
- }
-}
-
-/*! \internal
- * destroys all previously buffered widgets.
- */
-void QGtkStylePrivate::cleanupGtkWidgets()
-{
- if (!widgetMap)
- return;
- if (widgetMap->contains("GtkWindow")) // Gtk will destroy all children
- gtk_widget_destroy(widgetMap->value("GtkWindow"));
- for (QHash<QHashableLatin1Literal, GtkWidget *>::const_iterator it = widgetMap->constBegin();
- it != widgetMap->constEnd(); ++it)
- free(const_cast<char *>(it.key().data()));
-}
-
-static bool resolveGConf()
-{
-#ifndef QT_NO_LIBRARY
- if (!QGtkStylePrivate::gconf_client_get_default) {
- QGtkStylePrivate::gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_default");
- QGtkStylePrivate::gconf_client_get_string = (Ptr_gconf_client_get_string)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_string");
- QGtkStylePrivate::gconf_client_get_bool = (Ptr_gconf_client_get_bool)QLibrary::resolve(QLS("gconf-2"), 4, "gconf_client_get_bool");
- }
-#endif // !QT_NO_LIBRARY
- return (QGtkStylePrivate::gconf_client_get_default !=0);
-}
-
-QString QGtkStylePrivate::getGConfString(const QString &value, const QString &fallback)
-{
- QString retVal = fallback;
- if (resolveGConf()) {
-#if !defined(GLIB_VERSION_2_36)
- g_type_init();
-#endif
- GConfClient* client = gconf_client_get_default();
- GError *err = 0;
- char *str = gconf_client_get_string(client, qPrintable(value), &err);
- if (!err) {
- retVal = QString::fromUtf8(str);
- g_free(str);
- }
- g_object_unref(client);
- if (err)
- g_error_free (err);
- }
- return retVal;
-}
-
-bool QGtkStylePrivate::getGConfBool(const QString &key, bool fallback)
-{
- bool retVal = fallback;
- if (resolveGConf()) {
-#if !defined(GLIB_VERSION_2_36)
- g_type_init();
-#endif
- GConfClient* client = gconf_client_get_default();
- GError *err = 0;
- bool result = gconf_client_get_bool(client, qPrintable(key), &err);
- g_object_unref(client);
- if (!err)
- retVal = result;
- else
- g_error_free (err);
- }
- return retVal;
-}
-
-QString QGtkStylePrivate::getThemeName()
-{
- QString themeName;
- // Read the theme name from GtkSettings
- GtkSettings *settings = QGtkStylePrivate::gtk_settings_get_default();
- gchararray value;
- g_object_get(settings, "gtk-theme-name", &value, NULL);
- themeName = QString::fromUtf8(value);
- g_free(value);
- return themeName;
-}
-
-// Get size of the arrow controls in a GtkSpinButton
-int QGtkStylePrivate::getSpinboxArrowSize() const
-{
- const int MIN_ARROW_WIDTH = 6;
- GtkWidget *spinButton = gtkWidget("GtkSpinButton");
- GtkStyle *style = QGtkStylePrivate::gtk_widget_get_style(spinButton);
- gint size = pango_font_description_get_size (style->font_desc);
- gint arrow_size;
- arrow_size = qMax(PANGO_PIXELS (size), MIN_ARROW_WIDTH) + style->xthickness;
- arrow_size += arrow_size%2 + 1;
- return arrow_size;
-}
-
-
-bool QGtkStylePrivate::isKDE4Session()
-{
- static int version = -1;
- if (version == -1)
- version = qgetenv("KDE_SESSION_VERSION").toInt();
- return (version == 4);
-}
-
-void QGtkStylePrivate::applyCustomPaletteHash()
-{
- QPalette menuPal = gtkWidgetPalette("GtkMenu");
- GdkColor gdkBg = QGtkStylePrivate::gtk_widget_get_style(gtkWidget("GtkMenu"))->bg[GTK_STATE_NORMAL];
- QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
- menuPal.setBrush(QPalette::Base, bgColor);
- menuPal.setBrush(QPalette::Window, bgColor);
- qApp->setPalette(menuPal, "QMenu");
-
- QPalette toolbarPal = gtkWidgetPalette("GtkToolbar");
- qApp->setPalette(toolbarPal, "QToolBar");
-
- QPalette menuBarPal = gtkWidgetPalette("GtkMenuBar");
- qApp->setPalette(menuBarPal, "QMenuBar");
-}
-
-/*! \internal
- * Returns the gtk Widget that should be used to determine text foreground and background colors.
-*/
-GtkWidget* QGtkStylePrivate::getTextColorWidget() const
-{
- return gtkWidget("GtkEntry");
-}
-
-void QGtkStylePrivate::setupGtkWidget(GtkWidget* widget)
-{
- if (Q_GTK_IS_WIDGET(widget)) {
- GtkWidget *protoLayout = gtkWidgetMap()->value("GtkContainer");
- if (!protoLayout) {
- protoLayout = QGtkStylePrivate::gtk_fixed_new();
- QGtkStylePrivate::gtk_container_add((GtkContainer*)(gtkWidgetMap()->value("GtkWindow")), protoLayout);
- QHashableLatin1Literal widgetPath = QHashableLatin1Literal::fromData(strdup("GtkContainer"));
- gtkWidgetMap()->insert(widgetPath, protoLayout);
- }
- Q_ASSERT(protoLayout);
-
- if (!QGtkStylePrivate::gtk_widget_get_parent(widget) && !QGtkStylePrivate::gtk_widget_is_toplevel(widget))
- QGtkStylePrivate::gtk_container_add((GtkContainer*)(protoLayout), widget);
- QGtkStylePrivate::gtk_widget_realize(widget);
- }
-}
-
-void QGtkStylePrivate::removeWidgetFromMap(const QHashableLatin1Literal &path)
-{
- WidgetMap *map = gtkWidgetMap();
- WidgetMap::iterator it = map->find(path);
- if (it != map->end()) {
- char* keyData = const_cast<char *>(it.key().data());
- map->erase(it);
- free(keyData);
- }
-}
-
-void QGtkStylePrivate::addWidgetToMap(GtkWidget *widget)
-{
- if (Q_GTK_IS_WIDGET(widget)) {
- gtk_widget_realize(widget);
- QHashableLatin1Literal widgetPath = classPath(widget);
-
- removeWidgetFromMap(widgetPath);
- gtkWidgetMap()->insert(widgetPath, widget);
-#ifdef DUMP_GTK_WIDGET_TREE
- qWarning("Inserted Gtk Widget: %s", widgetPath.data());
-#endif
- }
- }
-
-void QGtkStylePrivate::addAllSubWidgets(GtkWidget *widget, gpointer v)
-{
- Q_UNUSED(v);
- addWidgetToMap(widget);
- if (G_TYPE_CHECK_INSTANCE_TYPE ((widget), gtk_container_get_type()))
- gtk_container_forall((GtkContainer*)widget, addAllSubWidgets, NULL);
-}
-
-// Updates window/windowtext palette based on the indicated gtk widget
-QPalette QGtkStylePrivate::gtkWidgetPalette(const QHashableLatin1Literal &gtkWidgetName) const
-{
- GtkWidget *gtkWidget = QGtkStylePrivate::gtkWidget(gtkWidgetName);
- Q_ASSERT(gtkWidget);
- QPalette pal = QApplication::palette();
- GdkColor gdkBg = gtk_widget_get_style(gtkWidget)->bg[GTK_STATE_NORMAL];
- GdkColor gdkText = gtk_widget_get_style(gtkWidget)->fg[GTK_STATE_NORMAL];
- GdkColor gdkDisabledText = gtk_widget_get_style(gtkWidget)->fg[GTK_STATE_INSENSITIVE];
- QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8);
- QColor textColor(gdkText.red>>8, gdkText.green>>8, gdkText.blue>>8);
- QColor disabledTextColor(gdkDisabledText.red>>8, gdkDisabledText.green>>8, gdkDisabledText.blue>>8);
- pal.setBrush(QPalette::Window, bgColor);
- pal.setBrush(QPalette::Button, bgColor);
- pal.setBrush(QPalette::All, QPalette::WindowText, textColor);
- pal.setBrush(QPalette::Disabled, QPalette::WindowText, disabledTextColor);
- pal.setBrush(QPalette::All, QPalette::ButtonText, textColor);
- pal.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledTextColor);
- return pal;
-}
-
-
-void QGtkStyleUpdateScheduler::updateTheme()
-{
- static QString oldTheme(QLS("qt_not_set"));
- QPixmapCache::clear();
-
- QFont font = QGtkStylePrivate::getThemeFont();
- if (QApplication::font() != font)
- qApp->setFont(font);
-
- if (oldTheme != QGtkStylePrivate::getThemeName()) {
- oldTheme = QGtkStylePrivate::getThemeName();
- QPalette newPalette = qApp->style()->standardPalette();
- QApplicationPrivate::setSystemPalette(newPalette);
- QApplication::setPalette(newPalette);
- if (!QGtkStylePrivate::instances.isEmpty()) {
- QGtkStylePrivate::instances.last()->initGtkWidgets();
- QGtkStylePrivate::instances.last()->applyCustomPaletteHash();
- }
- QList<QWidget*> widgets = QApplication::allWidgets();
- // Notify all widgets that size metrics might have changed
- foreach (QWidget *widget, widgets) {
- QEvent e(QEvent::StyleChange);
- QApplication::sendEvent(widget, &e);
- }
- }
- QIconLoader::instance()->updateSystemTheme();
-}
-
-void QGtkStylePrivate::addWidget(GtkWidget *widget)
-{
- if (widget) {
- setupGtkWidget(widget);
- addAllSubWidgets(widget);
- }
-}
-
-
-// Fetch the application font from the pango font description
-// contained in the theme.
-QFont QGtkStylePrivate::getThemeFont()
-{
- QFont font;
- GtkStyle *style = gtkStyle();
- if (style && qApp->desktopSettingsAware())
- {
- PangoFontDescription *gtk_font = style->font_desc;
- font.setPointSizeF((float)(pango_font_description_get_size(gtk_font))/PANGO_SCALE);
-
- QString family = QString::fromLatin1(pango_font_description_get_family(gtk_font));
- if (!family.isEmpty())
- font.setFamily(family);
-
- const int weight = pango_font_description_get_weight(gtk_font);
- font.setWeight(QPlatformFontDatabase::weightFromInteger(weight));
-
- PangoStyle fontstyle = pango_font_description_get_style(gtk_font);
- if (fontstyle == PANGO_STYLE_ITALIC)
- font.setStyle(QFont::StyleItalic);
- else if (fontstyle == PANGO_STYLE_OBLIQUE)
- font.setStyle(QFont::StyleOblique);
- else
- font.setStyle(QFont::StyleNormal);
- }
- return font;
-}
-
-QIcon QGtkStylePrivate::getFilesystemIcon(const QFileInfo &info)
-{
- QIcon icon;
- if (isThemeAvailable() && gnome_vfs_init && gnome_icon_lookup_sync) {
- gnome_vfs_init();
- GtkIconTheme *theme = gtk_icon_theme_get_default();
- QByteArray fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded();
- char * icon_name = gnome_icon_lookup_sync(theme,
- NULL,
- fileurl.data(),
- NULL,
- GNOME_ICON_LOOKUP_FLAGS_NONE,
- NULL);
- QString iconName = QString::fromUtf8(icon_name);
- g_free(icon_name);
- if (iconName.startsWith(QLatin1Char('/')))
- return QIcon(iconName);
- return QIcon::fromTheme(iconName);
- }
- return icon;
-}
-
-bool operator==(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2)
-{
- return l1.size() == l2.size() || qstrcmp(l1.data(), l2.data()) == 0;
-}
-
-// copied from qHash.cpp
-uint qHash(const QHashableLatin1Literal &key)
-{
- int n = key.size();
- const uchar *p = reinterpret_cast<const uchar *>(key.data());
- uint h = 0;
- uint g;
-
- while (n--) {
- h = (h << 4) + *p++;
- if ((g = (h & 0xf0000000)) != 0)
- h ^= g >> 23;
- h &= ~g;
- }
- return h;
-}
-
-QT_END_NAMESPACE
-
-#endif // !defined(QT_NO_STYLE_GTK)
diff --git a/src/widgets/styles/qgtkstyle_p.h b/src/widgets/styles/qgtkstyle_p.h
deleted file mode 100644
index 3dcd7bf6ef..0000000000
--- a/src/widgets/styles/qgtkstyle_p.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGTKSTYLE_P_H
-#define QGTKSTYLE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qwindowsstyle_p.h>
-#include <QtGui/QPalette>
-#include <QtGui/QFont>
-#include <QtWidgets/QFileDialog>
-
-QT_BEGIN_NAMESPACE
-
-
-#if !defined(QT_NO_STYLE_GTK)
-
-class QPainterPath;
-class QGtkStylePrivate;
-
-class QGtkStyle : public QCommonStyle
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QGtkStyle)
-
-public:
- QGtkStyle();
- QGtkStyle(QGtkStylePrivate &dd);
-
- ~QGtkStyle();
-
- QPalette standardPalette() const Q_DECL_OVERRIDE;
-
- void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const Q_DECL_OVERRIDE;
- void drawControl(ControlElement control, const QStyleOption *option,
- QPainter *painter, const QWidget *widget) const Q_DECL_OVERRIDE;
- void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- QPainter *painter, const QWidget *widget) const Q_DECL_OVERRIDE;
- void drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
- const QPixmap &pixmap) const Q_DECL_OVERRIDE;
- void drawItemText(QPainter *painter, const QRect &rect, int alignment, const QPalette &pal,
- bool enabled, const QString& text, QPalette::ColorRole textRole) const Q_DECL_OVERRIDE;
-
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
- const QWidget *widget = 0) const Q_DECL_OVERRIDE;
- int styleHint(StyleHint hint, const QStyleOption *option,
- const QWidget *widget, QStyleHintReturn *returnData) const Q_DECL_OVERRIDE;
-
- QStyle::SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt,
- const QPoint &pt, const QWidget *w) const Q_DECL_OVERRIDE;
-
- QRect subControlRect(ComplexControl control, const QStyleOptionComplex *option,
- SubControl subControl, const QWidget *widget) const Q_DECL_OVERRIDE;
- QRect subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *w) const Q_DECL_OVERRIDE;
- QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const Q_DECL_OVERRIDE;
-
-
- QSize sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &size, const QWidget *widget) const Q_DECL_OVERRIDE;
- QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0,
- const QWidget *widget = 0) const Q_DECL_OVERRIDE;
- QPixmap standardPixmap(StandardPixmap sp, const QStyleOption *option,
- const QWidget *widget) const Q_DECL_OVERRIDE;
- QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
- const QStyleOption *opt) const Q_DECL_OVERRIDE;
-
- void polish(QWidget *widget) Q_DECL_OVERRIDE;
- void polish(QApplication *app) Q_DECL_OVERRIDE;
- void polish(QPalette &palette) Q_DECL_OVERRIDE;
-
- void unpolish(QWidget *widget) Q_DECL_OVERRIDE;
- void unpolish(QApplication *app) Q_DECL_OVERRIDE;
-
- static bool getGConfBool(const QString &key, bool fallback = 0);
- static QString getGConfString(const QString &key, const QString &fallback = QString());
-};
-
-#endif //!defined(QT_NO_STYLE_QGTK)
-
-QT_END_NAMESPACE
-
-#endif //QGTKSTYLE_P_H
diff --git a/src/widgets/styles/qgtkstyle_p_p.h b/src/widgets/styles/qgtkstyle_p_p.h
deleted file mode 100644
index 4cb03ed833..0000000000
--- a/src/widgets/styles/qgtkstyle_p_p.h
+++ /dev/null
@@ -1,449 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGTKSTYLE_P_P_H
-#define QGTKSTYLE_P_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#if !defined(QT_NO_STYLE_GTK)
-
-#include <QtCore/qstring.h>
-#include <QtCore/qstringbuilder.h>
-#include <QtCore/qcoreapplication.h>
-
-#include <QtWidgets/QFileDialog>
-
-#include <private/qgtkstyle_p.h>
-#include <private/qcommonstyle_p.h>
-#include <private/qgtkglobal_p.h>
-
-#define Q_GTK_IS_WIDGET(widget) widget && G_TYPE_CHECK_INSTANCE_TYPE ((widget), QGtkStylePrivate::gtk_widget_get_type())
-
-QT_BEGIN_NAMESPACE
-
-class QHashableLatin1Literal
-{
-public:
- int size() const { return m_size; }
- const char *data() const { return m_data; }
-
-#ifdef __SUNPRO_CC
- QHashableLatin1Literal(const char* str)
- : m_size(strlen(str)), m_data(str) {}
-#else
- template <int N>
- QHashableLatin1Literal(const char (&str)[N])
- : m_size(N - 1), m_data(str) {}
-#endif
-
- QHashableLatin1Literal(const QHashableLatin1Literal &other)
- : m_size(other.m_size), m_data(other.m_data)
- {}
-
- QHashableLatin1Literal &operator=(const QHashableLatin1Literal &other)
- {
- if (this == &other)
- return *this;
- *const_cast<int *>(&m_size) = other.m_size;
- *const_cast<char **>(&m_data) = const_cast<char *>(other.m_data);
- return *this;
- }
-
- QString toString() const { return QString::fromLatin1(m_data, m_size); }
-
- static QHashableLatin1Literal fromData(const char *str)
- {
- return QHashableLatin1Literal(str, qstrlen(str));
- }
-
-private:
- QHashableLatin1Literal(const char *str, int length)
- : m_size(length), m_data(str)
- {}
-
- const int m_size;
- const char *m_data;
-};
-
-bool operator==(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2);
-inline bool operator!=(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2) { return !operator==(l1, l2); }
-uint qHash(const QHashableLatin1Literal &key);
-
-QT_END_NAMESPACE
-
-class GConf;
-class GConfClient;
-typedef struct _XDisplay Display;
-
-typedef GConfClient* (*Ptr_gconf_client_get_default)();
-typedef char* (*Ptr_gconf_client_get_string)(GConfClient*, const char*, GError **);
-typedef bool (*Ptr_gconf_client_get_bool)(GConfClient*, const char*, GError **);
-
-typedef void (*Ptr_gtk_init)(int *, char ***);
-typedef GtkWidget* (*Ptr_gtk_window_new) (GtkWindowType);
-typedef GtkStyle* (*Ptr_gtk_style_attach)(GtkStyle *, GdkWindow *);
-typedef void (*Ptr_gtk_widget_destroy) (GtkWidget *);
-typedef void (*Ptr_gtk_widget_realize) (GtkWidget *);
-typedef void (*Ptr_gtk_widget_set_default_direction) (GtkTextDirection);
-typedef void (*Ptr_gtk_widget_modify_color)(GtkWidget *widget, GtkStateType state, const GdkColor *color);
-typedef GtkWidget* (*Ptr_gtk_arrow_new)(GtkArrowType, GtkShadowType);
-typedef GtkWidget* (*Ptr_gtk_menu_item_new_with_label)(const gchar *);
-typedef GtkWidget* (*Ptr_gtk_separator_menu_item_new)(void);
-typedef GtkWidget* (*Ptr_gtk_check_menu_item_new_with_label)(const gchar *);
-typedef GtkWidget* (*Ptr_gtk_menu_bar_new)(void);
-typedef GtkWidget* (*Ptr_gtk_menu_new)(void);
-typedef GtkWidget* (*Ptr_gtk_combo_box_new)(void);
-typedef GtkWidget* (*Ptr_gtk_combo_box_entry_new)(void);
-typedef GtkWidget* (*Ptr_gtk_toolbar_new)(void);
-typedef GtkWidget* (*Ptr_gtk_spin_button_new)(GtkAdjustment*, double, int);
-typedef GtkWidget* (*Ptr_gtk_button_new)(void);
-typedef GtkWidget* (*Ptr_gtk_tool_button_new)(GtkWidget *, const gchar *);
-typedef GtkWidget* (*Ptr_gtk_hbutton_box_new)(void);
-typedef GtkWidget* (*Ptr_gtk_check_button_new)(void);
-typedef GtkWidget* (*Ptr_gtk_radio_button_new)(GSList *);
-typedef GtkWidget* (*Ptr_gtk_notebook_new)(void);
-typedef GtkWidget* (*Ptr_gtk_progress_bar_new)(void);
-typedef GtkWidget* (*Ptr_gtk_hscale_new)(GtkAdjustment*);
-typedef GtkWidget* (*Ptr_gtk_vscale_new)(GtkAdjustment*);
-typedef GtkWidget* (*Ptr_gtk_hscrollbar_new)(GtkAdjustment*);
-typedef GtkWidget* (*Ptr_gtk_vscrollbar_new)(GtkAdjustment*);
-typedef GtkWidget* (*Ptr_gtk_scrolled_window_new)(GtkAdjustment*, GtkAdjustment*);
-typedef gchar* (*Ptr_gtk_check_version)(guint, guint, guint);
-typedef GtkToolItem* (*Ptr_gtk_separator_tool_item_new) (void);
-typedef GtkWidget* (*Ptr_gtk_entry_new)(void);
-typedef GtkWidget* (*Ptr_gtk_tree_view_new)(void);
-typedef GtkTreeViewColumn* (*Ptr_gtk_tree_view_get_column)(GtkTreeView *, gint);
-typedef GtkWidget* (*Ptr_gtk_frame_new)(const gchar *);
-typedef GtkWidget* (*Ptr_gtk_expander_new)(const gchar*);
-typedef GtkWidget* (*Ptr_gtk_statusbar_new)(void);
-typedef GtkSettings* (*Ptr_gtk_settings_get_default)(void);
-typedef GtkAdjustment* (*Ptr_gtk_range_get_adjustment)(GtkRange *);
-typedef void (*Ptr_gtk_range_set_adjustment)(GtkRange *, GtkAdjustment *);
-typedef void (*Ptr_gtk_range_set_inverted)(GtkRange*, bool);
-typedef void (*Ptr_gtk_container_add)(GtkContainer *container, GtkWidget *widget);
-typedef GtkIconSet* (*Ptr_gtk_icon_factory_lookup_default) (const gchar*);
-typedef GtkIconTheme* (*Ptr_gtk_icon_theme_get_default) (void);
-typedef GtkStyle* (*Ptr_gtk_widget_get_style)(GtkWidget *);
-typedef void (*Ptr_gtk_widget_style_get)(GtkWidget *, const gchar *first_property_name, ...);
-typedef GtkTreeViewColumn* (*Ptr_gtk_tree_view_column_new)(void);
-typedef GtkWidget* (*Ptr_gtk_fixed_new)(void);
-typedef GdkPixbuf* (*Ptr_gtk_icon_set_render_icon)(GtkIconSet *, GtkStyle *, GtkTextDirection, GtkStateType, GtkIconSize, GtkWidget *,const char *);
-typedef void (*Ptr_gtk_tree_view_append_column) (GtkTreeView*, GtkTreeViewColumn*);
-typedef void (*Ptr_gtk_adjustment_configure) (GtkAdjustment *, double, double, double, double, double, double);
-typedef GtkAdjustment* (*Ptr_gtk_adjustment_new) (double, double, double, double, double, double);
-typedef void (*Ptr_gtk_menu_item_set_submenu) (GtkMenuItem *, GtkWidget *);
-typedef void (*Ptr_gtk_container_forall) (GtkContainer *, GtkCallback, gpointer);
-typedef void (*Ptr_gtk_widget_size_allocate) (GtkWidget *, GtkAllocation*);
-typedef void (*Ptr_gtk_widget_size_request) (GtkWidget *widget, GtkRequisition *requisition);
-typedef void (*Ptr_gtk_widget_set_direction) (GtkWidget *, GtkTextDirection);
-typedef void (*Ptr_gtk_widget_path) (GtkWidget *, guint *, gchar **, gchar**);
-
-typedef void (*Ptr_gtk_toolbar_insert) (GtkToolbar *toolbar, GtkToolItem *item, int pos);
-typedef void (*Ptr_gtk_menu_shell_append)(GtkMenuShell *, GtkWidget *);
-typedef GType (*Ptr_gtk_container_get_type) (void);
-typedef GType (*Ptr_gtk_window_get_type) (void);
-typedef GType (*Ptr_gtk_widget_get_type) (void);
-typedef GtkWidget* (*Ptr_gtk_widget_get_parent) (GtkWidget *);
-typedef gboolean (*Ptr_gtk_widget_is_toplevel) (GtkWidget *);
-typedef GtkWidget* (*Ptr_gtk_widget_get_toplevel) (GtkWidget *);
-typedef GtkStyle* (*Ptr_gtk_rc_get_style_by_paths) (GtkSettings *, const char *, const char *, GType);
-typedef gint (*Ptr_pango_font_description_get_size) (const PangoFontDescription *);
-typedef PangoWeight (*Ptr_pango_font_description_get_weight) (const PangoFontDescription *);
-typedef const char* (*Ptr_pango_font_description_get_family) (const PangoFontDescription *);
-typedef PangoStyle (*Ptr_pango_font_description_get_style) (const PangoFontDescription *desc);
-typedef void (*Ptr_gtk_border_free)(GtkBorder *);
-typedef void (*Ptr_gtk_widget_get_allocation) (GtkWidget*, GtkAllocation*);
-typedef void (*Ptr_gtk_widget_set_allocation) (GtkWidget*, const GtkAllocation*);
-
-typedef void (*Ptr_gtk_widget_set_can_default) (GtkWidget*, gboolean);
-typedef void (*Ptr_gtk_window_set_default) (GtkWindow*, GtkWidget*);
-
-typedef GdkEvent* (*Ptr_gdk_event_new) (GdkEventType);
-typedef void (*Ptr_gdk_event_free) (GdkEvent*);
-typedef void (*Ptr_gtk_widget_send_focus_change) (GtkWidget*, GdkEvent*);
-
-typedef guchar* (*Ptr_gdk_pixbuf_get_pixels) (const GdkPixbuf *pixbuf);
-typedef int (*Ptr_gdk_pixbuf_get_width) (const GdkPixbuf *pixbuf);
-typedef void (*Ptr_gdk_color_free) (const GdkColor *);
-typedef int (*Ptr_gdk_pixbuf_get_height) (const GdkPixbuf *pixbuf);
-typedef GdkPixbuf* (*Ptr_gdk_pixbuf_new) (GdkColorspace colorspace, gboolean has_alpha,
- int bits_per_sample, int width, int height);
-typedef void (*Ptr_gdk_pixbuf_unref)(GdkPixbuf *);
-typedef void (*Ptr_gdk_x11_window_set_user_time) (GdkWindow *window, guint32);
-typedef XID (*Ptr_gdk_x11_drawable_get_xid) (GdkDrawable *);
-typedef Display* (*Ptr_gdk_x11_drawable_get_xdisplay) ( GdkDrawable *);
-
-
-QT_BEGIN_NAMESPACE
-
-class QGtkPainter;
-class QGtkStylePrivate;
-
-class QGtkStyleFilter : public QObject
-{
-public:
- QGtkStyleFilter(QGtkStylePrivate* sp)
- : stylePrivate(sp)
- {}
-private:
- QGtkStylePrivate* stylePrivate;
- bool eventFilter(QObject *obj, QEvent *e) Q_DECL_OVERRIDE;
-};
-
-typedef enum {
- GNOME_ICON_LOOKUP_FLAGS_NONE = 0,
- GNOME_ICON_LOOKUP_FLAGS_EMBEDDING_TEXT = 1<<0,
- GNOME_ICON_LOOKUP_FLAGS_SHOW_SMALL_IMAGES_AS_THEMSELVES = 1<<1,
- GNOME_ICON_LOOKUP_FLAGS_ALLOW_SVG_AS_THEMSELVES = 1<<2
-} GnomeIconLookupFlags;
-
-typedef enum {
- GNOME_ICON_LOOKUP_RESULT_FLAGS_NONE = 0,
- GNOME_ICON_LOOKUP_RESULT_FLAGS_THUMBNAIL = 1<<0
-} GnomeIconLookupResultFlags;
-
-struct GnomeThumbnailFactory;
-typedef gboolean (*Ptr_gnome_vfs_init) (void);
-typedef char* (*Ptr_gnome_icon_lookup_sync) (
- GtkIconTheme *icon_theme,
- GnomeThumbnailFactory *,
- const char *file_uri,
- const char *custom_icon,
- GnomeIconLookupFlags flags,
- GnomeIconLookupResultFlags *result);
-
-class QGtkStylePrivate : public QCommonStylePrivate
-{
- Q_DECLARE_PUBLIC(QGtkStyle)
-public:
- QGtkStylePrivate();
- ~QGtkStylePrivate();
-
- QGtkStyleFilter filter;
-
- static QGtkPainter* gtkPainter(QPainter *painter = 0);
- static GtkWidget* gtkWidget(const QHashableLatin1Literal &path);
- static GtkStyle* gtkStyle(const QHashableLatin1Literal &path = QHashableLatin1Literal("GtkWindow"));
- static void gtkWidgetSetFocus(GtkWidget *widget, bool focus);
-
- virtual void resolveGtk() const;
- virtual void initGtkMenu() const;
- virtual void initGtkTreeview() const;
- virtual void initGtkWidgets() const;
-
- static void cleanupGtkWidgets();
-
- static bool isKDE4Session();
- void applyCustomPaletteHash();
- static QFont getThemeFont();
- static bool isThemeAvailable() { return gtkStyle() != 0; }
-
- static bool getGConfBool(const QString &key, bool fallback = 0);
- static QString getGConfString(const QString &key, const QString &fallback = QString());
-
- static QString getThemeName();
- virtual int getSpinboxArrowSize() const;
-
- static QIcon getFilesystemIcon(const QFileInfo &);
-
- static Ptr_gtk_container_forall gtk_container_forall;
- static Ptr_gtk_init gtk_init;
- static Ptr_gtk_style_attach gtk_style_attach;
- static Ptr_gtk_window_new gtk_window_new;
- static Ptr_gtk_widget_destroy gtk_widget_destroy;
- static Ptr_gtk_widget_realize gtk_widget_realize;
- static Ptr_gtk_widget_set_default_direction gtk_widget_set_default_direction;
- static Ptr_gtk_widget_modify_color gtk_widget_modify_fg;
- static Ptr_gtk_widget_modify_color gtk_widget_modify_bg;
- static Ptr_gtk_menu_item_new_with_label gtk_menu_item_new_with_label;
- static Ptr_gtk_arrow_new gtk_arrow_new;
- static Ptr_gtk_check_menu_item_new_with_label gtk_check_menu_item_new_with_label;
- static Ptr_gtk_menu_bar_new gtk_menu_bar_new;
- static Ptr_gtk_menu_new gtk_menu_new;
- static Ptr_gtk_expander_new gtk_expander_new;
- static Ptr_gtk_button_new gtk_button_new;
- static Ptr_gtk_tool_button_new gtk_tool_button_new;
- static Ptr_gtk_hbutton_box_new gtk_hbutton_box_new;
- static Ptr_gtk_check_button_new gtk_check_button_new;
- static Ptr_gtk_radio_button_new gtk_radio_button_new;
- static Ptr_gtk_spin_button_new gtk_spin_button_new;
- static Ptr_gtk_separator_tool_item_new gtk_separator_tool_item_new;
- static Ptr_gtk_toolbar_insert gtk_toolbar_insert;
- static Ptr_gtk_frame_new gtk_frame_new;
- static Ptr_gtk_statusbar_new gtk_statusbar_new;
- static Ptr_gtk_entry_new gtk_entry_new;
- static Ptr_gtk_hscale_new gtk_hscale_new;
- static Ptr_gtk_vscale_new gtk_vscale_new;
- static Ptr_gtk_hscrollbar_new gtk_hscrollbar_new;
- static Ptr_gtk_vscrollbar_new gtk_vscrollbar_new;
- static Ptr_gtk_scrolled_window_new gtk_scrolled_window_new;
- static Ptr_gtk_notebook_new gtk_notebook_new;
- static Ptr_gtk_toolbar_new gtk_toolbar_new;
- static Ptr_gtk_tree_view_new gtk_tree_view_new;
- static Ptr_gtk_tree_view_get_column gtk_tree_view_get_column;
- static Ptr_gtk_combo_box_new gtk_combo_box_new;
- static Ptr_gtk_combo_box_entry_new gtk_combo_box_entry_new;
- static Ptr_gtk_progress_bar_new gtk_progress_bar_new;
- static Ptr_gtk_container_add gtk_container_add;
- static Ptr_gtk_menu_shell_append gtk_menu_shell_append;
- static Ptr_gtk_range_get_adjustment gtk_range_get_adjustment;
- static Ptr_gtk_range_set_adjustment gtk_range_set_adjustment;
- static Ptr_gtk_range_set_inverted gtk_range_set_inverted;
- static Ptr_gtk_icon_factory_lookup_default gtk_icon_factory_lookup_default;
- static Ptr_gtk_icon_theme_get_default gtk_icon_theme_get_default;
- static Ptr_gtk_widget_get_style gtk_widget_get_style;
- static Ptr_gtk_widget_style_get gtk_widget_style_get;
- static Ptr_gtk_icon_set_render_icon gtk_icon_set_render_icon;
- static Ptr_gtk_fixed_new gtk_fixed_new;
- static Ptr_gtk_tree_view_column_new gtk_tree_view_column_new;
- static Ptr_gtk_tree_view_append_column gtk_tree_view_append_column;
- static Ptr_gtk_adjustment_configure gtk_adjustment_configure;
- static Ptr_gtk_adjustment_new gtk_adjustment_new;
- static Ptr_gtk_menu_item_set_submenu gtk_menu_item_set_submenu;
- static Ptr_gtk_settings_get_default gtk_settings_get_default;
- static Ptr_gtk_separator_menu_item_new gtk_separator_menu_item_new;
- static Ptr_gtk_widget_size_allocate gtk_widget_size_allocate;
- static Ptr_gtk_widget_size_request gtk_widget_size_request;
- static Ptr_gtk_widget_set_direction gtk_widget_set_direction;
- static Ptr_gtk_widget_path gtk_widget_path;
- static Ptr_gtk_container_get_type gtk_container_get_type;
- static Ptr_gtk_window_get_type gtk_window_get_type;
- static Ptr_gtk_widget_get_type gtk_widget_get_type;
- static Ptr_gtk_widget_get_parent gtk_widget_get_parent;
- static Ptr_gtk_widget_is_toplevel gtk_widget_is_toplevel;
- static Ptr_gtk_widget_get_toplevel gtk_widget_get_toplevel;
- static Ptr_gtk_rc_get_style_by_paths gtk_rc_get_style_by_paths;
- static Ptr_gtk_check_version gtk_check_version;
- static Ptr_gtk_border_free gtk_border_free;
- static Ptr_gtk_widget_get_allocation gtk_widget_get_allocation;
- static Ptr_gtk_widget_set_allocation gtk_widget_set_allocation;
- static Ptr_gtk_widget_set_can_default gtk_widget_set_can_default;
- static Ptr_gtk_window_set_default gtk_window_set_default;
-
- static Ptr_gdk_event_new gdk_event_new;
- static Ptr_gdk_event_free gdk_event_free;
- static Ptr_gtk_widget_send_focus_change gtk_widget_send_focus_change;
-
- static Ptr_pango_font_description_get_size pango_font_description_get_size;
- static Ptr_pango_font_description_get_weight pango_font_description_get_weight;
- static Ptr_pango_font_description_get_family pango_font_description_get_family;
- static Ptr_pango_font_description_get_style pango_font_description_get_style;
-
- static Ptr_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels;
- static Ptr_gdk_pixbuf_get_width gdk_pixbuf_get_width;
- static Ptr_gdk_pixbuf_get_height gdk_pixbuf_get_height;
- static Ptr_gdk_pixbuf_new gdk_pixbuf_new;
- static Ptr_gdk_pixbuf_unref gdk_pixbuf_unref;
- static Ptr_gdk_color_free gdk_color_free;
- static Ptr_gdk_x11_window_set_user_time gdk_x11_window_set_user_time;
- static Ptr_gdk_x11_drawable_get_xid gdk_x11_drawable_get_xid;
- static Ptr_gdk_x11_drawable_get_xdisplay gdk_x11_drawable_get_xdisplay;
-
- static Ptr_gconf_client_get_default gconf_client_get_default;
- static Ptr_gconf_client_get_string gconf_client_get_string;
- static Ptr_gconf_client_get_bool gconf_client_get_bool;
-
- static Ptr_gnome_icon_lookup_sync gnome_icon_lookup_sync;
- static Ptr_gnome_vfs_init gnome_vfs_init;
-
- virtual QPalette gtkWidgetPalette(const QHashableLatin1Literal &gtkWidgetName) const;
-
-protected:
- typedef QHash<QHashableLatin1Literal, GtkWidget*> WidgetMap;
-
- static inline void destroyWidgetMap()
- {
- cleanupGtkWidgets();
- delete widgetMap;
- widgetMap = 0;
- }
-
- static inline WidgetMap *gtkWidgetMap()
- {
- if (!widgetMap) {
- widgetMap = new WidgetMap();
- qAddPostRoutine(destroyWidgetMap);
- }
- return widgetMap;
- }
-
- static QStringList extract_filter(const QString &rawFilter);
-
- virtual GtkWidget* getTextColorWidget() const;
- static void setupGtkWidget(GtkWidget* widget);
- static void addWidgetToMap(GtkWidget* widget);
- static void addAllSubWidgets(GtkWidget *widget, gpointer v = 0);
- static void addWidget(GtkWidget *widget);
- static void removeWidgetFromMap(const QHashableLatin1Literal &path);
-
- virtual void init();
-
- enum {
- menuItemFrame = 2, // menu item frame width
- menuItemHMargin = 3, // menu item hor text margin
- menuArrowHMargin = 6, // menu arrow horizontal margin
- menuItemVMargin = 2, // menu item ver text margin
- menuRightBorder = 15, // right border on menus
- menuCheckMarkWidth = 12 // checkmarks width on menus
- };
-
-private:
- static QList<QGtkStylePrivate *> instances;
- static WidgetMap *widgetMap;
- friend class QGtkStyleUpdateScheduler;
-};
-
-// Helper to ensure that we have polished all our gtk widgets
-// before updating our own palettes
-class QGtkStyleUpdateScheduler : public QObject
-{
- Q_OBJECT
-public slots:
- void updateTheme();
-};
-
-QT_END_NAMESPACE
-
-#endif // !QT_NO_STYLE_GTK
-#endif // QGTKSTYLE_P_P_H
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index ac23512f1d..db9a5351e1 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -36,7 +36,7 @@
.../doc/src/qstyles.qdoc.
*/
-#include <Cocoa/Cocoa.h>
+#include <AppKit/AppKit.h>
#include "qmacstyle_mac_p.h"
#include "qmacstyle_mac_p_p.h"
@@ -118,14 +118,13 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver);
- (void)scrollBarStyleDidChange:(NSNotification *)notification
{
Q_UNUSED(notification);
+
+ // purge destroyed scroll bars:
+ QMacStylePrivate::scrollBars.removeAll(QPointer<QObject>());
+
QEvent event(QEvent::StyleChange);
- QMutableVectorIterator<QPointer<QObject> > it(QMacStylePrivate::scrollBars);
- while (it.hasNext()) {
- if (!it.next())
- it.remove();
- else
- QCoreApplication::sendEvent(it.value(), &event);
- }
+ for (const auto &o : QMacStylePrivate::scrollBars)
+ QCoreApplication::sendEvent(o, &event);
}
@end
@@ -1110,6 +1109,17 @@ static void qt_drawFocusRingOnPath(CGContextRef cg, NSBezierPath *focusRingPath)
CGContextRestoreGState(cg);
}
+QAquaWidgetSize QMacStylePrivate::effectiveAquaSizeConstrain(const QStyleOption *option,
+ const QWidget *widg,
+ QStyle::ContentsType ct,
+ QSize szHint, QSize *insz) const
+{
+ QAquaWidgetSize sz = aquaSizeConstrain(option, widg, ct, szHint, insz);
+ if (sz == QAquaSizeUnknown)
+ return QAquaSizeLarge;
+ return sz;
+}
+
QAquaWidgetSize QMacStylePrivate::aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
QStyle::ContentsType ct, QSize szHint, QSize *insz) const
{
@@ -2475,32 +2485,9 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
ret = 0;
break;
case PM_TitleBarHeight:
- if (const QStyleOptionTitleBar *tb = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
- HIThemeWindowDrawInfo wdi;
- wdi.version = qt_mac_hitheme_version;
- wdi.state = kThemeStateActive;
- wdi.windowType = QtWinType;
- if (tb->titleBarState)
- wdi.attributes = kThemeWindowHasFullZoom | kThemeWindowHasCloseBox
- | kThemeWindowHasCollapseBox;
- else if (tb->titleBarFlags & Qt::WindowSystemMenuHint)
- wdi.attributes = kThemeWindowHasCloseBox;
- else
- wdi.attributes = 0;
- wdi.titleHeight = tb->rect.height();
- wdi.titleWidth = tb->rect.width();
- QCFType<HIShapeRef> region;
- HIRect hirect = qt_hirectForQRect(tb->rect);
- if (hirect.size.width <= 0)
- hirect.size.width = 100;
- if (hirect.size.height <= 0)
- hirect.size.height = 30;
-
- HIThemeGetWindowShape(&hirect, &wdi, kWindowTitleBarRgn, &region);
- HIRect rect;
- ptrHIShapeGetBounds(region, &rect);
- ret = int(rect.size.height);
- }
+ // Always use NSTitledWindowMask since we never need any other type of window here
+ ret = int([NSWindow frameRectForContentRect:NSZeroRect
+ styleMask:NSTitledWindowMask].size.height);
break;
case PM_TabBarTabVSpace:
ret = 4;
@@ -2530,29 +2517,10 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
}
break;
case PM_ScrollBarExtent: {
- if ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay) {
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- ret = QSysInfo::macVersion() >= QSysInfo::MV_10_8 ? 16 : 9;
- break;
- case QAquaSizeMini:
- case QAquaSizeSmall:
- ret = QSysInfo::macVersion() >= QSysInfo::MV_10_8 ? 14 : 7;
- break;
- }
- break;
- }
- switch (d->aquaSizeConstrain(opt, widget)) {
- case QAquaSizeUnknown:
- case QAquaSizeLarge:
- GetThemeMetric(kThemeMetricScrollBarWidth, &ret);
- break;
- case QAquaSizeMini:
- case QAquaSizeSmall:
- GetThemeMetric(kThemeMetricSmallScrollBarWidth, &ret);
- break;
- }
+ const QAquaWidgetSize size = d->effectiveAquaSizeConstrain(opt, widget);
+ ret = static_cast<SInt32>([NSScroller
+ scrollerWidthForControlSize:static_cast<NSControlSize>(size)
+ scrollerStyle:[NSScroller preferredScrollerStyle]]);
break; }
case PM_IndicatorHeight: {
switch (d->aquaSizeConstrain(opt, widget)) {
diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h
index 33818568ec..8e138ea887 100644
--- a/src/widgets/styles/qmacstyle_mac_p_p.h
+++ b/src/widgets/styles/qmacstyle_mac_p_p.h
@@ -172,6 +172,9 @@ public:
QAquaWidgetSize aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
QStyle::ContentsType ct = QStyle::CT_CustomBase,
QSize szHint=QSize(-1, -1), QSize *insz = 0) const;
+ QAquaWidgetSize effectiveAquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
+ QStyle::ContentsType ct = QStyle::CT_CustomBase,
+ QSize szHint=QSize(-1, -1), QSize *insz = 0) const;
void getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider,
HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe) const;
inline int animateSpeed(Animates) const { return 33; }
diff --git a/src/plugins/styles/bb10style/qpixmapstyle.cpp b/src/widgets/styles/qpixmapstyle.cpp
index 3090c42959..b2f2e91d5f 100644
--- a/src/plugins/styles/bb10style/qpixmapstyle.cpp
+++ b/src/widgets/styles/qpixmapstyle.cpp
@@ -1,9 +1,11 @@
/***************************************************************************
**
** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
+** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
@@ -31,7 +33,8 @@
**
****************************************************************************/
-#include "qpixmapstyle.h"
+#include "qpixmapstyle_p.h"
+#include "qpixmapstyle_p_p.h"
#include <QDebug>
#include <QTextEdit>
@@ -55,15 +58,47 @@
QT_BEGIN_NAMESPACE
-QPixmapStyle::QPixmapStyle() :
- QCommonStyle()
+/*!
+ \class QPixmapStyle
+ \brief The QPixmapStyle class provides mechanism for writing pixmap based styles.
+
+ \since 5.7
+ \ingroup appearance
+ \inmodule QtWidgets
+ \internal
+
+ This is a convenience class that enables the implementation of a widget style using
+ pixmaps, on the same fashion used by the \l{BorderImage} QML type.
+
+ In order to style a QWidget, one simply needs to call QPixmapStyle::addDescriptor()
+ or QPixmapStyle::addPixmap() with the id of the component to be styled, the path of
+ the image to be used, the margins and the tiling rules:
+
+ \snippet styles/qcustompixmapstyle.cpp 0
+
+ \sa QStyle, QCommonStyle
+*/
+
+/*!
+ \internal
+
+ Constructs a QPixmapStyle object.
+*/
+QPixmapStyle::QPixmapStyle()
+ : QCommonStyle(*new QPixmapStylePrivate)
{
}
+/*!
+ Destroys the QPixmapStyle object.
+*/
QPixmapStyle::~QPixmapStyle()
{
}
+/*!
+ \reimp
+*/
void QPixmapStyle::polish(QApplication *application)
{
QCommonStyle::polish(application);
@@ -72,13 +107,21 @@ void QPixmapStyle::polish(QApplication *application)
#endif
}
+/*!
+ \reimp
+*/
void QPixmapStyle::polish(QPalette &palette)
{
palette = proxy()->standardPalette();
}
+/*!
+ \reimp
+*/
void QPixmapStyle::polish(QWidget *widget)
{
+ Q_D(QPixmapStyle);
+
// Don't fill the interior of the QTextEdit
if (qobject_cast<QTextEdit*>(widget)) {
QPalette p = widget->palette();
@@ -91,7 +134,7 @@ void QPixmapStyle::polish(QWidget *widget)
pb->setAlignment(Qt::AlignCenter);
// Change the font size if needed, as it's used to compute the minimum size
QFont font = pb->font();
- font.setPixelSize(m_descriptors.value(PB_HBackground).size.height()/2);
+ font.setPixelSize(d->descriptors.value(PB_HBackground).size.height()/2);
pb->setFont(font);
}
@@ -116,8 +159,8 @@ void QPixmapStyle::polish(QWidget *widget)
QFrame *frame = qobject_cast<QFrame*>(list->parent());
if (frame) {
- const Descriptor &desc = m_descriptors.value(DD_PopupDown);
- const Pixmap &pix = m_pixmaps.value(DD_ItemSeparator);
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(DD_PopupDown);
+ const QPixmapStylePixmap &pix = d->pixmaps.value(DD_ItemSeparator);
frame->setContentsMargins(pix.margins.left(), desc.margins.top(),
pix.margins.right(), desc.margins.bottom());
frame->setAttribute(Qt::WA_TranslucentBackground);
@@ -147,6 +190,17 @@ void QPixmapStyle::polish(QWidget *widget)
QCommonStyle::polish(widget);
}
+/*!
+ \reimp
+*/
+void QPixmapStyle::unpolish(QApplication *application)
+{
+ QCommonStyle::unpolish(application);
+}
+
+/*!
+ \reimp
+*/
void QPixmapStyle::unpolish(QWidget *widget)
{
if (qobject_cast<QSlider*>(widget) ||
@@ -163,6 +217,9 @@ void QPixmapStyle::unpolish(QWidget *widget)
QCommonStyle::unpolish(widget);
}
+/*!
+ \reimp
+*/
void QPixmapStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) const
{
@@ -199,9 +256,14 @@ void QPixmapStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *o
}
}
+/*!
+ \reimp
+*/
void QPixmapStyle::drawControl(ControlElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) const
{
+ Q_D(const QPixmapStyle);
+
switch (element) {
case CE_ProgressBarGroove:
drawProgressBarBackground(option, painter, widget);
@@ -215,8 +277,8 @@ void QPixmapStyle::drawControl(ControlElement element, const QStyleOption *optio
case CE_ShapedFrame:
// NOTE: This will break if the private API of QComboBox changes drastically
if (qstrcmp(widget->metaObject()->className(),"QComboBoxPrivateContainer") == 0) {
- const Descriptor &desc = m_descriptors.value(DD_PopupDown);
- const Pixmap &pix = m_pixmaps.value(DD_ItemSeparator);
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(DD_PopupDown);
+ const QPixmapStylePixmap &pix = d->pixmaps.value(DD_ItemSeparator);
QRect rect = option->rect;
rect.adjust(-pix.margins.left(), -desc.margins.top(),
pix.margins.right(), desc.margins.bottom());
@@ -232,6 +294,9 @@ void QPixmapStyle::drawControl(ControlElement element, const QStyleOption *optio
}
}
+/*!
+ \reimp
+*/
void QPixmapStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option,
QPainter *painter, const QWidget *widget) const
{
@@ -250,6 +315,9 @@ void QPixmapStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl
}
}
+/*!
+ \reimp
+*/
QSize QPixmapStyle::sizeFromContents(ContentsType type, const QStyleOption *option,
const QSize &contentsSize, const QWidget *widget) const
{
@@ -272,14 +340,19 @@ QSize QPixmapStyle::sizeFromContents(ContentsType type, const QStyleOption *opti
return QCommonStyle::sizeFromContents(type, option, contentsSize, widget);
}
+/*!
+ \reimp
+*/
QRect QPixmapStyle::subElementRect(SubElement element, const QStyleOption *option,
const QWidget *widget) const
{
+ Q_D(const QPixmapStyle);
+
switch (element) {
case SE_LineEditContents:
{
QRect rect = QCommonStyle::subElementRect(element, option, widget);
- const Descriptor &desc = m_descriptors.value(LE_Enabled);
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(LE_Enabled);
rect.adjust(desc.margins.left(), desc.margins.top(),
-desc.margins.right(), -desc.margins.bottom());
rect = visualRect(option->direction, option->rect, rect);
@@ -291,6 +364,9 @@ QRect QPixmapStyle::subElementRect(SubElement element, const QStyleOption *optio
return QCommonStyle::subElementRect(element, option, widget);
}
+/*!
+ \reimp
+*/
QRect QPixmapStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *option,
SubControl sc, const QWidget *widget) const
{
@@ -305,45 +381,51 @@ QRect QPixmapStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex
return QCommonStyle::subControlRect(cc, option, sc, widget);
}
+/*!
+ \reimp
+*/
int QPixmapStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
const QWidget *widget) const
{
+ Q_D(const QPixmapStyle);
+
switch (metric) {
case PM_ButtonShiftHorizontal:
case PM_ButtonShiftVertical:
return 0;
case PM_DefaultFrameWidth:
if (qobject_cast<const QTextEdit*>(widget)) {
- const Descriptor &desc = m_descriptors.value(LE_Enabled);
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(LE_Enabled);
return qMax(qMax(desc.margins.left(), desc.margins.right()),
qMax(desc.margins.top(), desc.margins.bottom()));
}
return 0;
case PM_IndicatorWidth:
- return m_pixmaps.value(CB_Enabled).pixmap.width();
+ return d->pixmaps.value(CB_Enabled).pixmap.width();
case PM_IndicatorHeight:
- return m_pixmaps.value(CB_Enabled).pixmap.height();
+ return d->pixmaps.value(CB_Enabled).pixmap.height();
case PM_CheckBoxLabelSpacing:
{
- const Pixmap &pix = m_pixmaps.value(CB_Enabled);
+ const QPixmapStylePixmap &pix = d->pixmaps.value(CB_Enabled);
return qMax(qMax(pix.margins.left(), pix.margins.right()),
qMax(pix.margins.top(), pix.margins.bottom()));
}
case PM_ExclusiveIndicatorWidth:
- return m_pixmaps.value(RB_Enabled).pixmap.width();
+ return d->pixmaps.value(RB_Enabled).pixmap.width();
case PM_ExclusiveIndicatorHeight:
- return m_pixmaps.value(RB_Enabled).pixmap.height();
+ return d->pixmaps.value(RB_Enabled).pixmap.height();
case PM_RadioButtonLabelSpacing:
{
- const Pixmap &pix = m_pixmaps.value(RB_Enabled);
+ const QPixmapStylePixmap &pix = d->pixmaps.value(RB_Enabled);
return qMax(qMax(pix.margins.left(), pix.margins.right()),
qMax(pix.margins.top(), pix.margins.bottom()));
}
case PM_SliderThickness:
if (const QStyleOptionSlider *slider =
qstyleoption_cast<const QStyleOptionSlider*>(option)) {
- const Descriptor desc = m_descriptors.value(slider->orientation == Qt::Horizontal
- ? SG_HEnabled : SG_VEnabled);
+ const QPixmapStyleDescriptor desc =
+ d->descriptors.value(slider->orientation == Qt::Horizontal
+ ? SG_HEnabled : SG_VEnabled);
return slider->orientation == Qt::Horizontal
? desc.size.height() : desc.size.width();
}
@@ -351,8 +433,9 @@ int QPixmapStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
case PM_SliderControlThickness:
if (const QStyleOptionSlider *slider =
qstyleoption_cast<const QStyleOptionSlider*>(option)) {
- const Pixmap pix = m_pixmaps.value(slider->orientation == Qt::Horizontal
- ? SH_HEnabled : SH_VEnabled);
+ const QPixmapStylePixmap pix =
+ d->pixmaps.value(slider->orientation == Qt::Horizontal
+ ? SH_HEnabled : SH_VEnabled);
return slider->orientation == Qt::Horizontal
? pix.pixmap.height() : pix.pixmap.width();
}
@@ -360,8 +443,9 @@ int QPixmapStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
case PM_SliderLength:
if (const QStyleOptionSlider *slider =
qstyleoption_cast<const QStyleOptionSlider*>(option)) {
- const Pixmap pix = m_pixmaps.value(slider->orientation == Qt::Horizontal
- ? SH_HEnabled : SH_VEnabled);
+ const QPixmapStylePixmap pix =
+ d->pixmaps.value(slider->orientation == Qt::Horizontal
+ ? SH_HEnabled : SH_VEnabled);
return slider->orientation == Qt::Horizontal
? pix.pixmap.width() : pix.pixmap.height();
}
@@ -369,8 +453,9 @@ int QPixmapStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
case PM_ScrollBarExtent:
if (const QStyleOptionSlider *slider =
qstyleoption_cast<const QStyleOptionSlider*>(option)) {
- const Descriptor desc = m_descriptors.value(slider->orientation == Qt::Horizontal
- ? SB_Horizontal : SB_Vertical);
+ const QPixmapStyleDescriptor desc =
+ d->descriptors.value(slider->orientation == Qt::Horizontal
+ ? SB_Horizontal : SB_Vertical);
return slider->orientation == Qt::Horizontal
? desc.size.height() : desc.size.width();
}
@@ -383,6 +468,9 @@ int QPixmapStyle::pixelMetric(PixelMetric metric, const QStyleOption *option,
return QCommonStyle::pixelMetric(metric, option, widget);
}
+/*!
+ \reimp
+*/
int QPixmapStyle::styleHint(StyleHint hint, const QStyleOption *option,
const QWidget *widget, QStyleHintReturn *returnData) const
{
@@ -397,6 +485,9 @@ int QPixmapStyle::styleHint(StyleHint hint, const QStyleOption *option,
return QCommonStyle::styleHint(hint, option, widget, returnData);
}
+/*!
+ \reimp
+*/
QStyle::SubControl QPixmapStyle::hitTestComplexControl(QStyle::ComplexControl control,
const QStyleOptionComplex *option,
const QPoint &pos,
@@ -413,8 +504,13 @@ QStyle::SubControl QPixmapStyle::hitTestComplexControl(QStyle::ComplexControl co
return sc;
}
+/*!
+ \reimp
+*/
bool QPixmapStyle::eventFilter(QObject *watched, QEvent *event)
{
+ Q_D(QPixmapStyle);
+
if (QSlider *slider = qobject_cast<QSlider*>(watched)) {
switch (event->type()) {
case QEvent::MouseButtonPress:
@@ -453,7 +549,7 @@ bool QPixmapStyle::eventFilter(QObject *watched, QEvent *event)
int yPopup = widget->geometry().top();
int yCombo = widget->parentWidget()->mapToGlobal(QPoint(0, 0)).y();
QRect geom = widget->geometry();
- const Descriptor &desc = m_descriptors.value(DD_ButtonEnabled);
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(DD_ButtonEnabled);
const bool up = yPopup < yCombo;
geom.moveTop(geom.top() + (up ? desc.margins.top() : -desc.margins.bottom()));
widget->setGeometry(geom);
@@ -465,12 +561,28 @@ bool QPixmapStyle::eventFilter(QObject *watched, QEvent *event)
return QCommonStyle::eventFilter(watched, event);
}
+/*!
+ \fn void QPixmapStyle::addDescriptor(QPixmapStyle::ControlDescriptor control, const QString &fileName, QMargins margins, QTileRules tileRules)
+
+ Associates the pixmap having the given \a fileName with the given \a control. The \a margins parameter describe the boundaries
+ of the pixmap's top-left, top-right, bottom-left and bottom-right corners, as well as the left, right, top and bottorm segments
+ and the middle. The \a tileRules parameter describes how QPixmapStyle is supposed to handle the scaling of the center of the pixmap.
+
+ Use QPixmapStyle::addPixmap() for controls that are not resizable.
+
+ \snippet styles/qcustompixmapstyle.cpp 1
+
+ \sa addPixmap, copyDescriptor
+
+*/
void QPixmapStyle::addDescriptor(QPixmapStyle::ControlDescriptor control, const QString &fileName,
QMargins margins, QTileRules tileRules)
{
- Descriptor desc;
+ Q_D(QPixmapStyle);
+ QPixmapStyleDescriptor desc;
QImage image(fileName);
+
if (image.isNull())
return;
@@ -479,46 +591,87 @@ void QPixmapStyle::addDescriptor(QPixmapStyle::ControlDescriptor control, const
desc.tileRules = tileRules;
desc.size = image.size();
- m_descriptors[control] = desc;
+ d->descriptors[control] = desc;
}
+/*!
+ \fn void QPixmapStyle::copyDescriptor(QPixmapStyle::ControlDescriptor source, QPixmapStyle::ControlDescriptor dest)
+
+ Copies the data associated with the \a source descriptor to the \a dest descriptor.
+
+ \snippet styles/qcustompixmapstyle.cpp 2
+*/
+
void QPixmapStyle::copyDescriptor(QPixmapStyle::ControlDescriptor source,
QPixmapStyle::ControlDescriptor dest)
{
- m_descriptors[dest] = m_descriptors.value(source);
+ Q_D(QPixmapStyle);
+ d->descriptors[dest] = d->descriptors.value(source);
}
+/*!
+ \fn void QPixmapStyle::drawCachedPixmap(QPixmapStyle::ControlDescriptor control, const QRect &rect, QPainter *painter) const
+
+ Draws the image associated with the current \a control on the given \a rect using the given \a painter.
+*/
void QPixmapStyle::drawCachedPixmap(QPixmapStyle::ControlDescriptor control, const QRect &rect,
QPainter *p) const
{
- if (!m_descriptors.contains(control))
+ Q_D(const QPixmapStyle);
+ if (!d->descriptors.contains(control))
return;
- const Descriptor &desc = m_descriptors.value(control);
- const QPixmap pix = getCachedPixmap(control, desc, rect.size());
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(control);
+ const QPixmap pix = d->getCachedPixmap(control, desc, rect.size());
Q_ASSERT(!pix.isNull());
p->drawPixmap(rect, pix);
}
+/*!
+ \fn void QPixmapStyle::addPixmap(ControlPixmap control, const QString &fileName, QMargins margins)
+
+ Use this function to style statically sized controls such as check boxes.
+
+ \sa addDescriptor, copyPixmap
+*/
void QPixmapStyle::addPixmap(ControlPixmap control, const QString &fileName,
QMargins margins)
{
- Pixmap pix;
+ Q_D(QPixmapStyle);
+ QPixmapStylePixmap pix;
QPixmap image(fileName);
+
if (image.isNull())
return;
pix.pixmap = image;
pix.margins = margins;
- m_pixmaps[control] = pix;
+ d->pixmaps[control] = pix;
}
+/*
+ \fn void QPixmapStyle::copyPixmap(QPixmapStyle::ControlPixmap source, QPixmapStyle::ControlPixmap dest)
+
+ Copies the data associated with the \a source pixmap to the \a dest pixmap.
+
+ \sa addPixmap, addDescriptor, copyDescriptor
+*/
void QPixmapStyle::copyPixmap(QPixmapStyle::ControlPixmap source, QPixmapStyle::ControlPixmap dest)
{
- m_pixmaps[dest] = m_pixmaps.value(source);
+ Q_D(QPixmapStyle);
+ d->pixmaps[dest] = d->pixmaps.value(source);
}
+/*!
+ \internal
+
+ Constructs a QPixmapStyle object.
+*/
+QPixmapStyle::QPixmapStyle(QPixmapStylePrivate &dd)
+ : QCommonStyle(dd)
+{}
+
void QPixmapStyle::drawPushButton(const QStyleOption *option,
QPainter *painter, const QWidget *) const
{
@@ -559,6 +712,8 @@ void QPixmapStyle::drawTextEdit(const QStyleOption *option,
void QPixmapStyle::drawCheckBox(const QStyleOption *option,
QPainter *painter, const QWidget *) const
{
+ Q_D(const QPixmapStyle);
+
const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option);
const bool down = button->state & State_Sunken;
@@ -570,12 +725,14 @@ void QPixmapStyle::drawCheckBox(const QStyleOption *option,
control = on ? (down ? CB_PressedChecked : CB_Checked) : (down ? CB_Pressed : CB_Enabled);
else
control = on ? CB_DisabledChecked : CB_Disabled;
- painter->drawPixmap(button->rect, m_pixmaps.value(control).pixmap);
+ painter->drawPixmap(button->rect, d->pixmaps.value(control).pixmap);
}
void QPixmapStyle::drawRadioButton(const QStyleOption *option,
QPainter *painter, const QWidget *) const
{
+ Q_D(const QPixmapStyle);
+
const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton*>(option);
const bool down = button->state & State_Sunken;
@@ -587,12 +744,14 @@ void QPixmapStyle::drawRadioButton(const QStyleOption *option,
control = on ? RB_Checked : (down ? RB_Pressed : RB_Enabled);
else
control = on ? RB_DisabledChecked : RB_Disabled;
- painter->drawPixmap(button->rect, m_pixmaps.value(control).pixmap);
+ painter->drawPixmap(button->rect, d->pixmaps.value(control).pixmap);
}
void QPixmapStyle::drawPanelItemViewItem(const QStyleOption *option, QPainter *painter,
const QWidget *widget) const
{
+ Q_D(const QPixmapStyle);
+
ControlPixmap cp = ID_Separator;
ControlDescriptor cd = ID_Selected;
@@ -601,7 +760,7 @@ void QPixmapStyle::drawPanelItemViewItem(const QStyleOption *option, QPainter *p
cd = DD_ItemSelected;
}
- QPixmap pix = m_pixmaps.value(cp).pixmap;
+ QPixmap pix = d->pixmaps.value(cp).pixmap;
QRect rect = option->rect;
rect.setBottom(rect.top() + pix.height()-1);
painter->drawPixmap(rect, pix);
@@ -676,6 +835,8 @@ void QPixmapStyle::drawProgressBarFill(const QStyleOption *option,
void QPixmapStyle::drawSlider(const QStyleOptionComplex *option,
QPainter *painter, const QWidget *widget) const
{
+ Q_D(const QPixmapStyle);
+
const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option);
if (!slider)
return;
@@ -704,8 +865,8 @@ void QPixmapStyle::drawSlider(const QStyleOptionComplex *option,
control = enabled ? (pressed ? SG_VActivePressed : SG_VActiveEnabled )
: SG_VActiveDisabled;
}
- const Descriptor &desc = m_descriptors.value(control);
- const QPixmap pix = getCachedPixmap(control, desc, groove.size());
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(control);
+ const QPixmap pix = d->getCachedPixmap(control, desc, groove.size());
if (!pix.isNull()) {
groove.setRight(orient == Qt::Horizontal
? handle.center().x() : handle.center().y());
@@ -720,7 +881,7 @@ void QPixmapStyle::drawSlider(const QStyleOptionComplex *option,
pix = enabled ? (pressed ? SH_HPressed : SH_HEnabled) : SH_HDisabled;
else
pix = enabled ? (pressed ? SH_VPressed : SH_VEnabled) : SH_VDisabled;
- painter->drawPixmap(handle, m_pixmaps.value(pix).pixmap);
+ painter->drawPixmap(handle, d->pixmaps.value(pix).pixmap);
}
}
}
@@ -728,6 +889,8 @@ void QPixmapStyle::drawSlider(const QStyleOptionComplex *option,
void QPixmapStyle::drawComboBox(const QStyleOptionComplex *option,
QPainter *painter, const QWidget *widget) const
{
+ Q_D(const QPixmapStyle);
+
const bool enabled = option->state & State_Enabled;
const bool pressed = widget->property("_pixmapstyle_combobox_pressed").toBool();
const bool opened = option->state & State_On;
@@ -739,7 +902,7 @@ void QPixmapStyle::drawComboBox(const QStyleOptionComplex *option,
ControlPixmap cp = enabled ? (opened ? DD_ArrowOpen
: (pressed ? DD_ArrowPressed : DD_ArrowEnabled))
: DD_ArrowDisabled;
- Pixmap pix = m_pixmaps.value(cp);
+ QPixmapStylePixmap pix = d->pixmaps.value(cp);
QRect rect = comboBoxSubControlRect(option, SC_ComboBoxArrow, widget);
painter->drawPixmap(rect, pix.pixmap);
}
@@ -764,7 +927,9 @@ QSize QPixmapStyle::pushButtonSizeFromContents(const QStyleOption *option,
const QSize &contentsSize,
const QWidget *widget) const
{
- const Descriptor &desc = m_descriptors.value(PB_Enabled);
+ Q_D(const QPixmapStyle);
+
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(PB_Enabled);
const int bm = proxy()->pixelMetric(PM_ButtonMargin, option, widget);
int w = contentsSize.width();
@@ -772,25 +937,29 @@ QSize QPixmapStyle::pushButtonSizeFromContents(const QStyleOption *option,
w += desc.margins.left() + desc.margins.right() + bm;
h += desc.margins.top() + desc.margins.bottom() + bm;
- return computeSize(desc, w, h);
+ return d->computeSize(desc, w, h);
}
QSize QPixmapStyle::lineEditSizeFromContents(const QStyleOption *,
const QSize &contentsSize, const QWidget *) const
{
- const Descriptor &desc = m_descriptors.value(LE_Enabled);
+ Q_D(const QPixmapStyle);
+
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(LE_Enabled);
const int border = 2 * proxy()->pixelMetric(PM_DefaultFrameWidth);
int w = contentsSize.width() + border + desc.margins.left() + desc.margins.right();
int h = contentsSize.height() + border + desc.margins.top() + desc.margins.bottom();
- return computeSize(desc, w, h);
+ return d->computeSize(desc, w, h);
}
QSize QPixmapStyle::progressBarSizeFromContents(const QStyleOption *option,
const QSize &contentsSize,
const QWidget *widget) const
{
+ Q_D(const QPixmapStyle);
+
bool vertical = false;
if (const QStyleOptionProgressBar *pb =
qstyleoption_cast<const QStyleOptionProgressBar *>(option)) {
@@ -798,10 +967,10 @@ QSize QPixmapStyle::progressBarSizeFromContents(const QStyleOption *option,
}
QSize result = QCommonStyle::sizeFromContents(CT_Slider, option, contentsSize, widget);
if (vertical) {
- const Descriptor desc = m_descriptors.value(PB_VBackground);
+ const QPixmapStyleDescriptor desc = d->descriptors.value(PB_VBackground);
return QSize(desc.size.height(), result.height());
} else {
- const Descriptor desc = m_descriptors.value(PB_HBackground);
+ const QPixmapStyleDescriptor desc = d->descriptors.value(PB_HBackground);
return QSize(result.width(), desc.size.height());
}
}
@@ -810,13 +979,15 @@ QSize QPixmapStyle::sliderSizeFromContents(const QStyleOption *option,
const QSize &contentsSize,
const QWidget *widget) const
{
+ Q_D(const QPixmapStyle);
+
const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider*>(option);
if (!slider)
return QSize();
QSize result = QCommonStyle::sizeFromContents(CT_Slider, option, contentsSize, widget);
- const Descriptor desc = m_descriptors.value(slider->orientation == Qt::Horizontal
+ const QPixmapStyleDescriptor desc = d->descriptors.value(slider->orientation == Qt::Horizontal
? SG_HEnabled : SG_VEnabled);
if (slider->orientation == Qt::Horizontal)
@@ -829,16 +1000,20 @@ QSize QPixmapStyle::comboBoxSizeFromContents(const QStyleOption *option,
const QSize &contentsSize,
const QWidget *widget) const
{
- const Descriptor &desc = m_descriptors.value(DD_ButtonEnabled);
+ Q_D(const QPixmapStyle);
+
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(DD_ButtonEnabled);
QSize result = QCommonStyle::sizeFromContents(CT_ComboBox, option, contentsSize, widget);
- return computeSize(desc, result.width(), result.height());
+ return d->computeSize(desc, result.width(), result.height());
}
QSize QPixmapStyle::itemViewSizeFromContents(const QStyleOption *option,
const QSize &contentsSize,
const QWidget *widget) const
{
+ Q_D(const QPixmapStyle);
+
QSize size = QCommonStyle::sizeFromContents(CT_ItemViewItem, option, contentsSize, widget);
ControlPixmap cp = ID_Separator;
@@ -848,8 +1023,8 @@ QSize QPixmapStyle::itemViewSizeFromContents(const QStyleOption *option,
cd = DD_ItemSelected;
}
- const Descriptor &desc = m_descriptors.value(cd);
- const Pixmap &pix = m_pixmaps.value(cp);
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(cd);
+ const QPixmapStylePixmap &pix = d->pixmaps.value(cp);
size.setHeight(qMax(size.height(),
desc.size.height() + pix.pixmap.height()));
return size;
@@ -858,9 +1033,11 @@ QSize QPixmapStyle::itemViewSizeFromContents(const QStyleOption *option,
QRect QPixmapStyle::comboBoxSubControlRect(const QStyleOptionComplex *option,
QStyle::SubControl sc, const QWidget *) const
{
+ Q_D(const QPixmapStyle);
+
QRect r = option->rect; // Default size
- const Pixmap &pix = m_pixmaps.value(DD_ArrowEnabled);
- const Descriptor &desc = m_descriptors.value(DD_ButtonEnabled);
+ const QPixmapStylePixmap &pix = d->pixmaps.value(DD_ArrowEnabled);
+ const QPixmapStyleDescriptor &desc = d->descriptors.value(DD_ButtonEnabled);
switch (sc) {
case SC_ComboBoxArrow:
@@ -933,7 +1110,7 @@ QRect QPixmapStyle::scrollBarSubControlRect(const QStyleOptionComplex *option,
return QRect();
}
-static QPixmap scale(int w, int h, const QPixmap &pixmap, const QPixmapStyle::Descriptor &desc)
+QPixmap QPixmapStylePrivate::scale(int w, int h, const QPixmap &pixmap, const QPixmapStyleDescriptor &desc)
{
QPixmap result(w, h);
{
@@ -947,12 +1124,15 @@ static QPixmap scale(int w, int h, const QPixmap &pixmap, const QPixmapStyle::De
return result;
}
-QPixmap QPixmapStyle::getCachedPixmap(ControlDescriptor control, const Descriptor &desc,
- const QSize &size) const
+QPixmap QPixmapStylePrivate::getCachedPixmap(QPixmapStyle::ControlDescriptor control,
+ const QPixmapStyleDescriptor &desc,
+ const QSize &size) const
{
+ Q_Q(const QPixmapStyle);
+
const QString sizeString = QString::number(size.width()) % QLatin1Char('*')
% QString::number(size.height());
- const QString key = QLatin1String(metaObject()->className()) % QString::number(control)
+ const QString key = QLatin1String(q->metaObject()->className()) % QString::number(control)
% QLatin1Char('@') % sizeString;
QPixmap result;
@@ -965,7 +1145,7 @@ QPixmap QPixmapStyle::getCachedPixmap(ControlDescriptor control, const Descripto
return result;
}
-QSize QPixmapStyle::computeSize(const QPixmapStyle::Descriptor &desc, int width, int height) const
+QSize QPixmapStylePrivate::computeSize(const QPixmapStyleDescriptor &desc, int width, int height) const
{
if (desc.tileRules.horizontal != Qt::RepeatTile)
width = qMax(width, desc.size.width());
diff --git a/src/plugins/styles/bb10style/qpixmapstyle.h b/src/widgets/styles/qpixmapstyle_p.h
index 3f35e79f23..4f5d27c285 100644
--- a/src/plugins/styles/bb10style/qpixmapstyle.h
+++ b/src/widgets/styles/qpixmapstyle_p.h
@@ -1,9 +1,11 @@
/***************************************************************************
**
** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
+** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
@@ -34,30 +36,31 @@
#ifndef QPIXMAPSTYLE_H
#define QPIXMAPSTYLE_H
-#include <QCommonStyle>
-#include <QString>
-#include <QPixmap>
-#include <QMargins>
-#include <QTileRules>
-#include <QHash>
-#include <QPainter>
+#include <QtWidgets/QCommonStyle>
+#include <QtWidgets/QTileRules>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
QT_BEGIN_NAMESPACE
-class QPixmapStyle : public QCommonStyle
+class QPixmapStylePrivate;
+
+class Q_WIDGETS_EXPORT QPixmapStyle : public QCommonStyle
{
Q_OBJECT
public:
- struct Descriptor {
- QString fileName;
- QSize size;
- QMargins margins;
- QTileRules tileRules;
- };
-
enum ControlDescriptor {
- BG_Background=0,
+ BG_Background,
LE_Enabled, // QLineEdit
LE_Disabled,
LE_Focused,
@@ -96,10 +99,6 @@ public:
SB_Vertical
};
- struct Pixmap {
- QPixmap pixmap;
- QMargins margins;
- };
enum ControlPixmap {
CB_Enabled, // QCheckBox
CB_Checked,
@@ -130,35 +129,35 @@ public:
QPixmapStyle();
~QPixmapStyle();
- void polish(QApplication *application);
- void polish(QPalette &palette);
- void polish(QWidget *widget);
- void unpolish(QWidget *widget);
+ void polish(QApplication *application) Q_DECL_OVERRIDE;
+ void polish(QPalette &palette) Q_DECL_OVERRIDE;
+ void polish(QWidget *widget) Q_DECL_OVERRIDE;
+ void unpolish(QApplication *application) Q_DECL_OVERRIDE;
+ void unpolish(QWidget *widget) Q_DECL_OVERRIDE;
void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget = 0) const;
+ QPainter *painter, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE;
void drawControl(ControlElement element, const QStyleOption *option,
- QPainter *painter, const QWidget *widget = 0) const;
+ QPainter *painter, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE;
void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *option,
- QPainter *painter, const QWidget *widget=0) const;
+ QPainter *painter, const QWidget *widget=0) const Q_DECL_OVERRIDE;
QSize sizeFromContents(ContentsType type, const QStyleOption *option,
- const QSize &contentsSize, const QWidget *widget = 0) const;
+ const QSize &contentsSize, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE;
QRect subElementRect(SubElement element, const QStyleOption *option,
- const QWidget *widget = 0) const;
+ const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE;
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *option,
- SubControl sc, const QWidget *widget = 0) const;
+ SubControl sc, const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE;
- int pixelMetric(PixelMetric metric, const QStyleOption *option = 0,
- const QWidget *widget = 0) const;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = Q_NULLPTR,
+ const QWidget *widget = Q_NULLPTR) const Q_DECL_OVERRIDE;
int styleHint(StyleHint hint, const QStyleOption *option,
- const QWidget *widget, QStyleHintReturn *returnData) const;
+ const QWidget *widget, QStyleHintReturn *returnData) const Q_DECL_OVERRIDE;
SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option,
- const QPoint &pos, const QWidget *widget) const;
+ const QPoint &pos, const QWidget *widget) const Q_DECL_OVERRIDE;
- bool eventFilter(QObject *watched, QEvent *event);
+ bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE;
-protected:
void addDescriptor(ControlDescriptor control, const QString &fileName,
QMargins margins = QMargins(),
QTileRules tileRules = QTileRules(Qt::RepeatTile, Qt::RepeatTile));
@@ -169,6 +168,7 @@ protected:
QMargins margins = QMargins());
void copyPixmap(ControlPixmap source, ControlPixmap dest);
+protected:
void drawPushButton(const QStyleOption *option,
QPainter *painter, const QWidget *widget) const;
void drawLineEdit(const QStyleOption *option,
@@ -207,20 +207,16 @@ protected:
QSize itemViewSizeFromContents(const QStyleOption *option,
const QSize &contentsSize, const QWidget *widget) const;
- QRect comboBoxSubControlRect(const QStyleOptionComplex *option,
- SubControl sc, const QWidget *widget) const;
- QRect scrollBarSubControlRect(const QStyleOptionComplex *option,
- SubControl sc, const QWidget *widget) const;
+ QRect comboBoxSubControlRect(const QStyleOptionComplex *option, QPixmapStyle::SubControl sc,
+ const QWidget *widget) const;
+ QRect scrollBarSubControlRect(const QStyleOptionComplex *option, QPixmapStyle::SubControl sc,
+ const QWidget *widget) const;
-private:
- QPixmap getCachedPixmap(ControlDescriptor control,
- const Descriptor &desc, const QSize &size) const;
-
- QSize computeSize(const Descriptor &desc, int width, int height) const;
+protected:
+ QPixmapStyle(QPixmapStylePrivate &dd);
private:
- QHash<ControlDescriptor, Descriptor> m_descriptors;
- QHash<ControlPixmap, Pixmap> m_pixmaps;
+ Q_DECLARE_PRIVATE(QPixmapStyle)
};
QT_END_NAMESPACE
diff --git a/src/widgets/styles/qpixmapstyle_p_p.h b/src/widgets/styles/qpixmapstyle_p_p.h
new file mode 100644
index 0000000000..6fb274d3a5
--- /dev/null
+++ b/src/widgets/styles/qpixmapstyle_p_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPIXMAPSTYLE_P_H
+#define QPIXMAPSTYLE_P_H
+
+#include "qpixmapstyle_p.h"
+#include "qcommonstyle_p.h"
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+struct QPixmapStyleDescriptor
+{
+ QString fileName;
+ QSize size;
+ QMargins margins;
+ QTileRules tileRules;
+};
+
+struct QPixmapStylePixmap
+{
+ QPixmap pixmap;
+ QMargins margins;
+};
+
+class QPixmapStylePrivate : public QCommonStylePrivate
+{
+ Q_DECLARE_PUBLIC(QPixmapStyle)
+
+public:
+ QHash<QPixmapStyle::ControlDescriptor, QPixmapStyleDescriptor> descriptors;
+ QHash<QPixmapStyle::ControlPixmap, QPixmapStylePixmap> pixmaps;
+
+ static QPixmap scale(int w, int h, const QPixmap &pixmap, const QPixmapStyleDescriptor &desc);
+
+ QPixmap getCachedPixmap(QPixmapStyle::ControlDescriptor control,
+ const QPixmapStyleDescriptor &desc,
+ const QSize &size) const;
+
+ QSize computeSize(const QPixmapStyleDescriptor &desc, int width, int height) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPIXMAPSTYLE_P_H
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 02c420e55c..9bca11b992 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -691,7 +691,9 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value PE_PanelToolBar The panel for a toolbar.
\value PE_PanelTipLabel The panel for a tip label.
\value PE_FrameTabBarBase The frame that is drawn for a tab bar, ususally drawn for a tab bar that isn't part of a tab widget.
- \value PE_IndicatorTabTear An indicator that a tab is partially scrolled out of the visible tab bar when there are many tabs.
+ \value PE_IndicatorTabTear Deprecated. Use \l{PE_IndicatorTabTearLeft} instead.
+ \value PE_IndicatorTabTearLeft An indicator that a tab is partially scrolled out on the left side of the visible tab bar when there are many tabs.
+ \value PE_IndicatorTabTearRight An indicator that a tab is partially scrolled out on the right side of the visible tab bar when there are many tabs.
\value PE_IndicatorColumnViewArrow An arrow in a QColumnView.
\value PE_Widget A plain QWidget.
@@ -1057,7 +1059,12 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SE_ItemViewItemCheckIndicator Area for a view item's check mark.
- \value SE_TabBarTearIndicator Area for the tear indicator on a tab bar with scroll arrows.
+ \value SE_TabBarTearIndicator Deprecated. Use SE_TabBarTearIndicatorLeft instead.
+ \value SE_TabBarTearIndicatorLeft Area for the tear indicator on the left side of a tab bar with scroll arrows.
+ \value SE_TabBarTearIndicatorRight Area for the tear indicator on the right side of a tab bar with scroll arrows.
+
+ \value SE_TabBarScrollLeftButton Area for the scroll left button on a tab bar with scroll buttons.
+ \value SE_TabBarScrollRightButton Area for the scroll right button on a tab bar with scroll buttons.
\value SE_TreeViewDisclosureItem Area for the actual disclosure item in a tree branch.
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index 1e9d15c993..dad93ec0fc 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -134,7 +134,7 @@ public:
PE_FrameGroupBox,
PE_FrameLineEdit,
PE_FrameMenu,
- PE_FrameStatusBar, // obsolete
+ PE_FrameStatusBar, // ### Qt 6: remove
PE_FrameStatusBarItem = PE_FrameStatusBar,
PE_FrameTabWidget,
PE_FrameWindow,
@@ -155,7 +155,7 @@ public:
PE_IndicatorArrowUp,
PE_IndicatorBranch,
PE_IndicatorButtonDropDown,
- PE_IndicatorViewItemCheck,
+ PE_IndicatorViewItemCheck, // ### Qt 6: remove
PE_IndicatorItemViewItemCheck = PE_IndicatorViewItemCheck,
PE_IndicatorCheckBox,
PE_IndicatorDockWidgetResizeHandle,
@@ -171,6 +171,7 @@ public:
PE_IndicatorToolBarSeparator,
PE_PanelTipLabel,
PE_IndicatorTabTear,
+ PE_IndicatorTabTearLeft = PE_IndicatorTabTear,
PE_PanelScrollAreaCorner,
PE_Widget,
@@ -186,6 +187,8 @@ public:
PE_IndicatorTabClose,
PE_PanelMenu,
+ PE_IndicatorTabTearRight,
+
// do not add any values below/greater this
PE_CustomBase = 0xf000000
};
@@ -298,10 +301,11 @@ public:
SE_TabWidgetLeftCorner,
SE_TabWidgetRightCorner,
- SE_ViewItemCheckIndicator,
+ SE_ViewItemCheckIndicator, // ### Qt 6: remove
SE_ItemViewItemCheckIndicator = SE_ViewItemCheckIndicator,
SE_TabBarTearIndicator,
+ SE_TabBarTearIndicatorLeft = SE_TabBarTearIndicator,
SE_TreeViewDisclosureItem,
@@ -341,6 +345,10 @@ public:
SE_ToolBarHandle,
+ SE_TabBarScrollLeftButton,
+ SE_TabBarScrollRightButton,
+ SE_TabBarTearIndicatorRight,
+
// do not add any values below/greater than this
SE_CustomBase = 0xf0000000
};
@@ -491,9 +499,9 @@ public:
PM_DialogButtonsButtonHeight,
PM_MdiSubWindowFrameWidth,
- PM_MDIFrameWidth = PM_MdiSubWindowFrameWidth, //obsolete
+ PM_MDIFrameWidth = PM_MdiSubWindowFrameWidth, // ### Qt 6: remove
PM_MdiSubWindowMinimizedWidth,
- PM_MDIMinimizedWidth = PM_MdiSubWindowMinimizedWidth, //obsolete
+ PM_MDIMinimizedWidth = PM_MdiSubWindowMinimizedWidth, // ### Qt 6: remove
PM_HeaderMargin,
PM_HeaderMarkSize,
@@ -511,9 +519,9 @@ public:
PM_SpinBoxSliderHeight,
- PM_DefaultTopLevelMargin,
- PM_DefaultChildMargin,
- PM_DefaultLayoutSpacing,
+ PM_DefaultTopLevelMargin, // ### Qt 6: remove
+ PM_DefaultChildMargin, // ### Qt 6: remove
+ PM_DefaultLayoutSpacing, // ### Qt 6: remove
PM_ToolBarIconSize,
PM_ListViewIconSize,
@@ -631,7 +639,7 @@ public:
SH_ComboBox_Popup,
SH_TitleBar_NoBorder,
SH_Slider_StopMouseOverSlider,
- SH_ScrollBar_StopMouseOverSlider = SH_Slider_StopMouseOverSlider, // obsolete
+ SH_ScrollBar_StopMouseOverSlider = SH_Slider_StopMouseOverSlider, // ### Qt 6: remove
SH_BlinkCursorWhenTextSelected,
SH_RichText_FullWidthSelection,
SH_Menu_Scrollable,
diff --git a/src/widgets/styles/qstylefactory.cpp b/src/widgets/styles/qstylefactory.cpp
index 520e303d93..f651521cbd 100644
--- a/src/widgets/styles/qstylefactory.cpp
+++ b/src/widgets/styles/qstylefactory.cpp
@@ -44,9 +44,6 @@
#include "qandroidstyle_p.h"
#endif
#endif
-#ifndef QT_NO_STYLE_GTK
-#include "qgtkstyle_p.h"
-#endif
#ifndef QT_NO_STYLE_WINDOWSXP
#include "qwindowsxpstyle_p.h"
#endif
@@ -86,7 +83,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
The valid keys can be retrieved using the keys()
function. Typically they include "windows" and "fusion".
- Depending on the platform, "windowsxp", "windowsvista", "gtk"
+ Depending on the platform, "windowsxp", "windowsvista"
and "macintosh" may be available.
Note that keys are case insensitive.
@@ -143,11 +140,6 @@ QStyle *QStyleFactory::create(const QString& key)
ret = new QAndroidStyle;
else
#endif
-#ifndef QT_NO_STYLE_GTK
- if (style == QLatin1String("gtk") || style == QLatin1String("gtk+"))
- ret = new QGtkStyle;
- else
-#endif
#ifndef QT_NO_STYLE_MAC
if (style.startsWith(QLatin1String("macintosh"))) {
ret = new QMacStyle;
@@ -210,10 +202,6 @@ QStringList QStyleFactory::keys()
if (!list.contains(QLatin1String("Android")))
list << QLatin1String("Android");
#endif
-#ifndef QT_NO_STYLE_GTK
- if (!list.contains(QLatin1String("GTK+")))
- list << QLatin1String("GTK+");
-#endif
#ifndef QT_NO_STYLE_FUSION
if (!list.contains(QLatin1String("Fusion")))
list << QLatin1String("Fusion");
diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h
index 9fd693d033..726bcd59d5 100644
--- a/src/widgets/styles/qstyleoption.h
+++ b/src/widgets/styles/qstyleoption.h
@@ -131,8 +131,8 @@ protected:
Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionFrame::FrameFeatures)
-typedef QStyleOptionFrame QStyleOptionFrameV2;
-typedef QStyleOptionFrame QStyleOptionFrameV3;
+typedef Q_DECL_DEPRECATED QStyleOptionFrame QStyleOptionFrameV2;
+typedef Q_DECL_DEPRECATED QStyleOptionFrame QStyleOptionFrameV3;
#ifndef QT_NO_TABWIDGET
class Q_WIDGETS_EXPORT QStyleOptionTabWidgetFrame : public QStyleOption
@@ -158,7 +158,7 @@ protected:
QStyleOptionTabWidgetFrame(int version);
};
-typedef QStyleOptionTabWidgetFrame QStyleOptionTabWidgetFrameV2;
+typedef Q_DECL_DEPRECATED QStyleOptionTabWidgetFrame QStyleOptionTabWidgetFrameV2;
#endif // QT_NO_TABWIDGET
@@ -181,7 +181,7 @@ protected:
QStyleOptionTabBarBase(int version);
};
-typedef QStyleOptionTabBarBase QStyleOptionTabBarBaseV2;
+typedef Q_DECL_DEPRECATED QStyleOptionTabBarBase QStyleOptionTabBarBaseV2;
#endif // QT_NO_TABBAR
class Q_WIDGETS_EXPORT QStyleOptionHeader : public QStyleOption
@@ -273,8 +273,8 @@ protected:
Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionTab::CornerWidgets)
-typedef QStyleOptionTab QStyleOptionTabV2;
-typedef QStyleOptionTab QStyleOptionTabV3;
+typedef Q_DECL_DEPRECATED QStyleOptionTab QStyleOptionTabV2;
+typedef Q_DECL_DEPRECATED QStyleOptionTab QStyleOptionTabV3;
#endif // QT_NO_TABBAR
@@ -328,7 +328,7 @@ protected:
QStyleOptionProgressBar(int version);
};
-typedef QStyleOptionProgressBar QStyleOptionProgressBarV2;
+typedef Q_DECL_DEPRECATED QStyleOptionProgressBar QStyleOptionProgressBarV2;
class Q_WIDGETS_EXPORT QStyleOptionMenuItem : public QStyleOption
{
@@ -377,7 +377,7 @@ protected:
QStyleOptionDockWidget(int version);
};
-typedef QStyleOptionDockWidget QStyleOptionDockWidgetV2;
+typedef Q_DECL_DEPRECATED QStyleOptionDockWidget QStyleOptionDockWidgetV2;
#ifndef QT_NO_ITEMVIEWS
@@ -430,9 +430,9 @@ protected:
Q_DECLARE_OPERATORS_FOR_FLAGS(QStyleOptionViewItem::ViewItemFeatures)
-typedef QStyleOptionViewItem QStyleOptionViewItemV2;
-typedef QStyleOptionViewItem QStyleOptionViewItemV3;
-typedef QStyleOptionViewItem QStyleOptionViewItemV4;
+typedef Q_DECL_DEPRECATED QStyleOptionViewItem QStyleOptionViewItemV2;
+typedef Q_DECL_DEPRECATED QStyleOptionViewItem QStyleOptionViewItemV3;
+typedef Q_DECL_DEPRECATED QStyleOptionViewItem QStyleOptionViewItemV4;
#endif // QT_NO_ITEMVIEWS
@@ -458,7 +458,7 @@ protected:
QStyleOptionToolBox(int version);
};
-typedef QStyleOptionToolBox QStyleOptionToolBoxV2;
+typedef Q_DECL_DEPRECATED QStyleOptionToolBox QStyleOptionToolBoxV2;
#ifndef QT_NO_RUBBERBAND
class Q_WIDGETS_EXPORT QStyleOptionRubberBand : public QStyleOption
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index d3f667748e..40cca059a8 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -1547,7 +1547,7 @@ QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QObject *obj) const
if (ss.startsWith(QLatin1String("file:///")))
ss.remove(0, 8);
parser.init(ss, qApp->styleSheet() != ss);
- if (!parser.parse(&appSs))
+ if (Q_UNLIKELY(!parser.parse(&appSs)))
qWarning("Could not parse application stylesheet");
appSs.origin = StyleSheetOrigin_Inline;
appSs.depth = 1;
@@ -1569,7 +1569,7 @@ QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QObject *obj) const
parser.init(styleSheet);
if (!parser.parse(&ss)) {
parser.init(QLatin1String("* {") + styleSheet + QLatin1Char('}'));
- if (!parser.parse(&ss))
+ if (Q_UNLIKELY(!parser.parse(&ss)))
qWarning("Could not parse stylesheet of object %p", o);
}
ss.origin = StyleSheetOrigin_Inline;
@@ -2515,12 +2515,12 @@ void QStyleSheetStyle::setProperties(QWidget *w)
const QMetaObject *metaObject = w->metaObject();
int index = metaObject->indexOfProperty(property.toLatin1());
- if (index == -1) {
+ if (Q_UNLIKELY(index == -1)) {
qWarning() << w << " does not have a property named " << property;
continue;
}
const QMetaProperty metaProperty = metaObject->property(index);
- if (!metaProperty.isWritable() || !metaProperty.isDesignable()) {
+ if (Q_UNLIKELY(!metaProperty.isWritable() || !metaProperty.isDesignable())) {
qWarning() << w << " cannot design property named " << property;
continue;
}
@@ -2556,7 +2556,13 @@ void QStyleSheetStyle::setPalette(QWidget *w)
{ PseudoClass_Enabled, QPalette::Inactive }
};
- QPalette p = w->palette();
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
+ QPalette p;
+ if (!useStyleSheetPropagationInWidgetStyles)
+ p = w->palette();
+
QWidget *ew = embeddedWidget(w);
for (int i = 0; i < 3; i++) {
@@ -2573,32 +2579,84 @@ void QStyleSheetStyle::setPalette(QWidget *w)
rule.configurePalette(&p, map[i].group, ew, ew != w);
}
- styleSheetCaches->customPaletteWidgets.insert(w, w->palette());
- w->setPalette(p);
- if (ew != w)
- ew->setPalette(p);
+ if (!useStyleSheetPropagationInWidgetStyles || p.resolve() != 0) {
+ QPalette wp = w->palette();
+ styleSheetCaches->customPaletteWidgets.insert(w, qMakePair(wp, p.resolve()));
+
+ if (useStyleSheetPropagationInWidgetStyles) {
+ p = p.resolve(wp);
+ p.resolve(p.resolve() | wp.resolve());
+ }
+
+ w->setPalette(p);
+ if (ew != w)
+ ew->setPalette(p);
+ }
}
void QStyleSheetStyle::unsetPalette(QWidget *w)
{
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
+
if (styleSheetCaches->customPaletteWidgets.contains(w)) {
- QPalette p = styleSheetCaches->customPaletteWidgets.value(w);
- w->setPalette(p);
+ QPair<QPalette, uint> p = styleSheetCaches->customPaletteWidgets.value(w);
+ styleSheetCaches->customPaletteWidgets.remove(w);
+
+ QPalette original = p.first;
+
+ if (useStyleSheetPropagationInWidgetStyles) {
+ original.resolve(original.resolve() & p.second);
+
+ QPalette wp = w->palette();
+ wp.resolve(wp.resolve() & ~p.second);
+ wp.resolve(original);
+ wp.resolve(wp.resolve() | original.resolve());
+ original = wp;
+ }
+
+ w->setPalette(original);
QWidget *ew = embeddedWidget(w);
if (ew != w)
- ew->setPalette(p);
- styleSheetCaches->customPaletteWidgets.remove(w);
+ ew->setPalette(original);
}
- QVariant oldFont = w->property("_q_styleSheetWidgetFont");
- if (oldFont.isValid()) {
- w->setFont(qvariant_cast<QFont>(oldFont));
+
+ if (useStyleSheetPropagationInWidgetStyles) {
+ unsetStyleSheetFont(w);
+ QWidget *ew = embeddedWidget(w);
+ if (ew != w)
+ unsetStyleSheetFont(ew);
+ } else {
+ QVariant oldFont = w->property("_q_styleSheetWidgetFont");
+ if (oldFont.isValid()) {
+ w->setFont(qvariant_cast<QFont>(oldFont));
+ }
}
+
if (styleSheetCaches->autoFillDisabledWidgets.contains(w)) {
embeddedWidget(w)->setAutoFillBackground(true);
styleSheetCaches->autoFillDisabledWidgets.remove(w);
}
}
+void QStyleSheetStyle::unsetStyleSheetFont(QWidget *w) const
+{
+ if (styleSheetCaches->customFontWidgets.contains(w)) {
+ QPair<QFont, uint> f = styleSheetCaches->customFontWidgets.value(w);
+ styleSheetCaches->customFontWidgets.remove(w);
+
+ QFont original = f.first;
+ original.resolve(original.resolve() & f.second);
+
+ QFont font = w->font();
+ font.resolve(font.resolve() & ~f.second);
+ font.resolve(original);
+ font.resolve(font.resolve() | original.resolve());
+
+ w->setFont(font);
+ }
+}
+
static void updateObjects(const QList<const QObject *>& objects)
{
if (!styleSheetCaches->styleRulesCache.isEmpty() || !styleSheetCaches->hasStyleRuleCache.isEmpty() || !styleSheetCaches->renderRulesCache.isEmpty()) {
@@ -2658,6 +2716,7 @@ void QStyleSheetStyleCaches::objectDestroyed(QObject *o)
hasStyleRuleCache.remove(o);
renderRulesCache.remove(o);
customPaletteWidgets.remove((const QWidget *)o);
+ customFontWidgets.remove(static_cast<QWidget *>(o));
styleSheetCache.remove(o);
autoFillDisabledWidgets.remove((const QWidget *)o);
}
@@ -5846,24 +5905,42 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const
// we should never override it.
if (w->objectName() == QLatin1String("qt_fontDialog_sampleEdit"))
return;
+
QWidget *container = containerWidget(w);
QRenderRule rule = renderRule(container, PseudoElement_None,
PseudoClass_Active | PseudoClass_Enabled | extendedPseudoClass(container));
- QFont font = rule.font.resolve(w->font());
- if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
- && isNaturalChild(w) && qobject_cast<QWidget *>(w->parent())) {
+ const bool useStyleSheetPropagationInWidgetStyles =
+ QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles);
- font = font.resolve(static_cast<QWidget *>(w->parent())->font());
- }
+ if (useStyleSheetPropagationInWidgetStyles) {
+ unsetStyleSheetFont(w);
- if (w->data->fnt == font)
- return;
+ if (rule.font.resolve()) {
+ QFont wf = w->font();
+ styleSheetCaches->customFontWidgets.insert(w, qMakePair(wf, rule.font.resolve()));
+
+ QFont font = rule.font.resolve(wf);
+ font.resolve(wf.resolve() | rule.font.resolve());
+ w->setFont(font);
+ }
+ } else {
+ QFont font = rule.font.resolve(w->font());
- w->data->fnt = font;
+ if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
+ && isNaturalChild(w) && qobject_cast<QWidget *>(w->parent())) {
- QEvent e(QEvent::FontChange);
- QApplication::sendEvent(w, &e);
+ font = font.resolve(static_cast<QWidget *>(w->parent())->font());
+ }
+
+ if (w->data->fnt == font)
+ return;
+
+ w->data->fnt = font;
+
+ QEvent e(QEvent::FontChange);
+ QApplication::sendEvent(w, &e);
+ }
}
void QStyleSheetStyle::saveWidgetFont(QWidget* w, const QFont& font) const
diff --git a/src/widgets/styles/qstylesheetstyle_default.cpp b/src/widgets/styles/qstylesheetstyle_default.cpp
index c3d00f1883..a444be006d 100644
--- a/src/widgets/styles/qstylesheetstyle_default.cpp
+++ b/src/widgets/styles/qstylesheetstyle_default.cpp
@@ -149,8 +149,7 @@ StyleSheet QStyleSheetStyle::getDefaultStyleSheet() const
// pixmap based style doesn't support any features
bool styleIsPixmapBased = baseStyle()->inherits("QMacStyle")
- || baseStyle()->inherits("QWindowsXPStyle")
- || baseStyle()->inherits("QGtkStyle");
+ || baseStyle()->inherits("QWindowsXPStyle");
/*QLineEdit {
diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h
index 9cd8cb889d..dd2a25aed3 100644
--- a/src/widgets/styles/qstylesheetstyle_p.h
+++ b/src/widgets/styles/qstylesheetstyle_p.h
@@ -42,6 +42,7 @@
#include "QtCore/qhash.h"
#include "QtGui/qevent.h"
#include "QtCore/qvector.h"
+#include "QtCore/qset.h"
#include "QtWidgets/qapplication.h"
#include "private/qcssparser_p.h"
#include "QtGui/qbrush.h"
@@ -149,6 +150,7 @@ private:
void unsetPalette(QWidget *);
void setProperties(QWidget *);
void setGeometry(QWidget *);
+ void unsetStyleSheetFont(QWidget *) const;
QVector<QCss::StyleRule> styleRules(const QObject *obj) const;
bool hasStyleRule(const QObject *obj, int part) const;
@@ -178,9 +180,12 @@ public:
QHash<const QObject *, QHash<int, bool> > hasStyleRuleCache;
typedef QHash<int, QHash<quint64, QRenderRule> > QRenderRules;
QHash<const QObject *, QRenderRules> renderRulesCache;
- QHash<const QWidget *, QPalette> customPaletteWidgets; // widgets whose palette we tampered
QHash<const void *, QCss::StyleSheet> styleSheetCache; // parsed style sheets
QSet<const QWidget *> autoFillDisabledWidgets;
+ // widgets whose palettes and fonts we have tampered. stored value pair is
+ // QPair<old widget value, resolve mask of stylesheet value>
+ QHash<const QWidget *, QPair<QPalette, uint> > customPaletteWidgets;
+ QHash<const QWidget *, QPair<QFont, uint> > customFontWidgets;
};
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
index 083b1d1707..4c16b182a8 100644
--- a/src/widgets/styles/qwindowsvistastyle.cpp
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -2471,12 +2471,12 @@ bool QWindowsVistaStylePrivate::initTreeViewTheming()
return true;
m_treeViewHelper = createTreeViewHelperWindow();
- if (!m_treeViewHelper) {
+ if (Q_UNLIKELY(!m_treeViewHelper)) {
qWarning("Unable to create the treeview helper window.");
return false;
}
const HRESULT hr = QWindowsXPStylePrivate::pSetWindowTheme(m_treeViewHelper, L"explorer", NULL);
- if (hr != S_OK) {
+ if (Q_UNLIKELY(hr != S_OK)) {
qErrnoWarning("SetWindowTheme() failed.");
return false;
}
diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp
index c350e82c69..d5f511b771 100644
--- a/src/widgets/styles/qwindowsxpstyle.cpp
+++ b/src/widgets/styles/qwindowsxpstyle.cpp
@@ -337,14 +337,14 @@ void QWindowsXPStylePrivate::cleanupHandleMap()
HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd)
{
- if (theme < 0 || theme >= NThemes || !hwnd) {
+ if (Q_UNLIKELY(theme < 0 || theme >= NThemes || !hwnd)) {
qWarning("Invalid parameters #%d, %p", theme, hwnd);
return 0;
}
if (!m_themes[theme]) {
const wchar_t *name = themeNames[theme];
m_themes[theme] = pOpenThemeData(hwnd, name);
- if (!m_themes[theme])
+ if (Q_UNLIKELY(!m_themes[theme]))
qErrnoWarning("OpenThemeData() failed for theme %d (%s).",
theme, qPrintable(themeName(theme)));
}
@@ -504,13 +504,13 @@ HBITMAP QWindowsXPStylePrivate::buffer(int w, int h)
GdiFlush();
nullBitmap = (HBITMAP)SelectObject(bufferDC, bufferBitmap);
- if (!bufferBitmap) {
+ if (Q_UNLIKELY(!bufferBitmap)) {
qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() failed.", w, h);
bufferW = 0;
bufferH = 0;
return 0;
}
- if (!bufferPixels) {
+ if (Q_UNLIKELY(!bufferPixels)) {
qErrnoWarning("QWindowsXPStylePrivate::buffer(%dx%d), CreateDIBSection() did not allocate pixel data.", w, h);
bufferW = 0;
bufferH = 0;
diff --git a/src/widgets/styles/styles.pri b/src/widgets/styles/styles.pri
index 3707090c4c..11f7d973cc 100644
--- a/src/widgets/styles/styles.pri
+++ b/src/widgets/styles/styles.pri
@@ -14,7 +14,9 @@ HEADERS += \
styles/qproxystyle_p.h \
styles/qcommonstyle_p.h \
styles/qstylepainter.h \
- styles/qstylesheetstyle_p.h
+ styles/qstylesheetstyle_p.h \
+ styles/qpixmapstyle_p.h \
+ styles/qpixmapstyle_p_p.h
SOURCES += \
styles/qdrawutil.cpp \
@@ -28,7 +30,8 @@ SOURCES += \
styles/qproxystyle.cpp \
styles/qstylepainter.cpp \
styles/qstylesheetstyle.cpp \
- styles/qstylesheetstyle_default.cpp
+ styles/qstylesheetstyle_default.cpp \
+ styles/qpixmapstyle.cpp
wince* {
RESOURCES += styles/qstyle_wince.qrc
@@ -42,18 +45,12 @@ contains( styles, all ) {
!macx:styles -= mac
-contains(QT_CONFIG, gtkstyle) {
- QMAKE_CXXFLAGS += $$QT_CFLAGS_QGTKSTYLE
- LIBS_PRIVATE += $$QT_LIBS_QGTKSTYLE
- styles += gtk
- CONFIG += x11
-}
-
contains( styles, mac ) {
HEADERS += \
styles/qmacstyle_mac_p.h \
styles/qmacstyle_mac_p_p.h
- OBJECTIVE_SOURCES += styles/qmacstyle_mac.mm
+ OBJECTIVE_SOURCES += styles/qmacstyle_mac.mm
+ LIBS_PRIVATE += -framework Carbon
} else {
DEFINES += QT_NO_STYLE_MAC
}
@@ -90,19 +87,6 @@ contains( styles, windows ) {
DEFINES += QT_NO_STYLE_WINDOWS
}
-contains( styles, gtk ) {
- HEADERS += styles/qgtkglobal_p.h
- HEADERS += styles/qgtkstyle_p.h
- HEADERS += styles/qgtkpainter_p.h
- HEADERS += styles/qgtk2painter_p.h
- HEADERS += styles/qgtkstyle_p_p.h
- SOURCES += styles/qgtkstyle.cpp
- SOURCES += styles/qgtkpainter.cpp
- SOURCES += styles/qgtk2painter.cpp
- SOURCES += styles/qgtkstyle_p.cpp
-} else {
- DEFINES += QT_NO_STYLE_GTK
-}
contains( styles, fusion ) {
HEADERS += styles/qfusionstyle_p.h
HEADERS += styles/qfusionstyle_p_p.h
diff --git a/src/widgets/util/qcolormap.cpp b/src/widgets/util/qcolormap.cpp
index fc4d511384..4bcf1501d2 100644
--- a/src/widgets/util/qcolormap.cpp
+++ b/src/widgets/util/qcolormap.cpp
@@ -58,7 +58,7 @@ static QColormapPrivate *screenMap = 0;
void QColormap::initialize()
{
screenMap = new QColormapPrivate;
- if (!QGuiApplication::primaryScreen()) {
+ if (Q_UNLIKELY(!QGuiApplication::primaryScreen())) {
qWarning("no screens available, assuming 24-bit color");
screenMap->depth = 24;
screenMap->mode = QColormap::Direct;
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp
index 4382abaf50..3eeb6683b1 100644
--- a/src/widgets/util/qcompleter.cpp
+++ b/src/widgets/util/qcompleter.cpp
@@ -1144,9 +1144,9 @@ void QCompleter::setFilterMode(Qt::MatchFlags filterMode)
if (d->filterMode == filterMode)
return;
- if (filterMode != Qt::MatchStartsWith
- && filterMode != Qt::MatchContains
- && filterMode != Qt::MatchEndsWith) {
+ if (Q_UNLIKELY(filterMode != Qt::MatchStartsWith &&
+ filterMode != Qt::MatchContains &&
+ filterMode != Qt::MatchEndsWith)) {
qWarning("Unhandled QCompleter::filterMode flag is used.");
return;
}
@@ -1641,7 +1641,7 @@ int QCompleter::maxVisibleItems() const
void QCompleter::setMaxVisibleItems(int maxItems)
{
Q_D(QCompleter);
- if (maxItems < 0) {
+ if (Q_UNLIKELY(maxItems < 0)) {
qWarning("QCompleter::setMaxVisibleItems: "
"Invalid max visible items (%d) must be >= 0", maxItems);
return;
diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp
index c7e0861a0f..7a195081ce 100644
--- a/src/widgets/util/qflickgesture.cpp
+++ b/src/widgets/util/qflickgesture.cpp
@@ -40,6 +40,7 @@
#include "qgraphicssceneevent.h"
#include "qgraphicsview.h"
#include "qscroller.h"
+#include <QtGui/qtouchdevice.h>
#include "private/qapplication_p.h"
#include "private/qevent_p.h"
#include "private/qflickgesture_p.h"
@@ -582,9 +583,10 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size());
#ifndef QT_NO_GRAPHICSVIEW
} else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(as->target())) {
- if (go->scene() && !go->scene()->views().isEmpty()) {
+ if (go->scene()) {
+ const auto goBoundingRectMappedToScene = go->mapToScene(go->boundingRect());
foreach (QGraphicsView *gv, go->scene()->views())
- scrollerRegion |= gv->mapFromScene(go->mapToScene(go->boundingRect()))
+ scrollerRegion |= gv->mapFromScene(goBoundingRectMappedToScene)
.translated(gv->mapToGlobal(QPoint(0, 0)));
}
#endif
diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp
index 38b104f9e9..5297c949a9 100644
--- a/src/widgets/util/qscroller.cpp
+++ b/src/widgets/util/qscroller.cpp
@@ -159,8 +159,8 @@ static qreal differentialForProgress(const QEasingCurve &curve, qreal pos)
static qreal progressForValue(const QEasingCurve &curve, qreal value)
{
- if (curve.type() >= QEasingCurve::InElastic &&
- curve.type() < QEasingCurve::Custom) {
+ if (Q_UNLIKELY(curve.type() >= QEasingCurve::InElastic &&
+ curve.type() < QEasingCurve::Custom)) {
qWarning("progressForValue(): QEasingCurves of type %d do not have an inverse, since they are not injective.", curve.type());
return value;
}
@@ -1005,7 +1005,7 @@ bool QScroller::handleInput(Input input, const QPointF &position, qint64 timesta
#if !defined(Q_DEAD_CODE_FROM_QT4_MAC)
// the Mac version is implemented in qscroller_mac.mm
-QPointF QScrollerPrivate::realDpi(int screen)
+QPointF QScrollerPrivate::realDpi(int screen) const
{
# if defined(Q_DEAD_CODE_FROM_QT4_X11) && !defined(QT_NO_XRANDR)
if (X11 && X11->use_xrandr && X11->ptrXRRSizes && X11->ptrXRRRootToScreen) {
@@ -1176,9 +1176,9 @@ qreal QScrollerPrivate::scrollingSegmentsEndPos(Qt::Orientation orientation) con
/*! \internal
Checks if the scroller segment end in a valid position.
*/
-bool QScrollerPrivate::scrollingSegmentsValid(Qt::Orientation orientation)
+bool QScrollerPrivate::scrollingSegmentsValid(Qt::Orientation orientation) const
{
- QQueue<ScrollSegment> *segments;
+ const QQueue<ScrollSegment> *segments;
qreal minPos;
qreal maxPos;
@@ -1893,7 +1893,7 @@ void QScrollerPrivate::setContentPositionHelperScrolling()
on a snap point.
Returns the nearest snap position or NaN if no such point could be found.
*/
-qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientation)
+qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientation) const
{
qreal bestSnapPos = Q_QNAN;
qreal bestSnapPosDist = Q_INFINITY;
diff --git a/src/widgets/util/qscroller_mac.mm b/src/widgets/util/qscroller_mac.mm
index 07de07de52..1d2780ccd1 100644
--- a/src/widgets/util/qscroller_mac.mm
+++ b/src/widgets/util/qscroller_mac.mm
@@ -35,13 +35,13 @@
#ifdef Q_DEAD_CODE_FROM_QT4_MAC
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
#include "qscroller_p.h"
QT_BEGIN_NAMESPACE
-QPointF QScrollerPrivate::realDpi(int screen)
+QPointF QScrollerPrivate::realDpi(int screen) const
{
QMacAutoReleasePool pool;
NSArray *nsscreens = [NSScreen screens];
diff --git a/src/widgets/util/qscroller_p.h b/src/widgets/util/qscroller_p.h
index d09f78d130..8266b6e611 100644
--- a/src/widgets/util/qscroller_p.h
+++ b/src/widgets/util/qscroller_p.h
@@ -112,7 +112,7 @@ public:
bool prepareScrolling(const QPointF &position);
void handleDrag(const QPointF &position, qint64 timestamp);
- QPointF realDpi(int screen);
+ QPointF realDpi(int screen) const;
QPointF dpi() const;
void setDpi(const QPointF &dpi);
void setDpiFromWidget(QWidget *widget);
@@ -121,7 +121,7 @@ public:
void pushSegment(ScrollType type, qreal deltaTime, qreal stopProgress, qreal startPos, qreal deltaPos, qreal stopPos, QEasingCurve::Type curve, Qt::Orientation orientation);
void recalcScrollingSegments(bool forceRecalc = false);
qreal scrollingSegmentsEndPos(Qt::Orientation orientation) const;
- bool scrollingSegmentsValid(Qt::Orientation orientation);
+ bool scrollingSegmentsValid(Qt::Orientation orientation) const;
void createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type);
void createScrollingSegments(qreal v, qreal startPos,
qreal deltaTime, qreal deltaPos,
@@ -131,7 +131,7 @@ public:
void setContentPositionHelperDragging(const QPointF &deltaPos);
void setContentPositionHelperScrolling();
- qreal nextSnapPos(qreal p, int dir, Qt::Orientation orientation);
+ qreal nextSnapPos(qreal p, int dir, Qt::Orientation orientation) const;
static qreal nextSegmentPosition(QQueue<ScrollSegment> &segments, qint64 now, qreal oldPos);
inline int frameRateSkip() const { return properties.d.data()->frameRate; }
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index 31bbbb9739..47bc88cb43 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -264,7 +264,7 @@ void QSystemTrayIcon::setVisible(bool visible)
Q_D(QSystemTrayIcon);
if (visible == d->visible)
return;
- if (d->icon.isNull() && visible)
+ if (Q_UNLIKELY(visible && d->icon.isNull()))
qWarning("QSystemTrayIcon::setVisible: No Icon set");
d->visible = visible;
if (d->visible)
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp
index 02bab236c8..13d58acebd 100644
--- a/src/widgets/util/qsystemtrayicon_x11.cpp
+++ b/src/widgets/util/qsystemtrayicon_x11.cpp
@@ -170,7 +170,9 @@ void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev)
#ifndef QT_NO_CONTEXTMENU
if (ev->button() == Qt::RightButton && q->contextMenu())
q->contextMenu()->popup(globalPos);
-#endif
+#else
+ Q_UNUSED(globalPos)
+#endif // QT_NO_CONTEXTMENU
if (QBalloonTip::isBalloonVisible()) {
emit q->messageClicked();
diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp
index 0272870537..35d8c10578 100644
--- a/src/widgets/util/qundostack.cpp
+++ b/src/widgets/util/qundostack.cpp
@@ -633,7 +633,7 @@ void QUndoStack::push(QUndoCommand *cmd)
void QUndoStack::setClean()
{
Q_D(QUndoStack);
- if (!d->macro_stack.isEmpty()) {
+ if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
qWarning("QUndoStack::setClean(): cannot set clean in the middle of a macro");
return;
}
@@ -688,7 +688,7 @@ void QUndoStack::undo()
if (d->index == 0)
return;
- if (!d->macro_stack.isEmpty()) {
+ if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
qWarning("QUndoStack::undo(): cannot undo in the middle of a macro");
return;
}
@@ -714,7 +714,7 @@ void QUndoStack::redo()
if (d->index == d->command_list.size())
return;
- if (!d->macro_stack.isEmpty()) {
+ if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
qWarning("QUndoStack::redo(): cannot redo in the middle of a macro");
return;
}
@@ -761,7 +761,7 @@ int QUndoStack::index() const
void QUndoStack::setIndex(int idx)
{
Q_D(QUndoStack);
- if (!d->macro_stack.isEmpty()) {
+ if (Q_UNLIKELY(!d->macro_stack.isEmpty())) {
qWarning("QUndoStack::setIndex(): cannot set index in the middle of a macro");
return;
}
@@ -981,7 +981,7 @@ void QUndoStack::beginMacro(const QString &text)
void QUndoStack::endMacro()
{
Q_D(QUndoStack);
- if (d->macro_stack.isEmpty()) {
+ if (Q_UNLIKELY(d->macro_stack.isEmpty())) {
qWarning("QUndoStack::endMacro(): no matching beginMacro()");
return;
}
@@ -1049,7 +1049,7 @@ void QUndoStack::setUndoLimit(int limit)
{
Q_D(QUndoStack);
- if (!d->command_list.isEmpty()) {
+ if (Q_UNLIKELY(!d->command_list.isEmpty())) {
qWarning("QUndoStack::setUndoLimit(): an undo limit can only be set when the stack is empty");
return;
}
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 65d06eafc5..946d683bf0 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -469,7 +469,7 @@ void QAbstractScrollAreaPrivate::layoutChildren()
if ((vscrollOverlap > 0 && needv) || (hscrollOverlap > 0 && needh)) {
const QList<QHeaderView *> headers = q->findChildren<QHeaderView*>();
if (headers.count() <= 2) {
- Q_FOREACH (const QHeaderView *header, headers) {
+ for (const QHeaderView *header : headers) {
const QRect geo = header->geometry();
if (header->orientation() == Qt::Vertical && header->isVisible() && QStyle::visualRect(opt.direction, opt.rect, geo).left() <= opt.rect.width() / 2)
vHeaderRight = QStyle::visualRect(opt.direction, opt.rect, geo).right();
@@ -705,7 +705,7 @@ QScrollBar *QAbstractScrollArea::verticalScrollBar() const
void QAbstractScrollArea::setVerticalScrollBar(QScrollBar *scrollBar)
{
Q_D(QAbstractScrollArea);
- if (!scrollBar) {
+ if (Q_UNLIKELY(!scrollBar)) {
qWarning("QAbstractScrollArea::setVerticalScrollBar: Cannot set a null scroll bar");
return;
}
@@ -766,7 +766,7 @@ QScrollBar *QAbstractScrollArea::horizontalScrollBar() const
void QAbstractScrollArea::setHorizontalScrollBar(QScrollBar *scrollBar)
{
Q_D(QAbstractScrollArea);
- if (!scrollBar) {
+ if (Q_UNLIKELY(!scrollBar)) {
qWarning("QAbstractScrollArea::setHorizontalScrollBar: Cannot set a null scroll bar");
return;
}
diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp
index 8d8c3aa4bc..c2d4d3278f 100644
--- a/src/widgets/widgets/qabstractslider.cpp
+++ b/src/widgets/widgets/qabstractslider.cpp
@@ -205,7 +205,7 @@ QT_BEGIN_NAMESPACE
QAbstractSliderPrivate::QAbstractSliderPrivate()
: minimum(0), maximum(99), pageStep(10), value(0), position(0), pressValue(-1),
- singleStep(1), offset_accumulated(0), tracking(true),
+ singleStep(1), singleStepFromItemView(-1), viewMayChangeSingleStep(true), offset_accumulated(0), tracking(true),
blocktracking(false), pressed(false),
invertedAppearance(false), invertedControls(false),
orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
@@ -378,6 +378,11 @@ int QAbstractSlider::maximum() const
void QAbstractSlider::setSingleStep(int step)
{
Q_D(QAbstractSlider);
+
+ d->viewMayChangeSingleStep = (step < 0);
+ if (step < 0 && d->singleStepFromItemView > 0)
+ step = d->singleStepFromItemView;
+
if (step != d->singleStep)
d->setSteps(step, d->pageStep);
}
@@ -936,4 +941,16 @@ bool QAbstractSlider::event(QEvent *e)
return QWidget::event(e);
}
+// This function is called from itemviews when doing scroll per pixel (on updateGeometries())
+// It will not have any effect if there has been a call to setSingleStep with
+// a 'reasonable' value (since viewMayChangeSingleStep will be set to false).
+// (If setSingleStep is called with -1 it will however allow the views to change singleStep.)
+
+void QAbstractSliderPrivate::itemviewChangeSingleStep(int step)
+{
+ singleStepFromItemView = step;
+ if (viewMayChangeSingleStep && singleStep != step)
+ setSteps(step, pageStep);
+}
+
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qabstractslider_p.h b/src/widgets/widgets/qabstractslider_p.h
index 3df73cf172..32ae55795b 100644
--- a/src/widgets/widgets/qabstractslider_p.h
+++ b/src/widgets/widgets/qabstractslider_p.h
@@ -67,6 +67,8 @@ public:
* Call effectiveSingleStep() when changing the slider value.
*/
int singleStep;
+ int singleStepFromItemView; // If we have itemViews we track the views preferred singleStep value.
+ bool viewMayChangeSingleStep;
float offset_accumulated;
uint tracking : 1;
@@ -108,6 +110,7 @@ public:
#endif
;
}
+ void itemviewChangeSingleStep(int step);
virtual int bound(int val) const { return qMax(minimum, qMin(maximum, val)); }
inline int overflowSafeAdd(int add) const
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index ba4bbe40a8..40c148f4c6 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -1931,7 +1931,7 @@ void QSpinBoxValidator::fixup(QString &input) const
QVariant operator+(const QVariant &arg1, const QVariant &arg2)
{
QVariant ret;
- if (arg1.type() != arg2.type())
+ if (Q_UNLIKELY(arg1.type() != arg2.type()))
qWarning("QAbstractSpinBox: Internal error: Different types (%s vs %s) (%s:%d)",
arg1.typeName(), arg2.typeName(), __FILE__, __LINE__);
switch (arg1.type()) {
@@ -1970,7 +1970,7 @@ QVariant operator+(const QVariant &arg1, const QVariant &arg2)
QVariant operator-(const QVariant &arg1, const QVariant &arg2)
{
QVariant ret;
- if (arg1.type() != arg2.type())
+ if (Q_UNLIKELY(arg1.type() != arg2.type()))
qWarning("QAbstractSpinBox: Internal error: Different types (%s vs %s) (%s:%d)",
arg1.typeName(), arg2.typeName(), __FILE__, __LINE__);
switch (arg1.type()) {
diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp
index 48b224fe13..eb216b1ad0 100644
--- a/src/widgets/widgets/qcalendarwidget.cpp
+++ b/src/widgets/widgets/qcalendarwidget.cpp
@@ -53,6 +53,8 @@
#include <qbasictimer.h>
#include <qstylepainter.h>
+#include <vector>
+
QT_BEGIN_NAMESPACE
enum {
@@ -423,6 +425,17 @@ QString QCalendarYearValidator::text(const QDate &date, int repeat) const
///////////////////////////////////
+struct SectionToken {
+ Q_DECL_CONSTEXPR SectionToken(QCalendarDateSectionValidator *v, int rep)
+ : validator(v), repeat(rep) {}
+
+ QCalendarDateSectionValidator *validator;
+ int repeat;
+};
+} // unnamed namespace
+Q_DECLARE_TYPEINFO(SectionToken, Q_PRIMITIVE_TYPE);
+namespace {
+
class QCalendarDateValidator
{
public:
@@ -438,13 +451,6 @@ public:
void setLocale(const QLocale &locale);
private:
-
- struct SectionToken {
- SectionToken(QCalendarDateSectionValidator *val, int rep) : validator(val), repeat(rep) {}
- QCalendarDateSectionValidator *validator;
- int repeat;
- };
-
void toNextToken();
void toPreviousToken();
void applyToDate();
@@ -453,12 +459,12 @@ private:
void clear();
QStringList m_separators;
- QList<SectionToken *> m_tokens;
+ std::vector<SectionToken> m_tokens;
QCalendarYearValidator m_yearValidator;
QCalendarMonthValidator m_monthValidator;
QCalendarDayValidator m_dayValidator;
- SectionToken *m_currentToken;
+ int m_currentToken;
QDate m_initialDate;
QDate m_currentDate;
@@ -467,7 +473,7 @@ private:
};
QCalendarDateValidator::QCalendarDateValidator()
- : m_currentToken(Q_NULLPTR),
+ : m_currentToken(-1),
m_initialDate(QDate::currentDate()),
m_currentDate(m_initialDate),
m_lastSectionMove(QCalendarDateSectionValidator::ThisSection)
@@ -510,17 +516,16 @@ void QCalendarDateValidator::setInitialDate(const QDate &date)
QString QCalendarDateValidator::currentText() const
{
QString str;
- QStringListIterator itSep(m_separators);
- QListIterator<SectionToken *> itTok(m_tokens);
- while (itSep.hasNext()) {
- str += itSep.next();
- if (itTok.hasNext()) {
- SectionToken *token = itTok.next();
- QCalendarDateSectionValidator *validator = token->validator;
- if (m_currentToken == token)
- str += validator->text();
+ const int numSeps = m_separators.size();
+ const int numTokens = int(m_tokens.size());
+ for (int i = 0; i < numSeps; ++i) {
+ str += m_separators.at(i);
+ if (i < numTokens) {
+ const SectionToken &token = m_tokens[i];
+ if (i == m_currentToken)
+ str += token.validator->text();
else
- str += validator->text(m_currentDate, token->repeat);
+ str += token.validator->text(m_currentDate, token.repeat);
}
}
return str;
@@ -528,14 +533,10 @@ QString QCalendarDateValidator::currentText() const
void QCalendarDateValidator::clear()
{
- QListIterator<SectionToken *> it(m_tokens);
- while (it.hasNext())
- delete it.next();
-
m_tokens.clear();
m_separators.clear();
- m_currentToken = 0;
+ m_currentToken = -1;
}
void QCalendarDateValidator::setFormat(const QString &format)
@@ -558,25 +559,25 @@ void QCalendarDateValidator::setFormat(const QString &format)
separator += nextChar;
quoting = false;
} else {
- SectionToken *token = 0;
+ QCalendarDateSectionValidator *validator = 0;
if (nextChar == QLatin1Char('d')) {
offset = qMin(4, countRepeat(format, pos));
- token = new SectionToken(&m_dayValidator, offset);
+ validator = &m_dayValidator;
} else if (nextChar == QLatin1Char('M')) {
offset = qMin(4, countRepeat(format, pos));
- token = new SectionToken(&m_monthValidator, offset);
+ validator = &m_monthValidator;
} else if (nextChar == QLatin1Char('y')) {
offset = qMin(4, countRepeat(format, pos));
- token = new SectionToken(&m_yearValidator, offset);
+ validator = &m_yearValidator;
} else {
separator += nextChar;
}
- if (token) {
- m_tokens.append(token);
+ if (validator) {
+ m_tokens.push_back(SectionToken(validator, offset));
m_separators.append(separator);
separator = QString();
- if (!m_currentToken)
- m_currentToken = token;
+ if (m_currentToken < 0)
+ m_currentToken = int(m_tokens.size()) - 1;
}
}
@@ -595,29 +596,23 @@ void QCalendarDateValidator::applyToDate()
void QCalendarDateValidator::toNextToken()
{
- const int idx = m_tokens.indexOf(m_currentToken);
- if (idx == -1)
+ if (m_currentToken < 0)
return;
- if (idx + 1 >= m_tokens.count())
- m_currentToken = m_tokens.first();
- else
- m_currentToken = m_tokens.at(idx + 1);
+ ++m_currentToken;
+ m_currentToken %= m_tokens.size();
}
void QCalendarDateValidator::toPreviousToken()
{
- const int idx = m_tokens.indexOf(m_currentToken);
- if (idx == -1)
+ if (m_currentToken < 0)
return;
- if (idx - 1 < 0)
- m_currentToken = m_tokens.last();
- else
- m_currentToken = m_tokens.at(idx - 1);
+ --m_currentToken;
+ m_currentToken %= m_tokens.size();
}
void QCalendarDateValidator::handleKeyEvent(QKeyEvent *keyEvent)
{
- if (!m_currentToken)
+ if (m_currentToken < 0)
return;
int key = keyEvent->key();
@@ -630,7 +625,7 @@ void QCalendarDateValidator::handleKeyEvent(QKeyEvent *keyEvent)
else if (key == Qt::Key_Left)
toPreviousToken();
- m_lastSectionMove = m_currentToken->validator->handleKey(key);
+ m_lastSectionMove = m_tokens[m_currentToken].validator->handleKey(key);
applyToDate();
if (m_lastSectionMove == QCalendarDateSectionValidator::NextSection)
@@ -821,6 +816,41 @@ void QCalendarTextNavigator::setDateEditAcceptDelay(int delay)
class QCalendarView;
+// a small helper class that replaces a QMap<Qt::DayOfWeek, T>,
+// but requires T to have a member-swap and a default constructor
+// which should be cheap (no memory allocations)
+
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_MSVC(4351) // "new behavior: elements of array ... will be default initialized"
+
+template <typename T>
+class StaticDayOfWeekAssociativeArray {
+ bool contained[7];
+ T data[7];
+
+ static Q_DECL_CONSTEXPR int day2idx(Qt::DayOfWeek day) Q_DECL_NOTHROW { return int(day) - 1; } // alt: day % 7
+public:
+ Q_DECL_CONSTEXPR StaticDayOfWeekAssociativeArray() Q_DECL_NOEXCEPT_EXPR(noexcept(T()))
+ : contained(), data() {}
+
+ Q_DECL_CONSTEXPR bool contains(Qt::DayOfWeek day) const Q_DECL_NOTHROW { return contained[day2idx(day)]; }
+ Q_DECL_CONSTEXPR const T &value(Qt::DayOfWeek day) const Q_DECL_NOTHROW { return data[day2idx(day)]; }
+
+ Q_DECL_RELAXED_CONSTEXPR T &operator[](Qt::DayOfWeek day) Q_DECL_NOTHROW
+ {
+ const int idx = day2idx(day);
+ contained[idx] = true;
+ return data[idx];
+ }
+
+ Q_DECL_RELAXED_CONSTEXPR void insert(Qt::DayOfWeek day, T v) Q_DECL_NOTHROW
+ {
+ operator[](day).swap(v);
+ }
+};
+
+QT_WARNING_POP
+
class QCalendarModel : public QAbstractTableModel
{
Q_OBJECT
@@ -899,7 +929,7 @@ public:
Qt::DayOfWeek m_firstDay;
QCalendarWidget::HorizontalHeaderFormat m_horizontalHeaderFormat;
bool m_weekNumbersShown;
- QMap<Qt::DayOfWeek, QTextCharFormat> m_dayFormats;
+ StaticDayOfWeekAssociativeArray<QTextCharFormat> m_dayFormats;
QMap<QDate, QTextCharFormat> m_dateFormats;
QTextCharFormat m_headerFormat;
QCalendarView *m_view;
@@ -2887,7 +2917,7 @@ void QCalendarWidget::setDateEditAcceptDelay(int delay)
*/
void QCalendarWidget::updateCell(const QDate &date)
{
- if (!date.isValid()) {
+ if (Q_UNLIKELY(!date.isValid())) {
qWarning("QCalendarWidget::updateCell: Invalid date");
return;
}
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index ed3af90532..c442ace476 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -1360,7 +1360,7 @@ int QComboBox::maxVisibleItems() const
void QComboBox::setMaxVisibleItems(int maxItems)
{
Q_D(QComboBox);
- if (maxItems < 0) {
+ if (Q_UNLIKELY(maxItems < 0)) {
qWarning("QComboBox::setMaxVisibleItems: "
"Invalid max visible items (%d) must be >= 0", maxItems);
return;
@@ -1395,13 +1395,14 @@ int QComboBox::count() const
void QComboBox::setMaxCount(int max)
{
Q_D(QComboBox);
- if (max < 0) {
+ if (Q_UNLIKELY(max < 0)) {
qWarning("QComboBox::setMaxCount: Invalid count (%d) must be >= 0", max);
return;
}
- if (max < count())
- d->model->removeRows(max, count() - max, d->root);
+ const int rowCount = count();
+ if (rowCount > max)
+ d->model->removeRows(max, rowCount - max, d->root);
d->maxCount = max;
}
@@ -1448,7 +1449,7 @@ void QComboBox::setAutoCompletion(bool enable)
Q_D(QComboBox);
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled() && !enable && isEditable())
+ if (Q_UNLIKELY(QApplication::keypadNavigationEnabled() && !enable && isEditable()))
qWarning("QComboBox::setAutoCompletion: auto completion is mandatory when combo box editable");
#endif
@@ -1547,9 +1548,8 @@ void QComboBox::setDuplicatesEnabled(bool enable)
int QComboBox::findData(const QVariant &data, int role, Qt::MatchFlags flags) const
{
Q_D(const QComboBox);
- QModelIndexList result;
QModelIndex start = d->model->index(0, d->modelColumn, d->root);
- result = d->model->match(start, role, data, 1, flags);
+ const QModelIndexList result = d->model->match(start, role, data, 1, flags);
if (result.isEmpty())
return -1;
return result.first().row();
@@ -1758,7 +1758,7 @@ void QComboBox::setEditable(bool editable)
void QComboBox::setLineEdit(QLineEdit *edit)
{
Q_D(QComboBox);
- if (!edit) {
+ if (Q_UNLIKELY(!edit)) {
qWarning("QComboBox::setLineEdit: cannot set a 0 line edit");
return;
}
@@ -1770,7 +1770,9 @@ void QComboBox::setLineEdit(QLineEdit *edit)
delete d->lineEdit;
d->lineEdit = edit;
+#ifndef QT_NO_IM
qt_widget_private(d->lineEdit)->inheritsInputMethodHints = 1;
+#endif
if (d->lineEdit->parent() != this)
d->lineEdit->setParent(this);
connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed()));
@@ -1915,7 +1917,7 @@ QAbstractItemDelegate *QComboBox::itemDelegate() const
*/
void QComboBox::setItemDelegate(QAbstractItemDelegate *delegate)
{
- if (!delegate) {
+ if (Q_UNLIKELY(!delegate)) {
qWarning("QComboBox::setItemDelegate: cannot set a 0 delegate");
return;
}
@@ -1947,7 +1949,7 @@ void QComboBox::setModel(QAbstractItemModel *model)
{
Q_D(QComboBox);
- if (!model) {
+ if (Q_UNLIKELY(!model)) {
qWarning("QComboBox::setModel: cannot set a 0 model");
return;
}
@@ -2393,7 +2395,7 @@ QAbstractItemView *QComboBox::view() const
void QComboBox::setView(QAbstractItemView *itemView)
{
Q_D(QComboBox);
- if (!itemView) {
+ if (Q_UNLIKELY(!itemView)) {
qWarning("QComboBox::setView: cannot set a 0 view");
return;
}
@@ -2583,7 +2585,7 @@ void QComboBox::showPopup()
#endif
while (!toCheck.isEmpty()) {
QModelIndex parent = toCheck.pop();
- for (int i = 0; i < d->model->rowCount(parent); ++i) {
+ for (int i = 0, end = d->model->rowCount(parent); i < end; ++i) {
QModelIndex idx = d->model->index(i, d->modelColumn, parent);
if (!idx.isValid())
continue;
@@ -3192,6 +3194,8 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
}
}
+ const int rowCount = count();
+
if (move != NoMove) {
e->accept();
switch (move) {
@@ -3199,11 +3203,11 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
newIndex = -1;
case MoveDown:
newIndex++;
- while ((newIndex < count()) && !(d->model->flags(d->model->index(newIndex,d->modelColumn,d->root)) & Qt::ItemIsEnabled))
+ while (newIndex < rowCount && !(d->model->index(newIndex, d->modelColumn, d->root).flags() & Qt::ItemIsEnabled))
newIndex++;
break;
case MoveLast:
- newIndex = count();
+ newIndex = rowCount;
case MoveUp:
newIndex--;
while ((newIndex >= 0) && !(d->model->flags(d->model->index(newIndex,d->modelColumn,d->root)) & Qt::ItemIsEnabled))
@@ -3214,7 +3218,7 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
break;
}
- if (newIndex >= 0 && newIndex < count() && newIndex != currentIndex()) {
+ if (newIndex >= 0 && newIndex < rowCount && newIndex != currentIndex()) {
setCurrentIndex(newIndex);
d->emitActivated(d->currentIndex);
}
@@ -3247,6 +3251,7 @@ void QComboBox::wheelEvent(QWheelEvent *e)
#else
Q_D(QComboBox);
if (!d->viewContainer()->isVisible()) {
+ const int rowCount = count();
int newIndex = currentIndex();
if (e->delta() > 0) {
@@ -3255,11 +3260,11 @@ void QComboBox::wheelEvent(QWheelEvent *e)
newIndex--;
} else if (e->delta() < 0) {
newIndex++;
- while ((newIndex < count()) && !(d->model->flags(d->model->index(newIndex,d->modelColumn,d->root)) & Qt::ItemIsEnabled))
+ while (newIndex < rowCount && !(d->model->index(newIndex, d->modelColumn, d->root).flags() & Qt::ItemIsEnabled))
newIndex++;
}
- if (newIndex >= 0 && newIndex < count() && newIndex != currentIndex()) {
+ if (newIndex >= 0 && newIndex < rowCount && newIndex != currentIndex()) {
setCurrentIndex(newIndex);
d->emitActivated(d->currentIndex);
}
diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h
index 3182a0a3aa..45b601788f 100644
--- a/src/widgets/widgets/qcombobox.h
+++ b/src/widgets/widgets/qcombobox.h
@@ -229,7 +229,9 @@ protected:
#ifndef QT_NO_WHEELEVENT
void wheelEvent(QWheelEvent *e) Q_DECL_OVERRIDE;
#endif
+#ifndef QT_NO_CONTEXTMENU
void contextMenuEvent(QContextMenuEvent *e) Q_DECL_OVERRIDE;
+#endif // QT_NO_CONTEXTMENU
void inputMethodEvent(QInputMethodEvent *) Q_DECL_OVERRIDE;
void initStyleOption(QStyleOptionComboBox *option) const;
diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp
index abee788a46..c2ed0d33e2 100644
--- a/src/widgets/widgets/qdatetimeedit.cpp
+++ b/src/widgets/widgets/qdatetimeedit.cpp
@@ -760,17 +760,17 @@ QCalendarWidget *QDateTimeEdit::calendarWidget() const
void QDateTimeEdit::setCalendarWidget(QCalendarWidget *calendarWidget)
{
Q_D(QDateTimeEdit);
- if (!calendarWidget) {
+ if (Q_UNLIKELY(!calendarWidget)) {
qWarning("QDateTimeEdit::setCalendarWidget: Cannot set a null calendar widget");
return;
}
- if (!d->calendarPopup) {
+ if (Q_UNLIKELY(!d->calendarPopup)) {
qWarning("QDateTimeEdit::setCalendarWidget: calendarPopup is set to false");
return;
}
- if (!(d->display & QDateTimeParser::DateSectionMask)) {
+ if (Q_UNLIKELY(!(d->display & QDateTimeParser::DateSectionMask))) {
qWarning("QDateTimeEdit::setCalendarWidget: no date sections specified");
return;
}
@@ -1868,7 +1868,7 @@ void QDateTimeEditPrivate::clearSection(int index)
const QSignalBlocker blocker(edit);
QString t = edit->text();
const int pos = sectionPos(index);
- if (pos == -1) {
+ if (Q_UNLIKELY(pos == -1)) {
qWarning("QDateTimeEdit: Internal error (%s:%d)", __FILE__, __LINE__);
return;
}
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
index 4d2c32d43e..cad5e6f9e4 100644
--- a/src/widgets/widgets/qdialogbuttonbox.cpp
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -405,11 +405,10 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut
button->setStyle(style);
standardButtonHash.insert(button, sbutton);
QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(static_cast<QPlatformDialogHelper::StandardButton>(sbutton));
- if (role != QPlatformDialogHelper::InvalidRole) {
- addButton(button, static_cast<QDialogButtonBox::ButtonRole>(role), doLayout);
- } else {
+ if (Q_UNLIKELY(role == QPlatformDialogHelper::InvalidRole))
qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
- }
+ else
+ addButton(button, static_cast<QDialogButtonBox::ButtonRole>(role), doLayout);
#ifdef Q_DEAD_CODE_FROM_QT4_MAC
// Since mnemonics is off by default on Mac, we add a Cmd-D
@@ -753,7 +752,7 @@ void QDialogButtonBox::removeButton(QAbstractButton *button)
void QDialogButtonBox::addButton(QAbstractButton *button, ButtonRole role)
{
Q_D(QDialogButtonBox);
- if (role <= InvalidRole || role >= NRoles) {
+ if (Q_UNLIKELY(role <= InvalidRole || role >= NRoles)) {
qWarning("QDialogButtonBox::addButton: Invalid ButtonRole, button not added");
return;
}
@@ -772,7 +771,7 @@ void QDialogButtonBox::addButton(QAbstractButton *button, ButtonRole role)
QPushButton *QDialogButtonBox::addButton(const QString &text, ButtonRole role)
{
Q_D(QDialogButtonBox);
- if (role <= InvalidRole || role >= NRoles) {
+ if (Q_UNLIKELY(role <= InvalidRole || role >= NRoles)) {
qWarning("QDialogButtonBox::addButton: Invalid ButtonRole, button not added");
return 0;
}
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp
index 8c79425e44..07efbafb31 100644
--- a/src/widgets/widgets/qdockarealayout.cpp
+++ b/src/widgets/widgets/qdockarealayout.cpp
@@ -1677,9 +1677,9 @@ void QDockAreaLayoutInfo::tab(int index, QLayoutItem *dockWidgetItem)
QDockAreaLayoutInfo *new_info
= new QDockAreaLayoutInfo(sep, dockPos, o, tabBarShape, mainWindow);
item_list[index].subinfo = new_info;
- new_info->item_list.append(item_list.at(index).widgetItem);
+ new_info->item_list.append(QDockAreaLayoutItem(item_list.at(index).widgetItem));
item_list[index].widgetItem = 0;
- new_info->item_list.append(dockWidgetItem);
+ new_info->item_list.append(QDockAreaLayoutItem(dockWidgetItem));
new_info->tabbed = true;
new_info->updateTabBar();
new_info->setCurrentTab(dockWidgetItem->widget());
@@ -1699,9 +1699,9 @@ void QDockAreaLayoutInfo::split(int index, Qt::Orientation orientation,
QDockAreaLayoutInfo *new_info
= new QDockAreaLayoutInfo(sep, dockPos, orientation, tabBarShape, mainWindow);
item_list[index].subinfo = new_info;
- new_info->item_list.append(item_list.at(index).widgetItem);
+ new_info->item_list.append(QDockAreaLayoutItem(item_list.at(index).widgetItem));
item_list[index].widgetItem = 0;
- new_info->item_list.append(dockWidgetItem);
+ new_info->item_list.append(QDockAreaLayoutItem(dockWidgetItem));
}
}
@@ -1802,9 +1802,9 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const
stream << (uchar) WidgetMarker;
QWidget *w = item.widgetItem->widget();
QString name = w->objectName();
- if (name.isEmpty()) {
- qWarning("QMainWindow::saveState(): 'objectName' not set for QDockWidget %p '%s;",
- w, qPrintable(w->windowTitle()));
+ if (Q_UNLIKELY(name.isEmpty())) {
+ qWarning("QMainWindow::saveState(): 'objectName' not set for QDockWidget %p '%ls;",
+ w, qUtf16Printable(w->windowTitle()));
}
stream << name;
@@ -3082,8 +3082,8 @@ void QDockAreaLayout::addDockWidget(QInternal::DockPosition pos, QDockWidget *do
int tbshape = 0;
#endif
QDockAreaLayoutInfo new_info(&sep, pos, orientation, tbshape, mainWindow);
- new_info.item_list.append(new QDockAreaLayoutInfo(info));
- new_info.item_list.append(dockWidgetItem);
+ new_info.item_list.append(QDockAreaLayoutItem(new QDockAreaLayoutInfo(info)));
+ new_info.item_list.append(QDockAreaLayoutItem(dockWidgetItem));
info = new_info;
}
@@ -3110,7 +3110,7 @@ void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks,
const QList<int> &sizes, Qt::Orientation o)
{
- if (docks.count() != sizes.count()) {
+ if (Q_UNLIKELY(docks.count() != sizes.count())) {
qWarning("QMainWidget::resizeDocks: size of the lists are not the same");
return;
}
@@ -3118,12 +3118,12 @@ void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks,
fallbackToSizeHints = false;
for (int i = 0; i < count; ++i) {
QList<int> path = indexOf(docks[i]);
- if (path.isEmpty()) {
+ if (Q_UNLIKELY(path.isEmpty())) {
qWarning("QMainWidget::resizeDocks: one QDockWidget is not part of the layout");
continue;
}
int size = sizes[i];
- if (size <= 0) {
+ if (Q_UNLIKELY(size <= 0)) {
qWarning("QMainWidget::resizeDocks: all sizes need to be larger than 0");
size = 1;
}
diff --git a/src/widgets/widgets/qdockarealayout_p.h b/src/widgets/widgets/qdockarealayout_p.h
index 5d352f0124..b0f2bdffa4 100644
--- a/src/widgets/widgets/qdockarealayout_p.h
+++ b/src/widgets/widgets/qdockarealayout_p.h
@@ -82,9 +82,9 @@ struct QDockAreaLayoutItem
{
enum ItemFlags { NoFlags = 0, GapItem = 1, KeepSize = 2 };
- QDockAreaLayoutItem(QLayoutItem *_widgetItem = 0);
- QDockAreaLayoutItem(QDockAreaLayoutInfo *_subinfo);
- QDockAreaLayoutItem(QPlaceHolderItem *_placeHolderItem);
+ explicit QDockAreaLayoutItem(QLayoutItem *_widgetItem = 0);
+ explicit QDockAreaLayoutItem(QDockAreaLayoutInfo *_subinfo);
+ explicit QDockAreaLayoutItem(QPlaceHolderItem *_placeHolderItem);
QDockAreaLayoutItem(const QDockAreaLayoutItem &other);
~QDockAreaLayoutItem();
@@ -109,7 +109,7 @@ class Q_AUTOTEST_EXPORT QPlaceHolderItem
{
public:
QPlaceHolderItem() : hidden(false), window(false) {}
- QPlaceHolderItem(QWidget *w);
+ explicit QPlaceHolderItem(QWidget *w);
QString objectName;
bool hidden, window;
diff --git a/src/widgets/widgets/qgroupbox.cpp b/src/widgets/widgets/qgroupbox.cpp
index 0ff5dc8753..559c8bbd33 100644
--- a/src/widgets/widgets/qgroupbox.cpp
+++ b/src/widgets/widgets/qgroupbox.cpp
@@ -653,9 +653,7 @@ void QGroupBox::setChecked(bool b)
void QGroupBoxPrivate::_q_setChildrenEnabled(bool b)
{
Q_Q(QGroupBox);
- QObjectList childList = q->children();
- for (int i = 0; i < childList.size(); ++i) {
- QObject *o = childList.at(i);
+ for (QObject *o : q->children()) {
if (o->isWidgetType()) {
QWidget *w = static_cast<QWidget *>(o);
if (b) {
@@ -707,6 +705,8 @@ void QGroupBox::mousePressEvent(QMouseEvent *event)
if (d->checkable && (d->pressedControl & (QStyle::SC_GroupBoxCheckBox | QStyle::SC_GroupBoxLabel))) {
d->overCheckBox = true;
update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
+ } else {
+ event->ignore();
}
}
@@ -723,6 +723,8 @@ void QGroupBox::mouseMoveEvent(QMouseEvent *event)
if (d->checkable && (d->pressedControl == QStyle::SC_GroupBoxCheckBox || d->pressedControl == QStyle::SC_GroupBoxLabel)
&& (d->overCheckBox != oldOverCheckBox))
update(style()->subControlRect(QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox, this));
+
+ event->ignore();
}
/*! \reimp */
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index 55e277026c..eeabd5db38 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -882,13 +882,11 @@ void QLabel::mouseReleaseEvent(QMouseEvent *ev)
d->sendControlEvent(ev);
}
+#ifndef QT_NO_CONTEXTMENU
/*!\reimp
*/
void QLabel::contextMenuEvent(QContextMenuEvent *ev)
{
-#ifdef QT_NO_CONTEXTMENU
- Q_UNUSED(ev);
-#else
Q_D(QLabel);
if (!d->isTextLabel) {
ev->ignore();
@@ -902,8 +900,8 @@ void QLabel::contextMenuEvent(QContextMenuEvent *ev)
ev->accept();
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->popup(ev->globalPos());
-#endif
}
+#endif // QT_NO_CONTEXTMENU
/*!
\reimp
diff --git a/src/widgets/widgets/qlabel.h b/src/widgets/widgets/qlabel.h
index 1a3a68db60..6b6e15e0a8 100644
--- a/src/widgets/widgets/qlabel.h
+++ b/src/widgets/widgets/qlabel.h
@@ -132,7 +132,9 @@ protected:
void mousePressEvent(QMouseEvent *ev) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *ev) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *ev) Q_DECL_OVERRIDE;
+#ifndef QT_NO_CONTEXTMENU
void contextMenuEvent(QContextMenuEvent *ev) Q_DECL_OVERRIDE;
+#endif // QT_NO_CONTEXTMENU
void focusInEvent(QFocusEvent *ev) Q_DECL_OVERRIDE;
void focusOutEvent(QFocusEvent *ev) Q_DECL_OVERRIDE;
bool focusNextPrevChild(bool next) Q_DECL_OVERRIDE;
diff --git a/src/widgets/widgets/qlcdnumber.cpp b/src/widgets/widgets/qlcdnumber.cpp
index d17e3e2470..b9c209ed3b 100644
--- a/src/widgets/widgets/qlcdnumber.cpp
+++ b/src/widgets/widgets/qlcdnumber.cpp
@@ -402,12 +402,12 @@ QLCDNumber::~QLCDNumber()
void QLCDNumber::setDigitCount(int numDigits)
{
Q_D(QLCDNumber);
- if (numDigits > 99) {
+ if (Q_UNLIKELY(numDigits > 99)) {
qWarning("QLCDNumber::setNumDigits: (%s) Max 99 digits allowed",
objectName().toLocal8Bit().constData());
numDigits = 99;
}
- if (numDigits < 0) {
+ if (Q_UNLIKELY(numDigits < 0)) {
qWarning("QLCDNumber::setNumDigits: (%s) Min 0 digits allowed",
objectName().toLocal8Bit().constData());
numDigits = 0;
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 6b32665065..59e1d647f9 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -982,7 +982,7 @@ int QLineEdit::selectionStart() const
void QLineEdit::setSelection(int start, int length)
{
Q_D(QLineEdit);
- if (start < 0 || start > (int)d->control->end()) {
+ if (Q_UNLIKELY(start < 0 || start > (int)d->control->end())) {
qWarning("QLineEdit::setSelection: Invalid start position (%d)", start);
return;
}
@@ -2180,9 +2180,10 @@ void QLineEdit::changeEvent(QEvent *ev)
update();
break;
case QEvent::LayoutDirectionChange:
- foreach (const QLineEditPrivate::SideWidgetEntry &e, d->trailingSideWidgets) // Refresh icon to show arrow in right direction.
+ for (const auto &e : d->trailingSideWidgets) { // Refresh icon to show arrow in right direction.
if (e.flags & QLineEditPrivate::SideWidgetClearButton)
static_cast<QLineEditIconButton *>(e.widget)->setIcon(d->clearButtonIcon());
+ }
d->positionSideWidgets();
break;
default:
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 599ebce0ab..59d8d79861 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -382,11 +382,11 @@ void QLineEditPrivate::_q_textChanged(const QString &text)
lastTextSize = newTextSize;
#ifndef QT_NO_ANIMATION
const bool fadeIn = newTextSize > 0;
- foreach (const SideWidgetEntry &e, leadingSideWidgets) {
+ for (const SideWidgetEntry &e : leadingSideWidgets) {
if (e.flags & SideWidgetFadeInWithText)
static_cast<QLineEditIconButton *>(e.widget)->animateShow(fadeIn);
}
- foreach (const SideWidgetEntry &e, trailingSideWidgets) {
+ for (const SideWidgetEntry &e : trailingSideWidgets) {
if (e.flags & SideWidgetFadeInWithText)
static_cast<QLineEditIconButton *>(e.widget)->animateShow(fadeIn);
}
@@ -453,13 +453,17 @@ void QLineEditPrivate::positionSideWidgets()
QLineEditPrivate::PositionIndexPair QLineEditPrivate::findSideWidget(const QAction *a) const
{
- for (int i = 0; i < leadingSideWidgets.size(); ++i) {
- if (a == leadingSideWidgets.at(i).action)
+ int i = 0;
+ for (const auto &e : leadingSideWidgets) {
+ if (a == e.action)
return PositionIndexPair(QLineEdit::LeadingPosition, i);
+ ++i;
}
- for (int i = 0; i < trailingSideWidgets.size(); ++i) {
- if (a == trailingSideWidgets.at(i).action)
+ i = 0;
+ for (const auto &e : trailingSideWidgets) {
+ if (a == e.action)
return PositionIndexPair(QLineEdit::TrailingPosition, i);
+ ++i;
}
return PositionIndexPair(QLineEdit::LeadingPosition, -1);
}
@@ -493,8 +497,8 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE
PositionIndexPair positionIndex = before ? findSideWidget(before) : PositionIndexPair(position, -1);
SideWidgetEntryList &list = positionIndex.first == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets;
if (positionIndex.second < 0)
- positionIndex.second = list.size();
- list.insert(positionIndex.second, SideWidgetEntry(w, newAction, flags));
+ positionIndex.second = int(list.size());
+ list.insert(list.begin() + positionIndex.second, SideWidgetEntry(w, newAction, flags));
positionSideWidgets();
w->show();
return w;
@@ -507,7 +511,8 @@ void QLineEditPrivate::removeAction(QAction *action)
if (positionIndex.second == -1)
return;
SideWidgetEntryList &list = positionIndex.first == QLineEdit::TrailingPosition ? trailingSideWidgets : leadingSideWidgets;
- SideWidgetEntry entry = list.takeAt(positionIndex.second);
+ SideWidgetEntry entry = list[positionIndex.second];
+ list.erase(list.begin() + positionIndex.second);
if (entry.flags & SideWidgetCreatedByWidgetAction)
static_cast<QWidgetAction *>(entry.action)->releaseWidget(entry.widget);
else
@@ -518,6 +523,28 @@ void QLineEditPrivate::removeAction(QAction *action)
q->update();
}
+static bool isSideWidgetVisible(const QLineEditPrivate::SideWidgetEntry &e)
+{
+ return e.widget->isVisible();
+}
+
+int QLineEditPrivate::effectiveLeftTextMargin() const
+{
+ const auto &list = leftSideWidgetList();
+ return leftTextMargin + (QLineEditIconButton::IconMargin + iconSize().width())
+ * int(std::count_if(list.begin(), list.end(),
+ isSideWidgetVisible));
+}
+
+int QLineEditPrivate::effectiveRightTextMargin() const
+{
+ const auto &list = rightSideWidgetList();
+ return rightTextMargin + (QLineEditIconButton::IconMargin + iconSize().width())
+ * int(std::count_if(list.begin(), list.end(),
+ isSideWidgetVisible));
+}
+
+
QT_END_NAMESPACE
#endif
diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h
index 60372ab393..b2f8e537e4 100644
--- a/src/widgets/widgets/qlineedit_p.h
+++ b/src/widgets/widgets/qlineedit_p.h
@@ -108,13 +108,13 @@ public:
};
struct SideWidgetEntry {
- SideWidgetEntry(QWidget *w = 0, QAction *a = 0, int _flags = 0) : widget(w), action(a), flags(_flags) {}
+ explicit SideWidgetEntry(QWidget *w = 0, QAction *a = 0, int _flags = 0) : widget(w), action(a), flags(_flags) {}
QWidget *widget;
QAction *action;
int flags;
};
- typedef QVector<SideWidgetEntry> SideWidgetEntryList;
+ typedef std::vector<SideWidgetEntry> SideWidgetEntryList;
QLineEditPrivate()
: control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
@@ -210,7 +210,7 @@ public:
QIcon clearButtonIcon() const;
void setClearButtonEnabled(bool enabled);
void positionSideWidgets();
- inline bool hasSideWidgets() const { return !leadingSideWidgets.isEmpty() || !trailingSideWidgets.isEmpty(); }
+ inline bool hasSideWidgets() const { return !leadingSideWidgets.empty() || !trailingSideWidgets.empty(); }
inline const SideWidgetEntryList &leftSideWidgetList() const
{ return q_func()->layoutDirection() == Qt::LeftToRight ? leadingSideWidgets : trailingSideWidgets; }
inline const SideWidgetEntryList &rightSideWidgetList() const
@@ -231,25 +231,6 @@ private:
};
Q_DECLARE_TYPEINFO(QLineEditPrivate::SideWidgetEntry, Q_PRIMITIVE_TYPE);
-static bool isSideWidgetVisible(const QLineEditPrivate::SideWidgetEntry &e)
-{
- return e.widget->isVisible();
-}
-
-inline int QLineEditPrivate::effectiveLeftTextMargin() const
-{
- return leftTextMargin + (QLineEditIconButton::IconMargin + iconSize().width())
- * int(std::count_if(leftSideWidgetList().constBegin(), leftSideWidgetList().constEnd(),
- isSideWidgetVisible));
-}
-
-inline int QLineEditPrivate::effectiveRightTextMargin() const
-{
- return rightTextMargin + (QLineEditIconButton::IconMargin + iconSize().width())
- * int(std::count_if(rightSideWidgetList().constBegin(), rightSideWidgetList().constEnd(),
- isSideWidgetVisible));
-}
-
#endif // QT_NO_LINEEDIT
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm
index a384e41d1b..7bd539033a 100644
--- a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm
+++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
#include "qmaccocoaviewcontainer_mac.h"
#include <QtCore/QDebug>
@@ -93,7 +93,7 @@ inline QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePla
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
nativeInterface->nativeResourceFunctionForIntegration(functionName);
- if (!function)
+ if (Q_UNLIKELY(!function))
qWarning() << "Qt could not resolve function" << functionName
<< "from QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration()";
return function;
diff --git a/src/widgets/widgets/qmacnativewidget_mac.mm b/src/widgets/widgets/qmacnativewidget_mac.mm
index 46a43c4110..729aa9aba0 100644
--- a/src/widgets/widgets/qmacnativewidget_mac.mm
+++ b/src/widgets/widgets/qmacnativewidget_mac.mm
@@ -31,7 +31,7 @@
**
****************************************************************************/
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
#include "qmacnativewidget_mac.h"
#include <QtCore/qdebug.h>
@@ -82,7 +82,7 @@ inline QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePla
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
nativeInterface->nativeResourceFunctionForIntegration(functionName);
- if (!function)
+ if (Q_UNLIKELY(!function))
qWarning() << "Qt could not resolve function" << functionName
<< "from QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration()";
return function;
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index ff4bb3cc98..2fbd83ef54 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -693,7 +693,7 @@ void QMainWindow::setCorner(Qt::Corner corner, Qt::DockWidgetArea area)
valid = (area == Qt::BottomDockWidgetArea || area == Qt::RightDockWidgetArea);
break;
}
- if (!valid)
+ if (Q_UNLIKELY(!valid))
qWarning("QMainWindow::setCorner(): 'area' is not valid for 'corner'");
else
d_func()->layout->setCorner(corner, area);
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 54e956c4cf..6b171ae452 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -1945,7 +1945,7 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
static_cast<QMainWindow*>(parentWidget()));
info->tabbed = true;
QLayout *parentLayout = currentHoveredFloat->parentWidget()->layout();
- info->item_list.append(parentLayout->takeAt(parentLayout->indexOf(currentHoveredFloat)));
+ info->item_list.append(QDockAreaLayoutItem(parentLayout->takeAt(parentLayout->indexOf(currentHoveredFloat))));
dropTo->setParent(floatingTabs);
dropTo->show();
diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h
index 9a13e5f5ce..b718a0ca4f 100644
--- a/src/widgets/widgets/qmainwindowlayout_p.h
+++ b/src/widgets/widgets/qmainwindowlayout_p.h
@@ -60,18 +60,6 @@
#include "qdockarealayout_p.h"
#include "qtoolbararealayout_p.h"
-#ifdef Q_DEAD_CODE_FROM_QT4_MAC
-// Forward defs to make avoid including Carbon.h (faster compile you know ;).
-struct OpaqueHIObjectRef;
-typedef struct OpaqueHIObjectRef* HIObjectRef;
-typedef HIObjectRef HIToolbarItemRef;
-typedef const void * CFTypeRef;
-typedef const struct __CFString * CFStringRef;
-
-#include <private/qunifiedtoolbarsurface_mac_p.h>
-
-#endif // Q_DEAD_CODE_FROM_QT4_MAC
-
QT_BEGIN_NAMESPACE
class QToolBar;
@@ -275,7 +263,7 @@ public:
// save/restore
- enum { // sentinel values used to validate state data
+ enum VersionMarkers { // sentinel values used to validate state data
VersionMarker = 0xff
};
void saveState(QDataStream &stream) const;
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index e683c48ad3..50685667d3 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -161,7 +161,6 @@
#include <QResizeEvent>
#include <QScrollBar>
#include <QtAlgorithms>
-#include <QMutableVectorIterator>
#include <QPainter>
#include <QFontMetrics>
#include <QStyleOption>
@@ -179,7 +178,7 @@ using namespace QMdi;
// Asserts in debug mode, gives warning otherwise.
static bool sanityCheck(const QMdiSubWindow * const child, const char *where)
{
- if (!child) {
+ if (Q_UNLIKELY(!child)) {
const char error[] = "null pointer";
Q_ASSERT_X(false, where, error);
qWarning("%s:%s", where, error);
@@ -190,13 +189,13 @@ static bool sanityCheck(const QMdiSubWindow * const child, const char *where)
static bool sanityCheck(const QList<QWidget *> &widgets, const int index, const char *where)
{
- if (index < 0 || index >= widgets.size()) {
+ if (Q_UNLIKELY(index < 0 || index >= widgets.size())) {
const char error[] = "index out of range";
Q_ASSERT_X(false, where, error);
qWarning("%s:%s", where, error);
return false;
}
- if (!widgets.at(index)) {
+ if (Q_UNLIKELY(!widgets.at(index))) {
const char error[] = "null pointer";
Q_ASSERT_X(false, where, error);
qWarning("%s:%s", where, error);
@@ -380,7 +379,7 @@ void IconTiler::rearrange(QList<QWidget *> &widgets, const QRect &domain) const
return;
const int n = widgets.size();
- const int width = widgets.at(0)->width();
+ const int width = qMax(widgets.at(0)->width(), 1);
const int height = widgets.at(0)->height();
const int ncols = qMax(domain.width() / width, 1);
const int nrows = n / ncols + ((n % ncols) ? 1 : 0);
@@ -409,7 +408,7 @@ void IconTiler::rearrange(QList<QWidget *> &widgets, const QRect &domain) const
int MinOverlapPlacer::accumulatedOverlap(const QRect &source, const QVector<QRect> &rects)
{
int accOverlap = 0;
- foreach (const QRect &rect, rects) {
+ for (const QRect &rect : rects) {
QRect intersection = source.intersected(rect);
accOverlap += intersection.width() * intersection.height();
}
@@ -426,7 +425,7 @@ QRect MinOverlapPlacer::findMinOverlapRect(const QVector<QRect> &source, const Q
{
int minAccOverlap = -1;
QRect minAccOverlapRect;
- foreach (const QRect &srcRect, source) {
+ for (const QRect &srcRect : source) {
const int accOverlap = accumulatedOverlap(srcRect, rects);
if (accOverlap < minAccOverlap || minAccOverlap == -1) {
minAccOverlap = accOverlap;
@@ -455,7 +454,7 @@ QVector<QRect> MinOverlapPlacer::getCandidatePlacements(const QSize &size, const
if (domain.bottom() - size.height() + 1 >= 0)
ylist << domain.bottom() - size.height() + 1;
- foreach (const QRect &rect, rects) {
+ for (const QRect &rect : rects) {
xlist << rect.right() + 1;
ylist << rect.bottom() + 1;
}
@@ -480,17 +479,16 @@ QVector<QRect> MinOverlapPlacer::getCandidatePlacements(const QSize &size, const
*/
QVector<QRect> MinOverlapPlacer::findNonInsiders(const QRect &domain, QVector<QRect> &source)
{
+ const auto containedInDomain =
+ [domain](const QRect &srcRect) { return domain.contains(srcRect); };
+
+ const auto firstOut = std::stable_partition(source.begin(), source.end(), containedInDomain);
+
QVector<QRect> result;
- result.reserve(source.size());
+ result.reserve(source.end() - firstOut);
+ std::copy(firstOut, source.end(), std::back_inserter(result));
- QMutableVectorIterator<QRect> it(source);
- while (it.hasNext()) {
- const QRect srcRect = it.next();
- if (!domain.contains(srcRect)) {
- result << srcRect;
- it.remove();
- }
- }
+ source.erase(firstOut, source.end());
return result;
}
@@ -506,13 +504,13 @@ QVector<QRect> MinOverlapPlacer::findMaxOverlappers(const QRect &domain, const Q
result.reserve(source.size());
int maxOverlap = -1;
- foreach (const QRect &srcRect, source) {
+ for (const QRect &srcRect : source) {
QRect intersection = domain.intersected(srcRect);
const int overlap = intersection.width() * intersection.height();
if (overlap >= maxOverlap || maxOverlap == -1) {
if (overlap > maxOverlap) {
maxOverlap = overlap;
- result.clear();
+ result.resize(0);
}
result << srcRect;
}
@@ -551,7 +549,7 @@ QPoint MinOverlapPlacer::place(const QSize &size, const QVector<QRect> &rects,
{
if (size.isEmpty() || !domain.isValid())
return QPoint();
- foreach (const QRect &rect, rects) {
+ for (const QRect &rect : rects) {
if (!rect.isValid())
return QPoint();
}
@@ -938,7 +936,7 @@ void QMdiAreaPrivate::rearrange(Rearranger *rearranger)
if (!sanityCheck(child, "QMdiArea::rearrange") || !child->isVisible())
continue;
if (rearranger->type() == Rearranger::IconTiler) {
- if (child->isMinimized() && !child->isShaded() && !(child->windowFlags() & Qt::FramelessWindowHint))
+ if (child->isMinimized() && !child->isShaded())
widgets.append(child);
} else {
if (child->isMinimized() && !child->isShaded())
@@ -1239,7 +1237,8 @@ void QMdiAreaPrivate::internalRaise(QMdiSubWindow *mdiChild) const
QMdiSubWindow *stackUnderChild = 0;
if (!windowStaysOnTop(mdiChild)) {
- foreach (QObject *object, viewport->children()) {
+ const auto children = viewport->children(); // take a copy, as raising/stacking under changes the order
+ for (QObject *object : children) {
QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(object);
if (!child || !childWindows.contains(child))
continue;
@@ -1394,7 +1393,7 @@ QMdiAreaPrivate::subWindowList(QMdiArea::WindowOrder order, bool reversed) const
list.prepend(child);
}
} else if (order == QMdiArea::StackingOrder) {
- foreach (QObject *object, viewport->children()) {
+ for (QObject *object : viewport->children()) {
QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(object);
if (!child || !childWindows.contains(child))
continue;
@@ -1743,7 +1742,7 @@ QSize QMdiArea::sizeHint() const
QSize desktopSize = QApplication::desktop()->size();
QSize size(desktopSize.width() * 2 / scaleFactor, desktopSize.height() * 2 / scaleFactor);
- foreach (QMdiSubWindow *child, d_func()->childWindows) {
+ for (QMdiSubWindow *child : d_func()->childWindows) {
if (!sanityCheck(child, "QMdiArea::sizeHint"))
continue;
size = size.expandedTo(child->sizeHint());
@@ -1761,7 +1760,7 @@ QSize QMdiArea::minimumSizeHint() const
style()->pixelMetric(QStyle::PM_TitleBarHeight, 0, this));
size = size.expandedTo(QAbstractScrollArea::minimumSizeHint());
if (!d->scrollBarsEnabled()) {
- foreach (QMdiSubWindow *child, d->childWindows) {
+ for (QMdiSubWindow *child : d->childWindows) {
if (!sanityCheck(child, "QMdiArea::sizeHint"))
continue;
size = size.expandedTo(child->minimumSizeHint());
@@ -1831,12 +1830,12 @@ void QMdiArea::setActiveSubWindow(QMdiSubWindow *window)
return;
}
- if (d->childWindows.isEmpty()) {
+ if (Q_UNLIKELY(d->childWindows.isEmpty())) {
qWarning("QMdiArea::setActiveSubWindow: workspace is empty");
return;
}
- if (d->childWindows.indexOf(window) == -1) {
+ if (Q_UNLIKELY(d->childWindows.indexOf(window) == -1)) {
qWarning("QMdiArea::setActiveSubWindow: window is not inside workspace");
return;
}
@@ -1960,7 +1959,7 @@ void QMdiArea::activatePreviousSubWindow()
*/
QMdiSubWindow *QMdiArea::addSubWindow(QWidget *widget, Qt::WindowFlags windowFlags)
{
- if (!widget) {
+ if (Q_UNLIKELY(!widget)) {
qWarning("QMdiArea::addSubWindow: null pointer to widget");
return 0;
}
@@ -1972,7 +1971,7 @@ QMdiSubWindow *QMdiArea::addSubWindow(QWidget *widget, Qt::WindowFlags windowFla
// Widget is already a QMdiSubWindow
if (child) {
- if (d->childWindows.indexOf(child) != -1) {
+ if (Q_UNLIKELY(d->childWindows.indexOf(child) != -1)) {
qWarning("QMdiArea::addSubWindow: window is already added");
return child;
}
@@ -2003,7 +2002,7 @@ QMdiSubWindow *QMdiArea::addSubWindow(QWidget *widget, Qt::WindowFlags windowFla
*/
void QMdiArea::removeSubWindow(QWidget *widget)
{
- if (!widget) {
+ if (Q_UNLIKELY(!widget)) {
qWarning("QMdiArea::removeSubWindow: null pointer to widget");
return;
}
@@ -2014,7 +2013,7 @@ void QMdiArea::removeSubWindow(QWidget *widget)
if (QMdiSubWindow *child = qobject_cast<QMdiSubWindow *>(widget)) {
int index = d->childWindows.indexOf(child);
- if (index == -1) {
+ if (Q_UNLIKELY(index == -1)) {
qWarning("QMdiArea::removeSubWindow: window is not inside workspace");
return;
}
@@ -2038,7 +2037,7 @@ void QMdiArea::removeSubWindow(QWidget *widget)
}
}
- if (!found)
+ if (Q_UNLIKELY(!found))
qWarning("QMdiArea::removeSubWindow: widget is not child of any window inside QMdiArea");
}
diff --git a/src/widgets/widgets/qmdiarea_p.h b/src/widgets/widgets/qmdiarea_p.h
index f6bdf61492..471703ea70 100644
--- a/src/widgets/widgets/qmdiarea_p.h
+++ b/src/widgets/widgets/qmdiarea_p.h
@@ -144,7 +144,7 @@ public:
QList<QMdi::Rearranger *> pendingRearrangements;
QVector< QPointer<QMdiSubWindow> > pendingPlacements;
QVector< QPointer<QMdiSubWindow> > childWindows;
- QList<int> indicesToActivatedChildren;
+ QVector<int> indicesToActivatedChildren;
QPointer<QMdiSubWindow> active;
QPointer<QMdiSubWindow> aboutToBecomeActive;
QBrush background;
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index 14aeb73baf..83a997dae0 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -1000,7 +1000,9 @@ void QMdiSubWindowPrivate::removeBaseWidget()
q->setWindowModified(false);
}
lastChildWindowTitle.clear();
- baseWidget->setParent(0);
+ // QTBUG-47993: parent widget can be reset before this call
+ if (baseWidget->parentWidget() == q)
+ baseWidget->setParent(0);
baseWidget = 0;
isWidgetHiddenByUs = false;
}
@@ -2204,8 +2206,8 @@ void QMdiSubWindowPrivate::setSizeGrip(QSizeGrip *newSizeGrip)
void QMdiSubWindowPrivate::setSizeGripVisible(bool visible) const
{
// See if we can find any size grips
- QList<QSizeGrip *> sizeGrips = q_func()->findChildren<QSizeGrip *>();
- foreach (QSizeGrip *grip, sizeGrips)
+ const QList<QSizeGrip *> sizeGrips = q_func()->findChildren<QSizeGrip *>();
+ for (QSizeGrip *grip : sizeGrips)
grip->setVisible(visible);
}
@@ -2307,7 +2309,7 @@ void QMdiSubWindow::setWidget(QWidget *widget)
return;
}
- if (widget == d->baseWidget) {
+ if (Q_UNLIKELY(widget == d->baseWidget)) {
qWarning("QMdiSubWindow::setWidget: widget is already set");
return;
}
@@ -2505,7 +2507,7 @@ void QMdiSubWindow::setKeyboardPageStep(int step)
void QMdiSubWindow::setSystemMenu(QMenu *systemMenu)
{
Q_D(QMdiSubWindow);
- if (systemMenu && systemMenu == d->systemMenu) {
+ if (Q_UNLIKELY(systemMenu && systemMenu == d->systemMenu)) {
qWarning("QMdiSubWindow::setSystemMenu: system menu is already set");
return;
}
@@ -2653,7 +2655,7 @@ void QMdiSubWindow::showShaded()
resize(d->internalMinimumSize);
// Hide the internal widget if not already hidden by the user.
- if (d->baseWidget && !d->baseWidget->isHidden()) {
+ if (d->baseWidget && !d->baseWidget->isHidden() && !(windowFlags() & Qt::FramelessWindowHint)) {
d->baseWidget->hide();
d->isWidgetHiddenByUs = true;
}
diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm
index 8b29011178..58dee37bd9 100644
--- a/src/widgets/widgets/qmenu_mac.mm
+++ b/src/widgets/widgets/qmenu_mac.mm
@@ -32,7 +32,7 @@
****************************************************************************/
#import <Foundation/Foundation.h>
-#import <Cocoa/Cocoa.h>
+#import <AppKit/AppKit.h>
#include "qmenu.h"
#include "qmenubar.h"
@@ -55,7 +55,7 @@ inline QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePla
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
nativeInterface->nativeResourceFunctionForIntegration(functionName);
- if (!function)
+ if (Q_UNLIKELY(!function))
qWarning() << "Qt could not resolve function" << functionName
<< "from QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration()";
return function;
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 91788a3383..7736356700 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -1291,7 +1291,7 @@ void QPlainTextEdit::setDocument(QTextDocument *document)
document->setDocumentLayout(documentLayout);
} else {
documentLayout = qobject_cast<QPlainTextDocumentLayout*>(document->documentLayout());
- if (!documentLayout) {
+ if (Q_UNLIKELY(!documentLayout)) {
qWarning("QPlainTextEdit::setDocument: Document set does not support QPlainTextDocumentLayout");
return;
}
@@ -1851,7 +1851,7 @@ void QPlainTextEditPrivate::relayoutDocument()
}
}
-static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, QRectF gradientRect = QRectF())
+static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, const QRectF &gradientRect = QRectF())
{
p->save();
if (brush.style() >= Qt::LinearGradientPattern && brush.style() <= Qt::ConicalGradientPattern) {
diff --git a/src/widgets/widgets/qscrollbar.h b/src/widgets/widgets/qscrollbar.h
index 4af5fb4a55..d044ec0519 100644
--- a/src/widgets/widgets/qscrollbar.h
+++ b/src/widgets/widgets/qscrollbar.h
@@ -78,6 +78,13 @@ private:
Q_DISABLE_COPY(QScrollBar)
Q_DECLARE_PRIVATE(QScrollBar)
+#ifndef QT_NO_ITEMVIEWS
+ friend class QTableView;
+ friend class QTreeViewPrivate;
+ friend class QCommonListViewBase;
+ friend class QListModeViewBase;
+ friend class QAbstractItemView;
+#endif
};
#endif // QT_NO_SCROLLBAR
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 457e2e1e4c..13076ad870 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -438,7 +438,7 @@ void QSpinBox::setDisplayIntegerBase(int base)
{
Q_D(QSpinBox);
// Falls back to base 10 on invalid bases (like QString)
- if (base < 2 || base > 36) {
+ if (Q_UNLIKELY(base < 2 || base > 36)) {
qWarning("QSpinBox::setDisplayIntegerBase: Invalid base (%d)", base);
base = 10;
}
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index c2081c15f8..9162ba3c12 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -1058,7 +1058,7 @@ void QSplitter::setCollapsible(int index, bool collapse)
{
Q_D(QSplitter);
- if (index < 0 || index >= d->list.size()) {
+ if (Q_UNLIKELY(index < 0 || index >= d->list.size())) {
qWarning("QSplitter::setCollapsible: Index %d out of range", index);
return;
}
@@ -1071,7 +1071,7 @@ void QSplitter::setCollapsible(int index, bool collapse)
bool QSplitter::isCollapsible(int index) const
{
Q_D(const QSplitter);
- if (index < 0 || index >= d->list.size()) {
+ if (Q_UNLIKELY(index < 0 || index >= d->list.size())) {
qWarning("QSplitter::isCollapsible: Index %d out of range", index);
return false;
}
@@ -1215,7 +1215,7 @@ void QSplitter::childEvent(QChildEvent *c)
{
Q_D(QSplitter);
if (!c->child()->isWidgetType()) {
- if (c->type() == QEvent::ChildAdded && qobject_cast<QLayout *>(c->child()))
+ if (Q_UNLIKELY(c->type() == QEvent::ChildAdded && qobject_cast<QLayout *>(c->child())))
qWarning("Adding a QLayout to a QSplitter is not supported.");
return;
}
diff --git a/src/widgets/widgets/qstackedwidget.cpp b/src/widgets/widgets/qstackedwidget.cpp
index 19a2edf0f2..8a2eff4e39 100644
--- a/src/widgets/widgets/qstackedwidget.cpp
+++ b/src/widgets/widgets/qstackedwidget.cpp
@@ -237,7 +237,7 @@ QWidget *QStackedWidget::currentWidget() const
void QStackedWidget::setCurrentWidget(QWidget *widget)
{
Q_D(QStackedWidget);
- if (d->layout->indexOf(widget) == -1) {
+ if (Q_UNLIKELY(d->layout->indexOf(widget) == -1)) {
qWarning("QStackedWidget::setCurrentWidget: widget %p not contained in stack", widget);
return;
}
diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp
index 19361fc793..2e8ca8510b 100644
--- a/src/widgets/widgets/qstatusbar.cpp
+++ b/src/widgets/widgets/qstatusbar.cpp
@@ -296,7 +296,7 @@ int QStatusBar::insertWidget(int index, QWidget *widget, int stretch)
QStatusBarPrivate::SBItem* item = new QStatusBarPrivate::SBItem(widget, stretch, false);
int idx = d->indexToLastNonPermanentWidget();
- if (index < 0 || index > d->items.size() || (idx >= 0 && index > idx + 1)) {
+ if (Q_UNLIKELY(index < 0 || index > d->items.size() || (idx >= 0 && index > idx + 1))) {
qWarning("QStatusBar::insertWidget: Index out of range (%d), appending widget", index);
index = idx + 1;
}
@@ -361,7 +361,7 @@ int QStatusBar::insertPermanentWidget(int index, QWidget *widget, int stretch)
QStatusBarPrivate::SBItem* item = new QStatusBarPrivate::SBItem(widget, stretch, true);
int idx = d->indexToLastNonPermanentWidget();
- if (index < 0 || index > d->items.size() || (idx >= 0 && index <= idx)) {
+ if (Q_UNLIKELY(index < 0 || index > d->items.size() || (idx >= 0 && index <= idx))) {
qWarning("QStatusBar::insertPermanentWidget: Index out of range (%d), appending widget", index);
index = d->items.size();
}
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 7ea5455bf7..d2d737059e 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -348,13 +348,6 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const
\since 5.2
*/
-int QTabBarPrivate::extraWidth() const
-{
- Q_Q(const QTabBar);
- return 2 * qMax(q->style()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, 0, q),
- QApplication::globalStrut().width());
-}
-
void QTabBarPrivate::init()
{
Q_Q(QTabBar);
@@ -408,7 +401,6 @@ int QTabBarPrivate::indexAtPos(const QPoint &p) const
void QTabBarPrivate::layoutTabs()
{
Q_Q(QTabBar);
- scrollOffset = 0;
layoutDirty = false;
QSize size = q->size();
int last, available;
@@ -508,39 +500,48 @@ void QTabBarPrivate::layoutTabs()
}
if (useScrollButtons && tabList.count() && last > available) {
- int extra = extraWidth();
- if (!vertTabs) {
- Qt::LayoutDirection ld = q->layoutDirection();
- QRect arrows = QStyle::visualRect(ld, q->rect(),
- QRect(available - extra, 0, extra, size.height()));
- int buttonOverlap = q->style()->pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, 0, q);
-
- if (ld == Qt::LeftToRight) {
- leftB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());
- rightB->setGeometry(arrows.right() - extra/2 + buttonOverlap, arrows.top(),
- extra/2, arrows.height());
- leftB->setArrowType(Qt::LeftArrow);
- rightB->setArrowType(Qt::RightArrow);
- } else {
- rightB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());
- leftB->setGeometry(arrows.right() - extra/2 + buttonOverlap, arrows.top(),
- extra/2, arrows.height());
- rightB->setArrowType(Qt::LeftArrow);
- leftB->setArrowType(Qt::RightArrow);
- }
- } else {
- QRect arrows = QRect(0, available - extra, size.width(), extra );
- leftB->setGeometry(arrows.left(), arrows.top(), arrows.width(), extra/2);
+ const QRect scrollRect = normalizedScrollRect(0);
+ scrollOffset = -scrollRect.left();
+
+ Q_Q(QTabBar);
+ QStyleOption opt;
+ opt.init(q);
+ QRect scrollButtonLeftRect = q->style()->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, q);
+ QRect scrollButtonRightRect = q->style()->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, q);
+ int scrollButtonWidth = q->style()->pixelMetric(QStyle::PM_TabBarScrollButtonWidth, &opt, q);
+
+ // Normally SE_TabBarScrollLeftButton should have the same width as PM_TabBarScrollButtonWidth.
+ // But if that is not the case, we set the actual button width to PM_TabBarScrollButtonWidth, and
+ // use the extra space from SE_TabBarScrollLeftButton as margins towards the tabs.
+ if (vertTabs) {
+ scrollButtonLeftRect.setHeight(scrollButtonWidth);
+ scrollButtonRightRect.setY(scrollButtonRightRect.bottom() + 1 - scrollButtonWidth);
+ scrollButtonRightRect.setHeight(scrollButtonWidth);
leftB->setArrowType(Qt::UpArrow);
- rightB->setGeometry(arrows.left(), arrows.bottom() - extra/2 + 1,
- arrows.width(), extra/2);
rightB->setArrowType(Qt::DownArrow);
+ } else if (q->layoutDirection() == Qt::RightToLeft) {
+ scrollButtonRightRect.setWidth(scrollButtonWidth);
+ scrollButtonLeftRect.setX(scrollButtonLeftRect.right() + 1 - scrollButtonWidth);
+ scrollButtonLeftRect.setWidth(scrollButtonWidth);
+ leftB->setArrowType(Qt::RightArrow);
+ rightB->setArrowType(Qt::LeftArrow);
+ } else {
+ scrollButtonLeftRect.setWidth(scrollButtonWidth);
+ scrollButtonRightRect.setX(scrollButtonRightRect.right() + 1 - scrollButtonWidth);
+ scrollButtonRightRect.setWidth(scrollButtonWidth);
+ leftB->setArrowType(Qt::LeftArrow);
+ rightB->setArrowType(Qt::RightArrow);
}
- leftB->setEnabled(scrollOffset > 0);
- rightB->setEnabled(last - scrollOffset >= available - extra);
+
+ leftB->setGeometry(scrollButtonLeftRect);
+ leftB->setEnabled(false);
leftB->show();
+
+ rightB->setGeometry(scrollButtonRightRect);
+ rightB->setEnabled(last - scrollOffset > scrollRect.x() + scrollRect.width());
rightB->show();
} else {
+ scrollOffset = 0;
rightB->hide();
leftB->hide();
}
@@ -549,6 +550,81 @@ void QTabBarPrivate::layoutTabs()
q->tabLayoutChange();
}
+QRect QTabBarPrivate::normalizedScrollRect(int index)
+{
+ // "Normalized scroll rect" means return the free space on the tab bar
+ // that doesn't overlap with scroll buttons or tear indicators, and
+ // always return the rect as horizontal Qt::LeftToRight, even if the
+ // tab bar itself is in a different orientation.
+
+ Q_Q(QTabBar);
+ QStyleOptionTab opt;
+ q->initStyleOption(&opt, currentIndex);
+ opt.rect = q->rect();
+
+ QRect scrollButtonLeftRect = q->style()->subElementRect(QStyle::SE_TabBarScrollLeftButton, &opt, q);
+ QRect scrollButtonRightRect = q->style()->subElementRect(QStyle::SE_TabBarScrollRightButton, &opt, q);
+ QRect tearLeftRect = q->style()->subElementRect(QStyle::SE_TabBarTearIndicatorLeft, &opt, q);
+ QRect tearRightRect = q->style()->subElementRect(QStyle::SE_TabBarTearIndicatorRight, &opt, q);
+
+ if (verticalTabs(shape)) {
+ int topEdge, bottomEdge;
+ bool leftButtonIsOnTop = scrollButtonLeftRect.y() < q->height() / 2;
+ bool rightButtonIsOnTop = scrollButtonRightRect.y() < q->height() / 2;
+
+ if (leftButtonIsOnTop && rightButtonIsOnTop) {
+ topEdge = scrollButtonRightRect.bottom() + 1;
+ bottomEdge = q->height();
+ } else if (!leftButtonIsOnTop && !rightButtonIsOnTop) {
+ topEdge = 0;
+ bottomEdge = scrollButtonLeftRect.top();
+ } else {
+ topEdge = scrollButtonLeftRect.bottom() + 1;
+ bottomEdge = scrollButtonRightRect.top();
+ }
+
+ bool tearTopVisible = index != 0 && topEdge != -scrollOffset;
+ bool tearBottomVisible = index != tabList.size() - 1 && bottomEdge != tabList.last().rect.bottom() + 1 - scrollOffset;
+ if (tearTopVisible && !tearLeftRect.isNull())
+ topEdge = tearLeftRect.bottom() + 1;
+ if (tearBottomVisible && !tearRightRect.isNull())
+ bottomEdge = tearRightRect.top();
+
+ return QRect(topEdge, 0, bottomEdge - topEdge, q->height());
+ } else {
+ if (q->layoutDirection() == Qt::RightToLeft) {
+ scrollButtonLeftRect = QStyle::visualRect(Qt::RightToLeft, q->rect(), scrollButtonLeftRect);
+ scrollButtonRightRect = QStyle::visualRect(Qt::RightToLeft, q->rect(), scrollButtonRightRect);
+ tearLeftRect = QStyle::visualRect(Qt::RightToLeft, q->rect(), tearLeftRect);
+ tearRightRect = QStyle::visualRect(Qt::RightToLeft, q->rect(), tearRightRect);
+ }
+
+ int leftEdge, rightEdge;
+ bool leftButtonIsOnLeftSide = scrollButtonLeftRect.x() < q->width() / 2;
+ bool rightButtonIsOnLeftSide = scrollButtonRightRect.x() < q->width() / 2;
+
+ if (leftButtonIsOnLeftSide && rightButtonIsOnLeftSide) {
+ leftEdge = scrollButtonRightRect.right() + 1;
+ rightEdge = q->width();
+ } else if (!leftButtonIsOnLeftSide && !rightButtonIsOnLeftSide) {
+ leftEdge = 0;
+ rightEdge = scrollButtonLeftRect.left();
+ } else {
+ leftEdge = scrollButtonLeftRect.right() + 1;
+ rightEdge = scrollButtonRightRect.left();
+ }
+
+ bool tearLeftVisible = index != 0 && leftEdge != -scrollOffset;
+ bool tearRightVisible = index != tabList.size() - 1 && rightEdge != tabList.last().rect.right() + 1 - scrollOffset;
+ if (tearLeftVisible && !tearLeftRect.isNull())
+ leftEdge = tearLeftRect.right() + 1;
+ if (tearRightVisible && !tearRightRect.isNull())
+ rightEdge = tearRightRect.left();
+
+ return QRect(leftEdge, 0, rightEdge - leftEdge, q->height());
+ }
+}
+
void QTabBarPrivate::makeVisible(int index)
{
Q_Q(QTabBar);
@@ -558,17 +634,24 @@ void QTabBarPrivate::makeVisible(int index)
const QRect tabRect = tabList.at(index).rect;
const int oldScrollOffset = scrollOffset;
const bool horiz = !verticalTabs(shape);
- const int available = (horiz ? q->width() : q->height()) - extraWidth();
- const int start = horiz ? tabRect.left() : tabRect.top();
- const int end = horiz ? tabRect.right() : tabRect.bottom();
- if (start < scrollOffset) // too far left
- scrollOffset = start - (index ? 8 : 0);
- else if (end > scrollOffset + available) // too far right
- scrollOffset = end - available + 1;
-
- leftB->setEnabled(scrollOffset > 0);
- const int last = horiz ? tabList.last().rect.right() : tabList.last().rect.bottom();
- rightB->setEnabled(last - scrollOffset >= available);
+ const int tabStart = horiz ? tabRect.left() : tabRect.top();
+ const int tabEnd = horiz ? tabRect.right() : tabRect.bottom();
+ const int lastTabEnd = horiz ? tabList.last().rect.right() : tabList.last().rect.bottom();
+ const QRect scrollRect = normalizedScrollRect(index);
+ const int scrolledTabBarStart = qMax(1, scrollRect.left() + scrollOffset);
+ const int scrolledTabBarEnd = qMin(lastTabEnd - 1, scrollRect.right() + scrollOffset);
+
+ if (tabStart < scrolledTabBarStart) {
+ // Tab is outside on the left, so scroll left.
+ scrollOffset = tabStart - scrollRect.left();
+ } else if (tabEnd > scrolledTabBarEnd) {
+ // Tab is outside on the right, so scroll right.
+ scrollOffset = tabEnd - scrollRect.right();
+ }
+
+ leftB->setEnabled(scrollOffset > -scrollRect.left());
+ rightB->setEnabled(scrollOffset < lastTabEnd - scrollRect.right());
+
if (oldScrollOffset != scrollOffset) {
q->update();
layoutWidgets();
@@ -664,39 +747,24 @@ void QTabBarPrivate::_q_scrollTabs()
{
Q_Q(QTabBar);
const QObject *sender = q->sender();
+ const bool horizontal = !verticalTabs(shape);
+ const QRect scrollRect = normalizedScrollRect();
int i = -1;
- if (!verticalTabs(shape)) {
- if (sender == leftB) {
- for (i = tabList.count() - 1; i >= 0; --i) {
- if (tabList.at(i).rect.left() - scrollOffset < 0) {
- makeVisible(i);
- return;
- }
- }
- } else if (sender == rightB) {
- int availableWidth = q->width() - extraWidth();
- for (i = 0; i < tabList.count(); ++i) {
- if (tabList.at(i).rect.right() - scrollOffset > availableWidth) {
- makeVisible(i);
- return;
- }
+
+ if (sender == leftB) {
+ for (i = tabList.count() - 1; i >= 0; --i) {
+ int start = horizontal ? tabList.at(i).rect.left() : tabList.at(i).rect.top();
+ if (start < scrollRect.left() + scrollOffset) {
+ makeVisible(i);
+ return;
}
}
- } else { // vertical
- if (sender == leftB) {
- for (i = tabList.count() - 1; i >= 0; --i) {
- if (tabList.at(i).rect.top() - scrollOffset < 0) {
- makeVisible(i);
- return;
- }
- }
- } else if (sender == rightB) {
- int available = q->height() - extraWidth();
- for (i = 0; i < tabList.count(); ++i) {
- if (tabList.at(i).rect.bottom() - scrollOffset > available) {
- makeVisible(i);
- return;
- }
+ } else if (sender == rightB) {
+ for (i = 0; i < tabList.count(); ++i) {
+ int end = horizontal ? tabList.at(i).rect.right() : tabList.at(i).rect.bottom();
+ if (end > scrollRect.right() + scrollOffset) {
+ makeVisible(i);
+ return;
}
}
}
@@ -1571,13 +1639,15 @@ void QTabBar::paintEvent(QPaintEvent *)
QStylePainter p(this);
int selected = -1;
- int cut = -1;
- bool rtl = optTabBase.direction == Qt::RightToLeft;
+ int cutLeft = -1;
+ int cutRight = -1;
bool vertical = verticalTabs(d->shape);
- QStyleOptionTab cutTab;
+ QStyleOptionTab cutTabLeft;
+ QStyleOptionTab cutTabRight;
selected = d->currentIndex;
if (d->dragInProgress)
selected = d->pressedIndex;
+ const QRect scrollRect = d->normalizedScrollRect();
for (int i = 0; i < d->tabList.count(); ++i)
optTabBase.tabBarRect |= tabRect(i);
@@ -1600,13 +1670,20 @@ void QTabBar::paintEvent(QPaintEvent *)
if (!(tab.state & QStyle::State_Enabled)) {
tab.palette.setCurrentColorGroup(QPalette::Disabled);
}
+
// If this tab is partially obscured, make a note of it so that we can pass the information
// along when we draw the tear.
- if (((!vertical && (!rtl && tab.rect.left() < 0)) || (rtl && tab.rect.right() > width()))
- || (vertical && tab.rect.top() < 0)) {
- cut = i;
- cutTab = tab;
+ QRect tabRect = d->tabList[i].rect;
+ int tabStart = vertical ? tabRect.top() : tabRect.left();
+ int tabEnd = vertical ? tabRect.bottom() : tabRect.right();
+ if (tabStart < scrollRect.left() + d->scrollOffset) {
+ cutLeft = i;
+ cutTabLeft = tab;
+ } else if (tabEnd > scrollRect.right() + d->scrollOffset) {
+ cutRight = i;
+ cutTabRight = tab;
}
+
// Don't bother drawing a tab if the entire tab is outside of the visible tab bar.
if ((!vertical && (tab.rect.right() < 0 || tab.rect.left() > width()))
|| (vertical && (tab.rect.bottom() < 0 || tab.rect.top() > height())))
@@ -1638,10 +1715,16 @@ void QTabBar::paintEvent(QPaintEvent *)
}
// Only draw the tear indicator if necessary. Most of the time we don't need too.
- if (d->leftB->isVisible() && cut >= 0) {
- cutTab.rect = rect();
- cutTab.rect = style()->subElementRect(QStyle::SE_TabBarTearIndicator, &cutTab, this);
- p.drawPrimitive(QStyle::PE_IndicatorTabTear, cutTab);
+ if (d->leftB->isVisible() && cutLeft >= 0) {
+ cutTabLeft.rect = rect();
+ cutTabLeft.rect = style()->subElementRect(QStyle::SE_TabBarTearIndicatorLeft, &cutTabLeft, this);
+ p.drawPrimitive(QStyle::PE_IndicatorTabTearLeft, cutTabLeft);
+ }
+
+ if (d->rightB->isVisible() && cutRight >= 0) {
+ cutTabRight.rect = rect();
+ cutTabRight.rect = style()->subElementRect(QStyle::SE_TabBarTearIndicatorRight, &cutTabRight, this);
+ p.drawPrimitive(QStyle::PE_IndicatorTabTearRight, cutTabRight);
}
}
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index 38a3c138cc..99b51199ed 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -150,7 +150,6 @@ public:
int calculateNewPosition(int from, int to, int index) const;
void slide(int from, int to);
void init();
- int extraWidth() const;
Tab *at(int index);
const Tab *at(int index) const;
@@ -178,6 +177,7 @@ public:
bool isTabInMacUnifiedToolbarArea() const;
void setupMovableTab();
void autoHideTabs();
+ QRect normalizedScrollRect(int index = -1);
void makeVisible(int index);
QSize iconSize;
@@ -248,7 +248,7 @@ class CloseButton : public QAbstractButton
Q_OBJECT
public:
- CloseButton(QWidget *parent = 0);
+ explicit CloseButton(QWidget *parent = 0);
QSize sizeHint() const Q_DECL_OVERRIDE;
QSize minimumSizeHint() const Q_DECL_OVERRIDE
diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp
index 2c073342b0..e88e280c16 100644
--- a/src/widgets/widgets/qtextbrowser.cpp
+++ b/src/widgets/widgets/qtextbrowser.cpp
@@ -93,7 +93,7 @@ public:
HistoryEntry createHistoryEntry() const;
- void restoreHistoryEntry(const HistoryEntry entry);
+ void restoreHistoryEntry(const HistoryEntry &entry);
QStack<HistoryEntry> stack;
QStack<HistoryEntry> forwardStack;
@@ -292,7 +292,7 @@ void QTextBrowserPrivate::setSource(const QUrl &url)
txt = data.toString();
#endif
}
- if (txt.isEmpty())
+ if (Q_UNLIKELY(txt.isEmpty()))
qWarning("QTextBrowser: No document for %s", url.toString().toLatin1().constData());
if (q->isVisible()) {
@@ -554,7 +554,7 @@ QTextBrowserPrivate::HistoryEntry QTextBrowserPrivate::createHistoryEntry() cons
return entry;
}
-void QTextBrowserPrivate::restoreHistoryEntry(const HistoryEntry entry)
+void QTextBrowserPrivate::restoreHistoryEntry(const HistoryEntry &entry)
{
setSource(entry.url);
hbar->setValue(entry.hpos);
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index 7439005b92..ba6db2971a 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -1060,6 +1060,8 @@ bool QTextEdit::event(QEvent *e)
|| e->type() == QEvent::ToolTip) {
d->sendControlEvent(e);
}
+#else
+ Q_UNUSED(d)
#endif // QT_NO_CONTEXTMENU
#ifdef QT_KEYPAD_NAVIGATION
if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) {
diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp
index 16b1115dd6..b5379f594c 100644
--- a/src/widgets/widgets/qtoolbararealayout.cpp
+++ b/src/widgets/widgets/qtoolbararealayout.cpp
@@ -1128,7 +1128,7 @@ QRect QToolBarAreaLayout::itemRect(const QList<int> &path) const
QLayoutItem *QToolBarAreaLayout::plug(const QList<int> &path)
{
QToolBarAreaLayoutItem *item = this->item(path);
- if (!item) {
+ if (Q_UNLIKELY(!item)) {
qWarning() << "No item at" << path;
return 0;
}
@@ -1260,7 +1260,7 @@ void QToolBarAreaLayout::saveState(QDataStream &stream) const
const QToolBarAreaLayoutItem &item = line.toolBarItems.at(k);
QWidget *widget = const_cast<QLayoutItem*>(item.widgetItem)->widget();
QString objectName = widget->objectName();
- if (objectName.isEmpty()) {
+ if (Q_UNLIKELY(objectName.isEmpty())) {
qWarning("QMainWindow::saveState(): 'objectName' not set for QToolBar %p '%s'",
widget, widget->windowTitle().toLocal8Bit().constData());
}
diff --git a/src/widgets/widgets/qtoolbox.cpp b/src/widgets/widgets/qtoolbox.cpp
index beb70f1283..a37747e138 100644
--- a/src/widgets/widgets/qtoolbox.cpp
+++ b/src/widgets/widgets/qtoolbox.cpp
@@ -521,10 +521,10 @@ QWidget * QToolBox::currentWidget() const
void QToolBox::setCurrentWidget(QWidget *widget)
{
int i = indexOf(widget);
- if (i >= 0)
- setCurrentIndex(i);
- else
+ if (Q_UNLIKELY(i < 0))
qWarning("QToolBox::setCurrentWidget: widget not contained in tool box");
+ else
+ setCurrentIndex(i);
}
/*!
diff --git a/src/widgets/widgets/qwidgetanimator.cpp b/src/widgets/widgets/qwidgetanimator.cpp
index 2bed11289f..3dc0e9a673 100644
--- a/src/widgets/widgets/qwidgetanimator.cpp
+++ b/src/widgets/widgets/qwidgetanimator.cpp
@@ -47,8 +47,8 @@ QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout
void QWidgetAnimator::abort(QWidget *w)
{
#ifndef QT_NO_ANIMATION
- AnimationMap::iterator it = m_animation_map.find(w);
- if (it == m_animation_map.end())
+ const auto it = m_animation_map.constFind(w);
+ if (it == m_animation_map.cend())
return;
QPropertyAnimation *anim = *it;
m_animation_map.erase(it);
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 436937be72..42cd51eca7 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -147,10 +147,7 @@ void QWidgetLineControl::copy(QClipboard::Mode mode) const
{
QString t = selectedText();
if (!t.isEmpty() && m_echoMode == QLineEdit::Normal) {
- disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), this, 0);
QApplication::clipboard()->setText(t, mode);
- connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
- this, SLOT(_q_clipboardChanged()));
}
}
@@ -309,7 +306,7 @@ void QWidgetLineControl::setSelection(int start, int length)
{
commitPreedit();
- if(start < 0 || start > (int)m_text.length()){
+ if (Q_UNLIKELY(start < 0 || start > m_text.size())) {
qWarning("QWidgetLineControl::setSelection: Invalid start position");
return;
}
@@ -339,10 +336,6 @@ void QWidgetLineControl::setSelection(int start, int length)
emitCursorPositionChanged();
}
-void QWidgetLineControl::_q_clipboardChanged()
-{
-}
-
void QWidgetLineControl::_q_deleteSelected()
{
if (!hasSelectedText())
@@ -1523,14 +1516,7 @@ void QWidgetLineControl::timerEvent(QTimerEvent *event)
#ifndef QT_NO_SHORTCUT
void QWidgetLineControl::processShortcutOverrideEvent(QKeyEvent *ke)
{
- if (isReadOnly())
- return;
-
if (ke == QKeySequence::Copy
- || ke == QKeySequence::Paste
- || ke == QKeySequence::Cut
- || ke == QKeySequence::Redo
- || ke == QKeySequence::Undo
|| ke == QKeySequence::MoveToNextWord
|| ke == QKeySequence::MoveToPreviousWord
|| ke == QKeySequence::MoveToEndOfLine
@@ -1544,22 +1530,35 @@ void QWidgetLineControl::processShortcutOverrideEvent(QKeyEvent *ke)
|| ke == QKeySequence::SelectEndOfBlock
|| ke == QKeySequence::SelectStartOfDocument
|| ke == QKeySequence::SelectAll
- || ke == QKeySequence::SelectEndOfDocument
- || ke == QKeySequence::DeleteCompleteLine) {
+ || ke == QKeySequence::SelectEndOfDocument) {
ke->accept();
+ } else if (ke == QKeySequence::Paste
+ || ke == QKeySequence::Cut
+ || ke == QKeySequence::Redo
+ || ke == QKeySequence::Undo
+ || ke == QKeySequence::DeleteCompleteLine) {
+ if (!isReadOnly())
+ ke->accept();
} else if (ke->modifiers() == Qt::NoModifier || ke->modifiers() == Qt::ShiftModifier
|| ke->modifiers() == Qt::KeypadModifier) {
if (ke->key() < Qt::Key_Escape) {
- ke->accept();
+ if (!isReadOnly())
+ ke->accept();
} else {
switch (ke->key()) {
case Qt::Key_Delete:
+ case Qt::Key_Backspace:
+ if (!isReadOnly())
+ ke->accept();
+ break;
+
case Qt::Key_Home:
case Qt::Key_End:
- case Qt::Key_Backspace:
case Qt::Key_Left:
case Qt::Key_Right:
ke->accept();
+ break;
+
default:
break;
}
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index 039453f0d5..1ba7e659f6 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -535,7 +535,6 @@ protected:
virtual void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
private Q_SLOTS:
- void _q_clipboardChanged();
void _q_deleteSelected();
private:
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index deca002bf5..1c249eee78 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -2401,8 +2401,8 @@ void QWidgetTextControl::setExtraSelections(const QList<QTextEdit::ExtraSelectio
for (int i = 0; i < selections.count(); ++i) {
const QTextEdit::ExtraSelection &sel = selections.at(i);
- QHash<int, int>::iterator it = hash.find(sel.cursor.anchor());
- if (it != hash.end()) {
+ const auto it = hash.constFind(sel.cursor.anchor());
+ if (it != hash.cend()) {
const QAbstractTextDocumentLayout::Selection &esel = d->extraSelections.at(it.value());
if (esel.cursor.position() == sel.cursor.position()
&& esel.format == sel.format) {
diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp
index 97a3b070d8..09504a8022 100644
--- a/src/xml/sax/qxml.cpp
+++ b/src/xml/sax/qxml.cpp
@@ -75,6 +75,14 @@
QT_BEGIN_NAMESPACE
+namespace {
+
+// work around missing std::stack::clear()
+template <typename Container>
+void clear(Container &c) { c = Container(); }
+
+}
+
// the constants for the lookup table
static const signed char cltWS = 0; // white space
static const signed char cltPer = 1; // %
@@ -3197,7 +3205,7 @@ bool QXmlSimpleReader::parse(const QXmlInputSource *input, bool incremental)
d->contentHnd->setDocumentLocator(d->locator.data());
if (!d->contentHnd->startDocument()) {
d->reportParseError(d->contentHnd->errorString());
- d->tags.clear();
+ clear(d->tags);
return false;
}
}
@@ -3253,7 +3261,7 @@ bool QXmlSimpleReaderPrivate::parseBeginOrContinue(int state, bool incremental)
pushParseState(0, 0);
return true;
} else {
- tags.clear();
+ clear(tags);
return false;
}
}
@@ -3265,7 +3273,7 @@ bool QXmlSimpleReaderPrivate::parseBeginOrContinue(int state, bool incremental)
pushParseState(0, 1);
return true;
} else {
- tags.clear();
+ clear(tags);
return false;
}
}
@@ -3278,7 +3286,7 @@ bool QXmlSimpleReaderPrivate::parseBeginOrContinue(int state, bool incremental)
pushParseState(0, 2);
return true;
} else {
- tags.clear();
+ clear(tags);
return false;
}
}
@@ -3289,9 +3297,9 @@ bool QXmlSimpleReaderPrivate::parseBeginOrContinue(int state, bool incremental)
return true;
}
// is stack empty?
- if (!tags.isEmpty() && !error.isNull()) {
+ if (!tags.empty() && !error.isNull()) {
reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF));
- tags.clear();
+ clear(tags);
return false;
}
// call the handler
@@ -3697,16 +3705,15 @@ bool QXmlSimpleReaderPrivate::parseElement()
case STagEnd:
// call the handler
if (contentHnd) {
- const QString &tagsTop = tags.top();
if (useNamespaces) {
QString uri, lname;
- namespaceSupport.processName(tagsTop, false, uri, lname);
- if (!contentHnd->startElement(uri, lname, tagsTop, attList)) {
+ namespaceSupport.processName(tags.top(), false, uri, lname);
+ if (!contentHnd->startElement(uri, lname, tags.top(), attList)) {
reportParseError(contentHnd->errorString());
return false;
}
} else {
- if (!contentHnd->startElement(QString(), QString(), tagsTop, attList)) {
+ if (!contentHnd->startElement(QString(), QString(), tags.top(), attList)) {
reportParseError(contentHnd->errorString());
return false;
}
@@ -3732,7 +3739,7 @@ bool QXmlSimpleReaderPrivate::parseElement()
}
break;
case EmptyTag:
- if (tags.isEmpty()) {
+ if (tags.empty()) {
reportParseError(QLatin1String(XMLERR_TAGMISMATCH));
return false;
}
@@ -3773,7 +3780,9 @@ bool QXmlSimpleReaderPrivate::processElementEmptyTag()
return false;
}
// ... followed by endElement...
- if (!contentHnd->endElement(uri, lname, tags.pop())) {
+ const bool endElementReturnedFalse = !contentHnd->endElement(uri, lname, tags.top());
+ tags.pop();
+ if (endElementReturnedFalse) {
reportParseError(contentHnd->errorString());
return false;
}
@@ -3800,13 +3809,15 @@ bool QXmlSimpleReaderPrivate::processElementEmptyTag()
return false;
}
// ... followed by endElement
- if (!contentHnd->endElement(QString(), QString(), tags.pop())) {
+ const bool endElementReturnedFalse = !contentHnd->endElement(QString(), QString(), tags.top());
+ tags.pop();
+ if (endElementReturnedFalse) {
reportParseError(contentHnd->errorString());
return false;
}
}
} else {
- tags.pop_back();
+ tags.pop();
namespaceSupport.popContext();
}
return true;
@@ -3820,7 +3831,9 @@ bool QXmlSimpleReaderPrivate::processElementETagBegin2()
const QString &name = QXmlSimpleReaderPrivate::name();
// pop the stack and compare it with the name
- if (tags.pop() != name) {
+ const bool nameIsTagsTop = tags.top() == name;
+ tags.pop();
+ if (!nameIsTagsTop) {
reportParseError(QLatin1String(XMLERR_TAGMISMATCH));
return false;
}
@@ -7839,7 +7852,7 @@ void QXmlSimpleReaderPrivate::init(const QXmlInputSource *i)
externEntities.clear();
entities.clear();
- tags.clear();
+ clear(tags);
doctype.clear();
xmlVersion.clear();
diff --git a/src/xml/sax/qxml_p.h b/src/xml/sax/qxml_p.h
index 013c2618a3..275f61a1f3 100644
--- a/src/xml/sax/qxml_p.h
+++ b/src/xml/sax/qxml_p.h
@@ -38,6 +38,8 @@
#include <qmap.h>
#include <qxml.h>
+#include <stack>
+
QT_BEGIN_NAMESPACE
//
@@ -61,7 +63,7 @@ private:
void initIncrementalParsing();
// used to determine if elements are correctly nested
- QStack<QString> tags;
+ std::stack<QString, QStringList> tags;
// used by parseReference() and parsePEReference()
enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };